Bug 143809 - Add $vm debugging tool.
Summary: Add $vm debugging tool.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Lam
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-15 19:05 PDT by Mark Lam
Modified: 2015-04-17 14:24 PDT (History)
12 users (show)

See Also:


Attachments
the patch. (46.98 KB, patch)
2015-04-16 12:45 PDT, Mark Lam
ggaren: review+
Details | Formatted Diff | Diff
patch 2: applied Geoff's suggestions and fixes. (47.83 KB, patch)
2015-04-16 15:48 PDT, Mark Lam
ggaren: review+
Details | Formatted Diff | Diff
patch 3: with fix for bitwise_cast complaint. (47.85 KB, patch)
2015-04-16 16:11 PDT, Mark Lam
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Lam 2015-04-15 19:05:22 PDT
For debugging VM bugs, it would be useful to be able to dump VM data structures from JS code that we instrument.  To this end, let's introduce a JS_enableDollarVM option that, if true, installs an $vm property into each JS global object at creation time.  The $vm property refers to an object that provides a collection of useful utility functions.  For this initial implementation, $vm will have the following:

    dfgTrue() - returns true if the current function is DFG compiled, else returns false.
    jitTrue() - returns true if the current function is compiled by the baseline JIT, else returns false.
    llintTrue() - returns true if the current function is interpreted by the LLINT, else returns false.

    gc() - runs a full GC and sweep all dead objects.
    fullGC() - runs a full GC but does not sweep dead objects. 
    edenGC() - runs an eden GC but does not sweep dead objects.

    codeBlockForFrame(frameNumber) - gets the codeBlock at the specified frame (0 = current, 1 = caller, etc).
    printSourceFor(codeBlock) - prints the source code for the codeBlock.
    printByteCodeFor(codeBlock) - prints the bytecode for the codeBlock.

    print(str) - prints a string to dataLog output.
    printCallFrame() - prints the current CallFrame.
    printStack() - prints the JS stack.
    printInternal(value) - prints the JSC internal info for the specified value.

With JS_enableDollarVM=true, JS code can use the above functions like so:

    $vm.print("Using $vm features\n");
Comment 1 Mark Lam 2015-04-16 12:45:55 PDT
Created attachment 250941 [details]
the patch.
Comment 2 Geoffrey Garen 2015-04-16 13:14:05 PDT
Comment on attachment 250941 [details]
the patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=250941&action=review

r=me if you fix the GTK build and the comments below.

> Source/JavaScriptCore/CMakeLists.txt:392
> +    tools/DollarVMPrototype.cpp
> +    tools/JSDollarVM.cpp

For consistency, these should be "JSDollarVM" and "JSDollarVMPrototype" or "DollarVM" and "DollarVMPrototype", but not a mix of the two.

We seem to be gravitating toward a style where we put "JS" in front of any JS API object, since it's so common for normal names -- like Map, for example -- to conflict with a standard name. So, I'd suggest "JSDollarVM" and "JSDollarVMPrototype" here.

> Source/JavaScriptCore/interpreter/StackVisitor.cpp:324
> +#define IDT printIndents(indent)

Rather than a macro, which is hard to decipher and debug, and which violates our coding standards by putting two statements on the same line, can you just make a helper function that, given an indentation level and some arguments, calls printIndents and then calls dataLog with its remaining arguments?

> Source/JavaScriptCore/tools/DollarVMPrototype.cpp:38
> +// lldb. The JS versions in DollarVMPrototype are implemented on top of these
> +// these.

"these these"

> Source/JavaScriptCore/tools/DollarVMPrototype.cpp:41
> +JS_EXPORT_PRIVATE void gcAndSweep(ExecState*);

This function name should specify whether it does full GC or eden GC.

> Source/JavaScriptCore/tools/DollarVMPrototype.cpp:48
> +JS_EXPORT_PRIVATE void printInternal(JSValue);

Let's call this printValue. "Internal" has little meaning.

> Source/JavaScriptCore/tools/DollarVMPrototype.cpp:88
> +// We'll pass C++ pointers into JS as a double token and convert back when
> +// we consume them. These are convenience functions to do that conversion.
> +template<typename T>
> +static double ptrToDouble(T* ptr)
> +{
> +    union {
> +        double d;
> +        T* ptr;
> +    } u;
> +    u.ptr = ptr;
> +    return u.d;
> +}
> +
> +template<typename T>
> +static T* doubleToPtr(double d)
> +{
> +    union {
> +        double d;
> +        T* ptr;
> +    } u;
> +    u.d = d;
> +    return u.ptr;
> +}

Can you just use bitwise_cast?
Comment 3 Mark Lam 2015-04-16 15:46:54 PDT
(In reply to comment #2)
> Comment on attachment 250941 [details]
> the patch.
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250941&action=review
> 
> r=me if you fix the GTK build and the comments below.

Looks like a conflict with the previous patch that I landed.  Just need to rebase to ToT.
 
> > Source/JavaScriptCore/CMakeLists.txt:392
> > +    tools/DollarVMPrototype.cpp
> > +    tools/JSDollarVM.cpp
> 
> For consistency, these should be "JSDollarVM" and "JSDollarVMPrototype" or
> "DollarVM" and "DollarVMPrototype", but not a mix of the two.
> 
> ... I'd suggest "JSDollarVM" and "JSDollarVMPrototype" here.

Done.

> > Source/JavaScriptCore/interpreter/StackVisitor.cpp:324
> > +#define IDT printIndents(indent)
> 
> Rather than a macro, ... make a helper function that, given an indentation level and some
> arguments, calls printIndents and then calls dataLog with its remaining
> arguments?

Done.  I now use 2 file local variadic templates (log() and logF()) that does the job of dataLog() and dataLogF() but with indentation support.

> > Source/JavaScriptCore/tools/DollarVMPrototype.cpp:38
> > +// lldb. The JS versions in DollarVMPrototype are implemented on top of these
> > +// these.
> 
> "these these"

Fixed.

> > Source/JavaScriptCore/tools/DollarVMPrototype.cpp:41
> > +JS_EXPORT_PRIVATE void gcAndSweep(ExecState*);
> 
> This function name should specify whether it does full GC or eden GC.

Per our offline discussion, I've removed fullGC().  What we have now is:
   gc() - does a synchronous full GC and sweep.
   edenGC() - does a synchronous eden GC and sweep.

> > Source/JavaScriptCore/tools/DollarVMPrototype.cpp:48
> > +JS_EXPORT_PRIVATE void printInternal(JSValue);
> 
> Let's call this printValue. "Internal" has little meaning.

Done.

> > Source/JavaScriptCore/tools/DollarVMPrototype.cpp:88
> Can you just use bitwise_cast?

Fixed.

In addition, I had to make 2 other changes:

1. Refactored Heap::collectAllGarbage() into Heap::collectAndSweep(HeapOperation).
   collectAllGarbage() is now a wrapper around collectAndSweep().  $vm.edenGC() calls collectAndSweep(EdenCollection).

2. Changed CodeBlock::printCallOp() to not compute the CallLinkStatus for FTL codeBlocks since the FTL does not support this.
   Otherwise, we'll get a crash when dumping bytecode for an FTL compiled codeBlock.

Updated patch coming shortly.
Comment 4 Mark Lam 2015-04-16 15:48:17 PDT
Created attachment 250960 [details]
patch 2: applied Geoff's suggestions and fixes.
Comment 5 Geoffrey Garen 2015-04-16 15:50:35 PDT
Comment on attachment 250960 [details]
patch 2: applied Geoff's suggestions and fixes.

r=me
Comment 6 WebKit Commit Bot 2015-04-16 15:50:51 PDT
Attachment 250960 [details] did not pass style-queue:


ERROR: Source/JavaScriptCore/interpreter/StackVisitor.cpp:319:  Weird number of spaces at line-start.  Are you using a 4-space indent?  [whitespace/indent] [3]
Total errors found: 1 in 16 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 7 Mark Lam 2015-04-16 15:51:57 PDT
(In reply to comment #6)
> ERROR: Source/JavaScriptCore/interpreter/StackVisitor.cpp:319:  Weird number
> of spaces at line-start.  Are you using a 4-space indent? 
> [whitespace/indent] [3]
> Total errors found: 1 in 16 files

Accidental extra space.  Will fix before landing.
Comment 8 Mark Lam 2015-04-16 16:11:06 PDT
Created attachment 250968 [details]
patch 3: with fix for bitwise_cast complaint.
Comment 9 Mark Lam 2015-04-16 17:27:00 PDT
Thanks for the review.  Landed in r182927: <http://trac.webkit.org/r182927>.
Comment 10 Mark Lam 2015-04-17 14:24:28 PDT
FYI, a build fix for this patch on 32-bit ports was landed in http://trac.webkit.org/changeset/182934.