1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HEAP_GC_TRACER_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_GC_TRACER_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A simple ring buffer class with maximum size known at compile time. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The class only implements the functionality required in GCTracer. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T, size_t MAX_SIZE> 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RingBuffer { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class const_iterator { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator() : index_(0), elements_(NULL) {} 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator(size_t index, const T* elements) 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : index_(index), elements_(elements) {} 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator==(const const_iterator& rhs) const { 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements_ == rhs.elements_ && index_ == rhs.index_; 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator!=(const const_iterator& rhs) const { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements_ != rhs.elements_ || index_ != rhs.index_; 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operator const T*() const { return elements_ + index_; } 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const T* operator->() const { return elements_ + index_; } 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const T& operator*() const { return elements_[index_]; } 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator& operator++() { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index_ = (index_ + 1) % (MAX_SIZE + 1); 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return *this; 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator& operator--() { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return *this; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t index_; 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const T* elements_; 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RingBuffer() : begin_(0), end_(0) {} 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool empty() const { return begin_ == end_; } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t size() const { 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator begin() const { return const_iterator(begin_, elements_); } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator end() const { return const_iterator(end_, elements_); } 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_iterator back() const { return --end(); } 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push_back(const T& element) { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_[end_] = element; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_ = (end_ + 1) % (MAX_SIZE + 1); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push_front(const T& element) { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1); 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_[begin_] = element; 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T elements_[MAX_SIZE + 1]; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t begin_; 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t end_; 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(RingBuffer); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GCTracer collects and prints ONE line after each garbage collector 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// invocation IFF --trace_gc is used. 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ernstm): Unit tests. 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass GCTracer { 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class Scope { 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum ScopeId { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EXTERNAL, 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_MARK, 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP, 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP_NEWSPACE, 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP_OLDSPACE, 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP_CODE, 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP_CELL, 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_SWEEP_MAP, 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_EVACUATE_PAGES, 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_NEW_TO_NEW_POINTERS, 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_ROOT_TO_NEW_POINTERS, 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_OLD_TO_NEW_POINTERS, 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_POINTERS_TO_EVACUATED, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_POINTERS_BETWEEN_EVACUATED, 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_UPDATE_MISC_POINTERS, 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_WEAKCOLLECTION_PROCESS, 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_WEAKCOLLECTION_CLEAR, 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_WEAKCOLLECTION_ABORT, 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MC_FLUSH_CODE, 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NUMBER_OF_SCOPES 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope(GCTracer* tracer, ScopeId scope) : tracer_(tracer), scope_(scope) { 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_time_ = base::OS::TimeCurrentMillis(); 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~Scope() { 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer_->current_.scopes[scope_] += 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::OS::TimeCurrentMillis() - start_time_; 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCTracer* tracer_; 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScopeId scope_; 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double start_time_; 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(Scope); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class AllocationEvent { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Default constructor leaves the event uninitialized. 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationEvent() {} 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationEvent(double duration, intptr_t allocation_in_bytes); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Time spent in the mutator during the end of the last garbage collection 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the beginning of the next garbage collection. 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double duration_; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Memory allocated in the new space during the end of the last garbage 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // collection to the beginning of the next garbage collection. 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t allocation_in_bytes_; 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class Event { 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 }; 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Default constructor leaves the event uninitialized. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Event() {} 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Event(Type type, const char* gc_reason, const char* collector_reason); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns a string describing the event type. 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* TypeName(bool short_name) const; 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Type of event 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type type; 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* gc_reason; 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* collector_reason; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Timestamp set in the constructor. 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double start_time; 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Timestamp set in the destructor. 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double end_time; 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of objects in heap set in constructor. 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t start_object_size; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of objects in heap set in destructor. 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t end_object_size; 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of memory allocated from OS set in constructor. 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t start_memory_size; 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of memory allocated from OS set in destructor. 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t end_memory_size; 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Total amount of space either wasted or contained in one of free lists 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before the current GC. 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t start_holes_size; 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Total amount of space either wasted or contained in one of free lists 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after the current GC. 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t end_holes_size; 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of new space objects in constructor. 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t new_space_object_size; 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of incremental marking steps since creation of tracer. 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (value at start of event) 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cumulative_incremental_marking_steps; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Incremental marking steps since 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last event for SCAVENGER events 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last MARK_COMPACTOR event for MARK_COMPACTOR events 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int incremental_marking_steps; 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bytes marked since creation of tracer (value at start of event). 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t cumulative_incremental_marking_bytes; 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bytes marked since 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last event for SCAVENGER events 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last MARK_COMPACTOR event for MARK_COMPACTOR events 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t incremental_marking_bytes; 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative duration of incremental marking steps since creation of 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tracer. (value at start of event) 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_incremental_marking_duration; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Duration of incremental marking steps since 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last event for SCAVENGER events 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last MARK_COMPACTOR event for MARK_COMPACTOR events 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double incremental_marking_duration; 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative pure duration of incremental marking steps since creation of 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tracer. (value at start of event) 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_pure_incremental_marking_duration; 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Duration of pure incremental marking steps since 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last event for SCAVENGER events 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - last MARK_COMPACTOR event for MARK_COMPACTOR events 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double pure_incremental_marking_duration; 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Longest incremental marking step since start of marking. 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (value at start of event) 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double longest_incremental_marking_step; 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Amounts of time spent in different scopes during GC. 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double scopes[Scope::NUMBER_OF_SCOPES]; 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kRingBufferMaxSize = 10; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef RingBuffer<AllocationEvent, kRingBufferMaxSize> AllocationEventBuffer; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit GCTracer(Heap* heap); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start collecting data. 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Start(GarbageCollector collector, const char* gc_reason, 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* collector_reason); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stop collecting data and print results. 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Stop(); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log an allocation throughput event. 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log an incremental marking step. 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddIncrementalMarkingStep(double duration, intptr_t bytes); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log time spent in marking. 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddMarkingTime(double duration) { 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cumulative_marking_duration_ += duration; 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Time spent in marking. 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_marking_duration() const { 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cumulative_marking_duration_; 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log time spent in sweeping on main thread. 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddSweepingTime(double duration) { 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cumulative_sweeping_duration_ += duration; 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Time spent in sweeping on main thread. 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_sweeping_duration() const { 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cumulative_sweeping_duration_; 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the mean duration of the last scavenger events. Returns 0 if no 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // events have been recorded. 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MeanScavengerDuration() const { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MeanDuration(scavenger_events_); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the max duration of the last scavenger events. Returns 0 if no 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // events have been recorded. 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MaxScavengerDuration() const { return MaxDuration(scavenger_events_); } 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the mean duration of the last mark compactor events. Returns 0 if 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // no events have been recorded. 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MeanMarkCompactorDuration() const { 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MeanDuration(mark_compactor_events_); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the max duration of the last mark compactor events. Return 0 if no 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // events have been recorded. 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MaxMarkCompactorDuration() const { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MaxDuration(mark_compactor_events_); 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the mean step duration of the last incremental marking round. 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no incremental marking round has been completed. 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MeanIncrementalMarkingDuration() const; 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the max step duration of the last incremental marking round. 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no incremental marking round has been completed. 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MaxIncrementalMarkingDuration() const; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the average incremental marking speed in bytes/millisecond. 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no events have been recorded. 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t IncrementalMarkingSpeedInBytesPerMillisecond() const; 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the average scavenge speed in bytes/millisecond. 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no events have been recorded. 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t ScavengeSpeedInBytesPerMillisecond() const; 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the max mark-sweep speed in bytes/millisecond. 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no events have been recorded. 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t MarkCompactSpeedInBytesPerMillisecond() const; 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocation throughput in the new space in bytes/millisecond. 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 0 if no events have been recorded. 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print one detailed trace line in name=value format. 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(ernstm): Move to Heap. 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrintNVP() const; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print one trace line. 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(ernstm): Move to Heap. 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Print() const; 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the mean duration of the events in the given ring buffer. 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MeanDuration(const EventBuffer& events) const; 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the max duration of the events in the given ring buffer. 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double MaxDuration(const EventBuffer& events) const; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pointer to the heap that owns this tracer. 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has returned. 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Event current_; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Previous tracer event. 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Event previous_; 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Previous MARK_COMPACTOR event. 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Event previous_mark_compactor_event_; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // RingBuffers for SCAVENGER events. 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EventBuffer scavenger_events_; 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // RingBuffers for MARK_COMPACTOR events. 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EventBuffer mark_compactor_events_; 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // RingBuffer for allocation events. 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationEventBuffer allocation_events_; 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative number of incremental marking steps since creation of tracer. 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cumulative_incremental_marking_steps_; 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative size of incremental marking steps (in bytes) since creation of 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tracer. 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t cumulative_incremental_marking_bytes_; 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative duration of incremental marking steps since creation of tracer. 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_incremental_marking_duration_; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cumulative duration of pure incremental marking steps since creation of 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tracer. 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_pure_incremental_marking_duration_; 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Longest incremental marking step since start of marking. 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double longest_incremental_marking_step_; 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Total marking time. 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This timer is precise when run with --print-cumulative-gc-stat 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_marking_duration_; 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Total sweeping time on the main thread. 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This timer is precise when run with --print-cumulative-gc-stat 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): Account for sweeping time on sweeper threads. Add a 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // different field for that. 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): This timer right now just holds the sweeping time 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the initial atomic sweeping pause. Make sure that it accumulates 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // all sweeping operations performed on the main thread. 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double cumulative_sweeping_duration_; 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Holds the new space top pointer recorded at the end of the last garbage 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // collection. 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t new_space_top_after_gc_; 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(GCTracer); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8::internal 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_HEAP_GC_TRACER_H_ 402