Commit 826451f0 authored by heimbuef's avatar heimbuef Committed by Commit bot

Added zone tracing

Added PrintF output whenever a zone is created or destroyed. Also
enables setting of a name for each zone, which can then be shown
in the v8-heap-stats tool: https://github.com/mlippautz/v8-heap-stats/pull/2

BUG=v8:5489

Review-Url: https://codereview.chromium.org/2397573007
Cr-Commit-Position: refs/heads/master@{#40168}
parent 14bf19af
...@@ -1936,6 +1936,7 @@ class VerboseAccountingAllocator : public AccountingAllocator { ...@@ -1936,6 +1936,7 @@ class VerboseAccountingAllocator : public AccountingAllocator {
: heap_(heap), : heap_(heap),
last_memory_usage_(0), last_memory_usage_(0),
last_pool_size_(0), last_pool_size_(0),
nesting_deepth_(0),
allocation_sample_bytes_(allocation_sample_bytes), allocation_sample_bytes_(allocation_sample_bytes),
pool_sample_bytes_(pool_sample_bytes) {} pool_sample_bytes_(pool_sample_bytes) {}
...@@ -1948,7 +1949,7 @@ class VerboseAccountingAllocator : public AccountingAllocator { ...@@ -1948,7 +1949,7 @@ class VerboseAccountingAllocator : public AccountingAllocator {
if (last_memory_usage_.Value() + allocation_sample_bytes_ < if (last_memory_usage_.Value() + allocation_sample_bytes_ <
malloced_current || malloced_current ||
last_pool_size_.Value() + pool_sample_bytes_ < pooled_current) { last_pool_size_.Value() + pool_sample_bytes_ < pooled_current) {
PrintJSON(malloced_current, pooled_current); PrintMemoryJSON(malloced_current, pooled_current);
last_memory_usage_.SetValue(malloced_current); last_memory_usage_.SetValue(malloced_current);
last_pool_size_.SetValue(pooled_current); last_pool_size_.SetValue(pooled_current);
} }
...@@ -1964,14 +1965,49 @@ class VerboseAccountingAllocator : public AccountingAllocator { ...@@ -1964,14 +1965,49 @@ class VerboseAccountingAllocator : public AccountingAllocator {
if (malloced_current + allocation_sample_bytes_ < if (malloced_current + allocation_sample_bytes_ <
last_memory_usage_.Value() || last_memory_usage_.Value() ||
pooled_current + pool_sample_bytes_ < last_pool_size_.Value()) { pooled_current + pool_sample_bytes_ < last_pool_size_.Value()) {
PrintJSON(malloced_current, pooled_current); PrintMemoryJSON(malloced_current, pooled_current);
last_memory_usage_.SetValue(malloced_current); last_memory_usage_.SetValue(malloced_current);
last_pool_size_.SetValue(pooled_current); last_pool_size_.SetValue(pooled_current);
} }
} }
void ZoneCreation(const Zone* zone) override {
double time = heap_->isolate()->time_millis_since_init();
PrintF(
"{"
"\"type\": \"zonecreation\", "
"\"isolate\": \"%p\", "
"\"time\": %f, "
"\"ptr\": \"%p\", "
"\"name\": \"%s\","
"\"nesting\": %zu"
"}\n",
reinterpret_cast<void*>(heap_->isolate()), time,
reinterpret_cast<const void*>(zone), zone->name(),
nesting_deepth_.Value());
nesting_deepth_.Increment(1);
}
void ZoneDestruction(const Zone* zone) override {
nesting_deepth_.Decrement(1);
double time = heap_->isolate()->time_millis_since_init();
PrintF(
"{"
"\"type\": \"zonedestruction\", "
"\"isolate\": \"%p\", "
"\"time\": %f, "
"\"ptr\": \"%p\", "
"\"name\": \"%s\", "
"\"size\": %zu,"
"\"nesting\": %zu"
"}\n",
reinterpret_cast<void*>(heap_->isolate()), time,
reinterpret_cast<const void*>(zone), zone->name(),
zone->allocation_size(), nesting_deepth_.Value());
}
private: private:
void PrintJSON(size_t malloced, size_t pooled) { void PrintMemoryJSON(size_t malloced, size_t pooled) {
// Note: Neither isolate, nor heap is locked, so be careful with accesses // Note: Neither isolate, nor heap is locked, so be careful with accesses
// as the allocator is potentially used on a concurrent thread. // as the allocator is potentially used on a concurrent thread.
double time = heap_->isolate()->time_millis_since_init(); double time = heap_->isolate()->time_millis_since_init();
...@@ -1989,6 +2025,7 @@ class VerboseAccountingAllocator : public AccountingAllocator { ...@@ -1989,6 +2025,7 @@ class VerboseAccountingAllocator : public AccountingAllocator {
Heap* heap_; Heap* heap_;
base::AtomicNumber<size_t> last_memory_usage_; base::AtomicNumber<size_t> last_memory_usage_;
base::AtomicNumber<size_t> last_pool_size_; base::AtomicNumber<size_t> last_pool_size_;
base::AtomicNumber<size_t> nesting_deepth_;
size_t allocation_sample_bytes_, pool_sample_bytes_; size_t allocation_sample_bytes_, pool_sample_bytes_;
}; };
......
...@@ -35,6 +35,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator { ...@@ -35,6 +35,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator {
void MemoryPressureNotification(MemoryPressureLevel level); void MemoryPressureNotification(MemoryPressureLevel level);
virtual void ZoneCreation(const Zone* zone) {}
virtual void ZoneDestruction(const Zone* zone) {}
private: private:
static const uint8_t kMinSegmentSizePower = 13; static const uint8_t kMinSegmentSizePower = 13;
static const uint8_t kMaxSegmentSizePower = 18; static const uint8_t kMaxSegmentSizePower = 18;
......
...@@ -41,15 +41,20 @@ const size_t kASanRedzoneBytes = 0; ...@@ -41,15 +41,20 @@ const size_t kASanRedzoneBytes = 0;
} // namespace } // namespace
Zone::Zone(AccountingAllocator* allocator) Zone::Zone(AccountingAllocator* allocator, const char* name)
: allocation_size_(0), : allocation_size_(0),
segment_bytes_allocated_(0), segment_bytes_allocated_(0),
position_(0), position_(0),
limit_(0), limit_(0),
allocator_(allocator), allocator_(allocator),
segment_head_(nullptr) {} segment_head_(nullptr),
name_(name) {
allocator_->ZoneCreation(this);
}
Zone::~Zone() { Zone::~Zone() {
allocator_->ZoneDestruction(this);
DeleteAll(); DeleteAll();
DCHECK(segment_bytes_allocated_ == 0); DCHECK(segment_bytes_allocated_ == 0);
......
...@@ -31,7 +31,7 @@ namespace internal { ...@@ -31,7 +31,7 @@ namespace internal {
// from multi-threaded code. // from multi-threaded code.
class V8_EXPORT_PRIVATE Zone final { class V8_EXPORT_PRIVATE Zone final {
public: public:
explicit Zone(AccountingAllocator* allocator); explicit Zone(AccountingAllocator* allocator, const char* name = "unnamed");
~Zone(); ~Zone();
// Allocate 'size' bytes of memory in the Zone; expands the Zone by // Allocate 'size' bytes of memory in the Zone; expands the Zone by
...@@ -50,6 +50,8 @@ class V8_EXPORT_PRIVATE Zone final { ...@@ -50,6 +50,8 @@ class V8_EXPORT_PRIVATE Zone final {
return segment_bytes_allocated_ > kExcessLimit; return segment_bytes_allocated_ > kExcessLimit;
} }
const char* name() const { return name_; }
size_t allocation_size() const { return allocation_size_; } size_t allocation_size() const { return allocation_size_; }
AccountingAllocator* allocator() const { return allocator_; } AccountingAllocator* allocator() const { return allocator_; }
...@@ -105,6 +107,7 @@ class V8_EXPORT_PRIVATE Zone final { ...@@ -105,6 +107,7 @@ class V8_EXPORT_PRIVATE Zone final {
AccountingAllocator* allocator_; AccountingAllocator* allocator_;
Segment* segment_head_; Segment* segment_head_;
const char* name_;
}; };
// ZoneObject is an abstraction that helps define classes of objects // ZoneObject is an abstraction that helps define classes of objects
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment