Changeset 36821 in webkit for trunk/JavaScriptCore/VM/Machine.cpp
- Timestamp:
- Sep 23, 2008, 5:27:18 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/Machine.cpp
r36808 r36821 84 84 #endif 85 85 86 #if ENABLE(CTI) 87 88 ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock* codeBlock, void* pc) 89 { 90 if (pc >= codeBlock->instructions.begin() && pc < codeBlock->instructions.end()) 91 return static_cast<Instruction*>(pc); 92 93 ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(pc)); 94 unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(pc); 95 return codeBlock->instructions.begin() + vPCIndex; 96 } 97 98 #else // #ENABLE(CTI) 99 100 ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock*, void* pc) 101 { 102 return static_cast<Instruction*>(pc); 103 } 104 105 #endif // #ENABLE(CTI) 106 86 107 // Returns the depth of the scope chain within a given call frame. 87 108 static int depth(CodeBlock* codeBlock, ScopeChain& sc) … … 499 520 } 500 521 501 ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int arg v, int argc, JSValue* function)522 ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argc, JSValue* function) 502 523 { 503 524 callFrame[RegisterFile::CallerCodeBlock] = codeBlock; 504 callFrame[RegisterFile::ReturnVPC] = vPC + 1;505 525 callFrame[RegisterFile::CallerScopeChain] = scopeChain; 506 526 callFrame[RegisterFile::CallerRegisters] = r; 527 callFrame[RegisterFile::ReturnPC] = vPC + 1; 507 528 callFrame[RegisterFile::ReturnValueRegister] = returnValueRegister; 508 callFrame[RegisterFile::ArgumentStartRegister] = argv; // original argument vector (for the sake of the "arguments" object)509 529 callFrame[RegisterFile::ArgumentCount] = argc; // original argument count (for the sake of the "arguments" object) 510 530 callFrame[RegisterFile::Callee] = function; … … 512 532 } 513 533 514 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* registerBase, Register* r, int argv, int argc, JSValue*& exceptionValue) 515 { 516 size_t registerOffset = argv + newCodeBlock->numLocals; 517 size_t size = r - registerBase + registerOffset + newCodeBlock->numConstants + newCodeBlock->numTemporaries; 534 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* registerBase, Register* r, size_t registerOffset, int argc, JSValue*& exceptionValue) 535 { 536 size_t size = r - registerBase + registerOffset + newCodeBlock->numCalleeRegisters; 518 537 519 538 if (argc == newCodeBlock->numParameters) { // correct number of arguments … … 524 543 r += registerOffset; 525 544 } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks 545 size_t omittedArgCount = newCodeBlock->numParameters - argc; 546 registerOffset += omittedArgCount; 547 size += omittedArgCount; 526 548 if (!registerFile->grow(size)) { 527 549 exceptionValue = createStackOverflowError(exec); … … 530 552 r += registerOffset; 531 553 532 int omittedArgCount = newCodeBlock->numParameters - argc; 533 Register* endOfParams = r - newCodeBlock->numVars; 534 for (Register* it = endOfParams - omittedArgCount; it != endOfParams; ++it) 535 (*it) = jsUndefined(); 536 } else { // too many arguments -- copy return info and expected arguments, leaving the extra arguments behind 537 int shift = argc + RegisterFile::CallFrameHeaderSize; 538 registerOffset += shift; 539 size += shift; 554 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; 555 for (size_t i = 0; i < omittedArgCount; ++i) 556 argv[i] = jsUndefined(); 557 } else { // too many arguments -- copy expected arguments, leaving the extra arguments behind 558 size_t numParameters = newCodeBlock->numParameters; 559 registerOffset += numParameters; 560 size += numParameters; 540 561 541 562 if (!registerFile->grow(size)) { … … 545 566 r += registerOffset; 546 567 547 Register* it = r - newCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize - shift; 548 Register* end = it + RegisterFile::CallFrameHeaderSize + newCodeBlock->numParameters; 549 for ( ; it != end; ++it) 550 *(it + shift) = *it; 551 } 552 553 // initialize local variable slots 554 #if ENABLE(CTI) 555 if (!newCodeBlock->ctiCode) 556 #endif 557 { 558 568 Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argc; 569 for (size_t i = 0; i < numParameters; ++i) 570 argv[i + argc] = argv[i]; 559 571 } 560 572 … … 566 578 if (newCodeBlock->needsFullScopeChain) { 567 579 JSActivation* activation = new (exec) JSActivation(exec, functionBodyNode, r); 568 r[RegisterFile::OptionalCalleeActivation - RegisterFile::CallFrameHeaderSize - newCodeBlock->numLocals] = activation;580 r[RegisterFile::OptionalCalleeActivation] = activation; 569 581 570 582 return callDataScopeChain->copy()->push(activation); … … 602 614 JSValue* result = 0; 603 615 if (evalNode) 604 result = exec->globalData().machine->execute(evalNode.get(), exec, thisObj, r - registerFile->base() + argv + argc, scopeChain, &exceptionValue);616 result = exec->globalData().machine->execute(evalNode.get(), exec, thisObj, r - registerFile->base() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue); 605 617 606 618 if (*profiler) … … 684 696 } 685 697 686 it = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize; 687 printf("[CallerCodeBlock] | %10p | %10p \n", it, (*it).v()); ++it; 688 printf("[ReturnVPC] | %10p | %10p \n", it, (*it).v()); ++it; 689 printf("[CallerScopeChain] | %10p | %10p \n", it, (*it).v()); ++it; 690 printf("[CallerRegisterOffset] | %10p | %10p \n", it, (*it).v()); ++it; 691 printf("[ReturnValueRegister] | %10p | %10p \n", it, (*it).v()); ++it; 692 printf("[ArgumentStartRegister] | %10p | %10p \n", it, (*it).v()); ++it; 693 printf("[ArgumentCount] | %10p | %10p \n", it, (*it).v()); ++it; 694 printf("[Callee] | %10p | %10p \n", it, (*it).v()); ++it; 695 printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it; 696 printf("----------------------------------------------------\n"); 697 698 it = r - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters; 698 699 printf("[this] | %10p | %10p \n", it, (*it).v()); ++it; 699 700 end = it + max(codeBlock->numParameters - 1, 0); // - 1 to skip "this" … … 706 707 printf("----------------------------------------------------\n"); 707 708 708 if (codeBlock->codeType != GlobalCode) { 709 end = it + codeBlock->numVars; 710 if (it != end) { 711 do { 712 printf("[var] | %10p | %10p \n", it, (*it).v()); 713 ++it; 714 } while (it != end); 715 printf("----------------------------------------------------\n"); 716 } 717 } 718 719 end = it + codeBlock->numTemporaries; 709 printf("[CallerCodeBlock] | %10p | %10p \n", it, (*it).v()); ++it; 710 printf("[CallerScopeChain] | %10p | %10p \n", it, (*it).v()); ++it; 711 printf("[CallerRegisters] | %10p | %10p \n", it, (*it).v()); ++it; 712 printf("[ReturnPC] | %10p | %10p \n", it, (*it).v()); ++it; 713 printf("[ReturnValueRegister] | %10p | %10p \n", it, (*it).v()); ++it; 714 printf("[ArgumentCount] | %10p | %10p \n", it, (*it).v()); ++it; 715 printf("[Callee] | %10p | %10p \n", it, (*it).v()); ++it; 716 printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it; 717 printf("----------------------------------------------------\n"); 718 719 int registerCount = 0; 720 721 end = it + codeBlock->numVars; 720 722 if (it != end) { 721 723 do { 722 printf("[ temp] | %10p | %10p \n", it, (*it).v());724 printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v()); 723 725 ++it; 726 ++registerCount; 724 727 } while (it != end); 725 728 } 729 printf("----------------------------------------------------\n"); 730 731 end = it + codeBlock->numConstants; 732 if (it != end) { 733 do { 734 printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v()); 735 ++it; 736 ++registerCount; 737 } while (it != end); 738 } 739 printf("----------------------------------------------------\n"); 740 741 end = it + codeBlock->numCalleeRegisters - codeBlock->numConstants - codeBlock->numVars; 742 if (it != end) { 743 do { 744 printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v()); 745 ++it; 746 ++registerCount; 747 } while (it != end); 748 } 749 printf("----------------------------------------------------\n"); 726 750 } 727 751 … … 746 770 { 747 771 CodeBlock* oldCodeBlock = codeBlock; 748 Register* callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;749 772 750 773 if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) { 751 774 DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue); 752 if ( callFrame[RegisterFile::Callee].jsValue(exec))775 if (r[RegisterFile::Callee].jsValue(exec)) 753 776 debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine()); 754 777 else … … 757 780 758 781 if (Profiler* profiler = *Profiler::enabledProfilerReference()) { 759 if ( callFrame[RegisterFile::Callee].jsValue(exec))760 profiler->didExecute(exec, static_cast<JSObject*>( callFrame[RegisterFile::Callee].jsValue(exec)));782 if (r[RegisterFile::Callee].jsValue(exec)) 783 profiler->didExecute(exec, static_cast<JSObject*>(r[RegisterFile::Callee].jsValue(exec))); 761 784 else 762 785 profiler->didExecute(exec, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo()); … … 767 790 768 791 // If this call frame created an activation, tear it off. 769 if (JSActivation* activation = static_cast<JSActivation*>( callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {792 if (JSActivation* activation = static_cast<JSActivation*>(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) { 770 793 ASSERT(activation->isActivationObject()); 771 794 activation->copyRegisters(); 772 795 } 773 796 774 codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();797 codeBlock = r[RegisterFile::CallerCodeBlock].codeBlock(); 775 798 if (!codeBlock) 776 799 return false; 777 800 778 scopeChain = callFrame[RegisterFile::CallerScopeChain].scopeChain();779 r = callFrame[RegisterFile::CallerRegisters].r();780 exec->m_callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;781 vPC = callFrame[RegisterFile::ReturnVPC].vPC();801 scopeChain = r[RegisterFile::CallerScopeChain].scopeChain(); 802 vPC = vPCForPC(codeBlock, r[RegisterFile::ReturnPC].v()); 803 r = r[RegisterFile::CallerRegisters].r(); 804 exec->m_callFrame = r; 782 805 783 806 return true; … … 863 886 864 887 size_t oldSize = m_registerFile.size(); 865 size_t newSize = oldSize + RegisterFile::CallFrameHeaderSize + codeBlock->numVars + codeBlock->numConstants + codeBlock->numTemporaries;888 size_t newSize = oldSize + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->numCalleeRegisters; 866 889 if (!m_registerFile.grow(newSize)) { 867 890 *exception = createStackOverflowError(exec); … … 873 896 globalObject->copyGlobalsTo(m_registerFile); 874 897 875 Register* callFrame = m_registerFile.base() + oldSize; 876 877 // a 0 codeBlock indicates a built-in caller 878 initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0); 879 880 Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars; 898 Register* r = m_registerFile.base() + oldSize + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize; 881 899 r[codeBlock->thisRegister] = thisObj; 882 883 for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i) 884 r[i] = codeBlock->constantRegisters[i]; 900 initializeCallFrame(r, 0, 0, 0, 0, 0, 0, 0); 885 901 886 902 if (codeBlock->needsFullScopeChain) … … 922 938 } 923 939 924 int argv = RegisterFile::CallFrameHeaderSize;925 int argc = args.size() + 1; // implicit "this" parameter926 927 940 size_t oldSize = m_registerFile.size(); 928 if (!m_registerFile.grow(oldSize + RegisterFile::CallFrameHeaderSize + argc)) { 941 int argc = 1 + args.size(); // implicit "this" parameter 942 943 if (!m_registerFile.grow(oldSize + argc)) { 929 944 *exception = createStackOverflowError(exec); 930 945 return 0; 931 946 } 932 947 933 Register* callFrame = m_registerFile.base() + oldSize; 934 935 // put args in place, including "this" 936 Register* dst = callFrame + RegisterFile::CallFrameHeaderSize; 937 (*dst) = thisObj; 948 Register* argv = m_registerFile.base() + oldSize; 949 size_t dst = 0; 950 argv[dst] = thisObj; 938 951 939 952 ArgList::const_iterator end = args.end(); 940 953 for (ArgList::const_iterator it = args.begin(); it != end; ++it) 941 (*++dst) = *it; 942 943 // a 0 codeBlock indicates a built-in caller 944 initializeCallFrame(callFrame, 0, 0, 0, callFrame, 0, argv, argc, function); 954 argv[++dst] = *it; 945 955 946 956 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(scopeChain); 947 Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), callFrame, argv, argc, *exception);948 if ( *exception) {957 Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), argv, argc + RegisterFile::CallFrameHeaderSize, argc, *exception); 958 if (UNLIKELY(*exception != 0)) { 949 959 m_registerFile.shrink(oldSize); 950 960 return 0; 951 961 } 952 953 ExecState newExec(exec, &m_registerFile, scopeChain, callFrame); 962 // a 0 codeBlock indicates a built-in caller 963 initializeCallFrame(r, 0, 0, 0, argv, 0, argc, function); 964 965 ExecState newExec(exec, &m_registerFile, scopeChain, r); 954 966 955 967 Profiler** profiler = Profiler::enabledProfilerReference(); … … 974 986 } 975 987 988 JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception) 989 { 990 return execute(evalNode, exec, thisObj, m_registerFile.size() + evalNode->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception); 991 } 992 976 993 JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception) 977 994 { … … 1016 1033 1017 1034 size_t oldSize = m_registerFile.size(); 1018 size_t newSize = registerOffset + codeBlock->num Vars + codeBlock->numConstants + codeBlock->numTemporaries + RegisterFile::CallFrameHeaderSize;1035 size_t newSize = registerOffset + codeBlock->numCalleeRegisters; 1019 1036 if (!m_registerFile.grow(newSize)) { 1020 1037 *exception = createStackOverflowError(exec); … … 1022 1039 } 1023 1040 1024 Register* callFrame= m_registerFile.base() + registerOffset;1041 Register* r = m_registerFile.base() + registerOffset; 1025 1042 1026 1043 // a 0 codeBlock indicates a built-in caller 1027 initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0);1028 1029 Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;1030 1044 r[codeBlock->thisRegister] = thisObj; 1031 1032 for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i) 1033 r[i] = codeBlock->constantRegisters[i]; 1045 initializeCallFrame(r, 0, 0, 0, 0, 0, 0, 0); 1034 1046 1035 1047 if (codeBlock->needsFullScopeChain) … … 3180 3192 int firstArg = (++vPC)->u.operand; 3181 3193 int argCount = (++vPC)->u.operand; 3194 ++vPC; // registerOffset 3182 3195 3183 3196 JSValue* funcVal = r[func].jsValue(exec); … … 3199 3212 // this instruction as a normal function call, supplying the proper 'this' 3200 3213 // value. 3201 vPC -= 5;3214 vPC -= 6; 3202 3215 r[thisVal] = baseVal->toThisObject(exec); 3203 3216 … … 3211 3224 } 3212 3225 BEGIN_OPCODE(op_call) { 3213 /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) 3226 /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n) 3214 3227 3215 3228 Perform a function call. Specifically, call register func … … 3252 3265 int firstArg = (++vPC)->u.operand; 3253 3266 int argCount = (++vPC)->u.operand; 3267 int registerOffset = (++vPC)->u.operand; 3254 3268 3255 3269 JSValue* v = r[func].jsValue(exec); … … 3258 3272 CallType callType = v->getCallData(callData); 3259 3273 3260 if (*enabledProfilerReference)3261 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));3262 3263 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;3264 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, v);3265 exec->m_callFrame = callFrame;3266 3267 3274 if (callType == CallTypeJS) { 3268 3269 3275 ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 3270 3276 FunctionBodyNode* functionBodyNode = callData.js.functionBody; … … 3272 3278 3273 3279 r[firstArg] = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : r[thisVal].jsValue(exec); 3274 3275 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue); 3280 3281 Register* savedR = r; 3282 3283 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue); 3276 3284 if (UNLIKELY(exceptionValue != 0)) 3277 3285 goto vm_throw; 3286 3287 initializeCallFrame(r, codeBlock, vPC, scopeChain, savedR, dst, argCount, v); 3288 exec->m_callFrame = r; 3289 3290 if (*enabledProfilerReference) 3291 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v)); 3278 3292 3279 3293 codeBlock = newCodeBlock; … … 3284 3298 OpcodeStats::resetLastInstruction(); 3285 3299 #endif 3286 3300 3287 3301 NEXT_OPCODE; 3288 3302 } … … 3292 3306 ArgList args(r + firstArg + 1, argCount - 1); 3293 3307 3308 initializeCallFrame(r + registerOffset, codeBlock, vPC, scopeChain, r, dst, argCount, v); 3309 exec->m_callFrame = r + registerOffset; 3310 3311 if (*enabledProfilerReference) 3312 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v)); 3313 3294 3314 MACHINE_SAMPLING_callingHostFunction(); 3295 3315 3296 3316 JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(v), thisValue, args); 3297 exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;3317 exec->m_callFrame = r; 3298 3318 VM_CHECK_EXCEPTION(); 3299 3319 … … 3310 3330 3311 3331 exceptionValue = createNotAFunctionError(exec, v, vPC, codeBlock); 3312 exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;3313 3332 goto vm_throw; 3314 3333 } … … 3325 3344 int result = (++vPC)->u.operand; 3326 3345 3327 Register* callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize; 3328 if (JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) { 3346 if (JSActivation* activation = static_cast<JSActivation*>(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) { 3329 3347 ASSERT(!codeBlock->needsFullScopeChain || scopeChain->object == activation); 3330 3348 ASSERT(activation->isActivationObject()); … … 3333 3351 3334 3352 if (*enabledProfilerReference) 3335 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>( callFrame[RegisterFile::Callee].jsValue(exec)));3353 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(r[RegisterFile::Callee].jsValue(exec))); 3336 3354 3337 3355 if (codeBlock->needsFullScopeChain) … … 3340 3358 JSValue* returnValue = r[result].jsValue(exec); 3341 3359 3342 codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();3360 codeBlock = r[RegisterFile::CallerCodeBlock].codeBlock(); 3343 3361 if (!codeBlock) 3344 3362 return returnValue; 3345 3363 3346 vPC = callFrame[RegisterFile::ReturnVPC].vPC();3347 setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());3348 r = callFrame[RegisterFile::CallerRegisters].r();3349 exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;3350 int dst = callFrame[RegisterFile::ReturnValueRegister].i();3364 vPC = r[RegisterFile::ReturnPC].vPC(); 3365 setScopeChain(exec, scopeChain, r[RegisterFile::CallerScopeChain].scopeChain()); 3366 int dst = r[RegisterFile::ReturnValueRegister].i(); 3367 r = r[RegisterFile::CallerRegisters].r(); 3368 exec->m_callFrame = r; 3351 3369 r[dst] = returnValue; 3352 3370 3353 3371 NEXT_OPCODE; 3354 3372 } 3355 BEGIN_OPCODE(op_initialise_locals) { 3356 for (Register* it = r - codeBlock->numVars + (codeBlock->codeType == EvalCode); it < r; ++it) 3357 (*it) = jsUndefined(); 3358 for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i) 3359 r[i] = codeBlock->constantRegisters[i]; 3373 BEGIN_OPCODE(op_init) { 3374 size_t i = 0; 3375 3376 for (size_t count = codeBlock->numVars; i < count; ++i) 3377 r[i] = jsUndefined(); 3378 3379 for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j) 3380 r[i] = codeBlock->constantRegisters[j]; 3381 3360 3382 ++vPC; 3361 3383 NEXT_OPCODE; 3362 3384 } 3363 3385 BEGIN_OPCODE(op_construct) { 3364 /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) 3386 /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n) 3365 3387 3366 3388 Invoke register "constr" as a constructor. For JS … … 3381 3403 int firstArg = (++vPC)->u.operand; 3382 3404 int argCount = (++vPC)->u.operand; 3383 3384 JSValue* constrVal = r[constr].jsValue(exec); 3405 int registerOffset = (++vPC)->u.operand; 3406 3407 JSValue* v = r[constr].jsValue(exec); 3385 3408 3386 3409 ConstructData constructData; 3387 ConstructType constructType = constrVal->getConstructData(constructData); 3388 3389 // Removing this line of code causes a measurable regression on squirrelfish. 3390 JSObject* constructor = static_cast<JSObject*>(constrVal); 3410 ConstructType constructType = v->getConstructData(constructData); 3391 3411 3392 3412 if (constructType == ConstructTypeJS) { 3393 3413 if (*enabledProfilerReference) 3394 (*enabledProfilerReference)->willExecute(exec, constructor);3414 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v)); 3395 3415 3396 3416 StructureID* structure; … … 3408 3428 r[firstArg] = newObject; // "this" value 3409 3429 3410 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize; 3411 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, constructor); 3412 exec->m_callFrame = callFrame; 3413 3414 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue); 3415 if (exceptionValue) 3430 Register* savedR = r; 3431 3432 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue); 3433 if (UNLIKELY(exceptionValue != 0)) 3416 3434 goto vm_throw; 3435 3436 initializeCallFrame(r, codeBlock, vPC, scopeChain, savedR, dst, argCount, v); 3437 exec->m_callFrame = r; 3438 3439 if (*enabledProfilerReference) 3440 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v)); 3417 3441 3418 3442 codeBlock = newCodeBlock; … … 3420 3444 vPC = codeBlock->instructions.begin(); 3421 3445 3446 #if DUMP_OPCODE_STATS 3447 OpcodeStats::resetLastInstruction(); 3448 #endif 3449 3422 3450 NEXT_OPCODE; 3423 3451 } 3424 3452 3425 3453 if (constructType == ConstructTypeHost) { 3454 ArgList args(r + firstArg + 1, argCount - 1); 3455 3456 initializeCallFrame(r + registerOffset, codeBlock, vPC, scopeChain, r, dst, argCount, v); 3457 exec->m_callFrame = r + registerOffset; 3458 3426 3459 if (*enabledProfilerReference) 3427 (*enabledProfilerReference)->willExecute(exec, constructor); 3428 3429 ArgList args(r + firstArg + 1, argCount - 1); 3460 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v)); 3430 3461 3431 3462 MACHINE_SAMPLING_callingHostFunction(); 3432 3463 3433 JSValue* returnValue = constructData.native.function(exec, constructor, args); 3464 JSValue* returnValue = constructData.native.function(exec, static_cast<JSObject*>(v), args); 3465 exec->m_callFrame = r; 3434 3466 3435 3467 VM_CHECK_EXCEPTION(); … … 3437 3469 3438 3470 if (*enabledProfilerReference) 3439 (*enabledProfilerReference)->didExecute(exec, constructor);3471 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v)); 3440 3472 3441 3473 ++vPC; … … 3445 3477 ASSERT(constructType == ConstructTypeNone); 3446 3478 3447 exceptionValue = createNotAConstructorError(exec, constrVal, vPC, codeBlock);3479 exceptionValue = createNotAConstructorError(exec, v, vPC, codeBlock); 3448 3480 goto vm_throw; 3449 3481 } … … 3777 3809 JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec)); 3778 3810 if (!activation) { 3779 CodeBlock* codeBlock = &function->m_body->generatedByteCode(); 3780 activation = new (exec) JSActivation(exec, function->m_body, callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numLocals); 3811 activation = new (exec) JSActivation(exec, function->m_body, callFrame); 3781 3812 callFrame[RegisterFile::OptionalCalleeActivation] = activation; 3782 3813 } … … 3795 3826 return jsNull(); 3796 3827 3797 Register* callerCallFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;3828 Register* callerCallFrame = callFrame[RegisterFile::CallerRegisters].r(); 3798 3829 if (JSValue* caller = callerCallFrame[RegisterFile::Callee].jsValue(exec)) 3799 3830 return caller; … … 3816 3847 return; 3817 3848 3818 Instruction* vPC = callFrame[RegisterFile::ReturnVPC].vPC();3849 Instruction* vPC = vPCForPC(callerCodeBlock, callFrame[RegisterFile::ReturnPC].v()); 3819 3850 lineNumber = callerCodeBlock->lineNumberForVPC(vPC - 1); 3820 3851 sourceId = callerCodeBlock->ownerNode->sourceId(); … … 3847 3878 } 3848 3879 3849 callFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;3850 } 3851 } 3852 3853 void Machine::getArgumentsData(Register* callFrame, JSFunction*& function, Register*& argv, int& argc)3880 callFrame = callFrame[RegisterFile::CallerRegisters].r(); 3881 } 3882 } 3883 3884 void Machine::getArgumentsData(Register* callFrame, JSFunction*& function, int& firstParameterIndex, Register*& argv, int& argc) 3854 3885 { 3855 3886 function = static_cast<JSFunction*>(callFrame[RegisterFile::Callee].getJSValue()); 3856 3887 ASSERT(function->inherits(&JSFunction::info)); 3857 3858 argv = callFrame[RegisterFile::CallerRegisters].r() + callFrame[RegisterFile::ArgumentStartRegister].i() + 1; // + 1 to skip "this" 3859 argc = callFrame[RegisterFile::ArgumentCount].i() - 1; // - 1 to skip "this" 3888 3889 CodeBlock* codeBlock = &function->m_body->generatedByteCode(); 3890 int numParameters = codeBlock->numParameters; 3891 argc = callFrame[RegisterFile::ArgumentCount].i(); 3892 3893 if (argc <= numParameters) 3894 argv = callFrame - RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this" 3895 else 3896 argv = callFrame - RegisterFile::CallFrameHeaderSize - numParameters - argc + 1; // + 1 to skip "this" 3897 3898 argc -= 1; // - 1 to skip "this" 3899 firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this" 3860 3900 } 3861 3901 … … 4370 4410 Register* r = ARG_r; 4371 4411 4372 JSValue* exceptionValue = 0;4373 4412 Register* registerBase = registerFile->base(); 4374 4413 4375 4414 JSValue* funcVal = ARG_src1; 4376 JSValue* thisValue = ARG_src2; 4377 int firstArg = ARG_int3; 4378 int argCount = ARG_int4; 4379 4380 // In the JIT code before entering this function we wil have checked the vptr, 4381 // and know this is an object of type JSFunction. 4415 int registerOffset = ARG_int2; 4416 int argCount = ARG_int3; 4417 4382 4418 #ifndef NDEBUG 4383 4419 CallData callData; 4420 ASSERT(funcVal->getCallData(callData) == CallTypeJS); 4384 4421 #endif 4385 ASSERT(funcVal->getCallData(callData) == CallTypeJS);4386 4422 4387 4423 if (*ARG_profilerReference) … … 4392 4428 4393 4429 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain); 4394 4395 r[firstArg] = thisValue; 4396 4397 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize; 4398 exec->m_callFrame = callFrame; 4399 4400 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue); 4430 4431 Register* savedR = r; 4432 4433 JSValue* exceptionValue = 0; 4434 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue); 4401 4435 JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue); 4402 4436 4437 // RegisterFile::CallerCodeBlock is set by caller 4438 r[RegisterFile::CallerScopeChain] = ARG_scopeChain; 4439 r[RegisterFile::CallerRegisters] = savedR; 4440 // RegisterFile::ReturnPC is set by callee 4441 // RegisterFile::ReturnValueRegister is set by caller 4442 r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object) 4443 r[RegisterFile::Callee] = funcVal; 4444 r[RegisterFile::OptionalCalleeActivation] = nullJSValue; 4445 4446 exec->m_callFrame = r; 4403 4447 exec->m_scopeChain = callDataScopeChain; 4404 4448 … … 4434 4478 { 4435 4479 ExecState* exec = ARG_exec; 4436 Register* r = ARG_r;4437 4480 4438 4481 JSValue* funcVal = ARG_src1; 4439 JSValue* thisValue = ARG_src2;4440 int firstArg = ARG_int3;4441 int argCount = ARG_int4;4442 4482 4443 4483 CallData callData; … … 4447 4487 4448 4488 if (callType == CallTypeHost) { 4449 Register* oldCallFrame = exec->m_callFrame; 4450 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize; 4451 exec->m_callFrame = callFrame; 4489 int registerOffset = ARG_int2; 4490 int argCount = ARG_int3; 4491 Register* r = ARG_r + registerOffset; 4492 4493 initializeCallFrame(r, ARG_codeBlock, ARG_instr4, ARG_scopeChain, ARG_r, 0, argCount, funcVal); 4494 exec->m_callFrame = r; 4452 4495 4453 4496 if (*ARG_profilerReference) 4454 4497 (*ARG_profilerReference)->willExecute(exec, static_cast<JSObject*>(funcVal)); 4455 4498 4456 ArgList argList(r + firstArg + 1, argCount - 1); 4499 Register* argv = r - RegisterFile::CallFrameHeaderSize - argCount; 4500 ArgList argList(argv + 1, argCount - 1); 4457 4501 4458 4502 CTI_MACHINE_SAMPLING_callingHostFunction(); 4459 4503 4460 JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(funcVal), thisValue, argList); 4461 exec->m_callFrame = oldCallFrame; 4504 JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(funcVal), argv[0].jsValue(exec), argList); 4462 4505 VM_CHECK_EXCEPTION(JSValue*); 4463 4506 … … 4465 4508 (*ARG_profilerReference)->didExecute(exec, static_cast<JSObject*>(funcVal)); 4466 4509 4510 exec->m_callFrame = ARG_r; 4467 4511 return returnValue; 4468 4469 4512 } 4470 4513 4471 4514 ASSERT(callType == CallTypeNone); 4472 4515 4473 exec->setException(createNotAFunctionError(exec, funcVal, ARG_instr 5, ARG_codeBlock));4516 exec->setException(createNotAFunctionError(exec, funcVal, ARG_instr4, ARG_codeBlock)); 4474 4517 VM_CHECK_EXCEPTION_AT_END(); 4475 4518 return 0; … … 4479 4522 { 4480 4523 ExecState* exec = ARG_exec; 4481 Register* callFrame = ARG_r - ARG_codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;4524 Register* callFrame = ARG_r; 4482 4525 4483 4526 JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec)); … … 4493 4536 ExecState* exec = ARG_exec; 4494 4537 4495 Register* callFrame = ARG_r - ARG_codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;4538 Register* callFrame = ARG_r; 4496 4539 ASSERT(*ARG_profilerReference); 4497 4540 (*ARG_profilerReference)->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec))); … … 4544 4587 RegisterFile* registerFile = ARG_registerFile; 4545 4588 Register* r = ARG_r; 4546 ScopeChainNode* scopeChain = ARG_scopeChain; 4547 4548 JSValue* exceptionValue = 0; 4589 4549 4590 Register* registerBase = registerFile->base(); 4550 4591 … … 4552 4593 JSValue* constrProtoVal = ARG_src2; 4553 4594 int firstArg = ARG_int3; 4554 int argCount = ARG_int4; 4555 4595 int registerOffset = ARG_int4; 4596 int argCount = ARG_int5; 4597 4598 #ifndef NDEBUG 4556 4599 ConstructData constructData; 4557 #ifndef NDEBUG 4558 ConstructType constructType = 4600 ASSERT(constrVal->getConstructData(constructData) == ConstructTypeJS); 4559 4601 #endif 4560 constrVal->getConstructData(constructData); 4561 4562 // Removing this line of code causes a measurable regression on sunspider. 4563 JSObject* constructor = static_cast<JSObject*>(constrVal); 4564 4565 ASSERT(constructType == ConstructTypeJS); 4602 4603 JSFunction* constructor = static_cast<JSFunction*>(constrVal); 4566 4604 4567 4605 if (*ARG_profilerReference) … … 4572 4610 structure = static_cast<JSObject*>(constrProtoVal)->inheritorID(); 4573 4611 else 4574 structure = scopeChain->globalObject()->emptyObjectStructure();4612 structure = ARG_scopeChain->globalObject()->emptyObjectStructure(); 4575 4613 JSObject* newObject = new (exec) JSObject(structure); 4576 4614 4577 ScopeChainNode* callDataScopeChain = construct Data.js.scopeChain;4578 FunctionBodyNode* functionBodyNode = construct Data.js.functionBody;4615 ScopeChainNode* callDataScopeChain = constructor->m_scopeChain.node(); 4616 FunctionBodyNode* functionBodyNode = constructor->m_body.get(); 4579 4617 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain); 4580 4618 4581 4619 r[firstArg] = newObject; // "this" value 4582 4620 4583 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;4584 exec->m_callFrame = callFrame; 4585 4586 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);4621 Register* savedR = r; 4622 4623 JSValue* exceptionValue = 0; 4624 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue); 4587 4625 JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue); 4588 4626 4627 // RegisterFile::CallerCodeBlock is set by caller 4628 r[RegisterFile::CallerScopeChain] = ARG_scopeChain; 4629 r[RegisterFile::CallerRegisters] = savedR; 4630 // RegisterFile::ReturnPC is set by callee 4631 // RegisterFile::ReturnValueRegister is set by caller 4632 r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object) 4633 r[RegisterFile::Callee] = constructor; 4634 r[RegisterFile::OptionalCalleeActivation] = nullJSValue; 4635 4636 exec->m_callFrame = r; 4589 4637 exec->m_scopeChain = callDataScopeChain; 4590 4638 … … 4602 4650 JSValue* constrVal = ARG_src1; 4603 4651 int firstArg = ARG_int3; 4604 int argCount = ARG_int 4;4652 int argCount = ARG_int5; 4605 4653 4606 4654 ConstructData constructData; 4607 4655 ConstructType constructType = constrVal->getConstructData(constructData); 4608 4656 4609 // Removing this line of code causes a measurable regression on squirrelfish.4610 4657 JSObject* constructor = static_cast<JSObject*>(constrVal); 4611 4658 4612 ASSERT(constructType != ConstructTypeJS);4613 4614 4659 if (constructType == ConstructTypeHost) { 4615 Register* oldCallFrame = exec->m_callFrame;4616 Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;4617 exec->m_callFrame = callFrame;4618 4619 4660 if (*ARG_profilerReference) 4620 4661 (*ARG_profilerReference)->willExecute(exec, constructor); … … 4625 4666 4626 4667 JSValue* returnValue = constructData.native.function(exec, constructor, argList); 4627 exec->m_callFrame = oldCallFrame;4628 4668 VM_CHECK_EXCEPTION(JSValue*); 4629 4669 … … 4636 4676 ASSERT(constructType == ConstructTypeNone); 4637 4677 4638 exec->setException(createNotAConstructorError(exec, constrVal, ARG_instr 5, ARG_codeBlock));4678 exec->setException(createNotAConstructorError(exec, constrVal, ARG_instr6, ARG_codeBlock)); 4639 4679 VM_CHECK_EXCEPTION_AT_END(); 4640 4680 return 0; … … 5194 5234 5195 5235 Machine* machine = exec->machine(); 5196 JSValue* exceptionValue = 0;5197 5236 5198 5237 JSValue* funcVal = ARG_src1; 5199 JSValue* baseVal = ARG_src2;5200 int firstArg= ARG_int3;5201 int argCount = ARG_int4;5238 int registerOffset = ARG_int2; 5239 int argCount = ARG_int3; 5240 JSValue* baseVal = ARG_src5; 5202 5241 5203 5242 if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) { 5204 5243 JSObject* thisObject = static_cast<JSObject*>(r[codeBlock->thisRegister].jsValue(exec)); 5205 JSValue* result = machine->callEval(exec, codeBlock, thisObject, scopeChain, registerFile, r, firstArg, argCount, exceptionValue); 5244 JSValue* exceptionValue = 0; 5245 JSValue* result = machine->callEval(exec, codeBlock, thisObject, scopeChain, registerFile, r, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue); 5206 5246 JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue); 5207 5247 return result;
Note:
See TracChangeset
for help on using the changeset viewer.