• Benedikt Meurer's avatar
    [stack-traces] Simplify and speedup stack trace collection. · eed0d27c
    Benedikt Meurer authored
    Following up on https://crrev.com/c/2689185, this CL significantly
    simplifies the whole implementation of the stack trace capturing.
    
    Before this CL, capturing any stack trace (for the purpose of the API or
    Error.stack) would roughly work like this:
    
      1. The CaptureStackTrace() function uses the StackFrameIterator to
         walk the system stack. For each native frame it uses the
         FrameSummary abstraction to get all (including potentially inlined)
         frames. For each of those it appends a record consisting of six
         elements to a FrameArray (this holds pointers to the actual
         closures and receivers).
      2. Afterwards the FrameArray is shrinked to the required size, and a
         new FixedArray is allocated, and initialized with new
         StackTraceFrame objects where each holds a reference to the
         FrameArray, the index of the frame, and an initially uninitialized
         StackFrameInfo reference. This new FixedArray is then returned from
         CaptureStackTrace() and either stored on a message object or
         provided to the API as v8::StackTrace.
    
    The new approach removes a lot of the machinery in between and directly
    creates a FixedArray of StackFrameInfo objects in CaptureStackTrace().
    These StackFrameInfo objects are directly exposed as v8::StackFrame on
    the public API, and they hold the six fields that were previously stored
    flat in the FrameArray. This not only avoids a lot of copying around of
    data and creation of temporary objects and handles, but most importantly
    unifies and simplifies the stack frame function inside StackFrameInfo,
    so you no longer need to wonder which function / object might be
    responsible for a certain API.
    
    There's still a lot of room for improvement. In particular we currently
    don't cache the source position for a given StackFrameInfo (or
    globally), but rather recompute it every time. This is still very fast,
    significantly faster than the previous approach.
    
    There are some notable (potentially user visible) changes:
    
      - The CallSite#GetPosition() method now consistently returns the
        Wasm module relative bytecode offset for all Wasm frames (previously
        it'd return the function relative bytecode offset for non-asm.js
        Wasm frames).
      - The column and line numbers returned from StackFrameInfo methods are
        consistently 1-based now, instead of sometimes being 0-based (Wasm)
        and sometimes being 1-based (JS and asm.js Wasm). The only
        potentially noticable difference is that for
        CallSite#GetLineNumber() no longer returns 0 for Wasm frames, but
        that was wrong and useless anyways.
      - CallSite#GetThis() would sometimes return the_hole, another bug
        flushed out by this CL.
    
    The CL also contains some other not noteworthy drive-by-cleanups.
    
    Fixed: chromium:1057211
    Bug: chromium:1077657, chromium:1069425, v8:8742
    Bug: chromium:1127391, chromium:1098530, chromium:981541
    Change-Id: Iff12f6838a4d99080db8dd96bccc14440affc5a5
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2689183
    Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
    Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
    Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
    Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#72694}
    eed0d27c
stack-frame-info.tq 678 Bytes