Changeset 37386 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 7, 2008, 1:27:50 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r37383 r37386 1 2008-10-07 Gavin Barraclough <[email protected]> 2 3 Reviewed by Oliver Hunt. 4 5 Move callframe initialization into JIT code, again. 6 7 As a part of the restructuring the second result from functions is now 8 returned in edx, allowing the new value of 'r' to be returned via a 9 register, and stored to the stack from JIT code, too. 10 11 4.5% progression on v8-tests. (3% in their harness) 12 13 * VM/CTI.cpp: 14 (JSC::): 15 (JSC::CTI::emitCall): 16 (JSC::CTI::compileOpCall): 17 (JSC::CTI::privateCompileMainPass): 18 (JSC::CTI::privateCompileSlowCases): 19 (JSC::CTI::privateCompile): 20 * VM/CTI.h: 21 (JSC::CallRecord::CallRecord): 22 * VM/Machine.cpp: 23 (JSC::Machine::cti_op_call_JSFunction): 24 (JSC::Machine::cti_op_construct_JSConstruct): 25 (JSC::Machine::cti_op_resolve_func): 26 (JSC::Machine::cti_op_post_inc): 27 (JSC::Machine::cti_op_resolve_with_base): 28 (JSC::Machine::cti_op_post_dec): 29 * VM/Machine.h: 30 * kjs/JSFunction.h: 31 * kjs/ScopeChain.h: 32 1 33 2008-10-07 Mark Rowe <[email protected]> 2 34 -
trunk/JavaScriptCore/VM/CTI.cpp
r37381 r37386 31 31 #include "CodeBlock.h" 32 32 #include "JSArray.h" 33 #include "JSFunction.h" 33 34 #include "Machine.h" 34 35 #include "wrec/WREC.h" … … 83 84 "subl $0x24, %esp" "\n" 84 85 "movl $512, %esi" "\n" 86 "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = CTI_ARGS_r 85 87 "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code 86 88 "addl $0x24, %esp" "\n" … … 112 114 mov esi, 512; 113 115 mov [esp], esp; 116 mov edi, [esp + 0x38]; 114 117 call [esp + 0x30]; 115 118 add esp, 0x24; … … 363 366 } 364 367 368 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_2 helper) 369 { 370 #if ENABLE(SAMPLING_TOOL) 371 m_jit.movl_i32m(1, &inCalledCode); 372 #endif 373 m_jit.emitRestoreArgumentReference(); 374 X86Assembler::JmpSrc call = m_jit.emitCall(); 375 m_calls.append(CallRecord(call, helper, opcodeIndex)); 376 #if ENABLE(SAMPLING_TOOL) 377 m_jit.movl_i32m(0, &inCalledCode); 378 #endif 379 380 return call; 381 } 382 365 383 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotJSCell(X86Assembler::RegisterID reg, unsigned opcodeIndex) 366 384 { … … 461 479 #endif 462 480 481 void CTI::compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount) 482 { 483 emitGetArg(callee, X86::ecx); // Load callee JSFunction into ecx 484 m_jit.movl_rm(X86::eax, RegisterFile::CodeBlock * static_cast<int>(sizeof(Register)), X86::edx); // callee CodeBlock was returned in eax 485 m_jit.movl_i32m(reinterpret_cast<unsigned>(nullJSValue), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edx); 486 m_jit.movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Register)), X86::edx); 487 488 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeChain, m_node), X86::ecx, X86::ecx); // newScopeChain 489 m_jit.movl_i32m(argCount, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)), X86::edx); 490 m_jit.movl_rm(X86::edi, RegisterFile::CallerRegisters * static_cast<int>(sizeof(Register)), X86::edx); 491 m_jit.movl_rm(X86::ecx, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)), X86::edx); 492 } 493 463 494 void CTI::compileOpCall(Instruction* instruction, unsigned i, CompileOpCallType type) 464 495 { 465 496 int dst = instruction[i + 1].u.operand; 497 int callee = instruction[i + 2].u.operand; 466 498 int firstArg = instruction[i + 4].u.operand; 467 499 int argCount = instruction[i + 5].u.operand; … … 494 526 X86Assembler::JmpSrc wasEval; 495 527 if (type == OpCallEval) { 496 emitGetPutArg( instruction[i + 2].u.operand, 0, X86::ecx);528 emitGetPutArg(callee, 0, X86::ecx); 497 529 emitCall(i, Machine::cti_op_call_eval); 498 499 emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r500 530 501 531 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(JSImmediate::impossibleValue()), X86::eax); … … 503 533 504 534 // this sets up the first arg to op_cti_call (func), and explicitly leaves the value in ecx (checked just below). 505 emitGetArg( instruction[i + 2].u.operand, X86::ecx);535 emitGetArg(callee, X86::ecx); 506 536 } else { 507 537 // this sets up the first arg to op_cti_call (func), and explicitly leaves the value in ecx (checked just below). 508 emitGetPutArg( instruction[i + 2].u.operand, 0, X86::ecx);538 emitGetPutArg(callee, 0, X86::ecx); 509 539 } 510 540 … … 523 553 524 554 // This handles JSFunctions 525 emitCall(i, ((type == OpConstruct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction)); 555 emitCall(i, (type == OpConstruct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction); 556 557 compileOpCallInitializeCallFrame(callee, argCount); 558 559 // load ctiCode from the new codeBlock. 560 m_jit.movl_mr(OBJECT_OFFSET(CodeBlock, ctiCode), X86::eax, X86::eax); 561 562 // Setup the new value of 'r' in edi, and on the stack, too. 563 emitPutCTIParam(X86::edx, CTI_ARGS_r); 564 m_jit.movl_rr(X86::edx, X86::edi); 526 565 527 566 // Check the ctiCode has been generated - if not, this is handled in a slow case. … … 1280 1319 emitCall(i, Machine::cti_op_resolve_func); 1281 1320 emitPutResult(instruction[i + 1].u.operand); 1282 emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax); 1283 emitPutResult(instruction[i + 2].u.operand); 1321 emitPutResult(instruction[i + 2].u.operand, X86::edx); 1284 1322 i += 4; 1285 1323 break; … … 1565 1603 emitCall(i, Machine::cti_op_resolve_with_base); 1566 1604 emitPutResult(instruction[i + 1].u.operand); 1567 emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax); 1568 emitPutResult(instruction[i + 2].u.operand); 1605 emitPutResult(instruction[i + 2].u.operand, X86::edx); 1569 1606 i += 4; 1570 1607 break; … … 2328 2365 emitCall(i, Machine::cti_op_post_inc); 2329 2366 emitPutResult(instruction[i + 1].u.operand); 2330 emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax); 2331 emitPutResult(srcDst); 2367 emitPutResult(srcDst, X86::edx); 2332 2368 i += 3; 2333 2369 break; … … 2384 2420 emitCall(i, Machine::cti_op_post_dec); 2385 2421 emitPutResult(instruction[i + 1].u.operand); 2386 emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax); 2387 emitPutResult(srcDst); 2422 emitPutResult(srcDst, X86::edx); 2388 2423 i += 3; 2389 2424 break; … … 2500 2535 // Could use a popl_m, but would need to offset the following instruction if so. 2501 2536 m_jit.popl_r(X86::ecx); 2502 emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r2503 2537 emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC); 2504 2538 -
trunk/JavaScriptCore/VM/CTI.h
r37316 r37386 46 46 #endif 47 47 48 #define CTI_ARGS_2ndResult 0x0849 50 48 #define CTI_ARGS_code 0x0C 51 49 #define CTI_ARGS_registerFile 0x0D … … 63 61 64 62 #define ARG_setR(newR) (*(Register**)&(ARGS)[CTI_ARGS_r] = newR) 65 #define ARG_set2ndResult(new2ndResult) (*(JSValue**)&(ARGS)[CTI_ARGS_2ndResult] = new2ndResult)66 63 67 64 #define ARG_src1 ((JSValue*)((ARGS)[1])) … … 109 106 struct OperandTypes; 110 107 108 struct VoidPtrPair { void* first; void* second; }; 109 111 110 typedef JSValue* (*CTIHelper_j)(CTI_ARGS); 112 111 typedef JSPropertyNameIterator* (*CTIHelper_p)(CTI_ARGS); … … 114 113 typedef void* (*CTIHelper_s)(CTI_ARGS); 115 114 typedef int (*CTIHelper_b)(CTI_ARGS); 115 typedef VoidPtrPair (*CTIHelper_2)(CTI_ARGS); 116 116 117 117 struct CallRecord { … … 153 153 154 154 CallRecord(X86Assembler::JmpSrc f, CTIHelper_b t, unsigned i) 155 : from(f) 156 , to((void*)t) 157 , opcodeIndex(i) 158 { 159 } 160 161 CallRecord(X86Assembler::JmpSrc f, CTIHelper_2 t, unsigned i) 155 162 : from(f) 156 163 , to((void*)t) … … 351 358 enum CompileOpCallType { OpCallNormal, OpCallEval, OpConstruct }; 352 359 void compileOpCall(Instruction* instruction, unsigned i, CompileOpCallType type = OpCallNormal); 360 void compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount); 353 361 enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; 354 362 void compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type); … … 393 401 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_j); 394 402 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_p); 395 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_b);396 403 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_v); 397 404 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_s); 398 405 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_b); 406 X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_2); 407 399 408 void emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst); 400 409 void emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index); -
trunk/JavaScriptCore/VM/Machine.cpp
r37381 r37386 4236 4236 return 0; \ 4237 4237 } while (0) 4238 #define VM_THROW_EXCEPTION_2() \ 4239 do { \ 4240 VM_THROW_EXCEPTION_AT_END(); \ 4241 VoidPtrPair pair = { (void*)0, (void*)0, }; \ 4242 return pair; \ 4243 } while (0) 4238 4244 #define VM_THROW_EXCEPTION_AT_END() \ 4239 4245 do { \ … … 4267 4273 } \ 4268 4274 } while (0) 4275 #define VM_CHECK_EXCEPTION_2() \ 4276 do { \ 4277 if (UNLIKELY(ARG_globalData->exception != 0)) { \ 4278 VM_THROW_EXCEPTION_2(); \ 4279 } \ 4280 } while (0) 4269 4281 4270 4282 JSValue* Machine::cti_op_convert_this(CTI_ARGS) … … 4561 4573 } 4562 4574 4563 void*Machine::cti_op_call_JSFunction(CTI_ARGS)4575 VoidPtrPair Machine::cti_op_call_JSFunction(CTI_ARGS) 4564 4576 { 4565 4577 #ifndef NDEBUG … … 4577 4589 if (UNLIKELY(!r)) { 4578 4590 ARG_globalData->exception = createStackOverflowError(CallFrame::create(ARG_r)); 4579 VM_THROW_EXCEPTION(); 4580 } 4581 4582 r[RegisterFile::CodeBlock] = newCodeBlock; 4583 r[RegisterFile::ScopeChain] = callDataScopeChain; 4584 r[RegisterFile::CallerRegisters] = ARG_r; 4585 // RegisterFile::ReturnPC is set by callee 4586 // RegisterFile::ReturnValueRegister is set by caller 4587 r[RegisterFile::ArgumentCount] = ARG_int3; // original argument count (for the sake of the "arguments" object) 4588 r[RegisterFile::Callee] = ARG_src1; 4589 r[RegisterFile::OptionalCalleeArguments] = nullJSValue; 4590 4591 ARG_setR(r); 4592 4593 return newCodeBlock->ctiCode; 4591 VM_THROW_EXCEPTION_2(); 4592 } 4593 4594 VoidPtrPair pair = { newCodeBlock, r }; 4595 return pair; 4594 4596 } 4595 4597 … … 4743 4745 } 4744 4746 4745 void*Machine::cti_op_construct_JSConstruct(CTI_ARGS)4747 VoidPtrPair Machine::cti_op_construct_JSConstruct(CTI_ARGS) 4746 4748 { 4747 4749 RegisterFile* registerFile = ARG_registerFile; 4748 4750 Register* r = ARG_r; 4749 4751 4750 JS Value* constrVal = ARG_src1;4752 JSFunction* constructor = static_cast<JSFunction*>(ARG_src1); 4751 4753 JSValue* constrProtoVal = ARG_src2; 4752 4754 int firstArg = ARG_int3; … … 4756 4758 #ifndef NDEBUG 4757 4759 ConstructData constructData; 4758 ASSERT( constrVal->getConstructData(constructData) == ConstructTypeJS);4760 ASSERT(ARG_src1->getConstructData(constructData) == ConstructTypeJS); 4759 4761 #endif 4760 4761 JSFunction* constructor = static_cast<JSFunction*>(constrVal);4762 4762 4763 4763 if (*ARG_profilerReference) … … 4780 4780 if (UNLIKELY(!r)) { 4781 4781 ARG_globalData->exception = createStackOverflowError(CallFrame::create(ARG_r)); 4782 VM_THROW_EXCEPTION(); 4783 } 4784 4785 r[RegisterFile::CodeBlock] = newCodeBlock; 4786 r[RegisterFile::ScopeChain] = callDataScopeChain; 4787 r[RegisterFile::CallerRegisters] = ARG_r; 4788 // RegisterFile::ReturnPC is set by callee 4789 // RegisterFile::ReturnValueRegister is set by caller 4790 r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object) 4791 r[RegisterFile::Callee] = constructor; 4792 r[RegisterFile::OptionalCalleeArguments] = nullJSValue; 4793 4794 ARG_setR(r); 4795 return newCodeBlock->ctiCode; 4782 VM_THROW_EXCEPTION_2(); 4783 } 4784 4785 VoidPtrPair pair = { newCodeBlock, r }; 4786 return pair; 4796 4787 } 4797 4788 … … 4865 4856 } 4866 4857 4867 JSValue*Machine::cti_op_resolve_func(CTI_ARGS)4858 VoidPtrPair Machine::cti_op_resolve_func(CTI_ARGS) 4868 4859 { 4869 4860 ExecState* exec = ARG_exec; … … 4895 4886 VM_CHECK_EXCEPTION_AT_END(); 4896 4887 4897 ARG_set2ndResult(result);4898 return thisObj;4888 VoidPtrPair pair = { thisObj, result }; 4889 return pair; 4899 4890 } 4900 4891 ++iter; … … 4905 4896 unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS); 4906 4897 exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock)); 4907 VM_THROW_EXCEPTION ();4898 VM_THROW_EXCEPTION_2(); 4908 4899 } 4909 4900 … … 5139 5130 } 5140 5131 5141 JSValue*Machine::cti_op_post_inc(CTI_ARGS)5132 VoidPtrPair Machine::cti_op_post_inc(CTI_ARGS) 5142 5133 { 5143 5134 JSValue* v = ARG_src1; … … 5146 5137 5147 5138 JSValue* number = v->toJSNumber(exec); 5148 VM_CHECK_EXCEPTION(); 5149 ARG_set2ndResult(jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1)); 5150 return number; 5139 VM_CHECK_EXCEPTION_2(); 5140 5141 VoidPtrPair pair = { number, jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1) }; 5142 return pair; 5151 5143 } 5152 5144 … … 5230 5222 } 5231 5223 5232 JSValue*Machine::cti_op_resolve_with_base(CTI_ARGS)5224 VoidPtrPair Machine::cti_op_resolve_with_base(CTI_ARGS) 5233 5225 { 5234 5226 ExecState* exec = ARG_exec; … … 5251 5243 JSValue* result = slot.getValue(exec, ident); 5252 5244 VM_CHECK_EXCEPTION_AT_END(); 5253 ARG_set2ndResult(result); 5254 return base; 5245 5246 VoidPtrPair pair = { base, result }; 5247 return pair; 5255 5248 } 5256 5249 ++iter; … … 5261 5254 unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS); 5262 5255 exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock)); 5263 VM_THROW_EXCEPTION ();5256 VM_THROW_EXCEPTION_2(); 5264 5257 } 5265 5258 … … 5302 5295 } 5303 5296 5304 JSValue*Machine::cti_op_post_dec(CTI_ARGS)5297 VoidPtrPair Machine::cti_op_post_dec(CTI_ARGS) 5305 5298 { 5306 5299 JSValue* v = ARG_src1; … … 5309 5302 5310 5303 JSValue* number = v->toJSNumber(exec); 5311 VM_CHECK_EXCEPTION ();5312 5313 ARG_set2ndResult(jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1));5314 return number;5304 VM_CHECK_EXCEPTION_2(); 5305 5306 VoidPtrPair pair = { number, jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1) }; 5307 return pair; 5315 5308 } 5316 5309 -
trunk/JavaScriptCore/VM/Machine.h
r37366 r37386 162 162 static JSValue* SFX_CALL cti_op_mul(CTI_ARGS); 163 163 static JSValue* SFX_CALL cti_op_new_func(CTI_ARGS); 164 static void*SFX_CALL cti_op_call_JSFunction(CTI_ARGS);164 static VoidPtrPair SFX_CALL cti_op_call_JSFunction(CTI_ARGS); 165 165 static JSValue* SFX_CALL cti_op_call_NotJSFunction(CTI_ARGS); 166 166 static void SFX_CALL cti_op_create_arguments(CTI_ARGS); … … 172 172 static JSValue* SFX_CALL cti_op_resolve(CTI_ARGS); 173 173 static JSValue* SFX_CALL cti_op_resolve_global(CTI_ARGS); 174 static void*SFX_CALL cti_op_construct_JSConstruct(CTI_ARGS);174 static VoidPtrPair SFX_CALL cti_op_construct_JSConstruct(CTI_ARGS); 175 175 static JSValue* SFX_CALL cti_op_construct_NotJSConstruct(CTI_ARGS); 176 176 static JSValue* SFX_CALL cti_op_get_by_val(CTI_ARGS); 177 static JSValue*SFX_CALL cti_op_resolve_func(CTI_ARGS);177 static VoidPtrPair SFX_CALL cti_op_resolve_func(CTI_ARGS); 178 178 static JSValue* SFX_CALL cti_op_sub(CTI_ARGS); 179 179 static void SFX_CALL cti_op_put_by_val(CTI_ARGS); … … 189 189 static JSValue* SFX_CALL cti_op_not(CTI_ARGS); 190 190 static int SFX_CALL cti_op_jtrue(CTI_ARGS); 191 static JSValue*SFX_CALL cti_op_post_inc(CTI_ARGS);191 static VoidPtrPair SFX_CALL cti_op_post_inc(CTI_ARGS); 192 192 static JSValue* SFX_CALL cti_op_eq(CTI_ARGS); 193 193 static JSValue* SFX_CALL cti_op_lshift(CTI_ARGS); … … 195 195 static JSValue* SFX_CALL cti_op_rshift(CTI_ARGS); 196 196 static JSValue* SFX_CALL cti_op_bitnot(CTI_ARGS); 197 static JSValue*SFX_CALL cti_op_resolve_with_base(CTI_ARGS);197 static VoidPtrPair SFX_CALL cti_op_resolve_with_base(CTI_ARGS); 198 198 static JSValue* SFX_CALL cti_op_new_func_exp(CTI_ARGS); 199 199 static JSValue* SFX_CALL cti_op_mod(CTI_ARGS); 200 200 static JSValue* SFX_CALL cti_op_less(CTI_ARGS); 201 201 static JSValue* SFX_CALL cti_op_neq(CTI_ARGS); 202 static JSValue*SFX_CALL cti_op_post_dec(CTI_ARGS);202 static VoidPtrPair SFX_CALL cti_op_post_dec(CTI_ARGS); 203 203 static JSValue* SFX_CALL cti_op_urshift(CTI_ARGS); 204 204 static JSValue* SFX_CALL cti_op_bitxor(CTI_ARGS); -
trunk/JavaScriptCore/kjs/JSFunction.h
r37184 r37386 39 39 40 40 class JSFunction : public InternalFunction { 41 friend class CTI; 41 42 friend class Machine; 42 43 -
trunk/JavaScriptCore/kjs/ScopeChain.h
r37259 r37386 154 154 155 155 class ScopeChain { 156 friend class CTI; 156 157 public: 157 158 ScopeChain(NoScopeChain)
Note:
See TracChangeset
for help on using the changeset viewer.