Changeset 92498 in webkit
- Timestamp:
- Aug 5, 2011 1:03:19 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r92437 r92498 1 2011-08-05 Oliver Hunt <oliver@apple.com> 2 3 Inline allocation of function objects 4 https://bugs.webkit.org/show_bug.cgi?id=65779 5 6 Reviewed by Gavin Barraclough. 7 8 Inline allocation and initilisation of function objects 9 in generated code. This ended up being a 60-70% improvement 10 in function allocation performance. This improvement shows 11 up as a ~2% improvement in 32bit sunspider and V8, but is a 12 wash on 64-bit. 13 14 We currently don't inline the allocation of named function 15 expressions, as that requires being able to gc allocate a 16 variable object. 17 18 * jit/JIT.cpp: 19 (JSC::JIT::privateCompileSlowCases): 20 * jit/JIT.h: 21 (JSC::JIT::emitStoreCell): 22 * jit/JITInlineMethods.h: 23 (JSC::JIT::emitAllocateBasicJSObject): 24 (JSC::JIT::emitAllocateJSFinalObject): 25 (JSC::JIT::emitAllocateJSFunction): 26 * jit/JITOpcodes.cpp: 27 (JSC::JIT::emit_op_new_func): 28 (JSC::JIT::emitSlow_op_new_func): 29 (JSC::JIT::emit_op_new_func_exp): 30 (JSC::JIT::emitSlow_op_new_func_exp): 31 * jit/JITOpcodes32_64.cpp: 32 Removed duplicate implementation of op_new_func and op_new_func_exp 33 * runtime/JSFunction.h: 34 (JSC::JSFunction::offsetOfScopeChain): 35 (JSC::JSFunction::offsetOfExecutable): 36 1 37 2011-08-04 David Levin <levin@chromium.org> 2 38 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r91952 r92498 432 432 DEFINE_SLOWCASE_OP(op_neq) 433 433 DEFINE_SLOWCASE_OP(op_new_object) 434 DEFINE_SLOWCASE_OP(op_new_func) 435 DEFINE_SLOWCASE_OP(op_new_func_exp) 434 436 DEFINE_SLOWCASE_OP(op_not) 435 437 DEFINE_SLOWCASE_OP(op_nstricteq) -
trunk/Source/JavaScriptCore/jit/JIT.h
r91199 r92498 50 50 51 51 class CodeBlock; 52 class FunctionExecutable; 52 53 class JIT; 53 54 class JSPropertyNameIterator; … … 300 301 301 302 void emitWriteBarrier(RegisterID owner, RegisterID scratch); 302 303 template<typename T> 304 void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch); 303 304 template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, void* vtable, RegisterID result, RegisterID storagePtr); 305 template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); 306 void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr); 305 307 306 308 #if USE(JSVALUE32_64) … … 529 531 void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2); 530 532 void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0); 533 void emitStoreCell(unsigned dst, RegisterID payload, bool /* only used in JSValue32_64 */ = false) 534 { 535 emitPutVirtualRegister(dst, payload); 536 } 531 537 532 538 int32_t getConstantOperandImmediateInt(unsigned src); … … 907 913 void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&); 908 914 void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&); 915 void emitSlow_op_new_func(Instruction*, Vector<SlowCaseEntry>::iterator&); 916 void emitSlow_op_new_func_exp(Instruction*, Vector<SlowCaseEntry>::iterator&); 909 917 910 918 -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r91199 r92498 375 375 } 376 376 377 template<typename T> 378 inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch) 379 { 380 NewSpace::SizeClass* sizeClass = &m_globalData->heap.sizeClassFor(sizeof(JSFinalObject)); 377 template <typename ClassType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, void* vtable, RegisterID result, RegisterID storagePtr) 378 { 379 NewSpace::SizeClass* sizeClass = &m_globalData->heap.sizeClassFor(sizeof(ClassType)); 381 380 loadPtr(&sizeClass->firstFreeCell, result); 382 381 addSlowCase(branchTestPtr(Zero, result)); 383 382 384 383 // remove the object from the free list 385 loadPtr(Address(result), s cratch);386 storePtr(s cratch, &sizeClass->firstFreeCell);387 384 loadPtr(Address(result), storagePtr); 385 storePtr(storagePtr, &sizeClass->firstFreeCell); 386 388 387 // initialize the object's vtable 389 storePtr( ImmPtr(m_globalData->jsFinalObjectVPtr), Address(result));390 388 storePtr(TrustedImmPtr(vtable), Address(result)); 389 391 390 // initialize the object's structure 392 391 storePtr(structure, Address(result, JSCell::structureOffset())); 392 393 // initialize the inheritor ID 394 storePtr(TrustedImmPtr(0), Address(result, JSObject::offsetOfInheritorID())); 395 396 // initialize the object's property storage pointer 397 addPtr(TrustedImm32(sizeof(JSObject)), result, storagePtr); 398 storePtr(storagePtr, Address(result, ClassType::offsetOfPropertyStorage())); 399 } 400 401 template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch) 402 { 403 emitAllocateBasicJSObject<JSFinalObject>(structure, m_globalData->jsFinalObjectVPtr, result, scratch); 404 } 405 406 inline void JIT::emitAllocateJSFunction(FunctionExecutable* executable, RegisterID scopeChain, RegisterID result, RegisterID storagePtr) 407 { 408 emitAllocateBasicJSObject<JSFunction>(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), m_globalData->jsFunctionVPtr, result, storagePtr); 409 410 // store the function's scope chain 411 storePtr(scopeChain, Address(result, JSFunction::offsetOfScopeChain())); 412 413 // store the function's executable member 414 storePtr(TrustedImmPtr(executable), Address(result, JSFunction::offsetOfExecutable())); 415 393 416 394 // initialize the inheritor ID 395 storePtr(ImmPtr(0), Address(result, JSObject::offsetOfInheritorID())); 396 397 // initialize the object's property storage pointer 398 addPtr(Imm32(sizeof(JSObject)), result, scratch); 399 storePtr(scratch, Address(result, JSObject::offsetOfPropertyStorage())); 417 // store the function's global object 418 int globalObjectOffset = sizeof(JSValue) * JSFunction::GlobalObjectSlot; 419 storePtr(TrustedImmPtr(m_codeBlock->globalObject()), Address(regT1, globalObjectOffset + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); 420 #if USE(JSVALUE32_64) 421 store32(TrustedImm32(JSValue::CellTag), Address(regT1, globalObjectOffset + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); 422 #endif 423 424 // store the function's name 425 ASSERT(executable->nameValue()); 426 int functionNameOffset = sizeof(JSValue) * m_codeBlock->globalObject()->functionNameOffset(); 427 storePtr(TrustedImmPtr(executable->nameValue()), Address(regT1, functionNameOffset + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); 428 #if USE(JSVALUE32_64) 429 store32(TrustedImm32(JSValue::CellTag), Address(regT1, functionNameOffset + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); 430 #endif 400 431 } 401 432 -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r91199 r92498 726 726 } 727 727 728 void JIT::emit_op_new_func_exp(Instruction* currentInstruction)729 {730 JITStubCall stubCall(this, cti_op_new_func_exp);731 stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));732 stubCall.call(currentInstruction[1].u.operand);733 }734 735 728 void JIT::emit_op_jtrue(Instruction* currentInstruction) 736 729 { … … 1622 1615 #endif 1623 1616 } 1617 1618 FunctionExecutable* executable = m_codeBlock->functionDecl(currentInstruction[2].u.operand); 1619 emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); 1620 emitAllocateJSFunction(executable, regT2, regT0, regT1); 1621 1622 emitStoreCell(dst, regT0); 1623 1624 if (currentInstruction[3].u.operand) { 1625 #if USE(JSVALUE32_64) 1626 unmap(); 1627 #else 1628 killLastResultRegister(); 1629 #endif 1630 lazyJump.link(this); 1631 } 1632 } 1633 1634 void JIT::emitSlow_op_new_func(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1635 { 1636 linkSlowCase(iter); 1624 1637 JITStubCall stubCall(this, cti_op_new_func); 1625 1638 stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand))); 1626 1639 stubCall.call(currentInstruction[1].u.operand); 1627 if (currentInstruction[3].u.operand) 1628 lazyJump.link(this); 1640 } 1641 1642 void JIT::emit_op_new_func_exp(Instruction* currentInstruction) 1643 { 1644 FunctionExecutable* executable = m_codeBlock->functionExpr(currentInstruction[2].u.operand); 1645 1646 // We only inline the allocation of a anonymous function expressions 1647 // If we want to be able to allocate a named function expression, we would 1648 // need to be able to do inline allocation of a JSStaticScopeObject. 1649 if (executable->name().isNull()) { 1650 emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); 1651 emitAllocateJSFunction(executable, regT2, regT0, regT1); 1652 emitStoreCell(currentInstruction[1].u.operand, regT0); 1653 return; 1654 } 1655 1656 JITStubCall stubCall(this, cti_op_new_func_exp); 1657 stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand))); 1658 stubCall.call(currentInstruction[1].u.operand); 1659 } 1660 1661 void JIT::emitSlow_op_new_func_exp(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1662 { 1663 FunctionExecutable* executable = m_codeBlock->functionExpr(currentInstruction[2].u.operand); 1664 if (!executable->name().isNull()) 1665 return; 1666 linkSlowCase(iter); 1667 JITStubCall stubCall(this, cti_op_new_func_exp); 1668 stubCall.addArgument(TrustedImmPtr(executable)); 1669 stubCall.call(currentInstruction[1].u.operand); 1629 1670 } 1630 1671 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r91199 r92498 1119 1119 } 1120 1120 1121 void JIT::emit_op_new_func_exp(Instruction* currentInstruction)1122 {1123 JITStubCall stubCall(this, cti_op_new_func_exp);1124 stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));1125 stubCall.call(currentInstruction[1].u.operand);1126 }1127 1128 1121 void JIT::emit_op_throw(Instruction* currentInstruction) 1129 1122 { -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r91194 r92498 111 111 virtual CallType getCallData(CallData&); 112 112 113 static inline size_t offsetOfScopeChain() 114 { 115 return OBJECT_OFFSETOF(JSFunction, m_scopeChain); 116 } 117 118 static inline size_t offsetOfExecutable() 119 { 120 return OBJECT_OFFSETOF(JSFunction, m_executable); 121 } 122 113 123 protected: 114 124 const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
Note: See TracChangeset
for help on using the changeset viewer.