Changeset 154821 in webkit
- Timestamp:
- Aug 29, 2013 10:41:44 AM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r154817 r154821 1 2013-08-29 Mark Lam <mark.lam@apple.com> 2 3 Change StackIterator to not require writes to the JS stack. 4 https://bugs.webkit.org/show_bug.cgi?id=119657. 5 6 Reviewed by Geoffrey Garen. 7 8 * GNUmakefile.list.am: 9 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 10 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 11 * JavaScriptCore.xcodeproj/project.pbxproj: 12 * interpreter/CallFrame.h: 13 - Removed references to StackIteratorPrivate.h. 14 * interpreter/StackIterator.cpp: 15 (JSC::StackIterator::numberOfFrames): 16 (JSC::StackIterator::gotoFrameAtIndex): 17 (JSC::StackIterator::gotoNextFrame): 18 (JSC::StackIterator::resetIterator): 19 (JSC::StackIterator::find): 20 (JSC::StackIterator::readFrame): 21 (JSC::StackIterator::readNonInlinedFrame): 22 - Reads in the current CallFrame's data for non-inlined frames. 23 (JSC::inlinedFrameOffset): 24 - Convenience function to compute the inlined frame offset based on the 25 CodeOrigin. If the offset is 0, then we're looking at the physical frame. 26 Otherwise, it's an inlined frame. 27 (JSC::StackIterator::readInlinedFrame): 28 - Determines the inlined frame's caller frame. Will read in the caller 29 frame if it is also an inlined frame i.e. we haven't reached the 30 outer most frame yet. Otherwise, will call readNonInlinedFrame() to 31 read on the outer most frame. 32 This is based on the old StackIterator::Frame::logicalFrame(). 33 (JSC::StackIterator::updateFrame): 34 - Reads the data of the caller frame of the current one. This function 35 is renamed and moved from the old StackIterator::Frame::logicalCallerFrame(), 36 but is now simplified because it delegates to the readInlinedFrame() 37 to get the caller for inlined frames. 38 (JSC::StackIterator::Frame::arguments): 39 - Fixed to use the inlined frame versions of Arguments::create() and 40 Arguments::tearOff() when the frame is an inlined frame. 41 (JSC::StackIterator::Frame::print): 42 (debugPrintCallFrame): 43 (debugPrintStack): 44 - Because sometimes, we want to see the whole stack while debugging. 45 * interpreter/StackIterator.h: 46 (JSC::StackIterator::Frame::argumentCount): 47 (JSC::StackIterator::Frame::callerFrame): 48 (JSC::StackIterator::Frame::callee): 49 (JSC::StackIterator::Frame::scope): 50 (JSC::StackIterator::Frame::codeBlock): 51 (JSC::StackIterator::Frame::bytecodeOffset): 52 (JSC::StackIterator::Frame::inlinedFrameInfo): 53 (JSC::StackIterator::Frame::isJSFrame): 54 (JSC::StackIterator::Frame::isInlinedFrame): 55 (JSC::StackIterator::Frame::callFrame): 56 (JSC::StackIterator::Frame::Frame): 57 (JSC::StackIterator::Frame::~Frame): 58 - StackIterator::Frame now caches commonly used accessed values from 59 the CallFrame. It still delegates argument queries to the CallFrame. 60 (JSC::StackIterator::operator*): 61 (JSC::StackIterator::operator->): 62 (JSC::StackIterator::operator!=): 63 (JSC::StackIterator::operator++): 64 (JSC::StackIterator::end): 65 (JSC::StackIterator::operator==): 66 * interpreter/StackIteratorPrivate.h: Removed. 67 1 68 2013-08-29 Chris Curtis <chris_curtis@apple.com> 2 69 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r154814 r154821 582 582 Source/JavaScriptCore/interpreter/StackIterator.cpp \ 583 583 Source/JavaScriptCore/interpreter/StackIterator.h \ 584 Source/JavaScriptCore/interpreter/StackIteratorPrivate.h \585 584 Source/JavaScriptCore/interpreter/VMInspector.cpp \ 586 585 Source/JavaScriptCore/interpreter/VMInspector.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r154814 r154821 730 730 <ClInclude Include="..\interpreter\Register.h" /> 731 731 <ClInclude Include="..\interpreter\StackIterator.h" /> 732 <ClInclude Include="..\interpreter\StackIteratorPrivate.h" />733 732 <ClInclude Include="..\interpreter\VMInspector.h" /> 734 733 <ClInclude Include="..\jit\ClosureCallStubRoutine.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r154638 r154821 1314 1314 <Filter>interpreter</Filter> 1315 1315 </ClInclude> 1316 <ClInclude Include="..\interpreter\StackIteratorPrivate.h">1317 <Filter>interpreter</Filter>1318 </ClInclude>1319 1316 <ClInclude Include="..\interpreter\VMInspector.h"> 1320 1317 <Filter>interpreter</Filter> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r154814 r154821 906 906 A7C1EAF117987AB600299DB2 /* StackIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C1EAEC17987AB600299DB2 /* StackIterator.cpp */; }; 907 907 A7C1EAF217987AB600299DB2 /* StackIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C1EAED17987AB600299DB2 /* StackIterator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 908 A7C1EAF317987AB600299DB2 /* StackIteratorPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C1EAEE17987AB600299DB2 /* StackIteratorPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };909 908 A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */; }; 910 909 A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */; }; … … 2079 2078 A7C1EAEC17987AB600299DB2 /* StackIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackIterator.cpp; sourceTree = "<group>"; }; 2080 2079 A7C1EAED17987AB600299DB2 /* StackIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackIterator.h; sourceTree = "<group>"; }; 2081 A7C1EAEE17987AB600299DB2 /* StackIteratorPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackIteratorPrivate.h; sourceTree = "<group>"; };2082 2080 A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; }; 2083 2081 A7C225CD1399849C00FF1662 /* KeywordLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeywordLookup.h; sourceTree = "<group>"; }; … … 2606 2604 A7C1EAEC17987AB600299DB2 /* StackIterator.cpp */, 2607 2605 A7C1EAED17987AB600299DB2 /* StackIterator.h */, 2608 A7C1EAEE17987AB600299DB2 /* StackIteratorPrivate.h */,2609 2606 FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */, 2610 2607 FE4A331E15BD2E07006F54F3 /* VMInspector.h */, … … 4282 4279 0FD82E54141DAEEE00179C94 /* SpeculatedType.h in Headers */, 4283 4280 A7C1EAF217987AB600299DB2 /* StackIterator.h in Headers */, 4284 A7C1EAF317987AB600299DB2 /* StackIteratorPrivate.h in Headers */,4285 4281 14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */, 4286 4282 14CA958B16AB50DE00938A06 /* StaticPropertyAnalyzer.h in Headers */, -
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r153218 r154821 112 112 } 113 113 114 StackIterator::Frame* CallFrame::end() 115 { 116 return StackIterator::end(); 117 } 118 119 } 114 } // namespace JSC -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r154797 r154821 29 29 #include "MacroAssemblerCodeRef.h" 30 30 #include "Register.h" 31 #include "StackIterator Private.h"31 #include "StackIterator.h" 32 32 33 33 namespace JSC { … … 284 284 JS_EXPORT_PRIVATE StackIterator begin(StackIterator::FrameFilter = 0); 285 285 JS_EXPORT_PRIVATE StackIterator find(JSFunction* calleeFunctionObj, StackIterator::FrameFilter = 0); 286 JS_EXPORT_PRIVATE StackIterator::Frame* end();286 StackIterator end() { return StackIterator::end(); } 287 287 288 288 private: -
trunk/Source/JavaScriptCore/interpreter/StackIterator.cpp
r153825 r154821 30 30 #include "CallFrameInlines.h" 31 31 #include "Executable.h" 32 #include "Interpreter.h" 32 33 #include "Operations.h" 33 34 #include <wtf/DataLog.h> … … 39 40 , m_filter(filter) 40 41 { 41 ASSERT(startFrame);42 42 resetIterator(); 43 43 } … … 47 47 int savedFrameIndex = m_frameIndex; 48 48 resetIterator(); 49 while (m_frame )50 gotoNextFrame ();49 while (m_frame.callFrame()) 50 gotoNextFrameWithFilter(); 51 51 size_t numberOfFrames = m_frameIndex; 52 52 … … 59 59 void StackIterator::gotoFrameAtIndex(size_t index) 60 60 { 61 while (m_frame && (m_frameIndex != index)) 61 while (m_frame.callFrame() && (m_frameIndex != index)) 62 gotoNextFrameWithFilter(); 63 } 64 65 void StackIterator::gotoNextFrame() 66 { 67 #if ENABLE(DFG_JIT) 68 if (m_frame.isInlinedFrame()) { 69 InlineCallFrame* inlineCallFrame = m_frame.inlineCallFrame(); 70 CodeOrigin* callerCodeOrigin = &inlineCallFrame->caller; 71 readInlinedFrame(m_frame.callFrame(), callerCodeOrigin); 72 73 } else 74 #endif // ENABLE(DFG_JIT) 75 readFrame(m_frame.callerFrame()); 76 } 77 78 void StackIterator::gotoNextFrameWithFilter() 79 { 80 ASSERT(m_frame.callFrame()); 81 while (m_frame.callFrame()) { 62 82 gotoNextFrame(); 63 } 64 65 void StackIterator::gotoNextFrame() 66 { 67 Frame* frame = m_frame; 68 while (frame) { 69 frame = frame->logicalCallerFrame(); 70 if (!frame || !m_filter || !m_filter(frame)) 83 if (!m_frame.callFrame() || !m_filter || !m_filter(&m_frame)) 71 84 break; 72 85 } 73 m_frame = frame;74 86 m_frameIndex++; 75 87 } … … 78 90 { 79 91 m_frameIndex = 0; 80 m_frame = Frame::create(m_startFrame); 81 m_frame = m_frame->logicalFrame(); 92 readFrame(m_startFrame); 93 } 94 95 StackIterator StackIterator::end() 96 { 97 return StackIterator(0, 0); 82 98 } 83 99 … … 86 102 ASSERT(functionObj); 87 103 JSObject* targetCallee = jsDynamicCast<JSObject*>(functionObj); 88 while (m_frame ) {89 if (m_frame ->callee() == targetCallee)104 while (m_frame.callFrame()) { 105 if (m_frame.callee() == targetCallee) 90 106 break; 91 gotoNextFrame(); 92 } 93 } 107 gotoNextFrameWithFilter(); 108 } 109 } 110 111 void StackIterator::readFrame(CallFrame* callFrame) 112 { 113 ASSERT(!callFrame->hasHostCallFrameFlag()); 114 if (!callFrame) { 115 m_frame.setToEnd(); 116 return; 117 } 118 119 #if !ENABLE(DFG_JIT) 120 readNonInlinedFrame(callFrame); 121 122 #else // !ENABLE(DFG_JIT) 123 // If the frame doesn't have a code block, then it's not a DFG frame. 124 // Hence, we're not at an inlined frame. 125 CodeBlock* codeBlock = callFrame->codeBlock(); 126 if (!codeBlock) { 127 readNonInlinedFrame(callFrame); 128 return; 129 } 130 131 // If the code block does not have any code origins, then there's no 132 // inlining. Hence, we're not at an inlined frame. 133 if (!codeBlock->hasCodeOrigins()) { 134 readNonInlinedFrame(callFrame); 135 return; 136 } 137 138 unsigned index = callFrame->locationAsCodeOriginIndex(); 139 ASSERT(codeBlock->canGetCodeOrigin(index)); 140 if (!codeBlock->canGetCodeOrigin(index)) { 141 // See assertion above. In release builds, we try to protect ourselves 142 // from crashing even though stack walking will be goofed up. 143 m_frame.setToEnd(); 144 return; 145 } 146 147 CodeOrigin codeOrigin = codeBlock->codeOrigin(index); 148 if (!codeOrigin.inlineCallFrame) { 149 readNonInlinedFrame(callFrame, &codeOrigin); 150 return; 151 } 152 153 readInlinedFrame(callFrame, &codeOrigin); 154 #endif // !ENABLE(DFG_JIT) 155 } 156 157 void StackIterator::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin) 158 { 159 m_frame.m_callFrame = callFrame; 160 m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); 161 m_frame.m_callerFrame = callFrame->callerFrame()->removeHostCallFrameFlag(); 162 m_frame.m_callee = callFrame->callee(); 163 m_frame.m_scope = callFrame->scope(); 164 m_frame.m_codeBlock = callFrame->codeBlock(); 165 m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0 166 : codeOrigin ? codeOrigin->bytecodeIndex 167 : callFrame->locationAsBytecodeOffset(); 168 #if ENABLE(DFG_JIT) 169 m_frame.m_inlineCallFrame = 0; 170 #endif 171 } 172 173 #if ENABLE(DFG_JIT) 174 static unsigned inlinedFrameOffset(CodeOrigin* codeOrigin) 175 { 176 InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame; 177 unsigned frameOffset = inlineCallFrame ? inlineCallFrame->stackOffset : 0; 178 return frameOffset; 179 } 180 181 void StackIterator::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin) 182 { 183 ASSERT(codeOrigin); 184 ASSERT(!callFrame->hasHostCallFrameFlag()); 185 186 unsigned frameOffset = inlinedFrameOffset(codeOrigin); 187 bool isInlined = !!frameOffset; 188 if (isInlined) { 189 InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame; 190 191 m_frame.m_callFrame = callFrame; 192 m_frame.m_inlineCallFrame = inlineCallFrame; 193 m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size(); 194 m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock(); 195 m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex; 196 197 JSFunction* callee = inlineCallFrame->callee.get(); 198 if (callee) { 199 m_frame.m_scope = callee->scope(); 200 m_frame.m_callee = callee; 201 } else { 202 CallFrame* inlinedFrame = callFrame + frameOffset; 203 m_frame.m_scope = inlinedFrame->scope(); 204 m_frame.m_callee = inlinedFrame->callee(); 205 } 206 ASSERT(m_frame.scope()); 207 ASSERT(m_frame.callee()); 208 209 // The callerFrame just needs to be non-null to indicate that we 210 // haven't reached the last frame yet. Setting it to the root 211 // frame (i.e. the callFrame that this inlined frame is called from) 212 // would work just fine. 213 m_frame.m_callerFrame = callFrame; 214 return; 215 } 216 217 readNonInlinedFrame(callFrame, codeOrigin); 218 } 219 #endif // ENABLE(DFG_JIT) 94 220 95 221 StackIterator::Frame::CodeType StackIterator::Frame::codeType() const … … 176 302 } 177 303 178 unsigned StackIterator::Frame::bytecodeOffset()179 {180 if (!isJSFrame())181 return 0;182 #if ENABLE(DFG_JIT)183 if (hasLocationAsCodeOriginIndex())184 return bytecodeOffsetFromCodeOriginIndex();185 #endif186 return locationAsBytecodeOffset();187 }188 189 304 Arguments* StackIterator::Frame::arguments() 190 305 { 191 CallFrame* callFrame = this->callFrame(); 192 Arguments* arguments = Arguments::create(vm(), callFrame); 193 arguments->tearOff(callFrame); 306 ASSERT(m_callFrame); 307 CallFrame* physicalFrame = m_callFrame; 308 VM& vm = physicalFrame->vm(); 309 Arguments* arguments; 310 #if ENABLE(DFG_JIT) 311 if (isInlinedFrame()) { 312 ASSERT(m_inlineCallFrame); 313 arguments = Arguments::create(vm, physicalFrame, m_inlineCallFrame); 314 arguments->tearOff(physicalFrame, m_inlineCallFrame); 315 } else 316 #endif 317 { 318 arguments = Arguments::create(vm, physicalFrame); 319 arguments->tearOff(physicalFrame); 320 } 194 321 return arguments; 195 322 } … … 222 349 } 223 350 224 225 StackIterator::Frame* StackIterator::Frame::logicalFrame() 226 { 227 #if !ENABLE(DFG_JIT) 228 return this; 229 230 #else // !ENABLE(DFG_JIT) 231 if (isInlinedFrame()) 232 return this; 233 234 // If I don't have a code block, then I'm not DFG code, so I'm the true call frame. 235 CodeBlock* codeBlock = this->codeBlock(); 236 if (!codeBlock) 237 return this; 238 239 // If the code block does not have any code origins, then there was no inlining, so 240 // I'm done. 241 if (!codeBlock->hasCodeOrigins()) 242 return this; 243 244 CodeBlock* outerMostCodeBlock = codeBlock; 245 unsigned index = locationAsCodeOriginIndex(); 246 ASSERT(outerMostCodeBlock->canGetCodeOrigin(index)); 247 if (!outerMostCodeBlock->canGetCodeOrigin(index)) { 248 // See above. In release builds, we try to protect ourselves from crashing even 249 // though stack walking will be goofed up. 250 return 0; 251 } 252 253 CodeOrigin codeOrigin = outerMostCodeBlock->codeOrigin(index); 254 if (!codeOrigin.inlineCallFrame) 255 return this; // Not currently in inlined code. 256 257 // We've got inlined frames. So, reify them so that the iterator can walk through them. 258 CallFrame* currFrame = this->callFrame(); 259 CallFrame* innerMostLogicalFrame = currFrame + codeOrigin.inlineCallFrame->stackOffset; 260 261 CallFrame* logicalFrame = innerMostLogicalFrame; 262 while (logicalFrame != currFrame) { 263 InlineCallFrame* inlinedFrameInfo = codeOrigin.inlineCallFrame; 264 265 // Fill in the logical (i.e. inlined) frame 266 logicalFrame->setCodeBlock(inlinedFrameInfo->baselineCodeBlock()); 267 logicalFrame->setInlineCallFrame(inlinedFrameInfo); 268 logicalFrame->setArgumentCountIncludingThis(inlinedFrameInfo->arguments.size()); 269 logicalFrame->setLocationAsBytecodeOffset(codeOrigin.bytecodeIndex); 270 logicalFrame->setIsInlinedFrame(); 271 272 JSFunction* callee = inlinedFrameInfo->callee.get(); 273 if (callee) { 274 logicalFrame->setScope(callee->scope()); 275 logicalFrame->setCallee(callee); 276 } 277 278 CodeOrigin* callerCodeOrigin = &inlinedFrameInfo->caller; 279 InlineCallFrame* callerInlinedFrameInfo = callerCodeOrigin->inlineCallFrame; 280 unsigned callerFrameOffset = callerInlinedFrameInfo ? callerInlinedFrameInfo->stackOffset : 0; 281 CallFrame* callerFrame = currFrame + callerFrameOffset; 282 logicalFrame->setCallerFrame(callerFrame); 283 284 codeOrigin = *callerCodeOrigin; 285 logicalFrame = callerFrame; 286 } 287 288 ASSERT(!innerMostLogicalFrame->hasHostCallFrameFlag()); 289 return Frame::create(innerMostLogicalFrame); 290 #endif // !ENABLE(DFG_JIT) 291 } 292 293 StackIterator::Frame* StackIterator::Frame::logicalCallerFrame() 294 { 295 Frame* callerFrame = create(this->callerFrame()->removeHostCallFrameFlag()); 296 #if !ENABLE(DFG_JIT) 297 return callerFrame; 298 299 #else // !ENABLE(DFG_JIT) 300 if (!isJSFrame() || !callerFrame) 301 return callerFrame; 302 303 // If I am known to be an inlined frame, then I've been reified already and 304 // have my caller. 305 if (isInlinedFrame()) 306 return callerFrame; 307 308 // I am not an inlined frame. So the question is: is my caller a CallFrame 309 // that has inlines or a CallFrame that doesn't? 310 311 // If my caller is not a JS frame, it cannot have inlines, and we're done. 312 if (!callerFrame->isJSFrame()) 313 return callerFrame; 314 315 ASSERT(!callerFrame->isInlinedFrame()); 316 return callerFrame->logicalFrame(); 317 318 #endif // !ENABLE(DFG_JIT) 351 void StackIterator::Frame::setToEnd() 352 { 353 m_callFrame = 0; 354 #if ENABLE(DFG_JIT) 355 m_inlineCallFrame = 0; 356 #endif 319 357 } 320 358 … … 370 408 printif(i, "frame %p {\n", this); 371 409 410 CallFrame* callFrame = m_callFrame; 372 411 CallFrame* callerFrame = this->callerFrame(); 373 void* returnPC = hasReturnPC() ? this->returnPC().value() : 0;412 void* returnPC = callFrame->hasReturnPC() ? callFrame->returnPC().value() : 0; 374 413 375 414 printif(i, " name '%s'\n", functionName().utf8().data()); 376 415 printif(i, " sourceURL '%s'\n", sourceURL().utf8().data()); 377 416 printif(i, " hostFlag %d\n", callerFrame->hasHostCallFrameFlag()); 417 418 #if ENABLE(DFG_JIT) 378 419 printif(i, " isInlinedFrame %d\n", isInlinedFrame()); 379 380 420 if (isInlinedFrame()) 381 printif(i, " InlineCallFrame %p\n", this->inlineCallFrame()); 421 printif(i, " InlineCallFrame %p\n", m_inlineCallFrame); 422 #endif 382 423 383 424 printif(i, " callee %p\n", callee()); 384 425 printif(i, " returnPC %p\n", returnPC); 385 426 printif(i, " callerFrame %p\n", callerFrame->removeHostCallFrameFlag()); 386 printif(i, " logicalCallerFrame %p\n", logicalCallerFrame());387 printif(i, " rawLocationBits %u 0x%x\n", location AsRawBits(), locationAsRawBits());427 unsigned locationRawBits = callFrame->locationAsRawBits(); 428 printif(i, " rawLocationBits %u 0x%x\n", locationRawBits, locationRawBits); 388 429 printif(i, " codeBlock %p\n", codeBlock); 389 430 if (codeBlock) { 390 431 JITCode::JITType jitType = codeBlock->jitType(); 391 if ( hasLocationAsBytecodeOffset()) {392 unsigned bytecodeOffset = locationAsBytecodeOffset();432 if (callFrame->hasLocationAsBytecodeOffset()) { 433 unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset(); 393 434 printif(i, " bytecodeOffset %u %p / %zu\n", bytecodeOffset, reinterpret_cast<void*>(bytecodeOffset), codeBlock->instructions().size()); 394 435 #if ENABLE(DFG_JIT) 395 436 } else { 396 unsigned codeOriginIndex = locationAsCodeOriginIndex();437 unsigned codeOriginIndex = callFrame->locationAsCodeOriginIndex(); 397 438 printif(i, " codeOriginIdex %u %p / %zu\n", codeOriginIndex, reinterpret_cast<void*>(codeOriginIndex), codeBlock->codeOrigins().size()); 398 439 #endif … … 420 461 421 462 #ifndef NDEBUG 422 // For use in the debugger463 // For debugging use 423 464 void debugPrintCallFrame(JSC::CallFrame*); 465 void debugPrintStack(JSC::CallFrame* topCallFrame); 424 466 425 467 void debugPrintCallFrame(JSC::CallFrame* callFrame) … … 427 469 if (!callFrame) 428 470 return; 429 JSC::StackIterator::Frame* frame = JSC::StackIterator::Frame::create(callFrame); 430 frame->print(2); 471 JSC::StackIterator iter = callFrame->begin(); 472 iter->print(2); 473 } 474 475 void debugPrintStack(JSC::CallFrame* topCallFrame) 476 { 477 if (!topCallFrame) 478 return; 479 JSC::StackIterator iter = topCallFrame->begin(); 480 for (; iter != topCallFrame->end(); ++iter) 481 iter->print(2); 431 482 } 432 483 #endif // !NDEBUG -
trunk/Source/JavaScriptCore/interpreter/StackIterator.h
r153218 r154821 27 27 #define StackIterator_h 28 28 29 #include "CallFrame.h" 30 #include "Interpreter.h" 31 #include "StackIteratorPrivate.h" 29 #include <wtf/text/WTFString.h> 32 30 33 31 namespace JSC { 34 32 33 struct CodeOrigin; 34 struct InlineCallFrame; 35 35 36 class Arguments; 37 class CodeBlock; 38 class ExecState; 39 class JSFunction; 40 class JSObject; 41 class JSScope; 36 42 37 class StackIterator::Frame : public CallFrame { 43 typedef ExecState CallFrame; 44 45 class StackIterator { 38 46 public: 39 enum CodeType { 40 Global = StackFrameGlobalCode, 41 Eval = StackFrameEvalCode, 42 Function = StackFrameFunctionCode, 43 Native = StackFrameNativeCode 47 class Frame { 48 public: 49 enum CodeType { 50 Global, 51 Eval, 52 Function, 53 Native 54 }; 55 56 size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; } 57 CallFrame* callerFrame() const { return m_callerFrame; } 58 JSObject* callee() const { return m_callee; } 59 JSScope* scope() const { return m_scope; } 60 CodeBlock* codeBlock() const { return m_codeBlock; } 61 unsigned bytecodeOffset() const { return m_bytecodeOffset; } 62 #if ENABLE(DFG_JIT) 63 InlineCallFrame* inlineCallFrame() const { return m_inlineCallFrame; } 64 #endif 65 66 bool isJSFrame() const { return !!codeBlock(); } 67 #if ENABLE(DFG_JIT) 68 bool isInlinedFrame() const { return !!m_inlineCallFrame; } 69 #endif 70 71 JS_EXPORT_PRIVATE String functionName(); 72 JS_EXPORT_PRIVATE String sourceURL(); 73 JS_EXPORT_PRIVATE String toString(); 74 75 CodeType codeType() const; 76 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column); 77 78 Arguments* arguments(); 79 CallFrame* callFrame() const { return m_callFrame; } 80 81 #ifndef NDEBUG 82 JS_EXPORT_PRIVATE void print(int indentLevel); 83 #endif 84 85 private: 86 Frame() { } 87 ~Frame() { } 88 89 void retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column); 90 #if ENABLE(DFG_JIT) 91 void setToEnd(); 92 #endif 93 94 size_t m_argumentCountIncludingThis; 95 CallFrame* m_callerFrame; 96 JSObject* m_callee; 97 JSScope* m_scope; 98 CodeBlock* m_codeBlock; 99 unsigned m_bytecodeOffset; 100 #if ENABLE(DFG_JIT) 101 InlineCallFrame* m_inlineCallFrame; 102 #endif 103 104 CallFrame* m_callFrame; 105 106 friend class StackIterator; 44 107 }; 45 108 46 static Frame* create(CallFrame* f) { return reinterpret_cast<Frame*>(f); }109 typedef bool (*FrameFilter)(Frame*); 47 110 48 bool isJSFrame() const { return !!codeBlock(); }111 JS_EXPORT_PRIVATE size_t numberOfFrames(); 49 112 50 JS_EXPORT_PRIVATE String functionName(); 51 JS_EXPORT_PRIVATE String sourceURL(); 52 JS_EXPORT_PRIVATE String toString(); 113 Frame& operator*() { return m_frame; } 114 ALWAYS_INLINE Frame* operator->() { return &m_frame; } 53 115 54 CodeType codeType() const; 55 unsigned bytecodeOffset(); 56 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column); 116 inline bool operator==(const StackIterator&); 117 bool operator!=(const StackIterator& other) { return !(*this == other); } 118 void operator++() { gotoNextFrameWithFilter(); } 119 void find(JSFunction*); 57 120 58 Arguments* arguments(); 59 CallFrame* callFrame() { return reinterpret_cast<CallFrame*>(this); } 60 61 Frame* logicalFrame(); 62 Frame* logicalCallerFrame(); 121 private: 122 JS_EXPORT_PRIVATE StackIterator(CallFrame* startFrame, FrameFilter = 0); 63 123 64 #ifndef NDEBUG 65 JS_EXPORT_PRIVATE void print(int indentLevel); 124 JS_EXPORT_PRIVATE static StackIterator end(); 125 void gotoFrameAtIndex(size_t frameIndex); 126 void gotoNextFrame(); 127 JS_EXPORT_PRIVATE void gotoNextFrameWithFilter(); 128 void resetIterator(); 129 130 void readFrame(CallFrame*); 131 void readNonInlinedFrame(CallFrame*, CodeOrigin* = 0); 132 #if ENABLE(DFG_JIT) 133 void readInlinedFrame(CallFrame*, CodeOrigin*); 66 134 #endif 67 135 68 private: 69 Frame(); 70 ~Frame(); 136 CallFrame* m_startFrame; 137 size_t m_frameIndex; 138 FrameFilter m_filter; 139 Frame m_frame; 71 140 72 void retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);141 friend class ExecState; 73 142 }; 143 144 inline bool StackIterator::operator==(const StackIterator& other) 145 { 146 return (m_frame.callFrame() == other.m_frame.callFrame()) 147 #if ENABLE(DFG_JIT) 148 && (m_frame.inlineCallFrame() == other.m_frame.inlineCallFrame()) 149 #endif 150 ; 151 } 74 152 75 153 } // namespace JSC
Note: See TracChangeset
for help on using the changeset viewer.