📄 ccminvokers_cpu.s
字号:
mov TEMP, #0 mcr p15, 0, TEMP, c7, c10, 5 /* memory barrier. */#endif /* Release the microlock: */ str TEMP2, [MICROLOCK] /* Check if the lockrec is the first one on the thread's owned list: */ cmp r3, LOCKREC bne _fastTryUnlockFindPrevLockRecordLoop /* Remove the lockrec from the ee's owned list: */ ldr TEMP, [LOCKREC, #OFFSET_CVMOwnedMonitor_next] /* INVARIANT: All branches and fallthroughs to * _fastTryUnlockAddLockRecordToFreeList must set up r3 to be * ee->objLocksFreeOwned first */ ldr r3, [EE, #OFFSET_CVMExecEnv_objLocksFreeOwned] str TEMP, [EE, #OFFSET_CVMExecEnv_objLocksOwned]LABEL(_fastTryUnlockAddLockRecordToFreeList) /* Add the lockrec to the ee's free list: */ str r3, [LOCKREC, #OFFSET_CVMOwnedMonitor_next] str LOCKREC, [EE, #OFFSET_CVMExecEnv_objLocksFreeOwned] /* Fall through to _fastTryUnlockDone */LABEL(_fastTryUnlockDone)#ifdef CVM_TRACE /* Do trace method return: */ mov r1, JFP ldr r0, [sp, #OFFSET_CVMCCExecEnv_ee] bl SYM_NAME(CCMtraceMethodReturn)#endif /* Restore the previous JFP: * Returning from one compiled method to another. * This, we can do ourselves. * Note: The Java SP is already set. */ and JFP, PREV, #~CONSTANT_CVM_FRAME_MASK_ALL#ifdef CVMCPU_HAS_CP_REG ldr CVMARM_CP_REGNAME, [JFP, #OFFSET_CVMCompiledFrame_cpBaseRegX]#endif ldr pc, [JFP, #OFFSET_CVMCompiledFrame_PC] /* Return to caller. */ /* End. */#define PREV_REC r3LABEL(_fastTryUnlockFindPrevLockRecordLoop) ldr r2, [PREV_REC, #OFFSET_CVMOwnedMonitor_next] cmp r2, LOCKREC beq _fastTryUnlockFoundPrevLockRecord mov PREV_REC, r2 b _fastTryUnlockFindPrevLockRecordLoopLABEL(_fastTryUnlockFoundPrevLockRecord) /* Remove the lockrec from the ee's owned list: */ ldr r2, [LOCKREC, #OFFSET_CVMOwnedMonitor_next] str r2, [PREV_REC, #OFFSET_CVMOwnedMonitor_next]#undef PREV_REC /* Satisfy invariant at _fastTryUnlockAddLockRecordToFreeList */ ldr r3, [EE, #OFFSET_CVMExecEnv_objLocksFreeOwned] b _fastTryUnlockAddLockRecordToFreeListLABEL(_fastTryUnlockSuccess) /* Set the new re-entry count: */ /* Decremented before we got here */ str TEMP, [LOCKREC, #OFFSET_CVMOwnedMonitor_count] /* Release the microlock: */ mov TEMP, #CVM_MICROLOCK_UNLOCKED str TEMP, [MICROLOCK] b _fastTryUnlockDoneLABEL(_fastUnlockAcquireMicrolock) /* Call a C function to acquire the microlock: */ mov r0, MICROLOCK CALL_VM_FUNCTION(CVMmicrolockLockImpl) /* Restore the ee and obj pointer: */ ldr EE, [sp, #OFFSET_CVMCCExecEnv_ee] ldr OBJ, [JFP, #OFFSET_CVMCompiledFrame_receiverObjX] ldr LOCKREC, [OBJ, #OFFSET_CVMObjectHeader_various32] /* Get obits.*/ b _unlockObj /* Go unlock the object if possible. */LABEL(_fastTryUnlockFailed) /* Release the microlock: */ mov r3, #CVM_MICROLOCK_UNLOCKED str r3, [MICROLOCK] /* Let the interpreter handle the hard cases: */ b returnToInterpreter#undef EE#undef OBJ#undef MICROLOCK#undef LOCKREC SET_SIZE( CVMCCMreturnFromSyncMethod )#undef TEMP#undef TEMP2#undef ORIG_LR/* Support for fastlocking with atomic ops */#elif CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPS/* * Native code doing a synchronized return comes here. * * CVMMethodBlock* * CVMCCMreturnFromSyncMethod(); */ ENTRY(CVMCCMreturnFromSyncMethod) ; GC check - gc will patch at this location when a rendezvous is ; needed. See ccmGcPatchPoints in jitinit_cpu.c. The patch will ; be a "b CVMARMhandleGCForReturnFromSyncMethod" /* r0 = a1 = ee r1 = a2 = obj r4 = v1 = JFP r5 = v2 = JSP r7 = v4 = PREV *//* TODO: This CVMCCMreturnFromSyncMethod code has not undergone thorough multi-threaded stress testing yet. It needs to undergo stress testing before release. */#if 0 ; ; If you just want to call the C helper and write very little assembler ; code, then just to branch to (and implement) returnToInterpreter. ; b returnToInterpreter#endif#define EE r8#define OBJ r1#define OWNEDREC r11#define EXPECTED_CNT r10#define TEMP r3#define TEMP2 ip ; ; see if previous frame is compiled or not ; PREV is set up by all code that branches here ; tst PREV, #CONSTANT_CVM_FRAME_MASK_SLOW bne returnToInterpreter /* Do fastTryUnlock(): */ ldr EE, [sp, #OFFSET_CVMCCExecEnv_ee] ldr OBJ, [JFP, #OFFSET_CVMCompiledFrame_receiverObjX] /* Check to see if the object is locked with a fastlock: */ ldr OWNEDREC, [OBJ, #OFFSET_CVMObjectHeader_various32] /* obits */ tst OWNEDREC, #0x3 /* (obits & 0x3) == CVM_LOCKSTATE_LOCKED? */ bne _fastTryUnlockFailed /* If not, we failed. */ /* If the OWNEDREC is NULL, it is currently being inflated */ cmp OWNEDREC, #0 beq _fastTryUnlockFailed /* If we get here, then the object is locked with a fastlock: */ /* Make sure that the current thread owns the monitor: */ ldr TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_owner] cmp TEMP, EE bne _fastTryUnlockFailed /* If not owner, we failed. */ /* If we get here, then the current thread does own the monitor, and all is well. Proceed with unlocking: */ ldr EXPECTED_CNT, [OWNEDREC, #OFFSET_CVMOwnedMonitor_count] cmp EXPECTED_CNT, #CONSTANT_CVM_INVALID_REENTRY_COUNT beq _fastTryUnlockFailed#define ACTUAL_CNT r0#define NEW_COUNT r2 subs NEW_COUNT, EXPECTED_CNT, #1 beq _doUnlock /* If zero, then unlock */ ; new monitor count > 0, so just update it and we're done: add r0, OWNEDREC, #OFFSET_CVMOwnedMonitor_count mov r1, EXPECTED_CNT ; r2 has already has NEW_COUNT. /* NOTE: We don't need the value of the lr register. Hence, we don't need to save and restore it around this call: */ CALL_VM_FUNCTION(InterlockedTestExchange) cmp ACTUAL_CNT, EXPECTED_CNT /* ACTUAL_CNT is in r0. */ bne _fastTryUnlockFailed /* Go slow way. */ ; we're done! monitor count was successfully decrement b _fastTryUnlockDone /* End. */#undef ACTUAL_CNT#undef NEW_COUNT_doUnlock#define ACTUAL_BITS r0#define EXPECTED_BITS OWNEDREC#define NEW_BITS r2 /* If we get here, then the re-entry count has reached 0. */ ; Restore the obits to the object header: ldr NEW_BITS, [OWNEDREC, #OFFSET_CVMOwnedMonitor_u_fast_bits] add r0, OBJ, #OFFSET_CVMObjectHeader_various32 mov r1, EXPECTED_BITS ; r2 already has NEW_BITS. /* NOTE: We don't need the value of the lr register. Hence, we don't need to save and restore it around this call: */ CALL_VM_FUNCTION(InterlockedTestExchange) cmp ACTUAL_BITS, EXPECTED_BITS /* ACTUAL_BITS is in r0. */ bne _fastTryUnlockFailed /* Go slow way. */#undef ACTUAL_BITS#undef EXPECTED_BITS#undef NEW_BITS#ifdef CVM_DEBUG ; Make the ownedRec play nice with the debug assertions: mov TEMP, #CONSTANT_CVM_OWNEDMON_FREE str TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_state] mov TEMP, #0 str TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_u_fast_bits] str TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_object] str TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_count]#endif ; Check if the ownedRec is the first one on the thread's owned list: ldr TEMP, [EE, #OFFSET_CVMExecEnv_objLocksOwned] cmp TEMP, OWNEDREC bne _fastTryUnlockFindPrevLockRecord ; Remove the ownedRec from the ee's owned list: ldr TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_next] str TEMP, [EE, #OFFSET_CVMExecEnv_objLocksOwned]_fastTryUnlockAddLockRecordToFreeList ; Add the lockrec to the ee's free list: ldr TEMP, [EE, #OFFSET_CVMExecEnv_objLocksFreeOwned] str TEMP, [OWNEDREC, #OFFSET_CVMOwnedMonitor_next] str OWNEDREC, [EE, #OFFSET_CVMExecEnv_objLocksFreeOwned] /* Fall thru to _fastTryUnlockDone below: */_fastTryUnlockDone ; we're done! lock was successfully released#ifdef CVM_TRACE ; Do trace method return mov r1, JFP ldr r0, [sp, #OFFSET_CVMCCExecEnv_ee] bl CCMtraceMethodReturn#endif ; Restore the previous JFP ; Returning from one compiled method to another. ; This, we can do ourselves. ; Note: The Java SP is already set. and JFP, PREV, #~CONSTANT_CVM_FRAME_MASK_ALL#ifdef CVMCPU_HAS_CP_REG ldr CVMARM_CP_REGNAME, [JFP, #OFFSET_CVMCompiledFrame_cpBaseRegX]#endif ldr pc, [JFP, #OFFSET_CVMCompiledFrame_PC] ; Return to caller./* NOTE: PREV_REC must be TEMP because the following code depends on TEMP containing the initial value of PREV_REC before branching here: */#define PREV_REC TEMP_fastTryUnlockFindPrevLockRecord ldr TEMP2, [PREV_REC, #OFFSET_CVMOwnedMonitor_next] cmp TEMP2, OWNEDREC beq _fastTryUnlockFoundPrevLockRecord mov PREV_REC, TEMP2 b _fastTryUnlockFindPrevLockRecord_fastTryUnlockFoundPrevLockRecord ; Remove the lockrec from the ee's owned list: ldr TEMP2, [OWNEDREC, #OFFSET_CVMOwnedMonitor_next] str TEMP2, [PREV_REC, #OFFSET_CVMOwnedMonitor_next] b _fastTryUnlockAddLockRecordToFreeList#undef PREV_REC_fastTryUnlockFailed ; Let the interpreter handle the hard cases: b returnToInterpreter#undef EE#undef OBJ#undef OWNEDREC#undef EXPECTED_CNT#undef TEMP#undef TEMP2 SET_SIZE( CVMCCMreturnFromSyncMethod )#else#error unsupported CVM_FASTLOCK_TYPE or CVM_MICROLOCK_TYPE#endif #ifdef CVM_TRACE ENTRY(CVMCCMtraceMethodCallGlue)ENTRY1(CVMCCMtraceMethodCallGlue)/* IAI-04 */#ifdef IAI_CACHE_GLOBAL_VARIABLES_IN_WMMX textrmuw ip, W_CVMGLOBALS, #0#else ldr ip, SYMBOL(CVMglobals)#endif ldr ip, [ip, #OFFSET_CVMGlobalState_debugFlags] tst ip, #CONSTANT_TRACE_METHOD streq lr, [JFP, #OFFSET_CVMCompiledFrame_PC] moveq pc, lr#define SAVESET {r0, r1, lr} FIXUP_FRAMES(JFP, SAVESET, 3)#undef SAVESET mov r2, #0 /* isJump */ BRANCH_TO_VM_FUNCTION(CVMtraceMethodCall) SET_SIZE(CVMCCMtraceMethodCallGlue) ENTRY(CCMtraceMethodReturn)ENTRY1(CCMtraceMethodReturn)/* IAI-04 */#ifdef IAI_CACHE_GLOBAL_VARIABLES_IN_WMMX textrmuw ip, W_CVMGLOBALS, #0#else ldr ip, SYMBOL(CVMglobals)#endif ldr ip, [ip, #OFFSET_CVMGlobalState_debugFlags] tst ip, #CONSTANT_TRACE_METHOD moveq pc, lr#define SAVESET {r0, r1, lr} FIXUP_FRAMES(JFP, SAVESET, 3)#undef SAVESET BRANCH_TO_VM_FUNCTION(CVMtraceMethodReturn) SET_SIZE(CCMtraceMethodReturn) ENTRY(CCMtraceFramelessMethodCall)ENTRY1(CCMtraceFramelessMethodCall)/* IAI-04 */#ifdef IAI_CACHE_GLOBAL_VARIABLES_IN_WMMX textrmuw ip, W_CVMGLOBALS, #0#else ldr ip, SYMBOL(CVMglobals)#endif ldr ip, [ip, #OFFSET_CVMGlobalState_debugFlags] tst ip, #CONSTANT_TRACE_METHOD moveq pc, lr mov r3, #0 /* isJump */ BRANCH_TO_VM_FUNCTION(CVMtraceFramelessMethodCall) SET_SIZE(CCMtraceFramelessMethodCall) ENTRY(CCMtraceFramelessMethodReturn)ENTRY1(CCMtraceFramelessMethodReturn)/* IAI-04 */#ifdef IAI_CACHE_GLOBAL_VARIABLES_IN_WMMX textrmuw ip, W_CVMGLOBALS, #0#else ldr ip, SYMBOL(CVMglobals)#endif ldr ip, [ip, #OFFSET_CVMGlobalState_debugFlags] tst ip, #CONSTANT_TRACE_METHOD moveq pc, lr BRANCH_TO_VM_FUNCTION(CVMtraceFramelessMethodReturn) SET_SIZE(CCMtraceFramelessMethodReturn)#endif /* CVM_TRACE */ POOL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -