Changeset 37570 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 13, 2008, 5:20:49 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r37563 r37570 1 2008-10-13 Cameron Zwarich <[email protected]> 2 3 Reviewed by Geoff Garen. 4 5 Bug 21541: Move RegisterFile growth check to callee 6 <https://bugs.webkit.org/show_bug.cgi?id=21541> 7 8 Move the RegisterFile growth check to the callee in the common case, 9 where some of the information is known statically at JIT time. There is 10 still a check in the caller in the case where the caller provides too 11 few arguments. 12 13 This is a 2.1% speedup on the V8 benchmark, including a 5.1% speedup on 14 the Richards benchmark, a 4.1% speedup on the DeltaBlue benchmark, and a 15 1.4% speedup on the Earley-Boyer benchmark. It is also a 0.5% speedup on 16 SunSpider. 17 18 * VM/CTI.cpp: 19 (JSC::CTI::privateCompile): 20 * VM/Machine.cpp: 21 (JSC::Machine::cti_register_file_check): 22 (JSC::Machine::cti_op_call_JSFunction): 23 (JSC::Machine::cti_op_construct_JSConstruct): 24 * VM/Machine.h: 25 * VM/RegisterFile.h: 26 * masm/X86Assembler.h: 27 (JSC::X86Assembler::): 28 (JSC::X86Assembler::cmpl_mr): 29 (JSC::X86Assembler::emitUnlinkedJg): 30 1 31 2008-10-13 Sam Weinig <[email protected]> 2 32 -
trunk/JavaScriptCore/VM/CTI.cpp
r37500 r37570 2616 2616 emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC); 2617 2617 2618 X86Assembler::JmpSrc slowRegisterFileCheck; 2619 X86Assembler::JmpDst afterRegisterFileCheck; 2620 if (m_codeBlock->codeType == FunctionCode) { 2621 emitGetCTIParam(CTI_ARGS_registerFile, X86::eax); 2622 m_jit.leal_mr(m_codeBlock->numCalleeRegisters * sizeof(Register), X86::edi, X86::edx); 2623 m_jit.cmpl_mr(OBJECT_OFFSET(RegisterFile, m_end), X86::eax, X86::edx); 2624 slowRegisterFileCheck = m_jit.emitUnlinkedJg(); 2625 afterRegisterFileCheck = m_jit.label(); 2626 } 2627 2618 2628 privateCompileMainPass(); 2619 2629 privateCompileLinkPass(); 2620 2630 privateCompileSlowCases(); 2631 2632 if (m_codeBlock->codeType == FunctionCode) { 2633 m_jit.link(slowRegisterFileCheck, m_jit.label()); 2634 emitCall(0, Machine::cti_register_file_check); 2635 X86Assembler::JmpSrc backToBody = m_jit.emitUnlinkedJmp(); 2636 m_jit.link(backToBody, afterRegisterFileCheck); 2637 } 2621 2638 2622 2639 ASSERT(m_jmpTable.isEmpty()); -
trunk/JavaScriptCore/VM/Machine.cpp
r37457 r37570 4337 4337 } 4338 4338 4339 void Machine::cti_register_file_check(CTI_ARGS) 4340 { 4341 CallFrame* callFrame = ARG_callFrame; 4342 CodeBlock* codeBlock = callFrame->codeBlock(); 4343 RegisterFile* registerFile = ARG_registerFile; 4344 4345 if (!registerFile->grow(callFrame + codeBlock->numCalleeRegisters)) { 4346 CallFrame* callerFrame = callFrame->callerFrame(); 4347 ARG_setCallFrame(callerFrame); 4348 ARG_globalData->exception = createStackOverflowError(callerFrame); 4349 ASSERT(ARG_globalData->exception); 4350 ARG_globalData->throwReturnAddress = callFrame->returnPC(); 4351 doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); 4352 } 4353 } 4354 4339 4355 int Machine::cti_op_loop_if_less(CTI_ARGS) 4340 4356 { … … 4551 4567 ScopeChainNode* callDataScopeChain = static_cast<JSFunction*>(ARG_src1)->m_scopeChain.node(); 4552 4568 CodeBlock* newCodeBlock = &static_cast<JSFunction*>(ARG_src1)->m_body->byteCode(callDataScopeChain); 4553 4554 CallFrame* callFrame = slideRegisterWindowForCall(newCodeBlock, ARG_registerFile, ARG_callFrame, ARG_int2, ARG_int3); 4555 if (UNLIKELY(!callFrame)) { 4556 ARG_globalData->exception = createStackOverflowError(ARG_callFrame); 4569 CallFrame* callFrame = ARG_callFrame; 4570 size_t registerOffset = ARG_int2; 4571 int argCount = ARG_int3; 4572 4573 if (LIKELY(argCount == newCodeBlock->numParameters)) { 4574 VoidPtrPair pair = { newCodeBlock, CallFrame::create(callFrame->registers() + registerOffset) }; 4575 return pair; 4576 } 4577 4578 if (argCount > newCodeBlock->numParameters) { 4579 size_t numParameters = newCodeBlock->numParameters; 4580 Register* r = callFrame->registers() + registerOffset + numParameters; 4581 4582 Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; 4583 for (size_t i = 0; i < numParameters; ++i) 4584 argv[i + argCount] = argv[i]; 4585 4586 VoidPtrPair pair = { newCodeBlock, CallFrame::create(r) }; 4587 return pair; 4588 } 4589 4590 size_t omittedArgCount = newCodeBlock->numParameters - argCount; 4591 Register* r = callFrame->registers() + registerOffset + omittedArgCount; 4592 Register* newEnd = r + newCodeBlock->numCalleeRegisters; 4593 if (!ARG_registerFile->grow(newEnd)) { 4594 ARG_globalData->exception = createStackOverflowError(callFrame); 4557 4595 VM_THROW_EXCEPTION_2(); 4558 4596 } 4559 4597 4560 VoidPtrPair pair = { newCodeBlock, callFrame }; 4598 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; 4599 for (size_t i = 0; i < omittedArgCount; ++i) 4600 argv[i] = jsUndefined(); 4601 4602 VoidPtrPair pair = { newCodeBlock, CallFrame::create(r) }; 4561 4603 return pair; 4562 4604 } … … 4686 4728 VoidPtrPair Machine::cti_op_construct_JSConstruct(CTI_ARGS) 4687 4729 { 4688 RegisterFile* registerFile = ARG_registerFile;4689 4730 CallFrame* callFrame = ARG_callFrame; 4690 4731 … … 4713 4754 structure = callDataScopeChain->globalObject()->emptyObjectStructure(); 4714 4755 JSObject* newObject = new (ARG_globalData) JSObject(structure); 4715 4716 4756 callFrame[firstArg] = newObject; // "this" value 4717 4757 4718 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 4719 if (UNLIKELY(!callFrame)) { 4720 ARG_globalData->exception = createStackOverflowError(ARG_callFrame); 4758 if (LIKELY(argCount == newCodeBlock->numParameters)) { 4759 VoidPtrPair pair = { newCodeBlock, CallFrame::create(callFrame->registers() + registerOffset) }; 4760 return pair; 4761 } 4762 4763 if (argCount > newCodeBlock->numParameters) { 4764 size_t numParameters = newCodeBlock->numParameters; 4765 Register* r = callFrame->registers() + registerOffset + numParameters; 4766 4767 Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; 4768 for (size_t i = 0; i < numParameters; ++i) 4769 argv[i + argCount] = argv[i]; 4770 4771 VoidPtrPair pair = { newCodeBlock, CallFrame::create(r) }; 4772 return pair; 4773 } 4774 4775 size_t omittedArgCount = newCodeBlock->numParameters - argCount; 4776 Register* r = callFrame->registers() + registerOffset + omittedArgCount; 4777 Register* newEnd = r + newCodeBlock->numCalleeRegisters; 4778 if (!ARG_registerFile->grow(newEnd)) { 4779 ARG_globalData->exception = createStackOverflowError(callFrame); 4721 4780 VM_THROW_EXCEPTION_2(); 4722 4781 } 4723 4782 4724 VoidPtrPair pair = { newCodeBlock, callFrame }; 4783 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; 4784 for (size_t i = 0; i < omittedArgCount; ++i) 4785 argv[i] = jsUndefined(); 4786 4787 VoidPtrPair pair = { newCodeBlock, CallFrame::create(r) }; 4725 4788 return pair; 4726 4789 } -
trunk/JavaScriptCore/VM/Machine.h
r37500 r37570 163 163 164 164 static void SFX_CALL cti_timeout_check(CTI_ARGS); 165 static void SFX_CALL cti_register_file_check(CTI_ARGS); 165 166 166 167 static JSValue* SFX_CALL cti_op_convert_this(CTI_ARGS); -
trunk/JavaScriptCore/VM/RegisterFile.h
r37433 r37570 89 89 90 90 class RegisterFile : Noncopyable { 91 friend class CTI; 91 92 public: 92 93 enum CallFrameHeaderEntry { -
trunk/JavaScriptCore/masm/X86Assembler.h
r37457 r37570 192 192 OP_XOR_EvGv = 0x31, 193 193 OP_CMP_EvGv = 0x39, 194 OP_CMP_GvEv = 0x3B, 194 195 OP_PUSH_EAX = 0x50, 195 196 OP_POP_EAX = 0x58, … … 241 242 OP2_JGE_rel32 = 0x8D, 242 243 OP2_JLE_rel32 = 0x8E, 244 OP2_JG_rel32 = 0x8F, 243 245 OP2_IMUL_GvEv = 0xAF, 244 246 OP2_MOVZX_GvEb = 0xB6, … … 372 374 m_buffer->putByte(OP_CMP_EvGv); 373 375 emitModRm_rm(src, base, offset); 376 } 377 378 void cmpl_mr(int offset, RegisterID base, RegisterID dst) 379 { 380 m_buffer->putByte(OP_CMP_GvEv); 381 emitModRm_rm(dst, base, offset); 374 382 } 375 383 … … 946 954 return JmpSrc(m_buffer->getOffset()); 947 955 } 948 956 957 JmpSrc emitUnlinkedJg() 958 { 959 m_buffer->putByte(OP_2BYTE_ESCAPE); 960 m_buffer->putByte(OP2_JG_rel32); 961 m_buffer->putInt(0); 962 return JmpSrc(m_buffer->getOffset()); 963 } 964 949 965 JmpSrc emitUnlinkedJa() 950 966 {
Note:
See TracChangeset
for help on using the changeset viewer.