LCOV - code coverage report
Current view: top level - js/public - ProfilingFrameIterator.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 28 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef js_ProfilingFrameIterator_h
       8             : #define js_ProfilingFrameIterator_h
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : #include "mozilla/Maybe.h"
      12             : 
      13             : #include "jsbytecode.h"
      14             : #include "js/GCAPI.h"
      15             : #include "js/TypeDecls.h"
      16             : #include "js/Utility.h"
      17             : 
      18             : struct JSContext;
      19             : struct JSRuntime;
      20             : class JSScript;
      21             : 
      22             : namespace js {
      23             :     class Activation;
      24             :     namespace jit {
      25             :         class JitActivation;
      26             :         class JitProfilingFrameIterator;
      27             :         class JitcodeGlobalEntry;
      28             :     } // namespace jit
      29             :     namespace wasm {
      30             :         class ProfilingFrameIterator;
      31             :     } // namespace wasm
      32             : } // namespace js
      33             : 
      34             : namespace JS {
      35             : 
      36             : struct ForEachTrackedOptimizationAttemptOp;
      37             : struct ForEachTrackedOptimizationTypeInfoOp;
      38             : 
      39             : // This iterator can be used to walk the stack of a thread suspended at an
      40             : // arbitrary pc. To provide accurate results, profiling must have been enabled
      41             : // (via EnableRuntimeProfilingStack) before executing the callstack being
      42             : // unwound.
      43             : //
      44             : // Note that the caller must not do anything that could cause GC to happen while
      45             : // the iterator is alive, since this could invalidate Ion code and cause its
      46             : // contents to become out of date.
      47             : class MOZ_NON_PARAM JS_PUBLIC_API(ProfilingFrameIterator)
      48             : {
      49             :     JSContext* cx_;
      50             :     uint32_t sampleBufferGen_;
      51             :     js::Activation* activation_;
      52             : 
      53             :     static const unsigned StorageSpace = 8 * sizeof(void*);
      54             :     alignas(void*) unsigned char storage_[StorageSpace];
      55             : 
      56           0 :     void* storage() { return storage_; }
      57           0 :     const void* storage() const { return storage_; }
      58             : 
      59           0 :     js::wasm::ProfilingFrameIterator& wasmIter() {
      60           0 :         MOZ_ASSERT(!done());
      61           0 :         MOZ_ASSERT(isWasm());
      62           0 :         return *static_cast<js::wasm::ProfilingFrameIterator*>(storage());
      63             :     }
      64           0 :     const js::wasm::ProfilingFrameIterator& wasmIter() const {
      65           0 :         MOZ_ASSERT(!done());
      66           0 :         MOZ_ASSERT(isWasm());
      67           0 :         return *static_cast<const js::wasm::ProfilingFrameIterator*>(storage());
      68             :     }
      69             : 
      70           0 :     js::jit::JitProfilingFrameIterator& jitIter() {
      71           0 :         MOZ_ASSERT(!done());
      72           0 :         MOZ_ASSERT(isJit());
      73           0 :         return *static_cast<js::jit::JitProfilingFrameIterator*>(storage());
      74             :     }
      75             : 
      76           0 :     const js::jit::JitProfilingFrameIterator& jitIter() const {
      77           0 :         MOZ_ASSERT(!done());
      78           0 :         MOZ_ASSERT(isJit());
      79           0 :         return *static_cast<const js::jit::JitProfilingFrameIterator*>(storage());
      80             :     }
      81             : 
      82             :     void settle();
      83             : 
      84           0 :     bool hasSampleBufferGen() const {
      85           0 :         return sampleBufferGen_ != UINT32_MAX;
      86             :     }
      87             : 
      88             :   public:
      89             :     struct RegisterState
      90             :     {
      91           0 :         RegisterState() : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
      92             :         void* pc;
      93             :         void* sp;
      94             :         void* fp;
      95             :         void* lr;
      96             :     };
      97             : 
      98             :     ProfilingFrameIterator(JSContext* cx, const RegisterState& state,
      99             :                            uint32_t sampleBufferGen = UINT32_MAX);
     100             :     ~ProfilingFrameIterator();
     101             :     void operator++();
     102           0 :     bool done() const { return !activation_; }
     103             : 
     104             :     // Assuming the stack grows down (we do), the return value:
     105             :     //  - always points into the stack
     106             :     //  - is weakly monotonically increasing (may be equal for successive frames)
     107             :     //  - will compare greater than newer native and psuedo-stack frame addresses
     108             :     //    and less than older native and psuedo-stack frame addresses
     109             :     void* stackAddress() const;
     110             : 
     111             :     enum FrameKind
     112             :     {
     113             :       Frame_Baseline,
     114             :       Frame_Ion,
     115             :       Frame_Wasm
     116             :     };
     117             : 
     118             :     struct Frame
     119             :     {
     120             :         FrameKind kind;
     121             :         void* stackAddress;
     122             :         void* returnAddress;
     123             :         void* activation;
     124             :         const char* label;
     125             :     } JS_HAZ_GC_INVALIDATED;
     126             : 
     127             :     bool isWasm() const;
     128             :     bool isJit() const;
     129             : 
     130             :     uint32_t extractStack(Frame* frames, uint32_t offset, uint32_t end) const;
     131             : 
     132             :     mozilla::Maybe<Frame> getPhysicalFrameWithoutLabel() const;
     133             : 
     134             :   private:
     135             :     mozilla::Maybe<Frame> getPhysicalFrameAndEntry(js::jit::JitcodeGlobalEntry* entry) const;
     136             : 
     137             :     void iteratorConstruct(const RegisterState& state);
     138             :     void iteratorConstruct();
     139             :     void iteratorDestroy();
     140             :     bool iteratorDone();
     141             : } JS_HAZ_GC_INVALIDATED;
     142             : 
     143             : JS_FRIEND_API(bool)
     144             : IsProfilingEnabledForContext(JSContext* cx);
     145             : 
     146             : /**
     147             :  * After each sample run, this method should be called with the latest sample
     148             :  * buffer generation, and the lapCount.  It will update corresponding fields on
     149             :  * JSRuntime.
     150             :  *
     151             :  * See fields |profilerSampleBufferGen|, |profilerSampleBufferLapCount| on
     152             :  * JSRuntime for documentation about what these values are used for.
     153             :  */
     154             : JS_FRIEND_API(void)
     155             : UpdateJSContextProfilerSampleBufferGen(JSContext* cx, uint32_t generation,
     156             :                                        uint32_t lapCount);
     157             : 
     158           0 : struct ForEachProfiledFrameOp
     159             : {
     160             :     // A handle to the underlying JitcodeGlobalEntry, so as to avoid repeated
     161             :     // lookups on JitcodeGlobalTable.
     162           0 :     class MOZ_STACK_CLASS FrameHandle
     163             :     {
     164             :         friend JS_PUBLIC_API(void) ForEachProfiledFrame(JSContext* cx, void* addr,
     165             :                                                         ForEachProfiledFrameOp& op);
     166             : 
     167             :         JSRuntime* rt_;
     168             :         js::jit::JitcodeGlobalEntry& entry_;
     169             :         void* addr_;
     170             :         void* canonicalAddr_;
     171             :         const char* label_;
     172             :         uint32_t depth_;
     173             :         mozilla::Maybe<uint8_t> optsIndex_;
     174             : 
     175             :         FrameHandle(JSRuntime* rt, js::jit::JitcodeGlobalEntry& entry, void* addr,
     176             :                     const char* label, uint32_t depth);
     177             : 
     178             :         void updateHasTrackedOptimizations();
     179             : 
     180             :       public:
     181           0 :         const char* label() const { return label_; }
     182           0 :         uint32_t depth() const { return depth_; }
     183           0 :         bool hasTrackedOptimizations() const { return optsIndex_.isSome(); }
     184           0 :         void* canonicalAddress() const { return canonicalAddr_; }
     185             : 
     186             :         JS_PUBLIC_API(ProfilingFrameIterator::FrameKind) frameKind() const;
     187             :         JS_PUBLIC_API(void) forEachOptimizationAttempt(ForEachTrackedOptimizationAttemptOp& op,
     188             :                                                        JSScript** scriptOut,
     189             :                                                        jsbytecode** pcOut) const;
     190             : 
     191             :         JS_PUBLIC_API(void)
     192             :         forEachOptimizationTypeInfo(ForEachTrackedOptimizationTypeInfoOp& op) const;
     193             :     };
     194             : 
     195             :     // Called once per frame.
     196             :     virtual void operator()(const FrameHandle& frame) = 0;
     197             : };
     198             : 
     199             : JS_PUBLIC_API(void)
     200             : ForEachProfiledFrame(JSContext* cx, void* addr, ForEachProfiledFrameOp& op);
     201             : 
     202             : } // namespace JS
     203             : 
     204             : #endif  /* js_ProfilingFrameIterator_h */

Generated by: LCOV version 1.13