Changeset 47597 in webkit
- Timestamp:
- Aug 20, 2009, 2:49:07 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r47592 r47597 1 2009-08-20 Gavin Barraclough <[email protected]> 2 3 Reviewed by Oliver Hunt. 4 5 Remove FunctionCodeBlock. 6 https://bugs.webkit.org/show_bug.cgi?id=28502 7 8 These only exist to allow JIT code to dereference properties off the 9 CodeBlock for any callee, regardless of whether it is a host function. 10 11 Instead just use the FunctionExecutable. Copy the m_parameters field 12 from the CodeBlock into the Executable, and use this to distinguish 13 between host functions, functions that have been bytecompiled, and 14 functions that have not. 15 16 m_parameters is moved to ExecutableBase rather than FunctionExecutable 17 so that (as a separate change) we can move make a separate class of 18 executable for host code, which is not devived from FunctionExecutable 19 (host code does not feature any of the properties that normal executable 20 do and will provide, such as source, attributes, and a parsed name). 21 22 1% win on v8 tests, 0.5% on sunspider. 23 24 * bytecode/CodeBlock.cpp: 25 (JSC::CodeBlock::derefStructures): 26 (JSC::CodeBlock::refStructures): 27 (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): 28 (JSC::CodeBlock::handlerForBytecodeOffset): 29 (JSC::CodeBlock::lineNumberForBytecodeOffset): 30 (JSC::CodeBlock::expressionRangeForBytecodeOffset): 31 (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset): 32 (JSC::CodeBlock::functionRegisterForBytecodeOffset): 33 (JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset): 34 (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset): 35 * bytecode/CodeBlock.h: 36 (JSC::): 37 (JSC::CodeBlock::source): 38 (JSC::CodeBlock::sourceOffset): 39 (JSC::CodeBlock::evalCodeCache): 40 (JSC::CodeBlock::createRareDataIfNecessary): 41 42 remove NativeCodeBlocks and the NativeCode code type. 43 44 * jit/JIT.cpp: 45 (JSC::JIT::linkCall): 46 47 Revert to previous behaviour (as currently still commented!) that Hhost functions have a null codeblock. 48 49 * jit/JITCall.cpp: 50 (JSC::JIT::compileOpCallInitializeCallFrame): 51 (JSC::JIT::compileOpCallSetupArgs): 52 (JSC::JIT::compileOpCallVarargsSetupArgs): 53 (JSC::JIT::compileOpConstructSetupArgs): 54 (JSC::JIT::compileOpCallVarargs): 55 (JSC::JIT::compileOpCall): 56 (JSC::JIT::compileOpCallSlowCase): 57 58 Bring the 32_64 & non-32_64 JITs into line with each other, callee in regT0. 59 60 * jit/JITOpcodes.cpp: 61 (JSC::JIT::privateCompileCTIMachineTrampolines): 62 63 Rewrite call trampolines to not use the CodeBlock. 64 65 * jit/JITStubs.cpp: 66 (JSC::DEFINE_STUB_FUNCTION): 67 68 Make call_JSFunction & call_arityCheck return the callee, don't expect to be passed the CodeBlock. 69 70 * runtime/Executable.cpp: 71 (JSC::FunctionExecutable::generateBytecode): 72 (JSC::FunctionExecutable::recompile): 73 (JSC::FunctionExecutable::FunctionExecutable): 74 * runtime/Executable.h: 75 (JSC::ExecutableBase::): 76 (JSC::ExecutableBase::ExecutableBase): 77 (JSC::FunctionExecutable::isHostFunction): 78 79 Add m_numParameters. 80 81 * runtime/JSFunction.cpp: 82 (JSC::JSFunction::~JSFunction): 83 84 Only call generatedBytecode() on JSFunctions non-host FunctionExecutables. 85 1 86 2009-08-20 Yongjun Zhang <[email protected]> 2 87 -
trunk/JavaScriptCore/bytecode/CodeBlock.cpp
r47412 r47597 1249 1249 } 1250 1250 1251 CodeBlock::CodeBlock(ExecutableBase* ownerExecutable)1252 : m_numCalleeRegisters(0)1253 , m_numVars(0)1254 , m_numParameters(0)1255 , m_ownerExecutable(ownerExecutable)1256 , m_globalData(0)1257 #ifndef NDEBUG1258 , m_instructionCount(0)1259 #endif1260 , m_needsFullScopeChain(false)1261 , m_usesEval(false)1262 , m_isNumericCompareFunction(false)1263 , m_codeType(NativeCode)1264 , m_source(0)1265 , m_sourceOffset(0)1266 , m_exceptionInfo(0)1267 {1268 #if DUMP_CODE_BLOCK_STATISTICS1269 liveCodeBlockSet.add(this);1270 #endif1271 }1272 1273 1251 CodeBlock::CodeBlock(ExecutableBase* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) 1274 1252 : m_numCalleeRegisters(0) … … 1353 1331 void CodeBlock::derefStructures(Instruction* vPC) const 1354 1332 { 1355 ASSERT(m_codeType != NativeCode);1356 1333 Interpreter* interpreter = m_globalData->interpreter; 1357 1334 … … 1399 1376 void CodeBlock::refStructures(Instruction* vPC) const 1400 1377 { 1401 ASSERT(m_codeType != NativeCode);1402 1378 Interpreter* interpreter = m_globalData->interpreter; 1403 1379 … … 1446 1422 void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) 1447 1423 { 1448 ASSERT(m_codeType != NativeCode);1449 1424 if (m_exceptionInfo) 1450 1425 return; … … 1468 1443 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) 1469 1444 { 1470 ASSERT(m_codeType != NativeCode);1471 1445 ASSERT(bytecodeOffset < m_instructionCount); 1472 1446 … … 1487 1461 int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset) 1488 1462 { 1489 ASSERT(m_codeType != NativeCode);1490 1463 ASSERT(bytecodeOffset < m_instructionCount); 1491 1464 … … 1513 1486 int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset) 1514 1487 { 1515 ASSERT(m_codeType != NativeCode);1516 1488 ASSERT(bytecodeOffset < m_instructionCount); 1517 1489 … … 1553 1525 bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID) 1554 1526 { 1555 ASSERT(m_codeType != NativeCode);1556 1527 ASSERT(bytecodeOffset < m_instructionCount); 1557 1528 … … 1582 1553 bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex) 1583 1554 { 1584 ASSERT(m_codeType != NativeCode);1585 1555 ASSERT(bytecodeOffset < m_instructionCount); 1586 1556 … … 1609 1579 bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset) 1610 1580 { 1611 ASSERT(m_codeType != NativeCode);1612 1581 if (m_globalResolveInstructions.isEmpty()) 1613 1582 return false; … … 1630 1599 bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) 1631 1600 { 1632 ASSERT(m_codeType != NativeCode);1633 1601 if (m_globalResolveInfos.isEmpty()) 1634 1602 return false; -
trunk/JavaScriptCore/bytecode/CodeBlock.h
r47519 r47597 62 62 class ExecState; 63 63 64 enum CodeType { GlobalCode, EvalCode, FunctionCode , NativeCode};64 enum CodeType { GlobalCode, EvalCode, FunctionCode }; 65 65 66 66 static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); } … … 262 262 friend class JIT; 263 263 protected: 264 CodeBlock(ExecutableBase* ownerExecutable);265 264 CodeBlock(ExecutableBase* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset); 266 265 public: … … 379 378 CodeType codeType() const { return m_codeType; } 380 379 381 SourceProvider* source() const { ASSERT(m_codeType != NativeCode);return m_source.get(); }382 unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode);return m_sourceOffset; }380 SourceProvider* source() const { return m_source.get(); } 381 unsigned sourceOffset() const { return m_sourceOffset; } 383 382 384 383 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); } … … 470 469 SymbolTable& symbolTable() { return m_symbolTable; } 471 470 472 EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode);createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }471 EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; } 473 472 474 473 void shrinkToFit(); … … 489 488 void createRareDataIfNecessary() 490 489 { 491 ASSERT(m_codeType != NativeCode);492 490 if (!m_rareData) 493 491 m_rareData.set(new RareData); … … 620 618 }; 621 619 622 class NativeCodeBlock : public CodeBlock {623 public:624 NativeCodeBlock(FunctionExecutable* ownerExecutable)625 : CodeBlock(ownerExecutable)626 {627 }628 };629 630 620 inline Register& ExecState::r(int index) 631 621 { -
trunk/JavaScriptCore/jit/JIT.cpp
r47412 r47597 588 588 void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData) 589 589 { 590 ASSERT(calleeCodeBlock);591 590 RepatchBuffer repatchBuffer(callerCodeBlock); 592 591 593 592 // Currently we only link calls with the exact number of arguments. 594 593 // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant 595 if ( callerArgCount == calleeCodeBlock->m_numParameters || calleeCodeBlock->codeType() == NativeCode) {594 if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) { 596 595 ASSERT(!callLinkInfo->isLinked()); 597 596 -
trunk/JavaScriptCore/jit/JITCall.cpp
r47186 r47597 440 440 store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); 441 441 442 loadPtr(Address(regT 2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain442 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain 443 443 444 444 storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)))); 445 storePtr(regT 2, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));445 storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); 446 446 storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); 447 447 } … … 453 453 454 454 // ecx holds func 455 emitPutJITStubArg(regT 2, 1);455 emitPutJITStubArg(regT0, 1); 456 456 emitPutJITStubArgConstant(argCount, 3); 457 457 emitPutJITStubArgConstant(registerOffset, 2); … … 463 463 464 464 // ecx holds func 465 emitPutJITStubArg(regT 2, 1);465 emitPutJITStubArg(regT0, 1); 466 466 emitPutJITStubArg(regT1, 3); 467 addPtr(Imm32(registerOffset), regT1, regT 0);468 emitPutJITStubArg(regT 0, 2);467 addPtr(Imm32(registerOffset), regT1, regT2); 468 emitPutJITStubArg(regT2, 2); 469 469 } 470 470 … … 477 477 478 478 // ecx holds func 479 emitPutJITStubArg(regT 2, 1);479 emitPutJITStubArg(regT0, 1); 480 480 emitPutJITStubArgConstant(registerOffset, 2); 481 481 emitPutJITStubArgConstant(argCount, 3); 482 emitPutJITStubArgFromVirtualRegister(proto, 4, regT 0);482 emitPutJITStubArgFromVirtualRegister(proto, 4, regT2); 483 483 emitPutJITStubArgConstant(thisRegister, 5); 484 484 } … … 491 491 492 492 emitGetVirtualRegister(argCountRegister, regT1); 493 emitGetVirtualRegister(callee, regT 2);493 emitGetVirtualRegister(callee, regT0); 494 494 compileOpCallVarargsSetupArgs(instruction); 495 495 496 496 // Check for JSFunctions. 497 emitJumpSlowCaseIfNotJSCell(regT 2);498 addSlowCase(branchPtr(NotEqual, Address(regT 2), ImmPtr(m_globalData->jsFunctionVPtr)));499 497 emitJumpSlowCaseIfNotJSCell(regT0); 498 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); 499 500 500 // Speculatively roll the callframe, assuming argCount will match the arity. 501 mul32(Imm32(sizeof(Register)), regT 0, regT0);501 mul32(Imm32(sizeof(Register)), regT2, regT2); 502 502 intptr_t offset = (intptr_t)sizeof(Register) * (intptr_t)RegisterFile::CallerFrame; 503 addPtr(Imm32((int32_t)offset), regT 0, regT3);503 addPtr(Imm32((int32_t)offset), regT2, regT3); 504 504 addPtr(callFrameRegister, regT3); 505 505 storePtr(callFrameRegister, regT3); 506 addPtr(regT 0, callFrameRegister);506 addPtr(regT2, callFrameRegister); 507 507 emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); 508 508 … … 540 540 if (opcodeID == op_call_eval) { 541 541 JITStubCall stubCall(this, cti_op_call_eval); 542 stubCall.addArgument(callee, regT 2);542 stubCall.addArgument(callee, regT0); 543 543 stubCall.addArgument(JIT::Imm32(registerOffset)); 544 544 stubCall.addArgument(JIT::Imm32(argCount)); … … 547 547 } 548 548 549 emitGetVirtualRegister(callee, regT 2);549 emitGetVirtualRegister(callee, regT0); 550 550 // The arguments have been set up on the hot path for op_call_eval 551 551 if (opcodeID == op_call) … … 555 555 556 556 // Check for JSFunctions. 557 emitJumpSlowCaseIfNotJSCell(regT 2);558 addSlowCase(branchPtr(NotEqual, Address(regT 2), ImmPtr(m_globalData->jsFunctionVPtr)));557 emitJumpSlowCaseIfNotJSCell(regT0); 558 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); 559 559 560 560 // First, in the case of a construct, allocate the new object. 561 561 if (opcodeID == op_construct) { 562 562 JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); 563 emitGetVirtualRegister(callee, regT 2);563 emitGetVirtualRegister(callee, regT0); 564 564 } 565 565 … … 607 607 if (opcodeID == op_call_eval) { 608 608 JITStubCall stubCall(this, cti_op_call_eval); 609 stubCall.addArgument(callee, regT 2);609 stubCall.addArgument(callee, regT0); 610 610 stubCall.addArgument(JIT::Imm32(registerOffset)); 611 611 stubCall.addArgument(JIT::Imm32(argCount)); … … 616 616 // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee. 617 617 // This deliberately leaves the callee in ecx, used when setting up the stack frame below 618 emitGetVirtualRegister(callee, regT 2);618 emitGetVirtualRegister(callee, regT0); 619 619 DataLabelPtr addressOfLinkedFunctionCheck; 620 620 621 621 BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall); 622 622 623 Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT 2, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue())));623 Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue()))); 624 624 625 625 END_UNINTERRUPTED_SEQUENCE(sequenceOpCall); … … 636 636 int thisRegister = instruction[6].u.operand; 637 637 638 emitPutJITStubArg(regT 2, 1);639 emitPutJITStubArgFromVirtualRegister(proto, 4, regT 0);638 emitPutJITStubArg(regT0, 1); 639 emitPutJITStubArgFromVirtualRegister(proto, 4, regT2); 640 640 JITStubCall stubCall(this, cti_op_construct_JSConstruct); 641 641 stubCall.call(thisRegister); 642 emitGetVirtualRegister(callee, regT 2);642 emitGetVirtualRegister(callee, regT0); 643 643 } 644 644 … … 646 646 // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee 647 647 storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)))); 648 storePtr(regT 2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));649 loadPtr(Address(regT 2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain648 storePtr(regT0, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)))); 649 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain 650 650 store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); 651 651 storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); … … 681 681 682 682 // Fast check for JS function. 683 Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT 2);684 Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT 2), ImmPtr(m_globalData->jsFunctionVPtr));683 Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT0); 684 Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)); 685 685 686 686 // First, in the case of a construct, allocate the new object. 687 687 if (opcodeID == op_construct) { 688 688 JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); 689 emitGetVirtualRegister(callee, regT 2);689 emitGetVirtualRegister(callee, regT0); 690 690 } 691 691 … … 694 694 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); 695 695 move(Imm32(argCount), regT1); 696 697 move(regT0, regT2); 696 698 697 699 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink()); -
trunk/JavaScriptCore/jit/JITOpcodes.cpp
r47530 r47597 65 65 66 66 #if ENABLE(JIT_OPTIMIZE_CALL) 67 /* VirtualCallLink Trampoline */ 67 // VirtualCallLink Trampoline 68 // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. 68 69 Label virtualCallLinkBegin = align(); 69 70 // regT0 holds callee, regT1 holds argCount.71 70 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 72 loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT2); 73 Jump hasCodeBlock2 = branchTestPtr(NonZero, regT2);74 75 // Lazily generate a CodeBlock.76 preserveReturnAddressAfterCall(regT3); // return address71 72 Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 73 74 Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 75 preserveReturnAddressAfterCall(regT3); 77 76 restoreArgumentReference(); 78 77 Call callJSFunction2 = call(); 79 move(regT0, regT2); 80 emitGetJITStubArg(1, regT0); // callee 78 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 81 79 emitGetJITStubArg(5, regT1); // argCount 82 restoreReturnAddressBeforeReturn(regT3); // return address80 restoreReturnAddressBeforeReturn(regT3); 83 81 hasCodeBlock2.link(this); 84 82 85 // regT2 holds codeBlock.86 Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));87 88 83 // Check argCount matches callee arity. 89 Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF( CodeBlock, m_numParameters)), regT1);84 Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); 90 85 preserveReturnAddressAfterCall(regT3); 91 86 emitPutJITStubArg(regT3, 3); // return address 92 emitPutJITStubArg(regT2, 7); // codeBlock93 87 restoreArgumentReference(); 94 88 Call callArityCheck2 = call(); 95 89 move(regT1, callFrameRegister); 96 emitGetJITStubArg(1, regT0); // callee97 90 emitGetJITStubArg(5, regT1); // argCount 98 restoreReturnAddressBeforeReturn(regT3); // return address 99 91 restoreReturnAddressBeforeReturn(regT3); 100 92 arityCheckOkay2.link(this); 93 101 94 isNativeFunc2.link(this); 102 95 … … 104 97 105 98 preserveReturnAddressAfterCall(regT3); 106 emitPutJITStubArg(regT3, 3); 99 emitPutJITStubArg(regT3, 3); // return address 107 100 restoreArgumentReference(); 108 101 Call callLazyLinkCall = call(); … … 111 104 #endif // ENABLE(JIT_OPTIMIZE_CALL) 112 105 113 /* VirtualCall Trampoline */ 106 // VirtualCall Trampoline 107 // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. 114 108 Label virtualCallBegin = align(); 115 116 // regT0 holds callee, regT1 holds argCount.117 109 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 118 loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT2); 119 Jump hasCodeBlock3 = branchTestPtr(NonZero, regT2);120 121 // Lazily generate a CodeBlock.122 preserveReturnAddressAfterCall(regT3); // return address110 111 Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 112 113 Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 114 preserveReturnAddressAfterCall(regT3); 123 115 restoreArgumentReference(); 124 116 Call callJSFunction1 = call(); 125 move(regT0, regT2);126 emitGetJITStubArg(1, regT0); // callee127 117 emitGetJITStubArg(5, regT1); // argCount 128 restoreReturnAddressBeforeReturn(regT3); // return address 118 restoreReturnAddressBeforeReturn(regT3); 119 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 129 120 hasCodeBlock3.link(this); 130 121 131 // regT2 holds codeBlock. 132 Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode)); 133 134 // Check argCount matches callee. 135 Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1); 122 // Check argCount matches callee arity. 123 Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); 136 124 preserveReturnAddressAfterCall(regT3); 137 125 emitPutJITStubArg(regT3, 3); // return address 138 emitPutJITStubArg(regT2, 7); // codeBlock139 126 restoreArgumentReference(); 140 127 Call callArityCheck1 = call(); 141 128 move(regT1, callFrameRegister); 142 emitGetJITStubArg(1, regT0); // callee143 129 emitGetJITStubArg(5, regT1); // argCount 144 restoreReturnAddressBeforeReturn(regT3); // return address145 130 restoreReturnAddressBeforeReturn(regT3); 131 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 146 132 arityCheckOkay3.link(this); 133 147 134 isNativeFunc3.link(this); 135 148 136 compileOpCallInitializeCallFrame(); 149 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT0); 150 loadPtr(Address(regT0, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); 137 loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); 151 138 jump(regT0); 152 139 … … 1485 1472 COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit); 1486 1473 1474 // VirtualCallLink Trampoline 1475 // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. 1487 1476 Label virtualCallLinkBegin = align(); 1488 1489 // Load the callee CodeBlock* into eax 1490 loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3);1491 loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT0); 1492 Jump hasCodeBlock2 = branch TestPtr(NonZero, regT0);1477 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 1478 1479 Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 1480 1481 Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 1493 1482 preserveReturnAddressAfterCall(regT3); 1494 1483 restoreArgumentReference(); 1495 1484 Call callJSFunction2 = call(); 1496 emitGetJITStubArg(1, regT2);1497 emitGetJITStubArg(3, regT1); 1485 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 1486 emitGetJITStubArg(3, regT1); // argCount 1498 1487 restoreReturnAddressBeforeReturn(regT3); 1499 1488 hasCodeBlock2.link(this); 1500 1489 1501 Jump isNativeFunc2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));1502 1503 1490 // Check argCount matches callee arity. 1504 Jump arityCheckOkay2 = branch32(Equal, Address(regT 0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);1491 Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); 1505 1492 preserveReturnAddressAfterCall(regT3); 1506 emitPutJITStubArg(regT3, 2); 1507 emitPutJITStubArg(regT0, 4); 1493 emitPutJITStubArg(regT3, 2); // return address 1508 1494 restoreArgumentReference(); 1509 1495 Call callArityCheck2 = call(); 1510 1496 move(regT1, callFrameRegister); 1511 emitGetJITStubArg(1, regT2); 1512 emitGetJITStubArg(3, regT1); 1497 emitGetJITStubArg(3, regT1); // argCount 1513 1498 restoreReturnAddressBeforeReturn(regT3); 1514 1499 arityCheckOkay2.link(this); 1500 1515 1501 isNativeFunc2.link(this); 1516 1502 1517 1503 compileOpCallInitializeCallFrame(); 1518 1519 1504 preserveReturnAddressAfterCall(regT3); 1520 emitPutJITStubArg(regT3, 2); 1505 emitPutJITStubArg(regT3, 2); // return address 1521 1506 restoreArgumentReference(); 1522 1507 Call callLazyLinkCall = call(); 1523 1508 restoreReturnAddressBeforeReturn(regT3); 1524 1525 1509 jump(regT0); 1526 1510 1511 // VirtualCall Trampoline 1512 // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. 1527 1513 Label virtualCallBegin = align(); 1528 1529 // Load the callee CodeBlock* into eax 1530 loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3);1531 loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT0); 1532 Jump hasCodeBlock3 = branch TestPtr(NonZero, regT0);1514 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 1515 1516 Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 1517 1518 Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); 1533 1519 preserveReturnAddressAfterCall(regT3); 1534 1520 restoreArgumentReference(); 1535 1521 Call callJSFunction1 = call(); 1536 emitGetJITStubArg(1, regT2); 1537 emitGetJITStubArg(3, regT1); 1522 emitGetJITStubArg(3, regT1); // argCount 1538 1523 restoreReturnAddressBeforeReturn(regT3); 1539 loadPtr(Address(regT 2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3); // reload the function body nody, so we can reload the code pointer.1524 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 1540 1525 hasCodeBlock3.link(this); 1541 1526 1542 Jump isNativeFunc3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));1543 1544 1527 // Check argCount matches callee arity. 1545 Jump arityCheckOkay3 = branch32(Equal, Address(regT 0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);1528 Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); 1546 1529 preserveReturnAddressAfterCall(regT3); 1547 emitPutJITStubArg(regT3, 2); 1548 emitPutJITStubArg(regT0, 4); 1530 emitPutJITStubArg(regT3, 2); // return address 1549 1531 restoreArgumentReference(); 1550 1532 Call callArityCheck1 = call(); 1551 1533 move(regT1, callFrameRegister); 1552 emitGetJITStubArg(1, regT2); 1553 emitGetJITStubArg(3, regT1); 1534 emitGetJITStubArg(3, regT1); // argCount 1554 1535 restoreReturnAddressBeforeReturn(regT3); 1555 loadPtr(Address(regT 2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3); // reload the function body nody, so we can reload the code pointer.1536 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); 1556 1537 arityCheckOkay3.link(this); 1538 1557 1539 isNativeFunc3.link(this); 1558 1540 1559 // load ctiCode from the new codeBlock.1560 loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);1561 1562 1541 compileOpCallInitializeCallFrame(); 1542 loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); 1563 1543 jump(regT0); 1564 1544 1565 1566 1545 Label nativeCallThunk = align(); 1567 1546 preserveReturnAddressAfterCall(regT0); -
trunk/JavaScriptCore/jit/JITStubs.cpp
r47412 r47597 1486 1486 executable->jitCode(callDataScopeChain); 1487 1487 1488 return &executable->generatedBytecode();1488 return function; 1489 1489 } 1490 1490 … … 1494 1494 1495 1495 CallFrame* callFrame = stackFrame.callFrame; 1496 CodeBlock* newCodeBlock = stackFrame.args[3].codeBlock();1497 ASSERT(newCodeBlock->codeType() != NativeCode);1496 JSFunction* callee = asFunction(stackFrame.args[0].jsValue()); 1497 CodeBlock* newCodeBlock = &callee->executable()->generatedBytecode(); 1498 1498 int argCount = stackFrame.args[2].int32(); 1499 1499 … … 1532 1532 } 1533 1533 1534 RETURN_POINTER_PAIR( newCodeBlock, callFrame);1534 RETURN_POINTER_PAIR(callee, callFrame); 1535 1535 } 1536 1536 … … 1546 1546 if (!executable->isHostFunction()) 1547 1547 codeBlock = &executable->bytecode(callee->scope().node()); 1548 else1549 codeBlock = &executable->generatedBytecode();1550 1548 CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress()); 1551 1549 -
trunk/JavaScriptCore/runtime/Executable.cpp
r47519 r47597 86 86 OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body(), globalObject->debugger(), scopeChain, &m_codeBlock->symbolTable(), m_codeBlock)); 87 87 generator->generate(); 88 m_numParameters = m_codeBlock->m_numParameters; 89 ASSERT(m_numParameters); 88 90 89 91 body()->destroyData(); … … 126 128 127 129 #endif 128 129 bool FunctionExecutable::isHostFunction() const130 {131 return m_codeBlock && m_codeBlock->codeType() == NativeCode;132 }133 130 134 131 void FunctionExecutable::markAggregate(MarkStack& markStack) … … 198 195 delete m_codeBlock; 199 196 m_codeBlock = 0; 197 m_numParameters = NUM_PARAMETERS_NOT_COMPILED; 200 198 #if ENABLE(JIT) 201 199 m_jitCode = JITCode(); … … 205 203 #if ENABLE(JIT) 206 204 FunctionExecutable::FunctionExecutable(ExecState* exec) 207 : m_codeBlock( new NativeCodeBlock(this))205 : m_codeBlock(0) 208 206 , m_name(Identifier(exec, "<native thunk>")) 209 207 { 210 208 m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk())); 209 m_numParameters = NUM_PARAMETERS_IS_HOST; 211 210 } 212 211 #endif -
trunk/JavaScriptCore/runtime/Executable.h
r47582 r47597 41 41 friend class JIT; 42 42 public: 43 enum Mode { 44 NoJITCode, 45 HasJITCode, 46 IsHost 47 }; 48 static const int NUM_PARAMETERS_IS_HOST = 0; 49 static const int NUM_PARAMETERS_NOT_COMPILED = -1; 50 43 51 virtual ~ExecutableBase() {} 44 52 45 53 ExecutableBase(const SourceCode& source) 46 54 : m_source(source) 55 , m_numParameters(NUM_PARAMETERS_NOT_COMPILED) 47 56 { 48 57 } … … 63 72 RefPtr<ScopeNode> m_node; 64 73 SourceCode m_source; 74 int m_numParameters; 65 75 66 76 private: … … 220 230 UString paramString() const { return body()->paramString(); } 221 231 222 bool isHostFunction() const ;232 bool isHostFunction() const { return m_numParameters == NUM_PARAMETERS_IS_HOST; } 223 233 bool isGenerated() const 224 234 { -
trunk/JavaScriptCore/runtime/JSFunction.cpp
r47412 r47597 90 90 // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once 91 91 // this memory is freed and may be reused (potentially for another, different JSFunction). 92 if (!isHostFunction()) { 92 93 #if ENABLE(JIT_OPTIMIZE_CALL) 93 if (m_executable && m_executable->isGenerated())94 m_executable->generatedBytecode().unlinkCallers();94 if (m_executable && m_executable->isGenerated()) 95 m_executable->generatedBytecode().unlinkCallers(); 95 96 #endif 96 if (!isHostFunction())97 97 scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too? 98 } 98 99 } 99 100
Note:
See TracChangeset
for help on using the changeset viewer.