Changeset 37831 in webkit for trunk/JavaScriptCore/VM/CTI.cpp
- Timestamp:
- Oct 23, 2008, 3:29:54 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CTI.cpp
r37812 r37831 514 514 , m_codeBlock(codeBlock) 515 515 , m_labels(codeBlock ? codeBlock->instructions.size() : 0) 516 , m_structureStubCompilationInfo(codeBlock ? codeBlock->structureIDInstructions.size() : 0) 516 , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->propertyAccessInstructions.size() : 0) 517 , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->callLinkInfos.size() : 0) 517 518 { 518 519 } … … 577 578 } 578 579 579 void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned structureIDInstructionIndex, CompileOpCallType type)580 void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned callLinkInfoIndex, CompileOpCallType type) 580 581 { 581 582 int dst = instruction[1].u.operand; … … 615 616 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 616 617 ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck, m_jit.label()) == repatchOffsetOpCallCall); 617 m_ structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = addressOfLinkedFunctionCheck;618 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; 618 619 619 620 // The following is the fast case, only used whan a callee can be linked. … … 639 640 640 641 // Call to the callee 641 m_ structureStubCompilationInfo[structureIDInstructionIndex].hotPathOther = emitNakedCall(i, unreachable);642 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(i, unreachable); 642 643 643 644 if (type == OpCallEval) … … 950 951 unsigned instructionCount = m_codeBlock->instructions.size(); 951 952 952 unsigned structureIDInstructionIndex = 0; 953 unsigned propertyAccessInstructionIndex = 0; 954 unsigned callLinkInfoIndex = 0; 953 955 954 956 for (unsigned i = 0; i < instructionCount; ) { … … 1095 1097 emitGetArg(instruction[i + 3].u.operand, X86::edx); 1096 1098 1097 ASSERT(m_codeBlock-> structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);1099 ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i); 1098 1100 X86Assembler::JmpDst hotPathBegin = m_jit.label(); 1099 m_ structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;1100 ++ structureIDInstructionIndex;1101 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; 1102 ++propertyAccessInstructionIndex; 1101 1103 1102 1104 // Jump to a slow case if either the base object is an immediate, or if the StructureID does not match. … … 1123 1125 emitGetArg(instruction[i + 2].u.operand, X86::eax); 1124 1126 1125 ASSERT(m_codeBlock-> structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);1127 ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i); 1126 1128 1127 1129 X86Assembler::JmpDst hotPathBegin = m_jit.label(); 1128 m_ structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;1129 ++ structureIDInstructionIndex;1130 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; 1131 ++propertyAccessInstructionIndex; 1130 1132 1131 1133 emitJumpSlowCaseIfNotJSCell(X86::eax, i); … … 1253 1255 } 1254 1256 case op_call: { 1255 compileOpCall(instruction + i, i, structureIDInstructionIndex++);1257 compileOpCall(instruction + i, i, callLinkInfoIndex++); 1256 1258 i += 7; 1257 1259 break; … … 1349 1351 } 1350 1352 case op_construct: { 1351 compileOpCall(instruction + i, i, structureIDInstructionIndex++, OpConstruct);1353 compileOpCall(instruction + i, i, callLinkInfoIndex++, OpConstruct); 1352 1354 i += 7; 1353 1355 break; … … 1491 1493 m_jit.movl_mr(structureIDAddr, X86::edx); 1492 1494 m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSCell, m_structureID), X86::eax); 1493 X86Assembler::JmpSrc slowCase = m_jit.emitUnlinkedJne(); // StructureIDs don't match 1494 m_slowCases.append(SlowCaseEntry(slowCase, i)); 1495 X86Assembler::JmpSrc noMatch = m_jit.emitUnlinkedJne(); // StructureIDs don't match 1495 1496 1496 1497 // Load cached property … … 1502 1503 1503 1504 // Slow case 1504 m_jit.link( slowCase, m_jit.label());1505 m_jit.link(noMatch, m_jit.label()); 1505 1506 emitPutArgConstant(globalObject, 0); 1506 1507 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); … … 1510 1511 m_jit.link(end, m_jit.label()); 1511 1512 i += 6; 1512 ++structureIDInstructionIndex;1513 1513 break; 1514 1514 } … … 1842 1842 } 1843 1843 case op_call_eval: { 1844 compileOpCall(instruction + i, i, structureIDInstructionIndex++, OpCallEval);1844 compileOpCall(instruction + i, i, callLinkInfoIndex++, OpCallEval); 1845 1845 i += 7; 1846 1846 break; … … 2193 2193 } 2194 2194 2195 ASSERT(structureIDInstructionIndex == m_codeBlock->structureIDInstructions.size()); 2195 ASSERT(propertyAccessInstructionIndex == m_codeBlock->propertyAccessInstructions.size()); 2196 ASSERT(callLinkInfoIndex == m_codeBlock->callLinkInfos.size()); 2196 2197 } 2197 2198 … … 2218 2219 void CTI::privateCompileSlowCases() 2219 2220 { 2220 unsigned structureIDInstructionIndex = 0; 2221 unsigned propertyAccessInstructionIndex = 0; 2222 unsigned callLinkInfoIndex = 0; 2221 2223 2222 2224 Instruction* instruction = m_codeBlock->instructions.begin(); … … 2362 2364 2363 2365 // Track the location of the call; this will be used to recover repatch information. 2364 ASSERT(m_codeBlock-> structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);2365 m_ structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;2366 ++ structureIDInstructionIndex;2366 ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i); 2367 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call; 2368 ++propertyAccessInstructionIndex; 2367 2369 2368 2370 i += 8; … … 2390 2392 2391 2393 // Track the location of the call; this will be used to recover repatch information. 2392 ASSERT(m_codeBlock-> structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);2393 m_ structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;2394 ++ structureIDInstructionIndex;2394 ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i); 2395 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call; 2396 ++propertyAccessInstructionIndex; 2395 2397 2396 2398 i += 8; 2397 break;2398 }2399 case op_resolve_global: {2400 ++structureIDInstructionIndex;2401 i += 6;2402 2399 break; 2403 2400 } … … 2711 2708 2712 2709 // Try to link & repatch this call. 2713 m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = 2710 CallLinkInfo* info = &(m_codeBlock->callLinkInfos[callLinkInfoIndex]); 2711 emitPutArgConstant(reinterpret_cast<unsigned>(info), 4); 2712 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = 2714 2713 emitCTICall(i, Machine::cti_vm_lazyLinkCall); 2715 2714 emitNakedCall(i, X86::eax); … … 2717 2716 2718 2717 // This is the address for the cold path *after* the first run (which tries to link the call). 2719 m_ structureStubCompilationInfo[structureIDInstructionIndex].coldPathOther = m_jit.label();2718 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = m_jit.label(); 2720 2719 2721 2720 // The arguments have been set up on the hot path for op_call_eval … … 2764 2763 emitPutResult(dst); 2765 2764 2766 ++ structureIDInstructionIndex;2765 ++callLinkInfoIndex; 2767 2766 i += 7; 2768 2767 break; … … 2788 2787 } 2789 2788 2790 ASSERT(structureIDInstructionIndex == m_codeBlock->structureIDInstructions.size()); 2789 ASSERT(propertyAccessInstructionIndex == m_codeBlock->propertyAccessInstructions.size()); 2790 ASSERT(callLinkInfoIndex == m_codeBlock->callLinkInfos.size()); 2791 2791 } 2792 2792 … … 2867 2867 X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target); 2868 2868 2869 for (unsigned i = 0; i < m_codeBlock->structureIDInstructions.size(); ++i) { 2870 StructureStubInfo& info = m_codeBlock->structureIDInstructions[i]; 2871 info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].callReturnLocation); 2872 info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].hotPathBegin); 2873 info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].hotPathOther); 2874 info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].coldPathOther); 2869 for (unsigned i = 0; i < m_codeBlock->propertyAccessInstructions.size(); ++i) { 2870 StructureStubInfo& info = m_codeBlock->propertyAccessInstructions[i]; 2871 info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].callReturnLocation); 2872 info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].hotPathBegin); 2873 } 2874 for (unsigned i = 0; i < m_codeBlock->callLinkInfos.size(); ++i) { 2875 CallLinkInfo& info = m_codeBlock->callLinkInfos[i]; 2876 info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].callReturnLocation); 2877 info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathBegin); 2878 info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathOther); 2879 info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].coldPathOther); 2875 2880 } 2876 2881 … … 3155 3160 } 3156 3161 3157 void CTI::unlinkCall( StructureStubInfo* structureStubInfo)3162 void CTI::unlinkCall(CallLinkInfo* callLinkInfo) 3158 3163 { 3159 3164 // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid 3160 3165 // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive 3161 3166 // match). Reset the check so it no longer matches. 3162 reinterpret_cast<void**>(structureStubInfo->hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue()); 3163 } 3164 3165 void CTI::linkCall(CodeBlock* callerCodeBlock, JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, void* returnAddress, int callerArgCount) 3166 { 3167 StructureStubInfo& stubInfo = callerCodeBlock->getStubInfo(returnAddress); 3168 3167 reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue()); 3168 } 3169 3170 void CTI::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount) 3171 { 3169 3172 // Currently we only link calls with the exact number of arguments. 3170 3173 if (callerArgCount == calleeCodeBlock->numParameters) { 3171 ASSERT(! stubInfo.linkInfoPtr);3174 ASSERT(!callLinkInfo->isLinked()); 3172 3175 3173 calleeCodeBlock->addCaller( &stubInfo);3176 calleeCodeBlock->addCaller(callLinkInfo); 3174 3177 3175 reinterpret_cast<void**>( stubInfo.hotPathBegin)[-1] = callee;3176 ctiRepatchCallByReturnAddress( stubInfo.hotPathOther, ctiCode);3178 reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = callee; 3179 ctiRepatchCallByReturnAddress(callLinkInfo->hotPathOther, ctiCode); 3177 3180 } 3178 3181 3179 3182 // repatch the instruction that jumps out to the cold path, so that we only try to link once. 3180 void* repatchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>( stubInfo.hotPathBegin) + repatchOffsetOpCallCall);3181 ctiRepatchCallByReturnAddress(repatchCheck, stubInfo.coldPathOther);3183 void* repatchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + repatchOffsetOpCallCall); 3184 ctiRepatchCallByReturnAddress(repatchCheck, callLinkInfo->coldPathOther); 3182 3185 } 3183 3186
Note:
See TracChangeset
for help on using the changeset viewer.