WebKit Bugzilla
Attachment 348346 Details for
Bug 189059
: Fix bit-rotted Interpreter::dumpRegisters() and move it to the VMInspector.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
proposed patch.
bug-189059.patch (text/plain), 27.00 KB, created by
Mark Lam
on 2018-08-28 15:04:30 PDT
(
hide
)
Description:
proposed patch.
Filename:
MIME Type:
Creator:
Mark Lam
Created:
2018-08-28 15:04:30 PDT
Size:
27.00 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 235441) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,92 @@ >+2018-08-28 Mark Lam <mark.lam@apple.com> >+ >+ Fix bit-rotted Interpreter::dumpRegisters() and move it to the VMInspector. >+ https://bugs.webkit.org/show_bug.cgi?id=189059 >+ <rdar://problem/40335354> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 1. Moved Interpreter::dumpRegisters() to VMInspector::dumpRegisters(). >+ 2. Added $vm.dumpRegisters(). >+ >+ Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame. >+ Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame. >+ >+ Note: Currently, $vm.dumpRegisters() only dump registers in the physical frame. >+ It will treat inlined frames content as registers in the bounding physical frame. >+ >+ Here's an example of such a dump on a DFG frame: >+ >+ Register frame: >+ >+ ----------------------------------------------------------------------------- >+ use | address | value >+ ----------------------------------------------------------------------------- >+ [r 12 arguments[ 7]] | 0x7ffeefbfd330 | 0xa Undefined >+ [r 11 arguments[ 6]] | 0x7ffeefbfd328 | 0x10bbb3e80 Object: 0x10bbb3e80 with butterfly 0x0 (Structure 0x10bbf20d0:[Object, {}, NonArray, Proto:0x10bbb4000]), StructureID: 76 >+ [r 10 arguments[ 5]] | 0x7ffeefbfd320 | 0xa Undefined >+ [r 9 arguments[ 4]] | 0x7ffeefbfd318 | 0xa Undefined >+ [r 8 arguments[ 3]] | 0x7ffeefbfd310 | 0xa Undefined >+ [r 7 arguments[ 2]] | 0x7ffeefbfd308 | 0xffff0000000a5eaa Int32: 679594 >+ [r 6 arguments[ 1]] | 0x7ffeefbfd300 | 0x10bbd00f0 Object: 0x10bbd00f0 with butterfly 0x8000f8248 (Structure 0x10bba4700:[Function, {name:100, prototype:101, length:102, Symbol.species:103, isArray:104}, NonArray, Proto:0x10bbd0000, Leaf]), StructureID: 160 >+ [r 5 this] | 0x7ffeefbfd2f8 | 0x10bbe0000 Object: 0x10bbe0000 with butterfly 0x8000d8808 (Structure 0x10bb35340:[global, {parseInt:100, parseFloat:101, Object:102, Function:103, Array:104, RegExp:105, RangeError:106, TypeError:107, PrivateSymbol.Object:108, PrivateSymbol.Array:109, ArrayBuffer:110, String:111, Symbol:112, Number:113, Boolean:114, Error:115, Map:116, Set:117, Promise:118, eval:119, Reflect:121, $vm:122, WebAssembly:123, debug:124, describe:125, describeArray:126, print:127, printErr:128, quit:129, gc:130, fullGC:131, edenGC:132, forceGCSlowPaths:133, gcHeapSize:134, addressOf:135, version:136, run:137, runString:138, load:139, loadString:140, readFile:141, read:142, checkSyntax:143, sleepSeconds:144, jscStack:145, readline:146, preciseTime:147, neverInlineFunction:148, noInline:149, noDFG:150, noFTL:151, numberOfDFGCompiles:153, jscOptions:154, optimizeNextInvocation:155, reoptimizationRetryCount:156, transferArrayBuffer:157, failNextNewCodeBlock:158, OSRExit:159, isFinalTier:160, predictInt32:161, isInt32:162, isPureNaN:163, fiatInt52:164, effectful42:165, makeMasquerader:166, hasCustomProperties:167, createGlobalObject:168, dumpTypesForAllVariables:169, drainMicrotasks:170, getRandomSeed:171, setRandomSeed:172, isRope:173, callerSourceOrigin:174, is32BitPlatform:175, loadModule:176, checkModuleSyntax:177, platformSupportsSamplingProfiler:178, generateHeapSnapshot:179, resetSuperSamplerState:180, ensureArrayStorage:181, startSamplingProfiler:182, samplingProfilerStackTraces:183, maxArguments:184, asyncTestStart:185, asyncTestPassed:186, WebAssemblyMemoryMode:187, console:188, $:189, $262:190, waitForReport:191, heapCapacity:192, flashHeapAccess:193, disableRichSourceInfo:194, mallocInALoop:195, totalCompileTime:196, Proxy:197, uneval:198, WScript:199, failWithMessage:200, triggerAssertFalse:201, isNaN:202, isFinite:203, escape:204, unescape:205, decodeURI:206, decodeURIComponent:207, encodeURI:208, encodeURIComponent:209, EvalError:210, ReferenceError:211, SyntaxError:212, URIError:213, JSON:214, Math:215, Int8Array:216, PrivateSymbol.Int8Array:217, Int16Array:218, PrivateSymbol.Int16Array:219, Int32Array:220, PrivateSymbol.Int32Array:221, Uint8Array:222, PrivateSymbol.Uint8Array:223, Uint8ClampedArray:224, PrivateSymbol.Uint8ClampedArray:225, Uint16Array:226, PrivateSymbol.Uint16Array:227, Uint32Array:228, PrivateSymbol.Uint32Array:229, Float32Array:230, PrivateSymbol.Float32Array:231, Float64Array:232, PrivateSymbol.Float64Array:233, DataView:234, Date:235, WeakMap:236, WeakSet:237, Intl:120, desc:238}, NonArray, Proto:0x10bbb4000, UncacheableDictionary, Leaf]), StructureID: 474 >+ ----------------------------------------------------------------------------- >+ [ArgumentCount] | 0x7ffeefbfd2f0 | 7 >+ [ReturnVPC] | 0x7ffeefbfd2f0 | 164 (line 57) >+ [Callee] | 0x7ffeefbfd2e8 | 0x10bb68db0 Object: 0x10bb68db0 with butterfly 0x0 (Structure 0x10bbf1c00:[Function, {}, NonArray, Proto:0x10bbd0000, Shady leaf]), StructureID: 65 >+ [CodeBlock] | 0x7ffeefbfd2e0 | 0x10bb2f8e0 __callRandomFunction#DmVXnv:[0x10bb2f8e0->0x10bbfd1e0, LLIntFunctionCall, 253] >+ [ReturnPC] | 0x7ffeefbfd2d8 | 0x10064d14c >+ [CallerFrame] | 0x7ffeefbfd2d0 | 0x7ffeefbfd380 >+ ----------------------------------------------------------------------------- >+ [r -1 CalleeSaveReg] | 0x7ffeefbfd2c8 | 0xffff000000000002 Int32: 2 >+ [r -2 CalleeSaveReg] | 0x7ffeefbfd2c0 | 0xffff000000000000 Int32: 0 >+ [r -3 CalleeSaveReg] | 0x7ffeefbfd2b8 | 0x10baf1608 >+ [r -4 ] | 0x7ffeefbfd2b0 | 0x10bbcc000 Object: 0x10bbcc000 with butterfly 0x0 (Structure 0x10bbf1960:[JSGlobalLexicalEnvironment, {}, NonArray, Leaf]), StructureID: 59 >+ [r -5 ] | 0x7ffeefbfd2a8 | 0x10bbcc000 Object: 0x10bbcc000 with butterfly 0x0 (Structure 0x10bbf1960:[JSGlobalLexicalEnvironment, {}, NonArray, Leaf]), StructureID: 59 >+ [r -6 ] | 0x7ffeefbfd2a0 | 0xa Undefined >+ ----------------------------------------------------------------------------- >+ [r -7] | 0x7ffeefbfd298 | 0x10bb6fdc0 String (atomic) (identifier): length, StructureID: 4 >+ [r -8] | 0x7ffeefbfd290 | 0x10bbb7ec0 Object: 0x10bbb7ec0 with butterfly 0x8000e0008 (Structure 0x10bbf2ae0:[Array, {}, ArrayWithContiguous, Proto:0x10bbc8080]), StructureID: 99 >+ [r -9] | 0x7ffeefbfd288 | 0x10bbc33f0 Object: 0x10bbc33f0 with butterfly 0x8000fdda8 (Structure 0x10bbf1dc0:[Function, {name:100, length:101}, NonArray, Proto:0x10bbd0000, Leaf]), StructureID: 69 >+ [r-10] | 0x7ffeefbfd280 | 0xffff000000000004 Int32: 4 >+ [r-11] | 0x7ffeefbfd278 | 0x10bbb4290 Object: 0x10bbb4290 with butterfly 0x8000e8408 (Structure 0x10bb74850:[DollarVM, {abort:100, crash:101, breakpoint:102, dfgTrue:103, ftlTrue:104, cpuMfence:105, cpuRdtsc:106, cpuCpuid:107, cpuPause:108, cpuClflush:109, llintTrue:110, jitTrue:111, noInline:112, gc:113, edenGC:114, callFrame:115, codeBlockFor:116, codeBlockForFrame:117, dumpSourceFor:118, dumpBytecodeFor:119, dataLog:120, print:121, dumpCallFrame:122, dumpStack:123, dumpRegisters:124, dumpCell:125, indexingMode:126, inlineCapacity:127, value:128, getpid:129, createProxy:130, createRuntimeArray:131, createImpureGetter:132, createCustomGetterObject:133, createDOMJITNodeObject:134, createDOMJITGetterObject:135, createDOMJITGetterComplexObject:136, createDOMJITFunctionObject:137, createDOMJITCheckSubClassObject:138, createDOMJITGetterBaseJSObject:139, createBuiltin:140, getPrivateProperty:141, setImpureGetterDelegate:142, Root:143, Element:144, getElement:145, SimpleObject:146, getHiddenValue:147, setHiddenValue:148, shadowChickenFunctionsOnStack:149, setGlobalConstRedeclarationShouldNotThrow:150, findTypeForExpression:151, returnTypeFor:152, flattenDictionaryObject:153, dumpBasicBlockExecutionRanges:154, hasBasicBlockExecuted:155, basicBlockExecutionCount:156, enableDebuggerModeWhenIdle:158, disableDebuggerModeWhenIdle:159, globalObjectCount:160, globalObjectForObject:161, getGetterSetter:162, loadGetterFromGetterSetter:163, createCustomTestGetterSetter:164, deltaBetweenButterflies:165, totalGCTime:166}, NonArray, Proto:0x10bbb4000, Dictionary, Leaf]), StructureID: 306 >+ [r-12] | 0x7ffeefbfd270 | 0x100000001 >+ [r-13] | 0x7ffeefbfd268 | 0x10bbc33f0 Object: 0x10bbc33f0 with butterfly 0x8000fdda8 (Structure 0x10bbf1dc0:[Function, {name:100, length:101}, NonArray, Proto:0x10bbd0000, Leaf]), StructureID: 69 >+ [r-14] | 0x7ffeefbfd260 | 0x0 >+ [r-15] | 0x7ffeefbfd258 | 0x10064d14c >+ [r-16] | 0x7ffeefbfd250 | 0x7ffeefbfd2d0 >+ [r-17] | 0x7ffeefbfd248 | 0x67ec87ee177 INVALID >+ [r-18] | 0x7ffeefbfd240 | 0x7ffeefbfd250 >+ ----------------------------------------------------------------------------- >+ >+ 3. Removed dumpCallFrame() from the jsc shell. We have the following tools that >+ we can use in its place: >+ >+ $vm.dumpCallFrame() >+ $vm.dumpBytecodeFor() >+ $vm.dumpRegisters() // Just added in this patch. >+ >+ 4. Also fixed a bug in BytecodeDumper: it should only access >+ CallLinkInfo::haveLastSeenCallee() only if CallLinkInfo::isDirect() is false. >+ >+ * bytecode/BytecodeDumper.cpp: >+ (JSC::BytecodeDumper<Block>::printCallOp): >+ * interpreter/Interpreter.cpp: >+ (JSC::Interpreter::dumpCallFrame): Deleted. >+ (JSC::DumpReturnVirtualPCFunctor::DumpReturnVirtualPCFunctor): Deleted. >+ (JSC::DumpReturnVirtualPCFunctor::operator() const): Deleted. >+ (JSC::Interpreter::dumpRegisters): Deleted. >+ * interpreter/Interpreter.h: >+ * jsc.cpp: >+ (GlobalObject::finishCreation): >+ (functionDumpCallFrame): Deleted. >+ * tools/JSDollarVM.cpp: >+ (JSC::functionDumpRegisters): >+ (JSC::JSDollarVM::finishCreation): >+ * tools/VMInspector.cpp: >+ (JSC::VMInspector::dumpRegisters): >+ * tools/VMInspector.h: >+ > 2018-08-28 Keith Miller <keith_miller@apple.com> > > Add nullablity attributes to JSValue >Index: Source/JavaScriptCore/jsc.cpp >=================================================================== >--- Source/JavaScriptCore/jsc.cpp (revision 235407) >+++ Source/JavaScriptCore/jsc.cpp (working copy) >@@ -268,9 +268,6 @@ static EncodedJSValue JSC_HOST_CALL func > static EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*); >-#ifndef NDEBUG >-static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*); >-#endif > static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionRunString(ExecState*); >@@ -489,9 +486,6 @@ protected: > addFunction(vm, "forceGCSlowPaths", functionForceGCSlowPaths, 0); > addFunction(vm, "gcHeapSize", functionHeapSize, 0); > addFunction(vm, "addressOf", functionAddressOf, 1); >-#ifndef NDEBUG >- addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0); >-#endif > addFunction(vm, "version", functionVersion, 1); > addFunction(vm, "run", functionRun, 1); > addFunction(vm, "runString", functionRunString, 1); >@@ -1053,18 +1047,6 @@ fail: > EncodedJSValue JSC_HOST_CALL functionPrintStdOut(ExecState* exec) { return printInternal(exec, stdout); } > EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState* exec) { return printInternal(exec, stderr); } > >-#ifndef NDEBUG >-EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec) >-{ >- VM& vm = exec->vm(); >- EntryFrame* topEntryFrame = vm.topEntryFrame; >- ExecState* callerFrame = exec->callerFrame(topEntryFrame); >- if (callerFrame) >- vm.interpreter->dumpCallFrame(callerFrame); >- return JSValue::encode(jsUndefined()); >-} >-#endif >- > EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec) > { > VM& vm = exec->vm(); >Index: Source/JavaScriptCore/bytecode/BytecodeDumper.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/BytecodeDumper.cpp (revision 235407) >+++ Source/JavaScriptCore/bytecode/BytecodeDumper.cpp (working copy) >@@ -614,7 +614,7 @@ void BytecodeDumper<Block>::printCallOp( > } > #if ENABLE(JIT) > if (CallLinkInfo* info = statusMap.get(CodeOrigin(location)).callLinkInfo) { >- if (info->haveLastSeenCallee()) { >+ if (!info->isDirect() && info->haveLastSeenCallee()) { > JSObject* object = info->lastSeenCallee(); > if (auto* function = jsDynamicCast<JSFunction*>(*vm(), object)) > out.printf(" jit(%p, exec %p)", function, function->executable()); >Index: Source/JavaScriptCore/interpreter/Interpreter.cpp >=================================================================== >--- Source/JavaScriptCore/interpreter/Interpreter.cpp (revision 235407) >+++ Source/JavaScriptCore/interpreter/Interpreter.cpp (working copy) >@@ -369,129 +369,6 @@ HashMap<Opcode, OpcodeID>& Interpreter:: > #endif // !USE(LLINT_EMBEDDED_OPCODE_ID) || !ASSERT_DISABLED > #endif // ENABLE(COMPUTED_GOTO_OPCODES) > >-#ifdef NDEBUG >- >-void Interpreter::dumpCallFrame(CallFrame*) >-{ >-} >- >-#else >- >-void Interpreter::dumpCallFrame(CallFrame* callFrame) >-{ >- callFrame->codeBlock()->dumpBytecode(); >- dumpRegisters(callFrame); >-} >- >-class DumpReturnVirtualPCFunctor { >-public: >- DumpReturnVirtualPCFunctor(const Register*& it) >- : m_hasSkippedFirstFrame(false) >- , m_it(it) >- { >- } >- >- StackVisitor::Status operator()(StackVisitor& visitor) const >- { >- if (!m_hasSkippedFirstFrame) { >- m_hasSkippedFirstFrame = true; >- return StackVisitor::Continue; >- } >- >- unsigned line = 0; >- unsigned unusedColumn = 0; >- visitor->computeLineAndColumn(line, unusedColumn); >- dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", m_it, visitor->bytecodeOffset(), line); >- return StackVisitor::Done; >- } >- >-private: >- mutable bool m_hasSkippedFirstFrame; >- const Register*& m_it; >-}; >- >-void Interpreter::dumpRegisters(CallFrame* callFrame) >-{ >- CodeBlock* codeBlock = callFrame->codeBlock(); >- if (!codeBlock) { >- dataLog("Dumping host frame registers not supported.\n"); >- return; >- } >- VM& vm = *codeBlock->vm(); >- >- dataLogF("Register frame: \n\n"); >- dataLogF("-----------------------------------------------------------------------------\n"); >- dataLogF(" use | address | value \n"); >- dataLogF("-----------------------------------------------------------------------------\n"); >- >- const Register* it; >- const Register* end; >- >- it = callFrame->registers() + CallFrameSlot::thisArgument + callFrame->argumentCount(); >- end = callFrame->registers() + CallFrameSlot::thisArgument - 1; >- while (it > end) { >- JSValue v = it->jsValue(); >- int registerNumber = it - callFrame->registers(); >- String name = codeBlock->nameForRegister(VirtualRegister(registerNumber)); >- dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v)); >- --it; >- } >- >- dataLogF("-----------------------------------------------------------------------------\n"); >- dataLogF("[ArgumentCount] | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount()); >- DumpReturnVirtualPCFunctor functor(it); >- callFrame->iterate(functor); >- --it; >- dataLogF("[Callee] | %10p | %p \n", it, callFrame->jsCallee()); >- --it; >- dataLogF("[CodeBlock] | %10p | %p \n", it, callFrame->codeBlock()); >- --it; >-#if ENABLE(JIT) >- AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm()); >- if (pc.hasJITReturnAddress()) >- dataLogF("[ReturnPC] | %10p | %p \n", it, pc.jitReturnAddress().value()); >- --it; >-#endif >- dataLogF("[CallerFrame] | %10p | %p \n", it, callFrame->callerFrame()); >- --it; >- dataLogF("-----------------------------------------------------------------------------\n"); >- >- size_t numberOfCalleeSaveSlots = codeBlock->calleeSaveSpaceAsVirtualRegisters(); >- const Register* endOfCalleeSaves = it - numberOfCalleeSaveSlots; >- >- end = it - codeBlock->numVars(); >- if (it != end) { >- do { >- JSValue v = it->jsValue(); >- int registerNumber = it - callFrame->registers(); >- String name = (it > endOfCalleeSaves) >- ? "CalleeSaveReg" >- : codeBlock->nameForRegister(VirtualRegister(registerNumber)); >- CString valueString = (it > endOfCalleeSaves) ? "" : toCString(v); >- dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, valueString.data(), (long long)JSValue::encode(v)); >- --it; >- } while (it != end); >- } >- dataLogF("-----------------------------------------------------------------------------\n"); >- >- end = it - codeBlock->numCalleeLocals() + codeBlock->numVars(); >- if (it != end) { >- do { >- JSValue v = (*it).jsValue(); >- int registerNumber = it - callFrame->registers(); >- CString valueString = >- (v.isCell() && !VMInspector::isValidCell(&vm.heap, reinterpret_cast<JSCell*>(JSValue::encode(v)))) >- ? "INVALID" >- : toCString(v); >- dataLogF("[r% 3d] | %10p | %-16s 0x%lld \n", registerNumber, it, valueString.data(), (long long)JSValue::encode(v)); >- --it; >- } while (it != end); >- } >- dataLogF("-----------------------------------------------------------------------------\n"); >-} >- >-#endif >- > #if !ASSERT_DISABLED > bool Interpreter::isOpcode(Opcode opcode) > { >Index: Source/JavaScriptCore/interpreter/Interpreter.h >=================================================================== >--- Source/JavaScriptCore/interpreter/Interpreter.h (revision 235407) >+++ Source/JavaScriptCore/interpreter/Interpreter.h (working copy) >@@ -127,8 +127,6 @@ namespace JSC { > static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*); > static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*); > >- JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*); >- > void getStackTrace(JSCell* owner, Vector<StackFrame>& results, size_t framesToSkip = 0, size_t maxStackSize = std::numeric_limits<size_t>::max()); > > private: >@@ -150,10 +148,6 @@ namespace JSC { > > JSValue execute(CallFrameClosure&); > >- >- >- void dumpRegisters(CallFrame*); >- > VM& m_vm; > #if !ENABLE(JIT) > CLoopStack m_cloopStack; >Index: Source/JavaScriptCore/tools/JSDollarVM.cpp >=================================================================== >--- Source/JavaScriptCore/tools/JSDollarVM.cpp (revision 235407) >+++ Source/JavaScriptCore/tools/JSDollarVM.cpp (working copy) >@@ -1490,6 +1490,36 @@ static EncodedJSValue JSC_HOST_CALL func > return JSValue::encode(jsUndefined()); > } > >+// Dumps the current CallFrame. >+// Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame. >+// Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame. >+// FIXME: Currently, this function dumps the physical frame. We should make >+// it dump the logical frame (i.e. be able to dump inlined frames as well). >+static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(ExecState* exec) >+{ >+ unsigned requestedFrameIndex = 1; >+ if (exec->argumentCount() >= 1) { >+ JSValue value = exec->uncheckedArgument(0); >+ if (!value.isUInt32()) >+ return JSValue::encode(jsUndefined()); >+ >+ // We need to inc the frame number because the caller would consider >+ // its own frame as frame 0. Hence, we need discount the frame for this >+ // function. >+ requestedFrameIndex = value.asUInt32() + 1; >+ } >+ >+ unsigned frameIndex = 0; >+ exec->iterate([&] (StackVisitor& visitor) { >+ if (frameIndex++ != requestedFrameIndex) >+ return StackVisitor::Continue; >+ VMInspector::dumpRegisters(visitor->callFrame()); >+ return StackVisitor::Done; >+ }); >+ >+ return encodedJSUndefined(); >+} >+ > // Dumps the internal memory layout of a JSCell. > // Usage: $vm.dumpCell(cell) > static EncodedJSValue JSC_HOST_CALL functionDumpCell(ExecState* exec) >@@ -2020,6 +2050,7 @@ void JSDollarVM::finishCreation(VM& vm) > addFunction(vm, "print", functionPrint, 1); > addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0); > addFunction(vm, "dumpStack", functionDumpStack, 0); >+ addFunction(vm, "dumpRegisters", functionDumpRegisters, 1); > > addFunction(vm, "dumpCell", functionDumpCell, 1); > >Index: Source/JavaScriptCore/tools/VMInspector.cpp >=================================================================== >--- Source/JavaScriptCore/tools/VMInspector.cpp (revision 235407) >+++ Source/JavaScriptCore/tools/VMInspector.cpp (working copy) >@@ -367,6 +367,97 @@ void VMInspector::dumpCallFrame(CallFram > callFrame->iterate(functor); > } > >+void VMInspector::dumpRegisters(CallFrame* callFrame) >+{ >+ CodeBlock* codeBlock = callFrame->codeBlock(); >+ if (!codeBlock) { >+ dataLog("Dumping host frame registers not supported.\n"); >+ return; >+ } >+ VM& vm = *codeBlock->vm(); >+ auto valueAsString = [&] (JSValue v) -> CString { >+ if (!v.isCell() || VMInspector::isValidCell(&vm.heap, reinterpret_cast<JSCell*>(JSValue::encode(v)))) >+ return toCString(v); >+ return ""; >+ }; >+ >+ dataLogF("Register frame: \n\n"); >+ dataLogF("-----------------------------------------------------------------------------\n"); >+ dataLogF(" use | address | value \n"); >+ dataLogF("-----------------------------------------------------------------------------\n"); >+ >+ const Register* it; >+ const Register* end; >+ >+ it = callFrame->registers() + CallFrameSlot::thisArgument + callFrame->argumentCount(); >+ end = callFrame->registers() + CallFrameSlot::thisArgument - 1; >+ while (it > end) { >+ JSValue v = it->jsValue(); >+ int registerNumber = it - callFrame->registers(); >+ String name = codeBlock->nameForRegister(VirtualRegister(registerNumber)); >+ dataLogF("[r% 3d %14s] | %10p | 0x%-16llx %s\n", registerNumber, name.ascii().data(), it, (long long)JSValue::encode(v), valueAsString(v).data()); >+ --it; >+ } >+ >+ dataLogF("-----------------------------------------------------------------------------\n"); >+ dataLogF("[ArgumentCount] | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount()); >+ >+ callFrame->iterate([&] (StackVisitor& visitor) { >+ if (visitor->callFrame() == callFrame) { >+ unsigned line = 0; >+ unsigned unusedColumn = 0; >+ visitor->computeLineAndColumn(line, unusedColumn); >+ dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", it, visitor->bytecodeOffset(), line); >+ return StackVisitor::Done; >+ } >+ return StackVisitor::Continue; >+ }); >+ >+ --it; >+ dataLogF("[Callee] | %10p | 0x%-16llx %s\n", it, (long long)callFrame->callee().rawPtr(), valueAsString(it->jsValue()).data()); >+ --it; >+ dataLogF("[CodeBlock] | %10p | 0x%-16llx ", it, (long long)codeBlock); >+ dataLogLn(codeBlock); >+ --it; >+#if ENABLE(JIT) >+ AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm()); >+ if (pc.hasJITReturnAddress()) >+ dataLogF("[ReturnPC] | %10p | %p \n", it, pc.jitReturnAddress().value()); >+ --it; >+#endif >+ dataLogF("[CallerFrame] | %10p | %p \n", it, callFrame->callerFrame()); >+ --it; >+ dataLogF("-----------------------------------------------------------------------------\n"); >+ >+ size_t numberOfCalleeSaveSlots = codeBlock->calleeSaveSpaceAsVirtualRegisters(); >+ const Register* endOfCalleeSaves = it - numberOfCalleeSaveSlots; >+ >+ end = it - codeBlock->numVars(); >+ if (it != end) { >+ do { >+ JSValue v = it->jsValue(); >+ int registerNumber = it - callFrame->registers(); >+ String name = (it > endOfCalleeSaves) >+ ? "CalleeSaveReg" >+ : codeBlock->nameForRegister(VirtualRegister(registerNumber)); >+ dataLogF("[r% 3d %14s] | %10p | 0x%-16llx %s\n", registerNumber, name.ascii().data(), it, (long long)JSValue::encode(v), valueAsString(v).data()); >+ --it; >+ } while (it != end); >+ } >+ dataLogF("-----------------------------------------------------------------------------\n"); >+ >+ end = it - codeBlock->numCalleeLocals() + codeBlock->numVars(); >+ if (it != end) { >+ do { >+ JSValue v = (*it).jsValue(); >+ int registerNumber = it - callFrame->registers(); >+ dataLogF("[r% 3d] | %10p | 0x%-16llx %s\n", registerNumber, it, (long long)JSValue::encode(v), valueAsString(v).data()); >+ --it; >+ } while (it != end); >+ } >+ dataLogF("-----------------------------------------------------------------------------\n"); >+} >+ > void VMInspector::dumpStack(CallFrame* topCallFrame, unsigned framesToSkip) > { > if (!ensureCurrentThreadOwnsJSLock(topCallFrame)) >Index: Source/JavaScriptCore/tools/VMInspector.h >=================================================================== >--- Source/JavaScriptCore/tools/VMInspector.h (revision 235407) >+++ Source/JavaScriptCore/tools/VMInspector.h (working copy) >@@ -70,6 +70,7 @@ public: > JS_EXPORT_PRIVATE static bool isValidCodeBlock(ExecState*, CodeBlock*); > JS_EXPORT_PRIVATE static CodeBlock* codeBlockForFrame(CallFrame* topCallFrame, unsigned frameNumber); > JS_EXPORT_PRIVATE static void dumpCallFrame(CallFrame*, unsigned framesToSkip = 0); >+ JS_EXPORT_PRIVATE static void dumpRegisters(CallFrame*); > JS_EXPORT_PRIVATE static void dumpStack(CallFrame* topCallFrame, unsigned framesToSkip = 0); > JS_EXPORT_PRIVATE static void dumpValue(JSValue); > JS_EXPORT_PRIVATE static void dumpCellMemory(JSCell*);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
saam
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189059
: 348346