[heap] Provide the number of native and detached context via Heap API.

This adds two fields to the HeapStatistics struct:
- number_of_native_contexts,
- number_of_detached_contexts.

Bug: chromium:793789
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: If6942a97fd22a9e70781eed2aa286aba4c0e7f70
Reviewed-on: https://chromium-review.googlesource.com/819730
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50007}
This commit is contained in:
Ulan Degenbaev 2017-12-11 17:51:59 +01:00 committed by Commit Bot
parent b846c7a612
commit 298f0cd438
5 changed files with 81 additions and 2 deletions

View File

@ -6508,6 +6508,8 @@ class V8_EXPORT HeapStatistics {
size_t heap_size_limit() { return heap_size_limit_; }
size_t malloced_memory() { return malloced_memory_; }
size_t peak_malloced_memory() { return peak_malloced_memory_; }
size_t number_of_native_contexts() { return number_of_native_contexts_; }
size_t number_of_detached_contexts() { return number_of_detached_contexts_; }
/**
* Returns a 0/1 boolean, which signifies whether the V8 overwrite heap
@ -6525,6 +6527,8 @@ class V8_EXPORT HeapStatistics {
size_t malloced_memory_;
size_t peak_malloced_memory_;
bool does_zap_garbage_;
size_t number_of_native_contexts_;
size_t number_of_detached_contexts_;
friend class V8;
friend class Isolate;

View File

@ -6445,7 +6445,9 @@ HeapStatistics::HeapStatistics()
heap_size_limit_(0),
malloced_memory_(0),
peak_malloced_memory_(0),
does_zap_garbage_(0) {}
does_zap_garbage_(0),
number_of_native_contexts_(0),
number_of_detached_contexts_(0) {}
HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
space_size_(0),
@ -8792,6 +8794,9 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
isolate->allocator()->GetCurrentMemoryUsage();
heap_statistics->peak_malloced_memory_ =
isolate->allocator()->GetMaxMemoryUsage();
heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
heap_statistics->number_of_detached_contexts_ =
heap->NumberOfDetachedContexts();
heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
}

View File

@ -6526,6 +6526,22 @@ bool Heap::GetObjectTypeName(size_t index, const char** object_type,
return false;
}
size_t Heap::NumberOfNativeContexts() {
int result = 0;
Object* context = native_contexts_list();
while (!context->IsUndefined(isolate())) {
++result;
Context* native_context = Context::cast(context);
context = native_context->next_context_link();
}
return result;
}
size_t Heap::NumberOfDetachedContexts() {
// The detached_contexts() array has two entries per detached context.
return detached_contexts()->length() / 2;
}
const char* AllocationSpaceName(AllocationSpace space) {
switch (space) {
case NEW_SPACE:

View File

@ -1366,6 +1366,12 @@ class Heap {
bool GetObjectTypeName(size_t index, const char** object_type,
const char** object_sub_type);
// The total number of native contexts object on the heap.
size_t NumberOfNativeContexts();
// The total number of native contexts that were detached but were not
// garbage collected yet.
size_t NumberOfDetachedContexts();
// ===========================================================================
// Code statistics. ==========================================================
// ===========================================================================

View File

@ -18467,7 +18467,6 @@ TEST(SetStackLimitInThread) {
}
}
THREADED_TEST(GetHeapStatistics) {
LocalContext c1;
v8::HandleScope scope(c1->GetIsolate());
@ -18479,6 +18478,55 @@ THREADED_TEST(GetHeapStatistics) {
CHECK_NE(static_cast<int>(heap_statistics.used_heap_size()), 0);
}
TEST(NumberOfNativeContexts) {
static const size_t kNumTestContexts = 10;
i::Isolate* isolate = CcTest::i_isolate();
i::HandleScope scope(isolate);
v8::Global<v8::Context> context[kNumTestContexts];
v8::HeapStatistics heap_statistics;
CHECK_EQ(0u, heap_statistics.number_of_native_contexts());
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(0u, heap_statistics.number_of_native_contexts());
for (size_t i = 0; i < kNumTestContexts; i++) {
i::HandleScope inner(isolate);
context[i].Reset(CcTest::isolate(), v8::Context::New(CcTest::isolate()));
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(i + 1, heap_statistics.number_of_native_contexts());
}
for (size_t i = 0; i < kNumTestContexts; i++) {
context[i].Reset();
CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(kNumTestContexts - i - 1u,
heap_statistics.number_of_native_contexts());
}
}
TEST(NumberOfDetachedContexts) {
static const size_t kNumTestContexts = 10;
i::Isolate* isolate = CcTest::i_isolate();
i::HandleScope scope(isolate);
v8::Global<v8::Context> context[kNumTestContexts];
v8::HeapStatistics heap_statistics;
CHECK_EQ(0u, heap_statistics.number_of_detached_contexts());
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(0u, heap_statistics.number_of_detached_contexts());
for (size_t i = 0; i < kNumTestContexts; i++) {
i::HandleScope inner(isolate);
v8::Local<v8::Context> local = v8::Context::New(CcTest::isolate());
context[i].Reset(CcTest::isolate(), local);
local->DetachGlobal();
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(i + 1, heap_statistics.number_of_detached_contexts());
}
for (size_t i = 0; i < kNumTestContexts; i++) {
context[i].Reset();
CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CcTest::isolate()->GetHeapStatistics(&heap_statistics);
CHECK_EQ(kNumTestContexts - i - 1u,
heap_statistics.number_of_detached_contexts());
}
}
class VisitorImpl : public v8::ExternalResourceVisitor {
public: