Changeset 235450 in webkit


Ignore:
Timestamp:
Aug 28, 2018, 4:43:59 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

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 Saam Barati.

  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
-----------------------------------------------------------------------------

  1. 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.

  1. 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:
Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r235436 r235450  
     12018-08-28  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix bit-rotted Interpreter::dumpRegisters() and move it to the VMInspector.
     4        https://bugs.webkit.org/show_bug.cgi?id=189059
     5        <rdar://problem/40335354>
     6
     7        Reviewed by Saam Barati.
     8
     9        1. Moved Interpreter::dumpRegisters() to VMInspector::dumpRegisters().
     10        2. Added $vm.dumpRegisters().
     11
     12            Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
     13            Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
     14
     15           Note: Currently, $vm.dumpRegisters() only dump registers in the physical frame.
     16           It will treat inlined frames content as registers in the bounding physical frame.
     17
     18           Here's an example of such a dump on a DFG frame:
     19
     20                Register frame:
     21
     22                -----------------------------------------------------------------------------
     23                            use            |   address  |                value               
     24                -----------------------------------------------------------------------------
     25                [r 12 arguments[  7]]      | 0x7ffeefbfd330 | 0xa                Undefined
     26                [r 11 arguments[  6]]      | 0x7ffeefbfd328 | 0x10bbb3e80        Object: 0x10bbb3e80 with butterfly 0x0 (Structure 0x10bbf20d0:[Object, {}, NonArray, Proto:0x10bbb4000]), StructureID: 76
     27                [r 10 arguments[  5]]      | 0x7ffeefbfd320 | 0xa                Undefined
     28                [r  9 arguments[  4]]      | 0x7ffeefbfd318 | 0xa                Undefined
     29                [r  8 arguments[  3]]      | 0x7ffeefbfd310 | 0xa                Undefined
     30                [r  7 arguments[  2]]      | 0x7ffeefbfd308 | 0xffff0000000a5eaa Int32: 679594
     31                [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
     32                [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
     33                -----------------------------------------------------------------------------
     34                [ArgumentCount]            | 0x7ffeefbfd2f0 | 7
     35                [ReturnVPC]                | 0x7ffeefbfd2f0 | 164 (line 57)
     36                [Callee]                   | 0x7ffeefbfd2e8 | 0x10bb68db0        Object: 0x10bb68db0 with butterfly 0x0 (Structure 0x10bbf1c00:[Function, {}, NonArray, Proto:0x10bbd0000, Shady leaf]), StructureID: 65
     37                [CodeBlock]                | 0x7ffeefbfd2e0 | 0x10bb2f8e0        __callRandomFunction#DmVXnv:[0x10bb2f8e0->0x10bbfd1e0, LLIntFunctionCall, 253]
     38                [ReturnPC]                 | 0x7ffeefbfd2d8 | 0x10064d14c
     39                [CallerFrame]              | 0x7ffeefbfd2d0 | 0x7ffeefbfd380
     40                -----------------------------------------------------------------------------
     41                [r -1  CalleeSaveReg]      | 0x7ffeefbfd2c8 | 0xffff000000000002 Int32: 2
     42                [r -2  CalleeSaveReg]      | 0x7ffeefbfd2c0 | 0xffff000000000000 Int32: 0
     43                [r -3  CalleeSaveReg]      | 0x7ffeefbfd2b8 | 0x10baf1608       
     44                [r -4               ]      | 0x7ffeefbfd2b0 | 0x10bbcc000        Object: 0x10bbcc000 with butterfly 0x0 (Structure 0x10bbf1960:[JSGlobalLexicalEnvironment, {}, NonArray, Leaf]), StructureID: 59
     45                [r -5               ]      | 0x7ffeefbfd2a8 | 0x10bbcc000        Object: 0x10bbcc000 with butterfly 0x0 (Structure 0x10bbf1960:[JSGlobalLexicalEnvironment, {}, NonArray, Leaf]), StructureID: 59
     46                [r -6               ]      | 0x7ffeefbfd2a0 | 0xa                Undefined
     47                -----------------------------------------------------------------------------
     48                [r -7]                     | 0x7ffeefbfd298 | 0x10bb6fdc0        String (atomic) (identifier): length, StructureID: 4
     49                [r -8]                     | 0x7ffeefbfd290 | 0x10bbb7ec0        Object: 0x10bbb7ec0 with butterfly 0x8000e0008 (Structure 0x10bbf2ae0:[Array, {}, ArrayWithContiguous, Proto:0x10bbc8080]), StructureID: 99
     50                [r -9]                     | 0x7ffeefbfd288 | 0x10bbc33f0        Object: 0x10bbc33f0 with butterfly 0x8000fdda8 (Structure 0x10bbf1dc0:[Function, {name:100, length:101}, NonArray, Proto:0x10bbd0000, Leaf]), StructureID: 69
     51                [r-10]                     | 0x7ffeefbfd280 | 0xffff000000000004 Int32: 4
     52                [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
     53                [r-12]                     | 0x7ffeefbfd270 | 0x100000001       
     54                [r-13]                     | 0x7ffeefbfd268 | 0x10bbc33f0        Object: 0x10bbc33f0 with butterfly 0x8000fdda8 (Structure 0x10bbf1dc0:[Function, {name:100, length:101}, NonArray, Proto:0x10bbd0000, Leaf]), StructureID: 69
     55                [r-14]                     | 0x7ffeefbfd260 | 0x0               
     56                [r-15]                     | 0x7ffeefbfd258 | 0x10064d14c       
     57                [r-16]                     | 0x7ffeefbfd250 | 0x7ffeefbfd2d0     
     58                [r-17]                     | 0x7ffeefbfd248 | 0x67ec87ee177      INVALID
     59                [r-18]                     | 0x7ffeefbfd240 | 0x7ffeefbfd250     
     60                -----------------------------------------------------------------------------
     61
     62        3. Removed dumpCallFrame() from the jsc shell.  We have the following tools that
     63           we can use in its place:
     64
     65            $vm.dumpCallFrame()
     66            $vm.dumpBytecodeFor()
     67            $vm.dumpRegisters()     // Just added in this patch.
     68
     69        4. Also fixed a bug in BytecodeDumper: it should only access
     70           CallLinkInfo::haveLastSeenCallee() only if CallLinkInfo::isDirect() is false.
     71
     72        * bytecode/BytecodeDumper.cpp:
     73        (JSC::BytecodeDumper<Block>::printCallOp):
     74        * interpreter/Interpreter.cpp:
     75        (JSC::Interpreter::dumpCallFrame): Deleted.
     76        (JSC::DumpReturnVirtualPCFunctor::DumpReturnVirtualPCFunctor): Deleted.
     77        (JSC::DumpReturnVirtualPCFunctor::operator() const): Deleted.
     78        (JSC::Interpreter::dumpRegisters): Deleted.
     79        * interpreter/Interpreter.h:
     80        * jsc.cpp:
     81        (GlobalObject::finishCreation):
     82        (functionDumpCallFrame): Deleted.
     83        * tools/JSDollarVM.cpp:
     84        (JSC::functionDumpRegisters):
     85        (JSC::JSDollarVM::finishCreation):
     86        * tools/VMInspector.cpp:
     87        (JSC::VMInspector::dumpRegisters):
     88        * tools/VMInspector.h:
     89
    1902018-08-28  Keith Miller  <keith_miller@apple.com>
    291
  • trunk/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp

    r234086 r235450  
    615615#if ENABLE(JIT)
    616616        if (CallLinkInfo* info = statusMap.get(CodeOrigin(location)).callLinkInfo) {
    617             if (info->haveLastSeenCallee()) {
     617            if (!info->isDirect() && info->haveLastSeenCallee()) {
    618618                JSObject* object = info->lastSeenCallee();
    619619                if (auto* function = jsDynamicCast<JSFunction*>(*vm(), object))
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r235419 r235450  
    370370#endif // ENABLE(COMPUTED_GOTO_OPCODES)
    371371
    372 #ifdef NDEBUG
    373 
    374 void Interpreter::dumpCallFrame(CallFrame*)
    375 {
    376 }
    377 
    378 #else
    379 
    380 void Interpreter::dumpCallFrame(CallFrame* callFrame)
    381 {
    382     callFrame->codeBlock()->dumpBytecode();
    383     dumpRegisters(callFrame);
    384 }
    385 
    386 class DumpReturnVirtualPCFunctor {
    387 public:
    388     DumpReturnVirtualPCFunctor(const Register*& it)
    389         : m_hasSkippedFirstFrame(false)
    390         , m_it(it)
    391     {
    392     }
    393 
    394     StackVisitor::Status operator()(StackVisitor& visitor) const
    395     {
    396         if (!m_hasSkippedFirstFrame) {
    397             m_hasSkippedFirstFrame = true;
    398             return StackVisitor::Continue;
    399         }
    400 
    401         unsigned line = 0;
    402         unsigned unusedColumn = 0;
    403         visitor->computeLineAndColumn(line, unusedColumn);
    404         dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", m_it, visitor->bytecodeOffset(), line);
    405         return StackVisitor::Done;
    406     }
    407 
    408 private:
    409     mutable bool m_hasSkippedFirstFrame;
    410     const Register*& m_it;
    411 };
    412 
    413 void Interpreter::dumpRegisters(CallFrame* callFrame)
    414 {
    415     CodeBlock* codeBlock = callFrame->codeBlock();
    416     if (!codeBlock) {
    417         dataLog("Dumping host frame registers not supported.\n");
    418         return;
    419     }
    420     VM& vm = *codeBlock->vm();
    421 
    422     dataLogF("Register frame: \n\n");
    423     dataLogF("-----------------------------------------------------------------------------\n");
    424     dataLogF("            use            |   address  |                value               \n");
    425     dataLogF("-----------------------------------------------------------------------------\n");
    426 
    427     const Register* it;
    428     const Register* end;
    429 
    430     it = callFrame->registers() + CallFrameSlot::thisArgument + callFrame->argumentCount();
    431     end = callFrame->registers() + CallFrameSlot::thisArgument - 1;
    432     while (it > end) {
    433         JSValue v = it->jsValue();
    434         int registerNumber = it - callFrame->registers();
    435         String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
    436         dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
    437         --it;
    438     }
    439    
    440     dataLogF("-----------------------------------------------------------------------------\n");
    441     dataLogF("[ArgumentCount]            | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
    442     DumpReturnVirtualPCFunctor functor(it);
    443     callFrame->iterate(functor);
    444     --it;
    445     dataLogF("[Callee]                   | %10p | %p \n", it, callFrame->jsCallee());
    446     --it;
    447     dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
    448     --it;
    449 #if ENABLE(JIT)
    450     AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
    451     if (pc.hasJITReturnAddress())
    452         dataLogF("[ReturnPC]                 | %10p | %p \n", it, pc.jitReturnAddress().value());
    453     --it;
    454 #endif
    455     dataLogF("[CallerFrame]              | %10p | %p \n", it, callFrame->callerFrame());
    456     --it;
    457     dataLogF("-----------------------------------------------------------------------------\n");
    458 
    459     size_t numberOfCalleeSaveSlots = codeBlock->calleeSaveSpaceAsVirtualRegisters();
    460     const Register* endOfCalleeSaves = it - numberOfCalleeSaveSlots;
    461 
    462     end = it - codeBlock->numVars();
    463     if (it != end) {
    464         do {
    465             JSValue v = it->jsValue();
    466             int registerNumber = it - callFrame->registers();
    467             String name = (it > endOfCalleeSaves)
    468                 ? "CalleeSaveReg"
    469                 : codeBlock->nameForRegister(VirtualRegister(registerNumber));
    470             CString valueString = (it > endOfCalleeSaves) ? "" : toCString(v);
    471             dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, valueString.data(), (long long)JSValue::encode(v));
    472             --it;
    473         } while (it != end);
    474     }
    475     dataLogF("-----------------------------------------------------------------------------\n");
    476 
    477     end = it - codeBlock->numCalleeLocals() + codeBlock->numVars();
    478     if (it != end) {
    479         do {
    480             JSValue v = (*it).jsValue();
    481             int registerNumber = it - callFrame->registers();
    482             CString valueString =
    483                 (v.isCell() && !VMInspector::isValidCell(&vm.heap, reinterpret_cast<JSCell*>(JSValue::encode(v))))
    484                 ? "INVALID"
    485                 : toCString(v);
    486             dataLogF("[r% 3d]                     | %10p | %-16s 0x%lld \n", registerNumber, it, valueString.data(), (long long)JSValue::encode(v));
    487             --it;
    488         } while (it != end);
    489     }
    490     dataLogF("-----------------------------------------------------------------------------\n");
    491 }
    492 
    493 #endif
    494 
    495372#if !ASSERT_DISABLED
    496373bool Interpreter::isOpcode(Opcode opcode)
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r235419 r235450  
    126126        static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
    127127
    128         JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
    129 
    130128        void getStackTrace(JSCell* owner, Vector<StackFrame>& results, size_t framesToSkip = 0, size_t maxStackSize = std::numeric_limits<size_t>::max());
    131129
     
    149147        JSValue execute(CallFrameClosure&);
    150148
    151 
    152 
    153         void dumpRegisters(CallFrame*);
    154        
    155149        VM& m_vm;
    156150#if !ENABLE(JIT)
  • trunk/Source/JavaScriptCore/jsc.cpp

    r234501 r235450  
    269269static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*);
    270270static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*);
    271 #ifndef NDEBUG
    272 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
    273 #endif
    274271static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
    275272static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
     
    490487        addFunction(vm, "gcHeapSize", functionHeapSize, 0);
    491488        addFunction(vm, "addressOf", functionAddressOf, 1);
    492 #ifndef NDEBUG
    493         addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
    494 #endif
    495489        addFunction(vm, "version", functionVersion, 1);
    496490        addFunction(vm, "run", functionRun, 1);
     
    10541048EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState* exec) { return printInternal(exec, stderr); }
    10551049
    1056 #ifndef NDEBUG
    1057 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
    1058 {
    1059     VM& vm = exec->vm();
    1060     EntryFrame* topEntryFrame = vm.topEntryFrame;
    1061     ExecState* callerFrame = exec->callerFrame(topEntryFrame);
    1062     if (callerFrame)
    1063         vm.interpreter->dumpCallFrame(callerFrame);
    1064     return JSValue::encode(jsUndefined());
    1065 }
    1066 #endif
    1067 
    10681050EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
    10691051{
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r235420 r235450  
    15701570}
    15711571
     1572// Dumps the current CallFrame.
     1573// Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
     1574// Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
     1575// FIXME: Currently, this function dumps the physical frame. We should make
     1576// it dump the logical frame (i.e. be able to dump inlined frames as well).
     1577static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(ExecState* exec)
     1578{
     1579    unsigned requestedFrameIndex = 1;
     1580    if (exec->argumentCount() >= 1) {
     1581        JSValue value = exec->uncheckedArgument(0);
     1582        if (!value.isUInt32())
     1583            return JSValue::encode(jsUndefined());
     1584
     1585        // We need to inc the frame number because the caller would consider
     1586        // its own frame as frame 0. Hence, we need discount the frame for this
     1587        // function.
     1588        requestedFrameIndex = value.asUInt32() + 1;
     1589    }
     1590
     1591    unsigned frameIndex = 0;
     1592    exec->iterate([&] (StackVisitor& visitor) {
     1593        if (frameIndex++ != requestedFrameIndex)
     1594            return StackVisitor::Continue;
     1595        VMInspector::dumpRegisters(visitor->callFrame());
     1596        return StackVisitor::Done;
     1597    });
     1598
     1599    return encodedJSUndefined();
     1600}
     1601
    15721602// Dumps the internal memory layout of a JSCell.
    15731603// Usage: $vm.dumpCell(cell)
     
    21092139    addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
    21102140    addFunction(vm, "dumpStack", functionDumpStack, 0);
     2141    addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
    21112142
    21122143    addFunction(vm, "dumpCell", functionDumpCell, 1);
  • trunk/Source/JavaScriptCore/tools/VMInspector.cpp

    r234363 r235450  
    368368}
    369369
     370void VMInspector::dumpRegisters(CallFrame* callFrame)
     371{
     372    CodeBlock* codeBlock = callFrame->codeBlock();
     373    if (!codeBlock) {
     374        dataLog("Dumping host frame registers not supported.\n");
     375        return;
     376    }
     377    VM& vm = *codeBlock->vm();
     378    auto valueAsString = [&] (JSValue v) -> CString {
     379        if (!v.isCell() || VMInspector::isValidCell(&vm.heap, reinterpret_cast<JSCell*>(JSValue::encode(v))))
     380            return toCString(v);
     381        return "";
     382    };
     383
     384    dataLogF("Register frame: \n\n");
     385    dataLogF("-----------------------------------------------------------------------------\n");
     386    dataLogF("            use            |   address  |                value               \n");
     387    dataLogF("-----------------------------------------------------------------------------\n");
     388
     389    const Register* it;
     390    const Register* end;
     391
     392    it = callFrame->registers() + CallFrameSlot::thisArgument + callFrame->argumentCount();
     393    end = callFrame->registers() + CallFrameSlot::thisArgument - 1;
     394    while (it > end) {
     395        JSValue v = it->jsValue();
     396        int registerNumber = it - callFrame->registers();
     397        String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
     398        dataLogF("[r% 3d %14s]      | %10p | 0x%-16llx %s\n", registerNumber, name.ascii().data(), it, (long long)JSValue::encode(v), valueAsString(v).data());
     399        --it;
     400    }
     401   
     402    dataLogF("-----------------------------------------------------------------------------\n");
     403    dataLogF("[ArgumentCount]            | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
     404
     405    callFrame->iterate([&] (StackVisitor& visitor) {
     406        if (visitor->callFrame() == callFrame) {
     407            unsigned line = 0;
     408            unsigned unusedColumn = 0;
     409            visitor->computeLineAndColumn(line, unusedColumn);
     410            dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", it, visitor->bytecodeOffset(), line);
     411            return StackVisitor::Done;
     412        }
     413        return StackVisitor::Continue;
     414    });
     415
     416    --it;
     417    dataLogF("[Callee]                   | %10p | 0x%-16llx %s\n", it, (long long)callFrame->callee().rawPtr(), valueAsString(it->jsValue()).data());
     418    --it;
     419    dataLogF("[CodeBlock]                | %10p | 0x%-16llx ", it, (long long)codeBlock);
     420    dataLogLn(codeBlock);
     421    --it;
     422#if ENABLE(JIT)
     423    AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
     424    if (pc.hasJITReturnAddress())
     425        dataLogF("[ReturnPC]                 | %10p | %p \n", it, pc.jitReturnAddress().value());
     426    --it;
     427#endif
     428    dataLogF("[CallerFrame]              | %10p | %p \n", it, callFrame->callerFrame());
     429    --it;
     430    dataLogF("-----------------------------------------------------------------------------\n");
     431
     432    size_t numberOfCalleeSaveSlots = codeBlock->calleeSaveSpaceAsVirtualRegisters();
     433    const Register* endOfCalleeSaves = it - numberOfCalleeSaveSlots;
     434
     435    end = it - codeBlock->numVars();
     436    if (it != end) {
     437        do {
     438            JSValue v = it->jsValue();
     439            int registerNumber = it - callFrame->registers();
     440            String name = (it > endOfCalleeSaves)
     441                ? "CalleeSaveReg"
     442                : codeBlock->nameForRegister(VirtualRegister(registerNumber));
     443            dataLogF("[r% 3d %14s]      | %10p | 0x%-16llx %s\n", registerNumber, name.ascii().data(), it, (long long)JSValue::encode(v), valueAsString(v).data());
     444            --it;
     445        } while (it != end);
     446    }
     447    dataLogF("-----------------------------------------------------------------------------\n");
     448
     449    end = it - codeBlock->numCalleeLocals() + codeBlock->numVars();
     450    if (it != end) {
     451        do {
     452            JSValue v = (*it).jsValue();
     453            int registerNumber = it - callFrame->registers();
     454            dataLogF("[r% 3d]                     | %10p | 0x%-16llx %s\n", registerNumber, it, (long long)JSValue::encode(v), valueAsString(v).data());
     455            --it;
     456        } while (it != end);
     457    }
     458    dataLogF("-----------------------------------------------------------------------------\n");
     459}
     460
    370461void VMInspector::dumpStack(CallFrame* topCallFrame, unsigned framesToSkip)
    371462{
  • trunk/Source/JavaScriptCore/tools/VMInspector.h

    r234363 r235450  
    7171    JS_EXPORT_PRIVATE static CodeBlock* codeBlockForFrame(CallFrame* topCallFrame, unsigned frameNumber);
    7272    JS_EXPORT_PRIVATE static void dumpCallFrame(CallFrame*, unsigned framesToSkip = 0);
     73    JS_EXPORT_PRIVATE static void dumpRegisters(CallFrame*);
    7374    JS_EXPORT_PRIVATE static void dumpStack(CallFrame* topCallFrame, unsigned framesToSkip = 0);
    7475    JS_EXPORT_PRIVATE static void dumpValue(JSValue);
Note: See TracChangeset for help on using the changeset viewer.