Changeset 106067 in webkit for trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
- Timestamp:
- Jan 26, 2012, 5:15:16 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r105894 r106067 62 62 return calleeAsFunction->executable() != codeBlock()->ownerExecutable(); 63 63 } 64 65 CallFrame* CallFrame::trueCallFrame(AbstractPC pc) 66 { 67 // Am I an inline call frame? If so, we're done. 68 if (isInlineCallFrame()) 69 return this; 70 71 // If I don't have a code block, then I'm not DFG code, so I'm the true call frame. 72 CodeBlock* machineCodeBlock = codeBlock(); 73 if (!machineCodeBlock) 74 return this; 75 76 // If the code block does not have any code origins, then there was no inlining, so 77 // I'm done. 78 if (!machineCodeBlock->hasCodeOrigins()) 79 return this; 80 81 // At this point the PC must be due either to the DFG, or it must be unset. 82 ASSERT(pc.hasJITReturnAddress() || !pc); 83 84 // Try to determine the CodeOrigin. If we don't have a pc set then the only way 85 // that this makes sense is if the CodeOrigin index was set in the call frame. 86 // FIXME: Note that you will see "Not currently in inlined code" comments below. 87 // Currently, we do not record code origins for code that is not inlined, because 88 // the only thing that we use code origins for is determining the inline stack. 89 // But in the future, we'll want to use this same functionality (having a code 90 // origin mapping for any calls out of JIT code) to determine the PC at any point 91 // in the stack even if not in inlined code. When that happens, the code below 92 // will have to change the way it detects the presence of inlining: it will always 93 // get a code origin, but sometimes, that code origin will not have an inline call 94 // frame. In that case, this method should bail and return this. 95 CodeOrigin codeOrigin; 96 if (pc.isSet()) { 97 ReturnAddressPtr currentReturnPC = pc.jitReturnAddress(); 98 99 if (!machineCodeBlock->codeOriginForReturn(currentReturnPC, codeOrigin)) 100 return this; // Not currently in inlined code. 101 } else { 102 unsigned index = codeOriginIndexForDFGWithInlining(); 103 if (index == UINT_MAX) 104 return this; // Not currently in inlined code. 105 106 codeOrigin = machineCodeBlock->codeOrigin(index); 107 } 108 109 for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { 110 InlineCallFrame* nextInlineCallFrame = inlineCallFrame->caller.inlineCallFrame; 111 112 CallFrame* inlinedCaller = this + inlineCallFrame->stackOffset; 113 114 JSFunction* calleeAsFunction = inlineCallFrame->callee.get(); 115 116 // Fill in the inlinedCaller 117 inlinedCaller->setCodeBlock(machineCodeBlock); 118 119 inlinedCaller->setScopeChain(calleeAsFunction->scope()); 120 if (nextInlineCallFrame) 121 inlinedCaller->setCallerFrame(this + nextInlineCallFrame->stackOffset); 122 else 123 inlinedCaller->setCallerFrame(this); 124 125 inlinedCaller->setInlineCallFrame(inlineCallFrame); 126 inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size()); 127 inlinedCaller->setCallee(calleeAsFunction); 128 129 inlineCallFrame = nextInlineCallFrame; 130 } 131 132 return this + codeOrigin.inlineCallFrame->stackOffset; 133 } 64 134 65 135 CallFrame* CallFrame::trueCallerFrame() … … 71 141 // machineCaller -> The caller according to the machine, which may be zero or 72 142 // more frames above the true caller due to inlining. 73 //74 // trueCaller -> The real caller.75 143 76 144 // Am I an inline call frame? If so, we're done. … … 84 152 return 0; 85 153 ASSERT(!machineCaller->isInlineCallFrame()); 86 if (!machineCaller->codeBlock())87 return machineCaller;88 if (!machineCaller->codeBlock()->hasCodeOrigins())89 return machineCaller; // No inlining, so machineCaller == trueCaller90 154 91 // Figure out where the caller frame would have gone relative to the machine 92 // caller, and rematerialize it. Do so for the entire inline stack. 155 // Figure out how we want to get the current code location. 156 if (hasHostCallFrameFlag() || returnAddressIsInCtiTrampoline(returnPC())) 157 return machineCaller->trueCallFrameFromVMCode(); 93 158 94 ReturnAddressPtr currentReturnPC = returnPC(); 95 CodeBlock* machineCodeBlock = machineCaller->codeBlock(); 96 97 CodeOrigin codeOrigin; 98 if (!machineCodeBlock->codeOriginForReturn(currentReturnPC, codeOrigin)) 99 return machineCaller; // Not currently in inlined code, so machineCaller == trueCaller 100 101 for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { 102 InlineCallFrame* nextInlineCallFrame = inlineCallFrame->caller.inlineCallFrame; 103 104 CallFrame* inlinedCaller = machineCaller + inlineCallFrame->stackOffset; 105 106 JSFunction* calleeAsFunction = inlineCallFrame->callee.get(); 107 108 // Fill in the inlinedCaller 109 inlinedCaller->setCodeBlock(machineCaller->codeBlock()); 110 111 inlinedCaller->setScopeChain(calleeAsFunction->scope()); 112 if (nextInlineCallFrame) 113 inlinedCaller->setCallerFrame(machineCaller + nextInlineCallFrame->stackOffset); 114 else 115 inlinedCaller->setCallerFrame(machineCaller); 116 117 inlinedCaller->setInlineCallFrame(inlineCallFrame); 118 inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size()); 119 inlinedCaller->setCallee(calleeAsFunction); 120 121 inlineCallFrame = nextInlineCallFrame; 122 } 123 124 return machineCaller + codeOrigin.inlineCallFrame->stackOffset; 159 return machineCaller->trueCallFrame(returnPC()); 125 160 } 126 161 #endif
Note:
See TracChangeset
for help on using the changeset viewer.