From: ulan Date: Thu, 5 Feb 2015 09:35:47 +0000 (-0800) Subject: Add a flag to track detached contexts. X-Git-Tag: upstream/4.7.83~4590 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7d27ea58307e9201c1196cf2cf523205cd8ab60;p=platform%2Fupstream%2Fv8.git Add a flag to track detached contexts. When embedder detaches the global objects, its context must be garbage collected eventually. BUG= Review URL: https://codereview.chromium.org/898663005 Cr-Commit-Position: refs/heads/master@{#26450} --- diff --git a/include/v8.h b/include/v8.h index eb7a8c3..b9edecd 100644 --- a/include/v8.h +++ b/include/v8.h @@ -6200,7 +6200,7 @@ class Internals { static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; static const int kFalseValueRootIndex = 9; - static const int kEmptyStringRootIndex = 155; + static const int kEmptyStringRootIndex = 156; // The external allocation limit should be below 256 MB on all architectures // to avoid that resource-constrained embedders run low on memory. diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 22e5953..ac24ccd 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -374,6 +374,9 @@ void Bootstrapper::DetachGlobal(Handle env) { global_proxy->set_native_context(*factory->null_value()); SetObjectPrototype(global_proxy, factory->null_value()); global_proxy->map()->set_constructor(*factory->null_value()); + if (FLAG_track_detached_contexts) { + env->GetIsolate()->AddDetachedContext(env); + } } diff --git a/src/flag-definitions.h b/src/flag-definitions.h index ef89cac..d458aae 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -615,6 +615,8 @@ DEFINE_BOOL(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_BOOL(track_gc_object_stats, false, "track object counts and memory usage") +DEFINE_BOOL(track_detached_contexts, false, + "track native contexts that are expected to be garbage collected") #ifdef VERIFY_HEAP DEFINE_BOOL(verify_heap, false, "verify heap pointers before and after GC") #endif diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 05c302f..4f262ff 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -854,6 +854,9 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason, } GarbageCollectionEpilogue(); + if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) { + isolate()->CheckDetachedContextsAfterGC(); + } tracer()->Stop(collector); } @@ -3071,6 +3074,8 @@ void Heap::CreateInitialObjects() { set_keyed_load_dummy_vector(empty_fixed_array()); } + set_detached_contexts(empty_fixed_array()); + Handle slow_element_dictionary = SeededNumberDictionary::New(isolate(), 0, TENURED); slow_element_dictionary->set_requires_slow_elements(); diff --git a/src/heap/heap.h b/src/heap/heap.h index 2975d09..e78a7be 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -183,7 +183,8 @@ namespace internal { V(FixedArray, materialized_objects, MaterializedObjects) \ V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad) \ V(FixedArray, microtask_queue, MicrotaskQueue) \ - V(FixedArray, keyed_load_dummy_vector, KeyedLoadDummyVector) + V(FixedArray, keyed_load_dummy_vector, KeyedLoadDummyVector) \ + V(FixedArray, detached_contexts, DetachedContexts) // Entries in this list are limited to Smis and are not visited during GC. #define SMI_ROOT_LIST(V) \ diff --git a/src/isolate.cc b/src/isolate.cc index 6321b90..37020da 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -2568,6 +2568,54 @@ std::string Isolate::GetTurboCfgFileName() { } +// Heap::detached_contexts tracks detached contexts as pairs +// (number of GC since the context was detached, the context). +void Isolate::AddDetachedContext(Handle context) { + HandleScope scope(this); + Handle cell = factory()->NewWeakCell(context); + Handle detached_contexts(heap()->detached_contexts()); + int length = detached_contexts->length(); + detached_contexts = FixedArray::CopySize(detached_contexts, length + 2); + detached_contexts->set(length, Smi::FromInt(0)); + detached_contexts->set(length + 1, *cell); + heap()->set_detached_contexts(*detached_contexts); +} + + +void Isolate::CheckDetachedContextsAfterGC() { + HandleScope scope(this); + Handle detached_contexts(heap()->detached_contexts()); + int length = detached_contexts->length(); + if (length == 0) return; + int new_length = 0; + for (int i = 0; i < length; i += 2) { + int mark_sweeps = Smi::cast(detached_contexts->get(i))->value(); + WeakCell* cell = WeakCell::cast(detached_contexts->get(i + 1)); + if (!cell->cleared()) { + detached_contexts->set(new_length, Smi::FromInt(mark_sweeps + 1)); + detached_contexts->set(new_length + 1, cell); + new_length += 2; + } + } + PrintF("%d detached contexts are collected out of %d\n", length - new_length, + length); + for (int i = 0; i < new_length; i += 2) { + int mark_sweeps = Smi::cast(detached_contexts->get(i))->value(); + WeakCell* cell = WeakCell::cast(detached_contexts->get(i + 1)); + if (mark_sweeps > 3) { + PrintF("detached context 0x%p\n survived %d GCs (leak?)\n", + static_cast(cell->value()), mark_sweeps); + } + } + if (length == new_length) { + heap()->set_detached_contexts(heap()->empty_fixed_array()); + } else { + heap()->RightTrimFixedArray(*detached_contexts, + length - new_length); + } +} + + bool StackLimitCheck::JsHasOverflowed() const { StackGuard* stack_guard = isolate_->stack_guard(); #ifdef USE_SIMULATOR diff --git a/src/isolate.h b/src/isolate.h index 21ac999..4fb8272 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -1141,6 +1141,9 @@ class Isolate { return store_buffer_hash_set_2_address_; } + void AddDetachedContext(Handle context); + void CheckDetachedContextsAfterGC(); + private: explicit Isolate(bool enable_serializer); @@ -1362,6 +1365,7 @@ class Isolate { v8::Isolate::UseCounterCallback use_counter_callback_; BasicBlockProfiler* basic_block_profiler_; + friend class ExecutionAccess; friend class HandleScopeImplementer; friend class OptimizingCompilerThread;