Changeset 153211 in webkit for trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
- Timestamp:
- Jul 24, 2013, 9:02:07 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r153209 r153211 53 53 { 54 54 ASSERT(codeBlock()); 55 ASSERT( !CodeOrigin::isHandle(offset));55 ASSERT(Location::isBytecodeOffset(offset)); 56 56 setCurrentVPC(codeBlock()->instructions().begin() + offset); 57 57 ASSERT(hasLocationAsBytecodeOffset()); … … 69 69 70 70 #if ENABLE(DFG_JIT) 71 bool CallFrame::isInlineCallFrameSlow() 72 { 73 if (!callee()) 74 return false; 75 JSCell* calleeAsFunctionCell = getJSFunction(callee()); 76 if (!calleeAsFunctionCell) 77 return false; 78 JSFunction* calleeAsFunction = jsCast<JSFunction*>(calleeAsFunctionCell); 79 return calleeAsFunction->executable() != codeBlock()->ownerExecutable(); 80 } 81 82 CallFrame* CallFrame::trueCallFrame(AbstractPC pc) 71 CallFrame* CallFrame::trueCallFrame() 83 72 { 84 73 // Am I an inline call frame? If so, we're done. 85 if (isInline CallFrame())74 if (isInlinedFrame()) 86 75 return this; 87 76 … … 96 85 return this; 97 86 98 // At this point the PC must be due either to the DFG, or it must be unset.99 ASSERT(pc.hasJITReturnAddress() || !pc);100 101 87 // Try to determine the CodeOrigin. If we don't have a pc set then the only way 102 88 // that this makes sense is if the CodeOrigin index was set in the call frame. 103 // FIXME: Note that you will see "Not currently in inlined code" comments below.104 // Currently, we do not record code origins for code that is not inlined, because105 // the only thing that we use code origins for is determining the inline stack.106 // But in the future, we'll want to use this same functionality (having a code107 // origin mapping for any calls out of JIT code) to determine the PC at any point108 // in the stack even if not in inlined code. When that happens, the code below109 // will have to change the way it detects the presence of inlining: it will always110 // get a code origin, but sometimes, that code origin will not have an inline call111 // frame. In that case, this method should bail and return this.112 89 CodeOrigin codeOrigin; 113 if (pc.isSet()) { 114 ReturnAddressPtr currentReturnPC = pc.jitReturnAddress(); 115 116 bool hasCodeOrigin = machineCodeBlock->codeOriginForReturn(currentReturnPC, codeOrigin); 117 ASSERT(hasCodeOrigin); 118 if (!hasCodeOrigin) { 119 // In release builds, if we find ourselves in a situation where the return PC doesn't 120 // correspond to a valid CodeOrigin, we return zero instead of continuing. Some of 121 // the callers of trueCallFrame() will be able to recover and do conservative things, 122 // while others will crash. 123 return 0; 124 } 125 } else { 126 unsigned index = locationAsCodeOriginIndex(); 127 ASSERT(machineCodeBlock->canGetCodeOrigin(index)); 128 if (!machineCodeBlock->canGetCodeOrigin(index)) { 129 // See above. In release builds, we try to protect ourselves from crashing even 130 // though stack walking will be goofed up. 131 return 0; 132 } 133 codeOrigin = machineCodeBlock->codeOrigin(index); 90 unsigned index = locationAsCodeOriginIndex(); 91 ASSERT(machineCodeBlock->canGetCodeOrigin(index)); 92 if (!machineCodeBlock->canGetCodeOrigin(index)) { 93 // See above. In release builds, we try to protect ourselves from crashing even 94 // though stack walking will be goofed up. 95 return 0; 134 96 } 97 codeOrigin = machineCodeBlock->codeOrigin(index); 135 98 136 99 if (!codeOrigin.inlineCallFrame) 137 100 return this; // Not currently in inlined code. 138 101 102 CodeOrigin innerMostCodeOrigin = codeOrigin; 103 139 104 for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { 140 105 InlineCallFrame* nextInlineCallFrame = inlineCallFrame->caller.inlineCallFrame; … … 145 110 146 111 // Fill in the inlinedCaller 147 inlinedCaller->setCodeBlock( machineCodeBlock);112 inlinedCaller->setCodeBlock(inlineCallFrame->baselineCodeBlock()); 148 113 if (calleeAsFunction) 149 114 inlinedCaller->setScope(calleeAsFunction->scope()); … … 155 120 inlinedCaller->setInlineCallFrame(inlineCallFrame); 156 121 inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size()); 122 inlinedCaller->setLocationAsBytecodeOffset(codeOrigin.bytecodeIndex); 123 inlinedCaller->setIsInlinedFrame(); 157 124 if (calleeAsFunction) 158 125 inlinedCaller->setCallee(calleeAsFunction); 159 126 127 codeOrigin = inlineCallFrame->caller; 160 128 inlineCallFrame = nextInlineCallFrame; 161 129 } 162 130 163 return this + codeOrigin.inlineCallFrame->stackOffset;131 return this + innerMostCodeOrigin.inlineCallFrame->stackOffset; 164 132 } 165 133 166 134 CallFrame* CallFrame::trueCallerFrame() 167 135 { 136 CallFrame* callerFrame = this->callerFrame()->removeHostCallFrameFlag(); 168 137 if (!codeBlock()) 169 return callerFrame ()->removeHostCallFrameFlag();138 return callerFrame; 170 139 171 140 // this -> The callee; this is either an inlined callee in which case it already has … … 177 146 178 147 // Am I an inline call frame? If so, we're done. 179 if (isInline CallFrame())180 return callerFrame ()->removeHostCallFrameFlag();148 if (isInlinedFrame()) 149 return callerFrame; 181 150 182 151 // I am a machine call frame, so the question is: is my caller a machine call frame 183 152 // that has inlines or a machine call frame that doesn't? 184 CallFrame* machineCaller = callerFrame()->removeHostCallFrameFlag(); 185 if (!machineCaller) 153 if (!callerFrame) 186 154 return 0; 187 ASSERT(!machineCaller->isInlineCallFrame()); 155 156 if (!callerFrame->codeBlock()) 157 return callerFrame; 158 ASSERT(!callerFrame->isInlinedFrame()); 188 159 189 // Figure out how we want to get the current code location. 190 if (!hasReturnPC() || returnAddressIsInCtiTrampoline(returnPC())) 191 return machineCaller->trueCallFrameFromVMCode()->removeHostCallFrameFlag(); 192 193 return machineCaller->trueCallFrame(returnPC())->removeHostCallFrameFlag(); 160 return callerFrame->trueCallFrame()->removeHostCallFrameFlag(); 194 161 } 195 162 196 CodeBlock* CallFrame::someCodeBlockForPossiblyInlinedCode()163 unsigned CallFrame::bytecodeOffsetFromCodeOriginIndex() 197 164 { 198 if (!isInlineCallFrame()) 199 return codeBlock(); 200 201 return jsCast<FunctionExecutable*>(inlineCallFrame()->executable.get())->baselineCodeBlockFor( 202 inlineCallFrame()->isCall ? CodeForCall : CodeForConstruct); 165 ASSERT(hasLocationAsCodeOriginIndex()); 166 CodeBlock* codeBlock = this->codeBlock(); 167 ASSERT(codeBlock); 168 169 CodeOrigin codeOrigin; 170 unsigned index = locationAsCodeOriginIndex(); 171 ASSERT(codeBlock->canGetCodeOrigin(index)); 172 codeOrigin = codeBlock->codeOrigin(index); 173 174 for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { 175 if (inlineCallFrame->baselineCodeBlock() == codeBlock) 176 return codeOrigin.bytecodeIndex; 177 178 codeOrigin = inlineCallFrame->caller; 179 inlineCallFrame = codeOrigin.inlineCallFrame; 180 } 181 return codeOrigin.bytecodeIndex; 203 182 } 204 183 205 #endif 184 #endif // ENABLE(DFG_JIT) 206 185 207 186 Register* CallFrame::frameExtentInternal()
Note:
See TracChangeset
for help on using the changeset viewer.