LCOV - code coverage report
Current view: top level - src/profiler - sampling-heap-profiler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2017-04-26 Functions: 7 9 77.8 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_PROFILER_SAMPLING_HEAP_PROFILER_H_
       6             : #define V8_PROFILER_SAMPLING_HEAP_PROFILER_H_
       7             : 
       8             : #include <deque>
       9             : #include <map>
      10             : #include <memory>
      11             : #include <set>
      12             : #include "include/v8-profiler.h"
      13             : #include "src/heap/heap.h"
      14             : #include "src/profiler/strings-storage.h"
      15             : 
      16             : namespace v8 {
      17             : 
      18             : namespace base {
      19             : class RandomNumberGenerator;
      20             : }
      21             : 
      22             : namespace internal {
      23             : 
      24             : class SamplingAllocationObserver;
      25             : 
      26          60 : class AllocationProfile : public v8::AllocationProfile {
      27             :  public:
      28          30 :   AllocationProfile() : nodes_() {}
      29             : 
      30          36 :   v8::AllocationProfile::Node* GetRootNode() override {
      31          36 :     return nodes_.size() == 0 ? nullptr : &nodes_.front();
      32             :   }
      33             : 
      34             :   std::deque<v8::AllocationProfile::Node>& nodes() { return nodes_; }
      35             : 
      36             :  private:
      37             :   std::deque<v8::AllocationProfile::Node> nodes_;
      38             : 
      39             :   DISALLOW_COPY_AND_ASSIGN(AllocationProfile);
      40             : };
      41             : 
      42             : class SamplingHeapProfiler {
      43             :  public:
      44             :   SamplingHeapProfiler(Heap* heap, StringsStorage* names, uint64_t rate,
      45             :                        int stack_depth, v8::HeapProfiler::SamplingFlags flags);
      46             :   ~SamplingHeapProfiler();
      47             : 
      48             :   v8::AllocationProfile* GetAllocationProfile();
      49             : 
      50             :   StringsStorage* names() const { return names_; }
      51             : 
      52             :   class AllocationNode;
      53             : 
      54             :   struct Sample {
      55             :    public:
      56             :     Sample(size_t size_, AllocationNode* owner_, Local<Value> local_,
      57             :            SamplingHeapProfiler* profiler_)
      58             :         : size(size_),
      59             :           owner(owner_),
      60             :           global(Global<Value>(
      61             :               reinterpret_cast<v8::Isolate*>(profiler_->isolate_), local_)),
      62       81326 :           profiler(profiler_) {}
      63       81326 :     ~Sample() { global.Reset(); }
      64             :     const size_t size;
      65             :     AllocationNode* const owner;
      66             :     Global<Value> global;
      67             :     SamplingHeapProfiler* const profiler;
      68             : 
      69             :    private:
      70             :     DISALLOW_COPY_AND_ASSIGN(Sample);
      71             :   };
      72             : 
      73             :   class AllocationNode {
      74             :    public:
      75             :     AllocationNode(AllocationNode* parent, const char* name, int script_id,
      76             :                    int start_position)
      77             :         : parent_(parent),
      78             :           script_id_(script_id),
      79             :           script_position_(start_position),
      80             :           name_(name),
      81         302 :           pinned_(false) {}
      82         302 :     ~AllocationNode() {
      83         864 :       for (auto child : children_) {
      84         260 :         delete child.second;
      85             :       }
      86         302 :     }
      87             : 
      88             :    private:
      89             :     typedef uint64_t FunctionId;
      90             :     static FunctionId function_id(int script_id, int start_position,
      91             :                                   const char* name) {
      92             :       // script_id == kNoScriptId case:
      93             :       //   Use function name pointer as an id. Names derived from VM state
      94             :       //   must not collide with the builtin names. The least significant bit
      95             :       //   of the id is set to 1.
      96       78332 :       if (script_id == v8::UnboundScript::kNoScriptId) {
      97       10259 :         return reinterpret_cast<intptr_t>(name) | 1;
      98             :       }
      99             :       // script_id != kNoScriptId case:
     100             :       //   Use script_id, start_position pair to uniquelly identify the node.
     101             :       //   The least significant bit of the id is set to 0.
     102             :       DCHECK(static_cast<unsigned>(start_position) < (1u << 31));
     103       68073 :       return (static_cast<uint64_t>(script_id) << 32) + (start_position << 1);
     104             :     }
     105             :     AllocationNode* FindOrAddChildNode(const char* name, int script_id,
     106             :                                        int start_position);
     107             :     // TODO(alph): make use of unordered_map's here. Pay attention to
     108             :     // iterator invalidation during TranslateAllocationNode.
     109             :     std::map<size_t, unsigned int> allocations_;
     110             :     std::map<FunctionId, AllocationNode*> children_;
     111             :     AllocationNode* const parent_;
     112             :     const int script_id_;
     113             :     const int script_position_;
     114             :     const char* const name_;
     115             :     bool pinned_;
     116             : 
     117             :     friend class SamplingHeapProfiler;
     118             : 
     119             :     DISALLOW_COPY_AND_ASSIGN(AllocationNode);
     120             :   };
     121             : 
     122             :  private:
     123             :   Heap* heap() const { return heap_; }
     124             : 
     125             :   void SampleObject(Address soon_object, size_t size);
     126             : 
     127             :   static void OnWeakCallback(const WeakCallbackInfo<Sample>& data);
     128             : 
     129             :   // Methods that construct v8::AllocationProfile.
     130             : 
     131             :   // Translates the provided AllocationNode *node* returning an equivalent
     132             :   // AllocationProfile::Node. The newly created AllocationProfile::Node is added
     133             :   // to the provided AllocationProfile *profile*. Line numbers, column numbers,
     134             :   // and script names are resolved using *scripts* which maps all currently
     135             :   // loaded scripts keyed by their script id.
     136             :   v8::AllocationProfile::Node* TranslateAllocationNode(
     137             :       AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node,
     138             :       const std::map<int, Handle<Script>>& scripts);
     139             :   v8::AllocationProfile::Allocation ScaleSample(size_t size,
     140             :                                                 unsigned int count);
     141             :   AllocationNode* AddStack();
     142             : 
     143             :   Isolate* const isolate_;
     144             :   Heap* const heap_;
     145             :   std::unique_ptr<SamplingAllocationObserver> new_space_observer_;
     146             :   std::unique_ptr<SamplingAllocationObserver> other_spaces_observer_;
     147             :   StringsStorage* const names_;
     148             :   AllocationNode profile_root_;
     149             :   std::set<Sample*> samples_;
     150             :   const int stack_depth_;
     151             :   const uint64_t rate_;
     152             :   v8::HeapProfiler::SamplingFlags flags_;
     153             : 
     154             :   friend class SamplingAllocationObserver;
     155             : 
     156             :   DISALLOW_COPY_AND_ASSIGN(SamplingHeapProfiler);
     157             : };
     158             : 
     159             : class SamplingAllocationObserver : public AllocationObserver {
     160             :  public:
     161             :   SamplingAllocationObserver(Heap* heap, intptr_t step_size, uint64_t rate,
     162             :                              SamplingHeapProfiler* profiler,
     163             :                              base::RandomNumberGenerator* random)
     164             :       : AllocationObserver(step_size),
     165             :         profiler_(profiler),
     166             :         heap_(heap),
     167             :         random_(random),
     168          72 :         rate_(rate) {}
     169         144 :   virtual ~SamplingAllocationObserver() {}
     170             : 
     171             :  protected:
     172       40663 :   void Step(int bytes_allocated, Address soon_object, size_t size) override {
     173             :     USE(heap_);
     174             :     DCHECK(heap_->gc_state() == Heap::NOT_IN_GC);
     175             :     DCHECK(soon_object);
     176       40663 :     profiler_->SampleObject(soon_object, size);
     177       40663 :   }
     178             : 
     179       40663 :   intptr_t GetNextStepSize() override { return GetNextSampleInterval(rate_); }
     180             : 
     181             :  private:
     182             :   intptr_t GetNextSampleInterval(uint64_t rate);
     183             :   SamplingHeapProfiler* const profiler_;
     184             :   Heap* const heap_;
     185             :   base::RandomNumberGenerator* const random_;
     186             :   uint64_t const rate_;
     187             : };
     188             : 
     189             : }  // namespace internal
     190             : }  // namespace v8
     191             : 
     192             : #endif  // V8_PROFILER_SAMPLING_HEAP_PROFILER_H_

Generated by: LCOV version 1.10