diff --git a/include/v8-internal.h b/include/v8-internal.h index 8e700a4d4d..61bdb58c1a 100644 --- a/include/v8-internal.h +++ b/include/v8-internal.h @@ -165,8 +165,6 @@ class Internals { static const int kNodeStateMask = 0x7; static const int kNodeStateIsWeakValue = 2; static const int kNodeStateIsPendingValue = 3; - static const int kNodeIsIndependentShift = 3; - static const int kNodeIsActiveShift = 4; static const int kFirstNonstringType = 0x40; static const int kOddballType = 0x43; diff --git a/include/v8-util.h b/include/v8-util.h index 2496260707..29d813e427 100644 --- a/include/v8-util.h +++ b/include/v8-util.h @@ -194,14 +194,6 @@ class PersistentValueMapBase { return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); } - /** - * Call V8::RegisterExternallyReferencedObject with the map value for given - * key. - */ - V8_DEPRECATED( - "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference", - inline void RegisterExternallyReferencedObject(K& key)); - /** * Return value for key and remove it from the map. */ @@ -352,16 +344,6 @@ class PersistentValueMapBase { const char* label_; }; -template -inline void -PersistentValueMapBase::RegisterExternallyReferencedObject( - K& key) { - assert(Contains(key)); - V8::RegisterExternallyReferencedObject( - reinterpret_cast(FromVal(Traits::Get(&impl_, key))), - reinterpret_cast(GetIsolate())); -} - template class PersistentValueMap : public PersistentValueMapBase { public: diff --git a/include/v8.h b/include/v8.h index b4b920555b..a716793ccc 100644 --- a/include/v8.h +++ b/include/v8.h @@ -545,38 +545,6 @@ template class PersistentBase { */ V8_INLINE void AnnotateStrongRetainer(const char* label); - /** - * Allows the embedder to tell the v8 garbage collector that a certain object - * is alive. Only allowed when the embedder is asked to trace its heap by - * EmbedderHeapTracer. - */ - V8_DEPRECATED( - "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference", - V8_INLINE void RegisterExternalReference(Isolate* isolate) const); - - /** - * Marks the reference to this object independent. Garbage collector is free - * to ignore any object groups containing this object. Weak callback for an - * independent handle should not assume that it will be preceded by a global - * GC prologue callback or followed by a global GC epilogue callback. - */ - V8_DEPRECATED( - "Weak objects are always considered independent. " - "Use TracedGlobal when trying to use EmbedderHeapTracer. " - "Use a strong handle when trying to keep an object alive.", - V8_INLINE void MarkIndependent()); - - /** - * Marks the reference to this object as active. The scavenge garbage - * collection should not reclaim the objects marked as active, even if the - * object held by the handle is otherwise unreachable. - * - * This bit is cleared after the each garbage collection pass. - */ - V8_DEPRECATED("Use TracedGlobal.", V8_INLINE void MarkActive()); - - V8_DEPRECATED("See MarkIndependent.", V8_INLINE bool IsIndependent() const); - /** Returns true if the handle's reference is weak. */ V8_INLINE bool IsWeak() const; @@ -8839,9 +8807,6 @@ class V8_EXPORT V8 { const char* label); static Value* Eternalize(Isolate* isolate, Value* handle); - static void RegisterExternallyReferencedObject(internal::Address* location, - internal::Isolate* isolate); - template friend class PersistentValueMapBase; @@ -9788,14 +9753,6 @@ void Persistent::Copy(const Persistent& that) { M::Copy(that, this); } -template -bool PersistentBase::IsIndependent() const { - typedef internal::Internals I; - if (this->IsEmpty()) return false; - return I::GetNodeFlag(reinterpret_cast(this->val_), - I::kNodeIsIndependentShift); -} - template bool PersistentBase::IsWeak() const { typedef internal::Internals I; @@ -9862,31 +9819,6 @@ void PersistentBase::AnnotateStrongRetainer(const char* label) { label); } -template -void PersistentBase::RegisterExternalReference(Isolate* isolate) const { - if (IsEmpty()) return; - V8::RegisterExternallyReferencedObject( - reinterpret_cast(this->val_), - reinterpret_cast(isolate)); -} - -template -void PersistentBase::MarkIndependent() { - typedef internal::Internals I; - if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast(this->val_), true, - I::kNodeIsIndependentShift); -} - -template -void PersistentBase::MarkActive() { - typedef internal::Internals I; - if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast(this->val_), true, - I::kNodeIsActiveShift); -} - - template void PersistentBase::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; diff --git a/src/api.cc b/src/api.cc index cafb4acff7..5cc20b077c 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1037,11 +1037,6 @@ void V8::MoveTracedGlobalReference(internal::Address** from, i::GlobalHandles::MoveTracedGlobal(from, to); } -void V8::RegisterExternallyReferencedObject(i::Address* location, - i::Isolate* isolate) { - isolate->heap()->RegisterExternallyReferencedObject(location); -} - void V8::MakeWeak(i::Address* location, void* parameter, WeakCallbackInfo::Callback weak_callback, WeakCallbackType type) { diff --git a/src/global-handles.cc b/src/global-handles.cc index 350380b23c..fb5087b8a7 100644 --- a/src/global-handles.cc +++ b/src/global-handles.cc @@ -379,10 +379,6 @@ class GlobalHandles::Node final : public NodeBase { Internals::kNodeStateMask); STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue); STATIC_ASSERT(PENDING == Internals::kNodeStateIsPendingValue); - STATIC_ASSERT(static_cast(IsIndependent::kShift) == - Internals::kNodeIsIndependentShift); - STATIC_ASSERT(static_cast(IsActive::kShift) == - Internals::kNodeIsActiveShift); set_in_young_list(false); } @@ -406,16 +402,6 @@ class GlobalHandles::Node final : public NodeBase { flags_ = NodeState::update(flags_, state); } - bool is_independent() { return IsIndependent::decode(flags_); } - void set_independent(bool v) { flags_ = IsIndependent::update(flags_, v); } - - bool is_active() { - return IsActive::decode(flags_); - } - void set_active(bool v) { - flags_ = IsActive::update(flags_, v); - } - bool is_in_young_list() const { return IsInYoungList::decode(flags_); } void set_in_young_list(bool v) { flags_ = IsInYoungList::update(flags_, v); } @@ -562,7 +548,6 @@ class GlobalHandles::Node final : public NodeBase { // This method invokes a finalizer. Updating the method name would require // adjusting CFI blacklist as weak_callback_ is invoked on the wrong type. CHECK(IsPendingFinalizer()); - CHECK(!is_active()); set_state(NEAR_DEATH); // Check that we are not passing a finalized external string to // the callback. @@ -593,24 +578,17 @@ class GlobalHandles::Node final : public NodeBase { private: // Fields that are not used for managing node memory. void ClearImplFields() { - set_independent(false); - set_active(false); weak_callback_ = nullptr; } void CheckImplFieldsAreCleared() { - DCHECK(!is_independent()); - DCHECK(!is_active()); DCHECK_EQ(nullptr, weak_callback_); } // This stores three flags (independent, partially_dependent and // in_young_list) and a State. class NodeState : public BitField8 {}; - class IsIndependent : public BitField8 {}; - // The following two fields are mutually exclusive - class IsActive : public BitField8 {}; - class IsInYoungList : public BitField8 {}; + class IsInYoungList : public BitField8 {}; class NodeWeaknessType : public BitField8 {}; @@ -873,12 +851,6 @@ void GlobalHandles::IterateWeakRootsIdentifyFinalizers( void GlobalHandles::IdentifyWeakUnmodifiedObjects( WeakSlotCallback is_unmodified) { - for (Node* node : young_nodes_) { - if (node->IsWeak() && !is_unmodified(node->location())) { - node->set_active(true); - } - } - LocalEmbedderHeapTracer* const tracer = isolate()->heap()->local_embedder_heap_tracer(); for (TracedNode* node : traced_young_nodes_) { @@ -895,9 +867,7 @@ void GlobalHandles::IdentifyWeakUnmodifiedObjects( void GlobalHandles::IterateYoungStrongAndDependentRoots(RootVisitor* v) { for (Node* node : young_nodes_) { - if (node->IsStrongRetainer() || - (node->IsWeakRetainer() && !node->is_independent() && - node->is_active())) { + if (node->IsStrongRetainer()) { v->VisitRootPointer(Root::kGlobalHandles, node->label(), node->location()); } @@ -913,8 +883,7 @@ void GlobalHandles::MarkYoungWeakUnmodifiedObjectsPending( WeakSlotCallbackWithHeap is_dead) { for (Node* node : young_nodes_) { DCHECK(node->is_in_young_list()); - if ((node->is_independent() || !node->is_active()) && node->IsWeak() && - is_dead(isolate_->heap(), node->location())) { + if (node->IsWeak() && is_dead(isolate_->heap(), node->location())) { if (!node->IsPhantomCallback() && !node->IsPhantomResetHandle()) { node->MarkPending(); } @@ -926,8 +895,7 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForFinalizers( RootVisitor* v) { for (Node* node : young_nodes_) { DCHECK(node->is_in_young_list()); - if ((node->is_independent() || !node->is_active()) && - node->IsWeakRetainer() && (node->state() == Node::PENDING)) { + if (node->IsWeakRetainer() && (node->state() == Node::PENDING)) { DCHECK(!node->IsPhantomCallback()); DCHECK(!node->IsPhantomResetHandle()); // Finalizers need to survive. @@ -941,8 +909,7 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles( RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle) { for (Node* node : young_nodes_) { DCHECK(node->is_in_young_list()); - if ((node->is_independent() || !node->is_active()) && - node->IsWeakRetainer() && (node->state() != Node::PENDING)) { + if (node->IsWeakRetainer() && (node->state() != Node::PENDING)) { if (should_reset_handle(isolate_->heap(), node->location())) { DCHECK(node->IsPhantomResetHandle() || node->IsPhantomCallback()); if (node->IsPhantomResetHandle()) { @@ -1008,9 +975,6 @@ size_t GlobalHandles::PostScavengeProcessing(unsigned post_processing_count) { // Filter free nodes. if (!node->IsRetainer()) continue; - // Reset active state for all affected nodes. - node->set_active(false); - if (node->IsPending()) { DCHECK(node->has_callback()); DCHECK(node->IsPendingFinalizer()); @@ -1029,9 +993,6 @@ size_t GlobalHandles::PostMarkSweepProcessing(unsigned post_processing_count) { // Filter free nodes. if (!node->IsRetainer()) continue; - // Reset active state for all affected nodes. - node->set_active(false); - if (node->IsPending()) { DCHECK(node->has_callback()); DCHECK(node->IsPendingFinalizer()); diff --git a/src/profiler/sampling-heap-profiler.cc b/src/profiler/sampling-heap-profiler.cc index 659ed25c00..a13dd2916a 100644 --- a/src/profiler/sampling-heap-profiler.cc +++ b/src/profiler/sampling-heap-profiler.cc @@ -97,16 +97,6 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) { base::make_unique(size, node, loc, this, next_sample_id()); sample->global.SetWeak(sample.get(), OnWeakCallback, WeakCallbackType::kParameter); -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - // MarkIndependent is marked deprecated but we still rely on it here - // temporarily. - sample->global.MarkIndependent(); -#if __clang__ -#pragma clang diagnostic pop -#endif samples_.emplace(sample.get(), std::move(sample)); } diff --git a/test/cctest/heap/heap-utils.h b/test/cctest/heap/heap-utils.h index dbe8e30a49..082d255a3f 100644 --- a/test/cctest/heap/heap-utils.h +++ b/test/cctest/heap/heap-utils.h @@ -12,6 +12,22 @@ namespace v8 { namespace internal { namespace heap { +class TemporaryEmbedderHeapTracerScope { + public: + TemporaryEmbedderHeapTracerScope(v8::Isolate* isolate, + v8::EmbedderHeapTracer* tracer) + : isolate_(isolate) { + isolate_->SetEmbedderHeapTracer(tracer); + } + + ~TemporaryEmbedderHeapTracerScope() { + isolate_->SetEmbedderHeapTracer(nullptr); + } + + private: + v8::Isolate* const isolate_; +}; + void SealCurrentObjects(Heap* heap); int FixedArrayLenFromSize(int size); diff --git a/test/cctest/heap/test-embedder-tracing.cc b/test/cctest/heap/test-embedder-tracing.cc index ace016dbd0..d6825924ff 100644 --- a/test/cctest/heap/test-embedder-tracing.cc +++ b/test/cctest/heap/test-embedder-tracing.cc @@ -103,22 +103,6 @@ class TestEmbedderHeapTracer final : public v8::EmbedderHeapTracer { v8::Global array_; }; -class TemporaryEmbedderHeapTracerScope { - public: - TemporaryEmbedderHeapTracerScope(v8::Isolate* isolate, - EmbedderHeapTracer* tracer) - : isolate_(isolate) { - isolate_->SetEmbedderHeapTracer(tracer); - } - - ~TemporaryEmbedderHeapTracerScope() { - isolate_->SetEmbedderHeapTracer(nullptr); - } - - private: - v8::Isolate* const isolate_; -}; - } // namespace TEST(V8RegisteringEmbedderReference) { @@ -128,7 +112,7 @@ TEST(V8RegisteringEmbedderReference) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -148,7 +132,7 @@ TEST(EmbedderRegisteringV8Reference) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -181,7 +165,7 @@ TEST(TracingInRevivedSubgraph) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -209,7 +193,7 @@ TEST(TracingInEphemerons) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -240,7 +224,7 @@ TEST(FinalizeTracingIsNoopWhenNotMarking) { v8::Isolate* isolate = CcTest::isolate(); Isolate* i_isolate = CcTest::i_isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); // Finalize a potentially running garbage collection. i_isolate->heap()->CollectGarbage(OLD_SPACE, @@ -259,7 +243,7 @@ TEST(FinalizeTracingWhenMarking) { v8::Isolate* isolate = CcTest::isolate(); Isolate* i_isolate = CcTest::i_isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); // Finalize a potentially running garbage collection. i_isolate->heap()->CollectGarbage(OLD_SPACE, @@ -284,7 +268,7 @@ TEST(GarbageCollectionForTesting) { v8::Isolate* isolate = CcTest::isolate(); Isolate* i_isolate = CcTest::i_isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); int saved_gc_counter = i_isolate->heap()->gc_count(); tracer.GarbageCollectionForTesting(EmbedderHeapTracer::kUnknown); @@ -414,7 +398,7 @@ TEST(TracedGlobalToUnmodifiedJSObjectSurvivesScavengeWhenExcludedFromRoots) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(false); TracedGlobalTest( CcTest::isolate(), ConstructJSObject, @@ -427,7 +411,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectSurvivesScavengePerDefault) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(true); TracedGlobalTest( CcTest::isolate(), ConstructJSApiObject, @@ -440,7 +424,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectDiesOnScavengeWhenExcludedFromRoots) { CcTest::InitializeVM(); v8::Isolate* isolate = CcTest::isolate(); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(false); TracedGlobalTest( CcTest::isolate(), ConstructJSApiObject, @@ -454,7 +438,7 @@ TEST(TracedGlobalWrapperClassId) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::TracedGlobal traced; ConstructJSObject(isolate, isolate->GetCurrentContext(), &traced); @@ -489,7 +473,7 @@ TEST(TracedGlobalIteration) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::TracedGlobal traced; ConstructJSObject(isolate, isolate->GetCurrentContext(), &traced); @@ -522,7 +506,7 @@ TEST(TracedGlobalSetFinalizationCallbackScavenge) { v8::HandleScope scope(isolate); TestEmbedderHeapTracer tracer; tracer.ConsiderTracedGlobalAsRoot(false); - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::TracedGlobal traced; ConstructJSApiObject(isolate, isolate->GetCurrentContext(), &traced); @@ -544,7 +528,7 @@ TEST(TracedGlobalSetFinalizationCallbackMarkSweep) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); TestEmbedderHeapTracer tracer; - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); v8::TracedGlobal traced; ConstructJSApiObject(isolate, isolate->GetCurrentContext(), &traced); @@ -574,7 +558,7 @@ TEST(TracePrologueCallingIntoV8WriteBarrier) { } TestEmbedderHeapTracer tracer(TracePrologueBehavior::kCallV8WriteBarrier, std::move(global)); - TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); SimulateIncrementalMarking(CcTest::i_isolate()->heap()); } diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc index 50ac47a7ab..166e1e7019 100644 --- a/test/cctest/heap/test-heap.cc +++ b/test/cctest/heap/test-heap.cc @@ -500,44 +500,6 @@ static void TestWeakGlobalHandleCallback( p->first->Reset(); } - -TEST(WeakGlobalHandlesScavenge) { - FLAG_stress_compaction = false; - FLAG_stress_incremental_marking = false; - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - GlobalHandles* global_handles = isolate->global_handles(); - - WeakPointerCleared = false; - - Handle h1; - Handle h2; - - { - HandleScope scope(isolate); - - Handle i = factory->NewStringFromStaticChars("fisk"); - Handle u = factory->NewNumber(1.12344); - - h1 = global_handles->Create(*i); - h2 = global_handles->Create(*u); - } - - std::pair*, int> handle_and_id(&h2, 1234); - GlobalHandles::MakeWeak( - h2.location(), reinterpret_cast(&handle_and_id), - &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); - - // Scavenge treats weak pointers as normal roots. - CcTest::CollectGarbage(NEW_SPACE); - CHECK((*h1)->IsString()); - CHECK((*h2)->IsHeapNumber()); - CHECK(!WeakPointerCleared); - GlobalHandles::Destroy(h1.location()); - GlobalHandles::Destroy(h2.location()); -} - TEST(WeakGlobalUnmodifiedApiHandlesScavenge) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -576,84 +538,6 @@ TEST(WeakGlobalUnmodifiedApiHandlesScavenge) { GlobalHandles::Destroy(h1.location()); } -TEST(WeakGlobalApiHandleModifiedMapScavenge) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - LocalContext context; - GlobalHandles* global_handles = isolate->global_handles(); - - WeakPointerCleared = false; - - Handle h1; - - { - HandleScope scope(isolate); - - // Create an API object which does not have the same map as constructor. - auto function_template = FunctionTemplate::New(context->GetIsolate()); - auto instance_t = function_template->InstanceTemplate(); - instance_t->Set(v8::String::NewFromUtf8(context->GetIsolate(), "a", - NewStringType::kNormal) - .ToLocalChecked(), - v8::Number::New(context->GetIsolate(), 10)); - auto function = - function_template->GetFunction(context.local()).ToLocalChecked(); - auto i = function->NewInstance(context.local()).ToLocalChecked(); - - h1 = global_handles->Create(*(reinterpret_cast(*i))); - } - - std::pair*, int> handle_and_id(&h1, 1234); - GlobalHandles::MakeWeak( - h1.location(), reinterpret_cast(&handle_and_id), - &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); - - CcTest::CollectGarbage(NEW_SPACE); - CHECK(!WeakPointerCleared); - GlobalHandles::Destroy(h1.location()); -} - -TEST(WeakGlobalApiHandleWithElementsScavenge) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - LocalContext context; - GlobalHandles* global_handles = isolate->global_handles(); - - WeakPointerCleared = false; - - Handle h1; - - { - HandleScope scope(isolate); - - // Create an API object which has elements. - auto function_template = FunctionTemplate::New(context->GetIsolate()); - auto instance_t = function_template->InstanceTemplate(); - instance_t->Set(v8::String::NewFromUtf8(context->GetIsolate(), "1", - NewStringType::kNormal) - .ToLocalChecked(), - v8::Number::New(context->GetIsolate(), 10)); - instance_t->Set(v8::String::NewFromUtf8(context->GetIsolate(), "2", - NewStringType::kNormal) - .ToLocalChecked(), - v8::Number::New(context->GetIsolate(), 10)); - auto function = - function_template->GetFunction(context.local()).ToLocalChecked(); - auto i = function->NewInstance(context.local()).ToLocalChecked(); - - h1 = global_handles->Create(*(reinterpret_cast(*i))); - } - - std::pair*, int> handle_and_id(&h1, 1234); - GlobalHandles::MakeWeak( - h1.location(), reinterpret_cast(&handle_and_id), - &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); - - CcTest::CollectGarbage(NEW_SPACE); - CHECK(!WeakPointerCleared); - GlobalHandles::Destroy(h1.location()); -} - TEST(WeakGlobalHandlesMark) { FLAG_stress_incremental_marking = false; CcTest::InitializeVM(); @@ -703,9 +587,7 @@ TEST(DeleteWeakGlobalHandle) { GlobalHandles* global_handles = isolate->global_handles(); WeakPointerCleared = false; - Handle h; - { HandleScope scope(isolate); @@ -717,15 +599,8 @@ TEST(DeleteWeakGlobalHandle) { GlobalHandles::MakeWeak(h.location(), reinterpret_cast(&handle_and_id), &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); - - // Scanvenge does not recognize weak reference. - CcTest::CollectGarbage(NEW_SPACE); - CHECK(!WeakPointerCleared); - - // Mark-compact treats weak reference properly. CcTest::CollectGarbage(OLD_SPACE); - CHECK(WeakPointerCleared); } diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 59903ddd92..fa03bf6bac 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -7956,18 +7956,6 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) { v8::WeakCallbackType::kParameter); object_b.handle.SetWeak(&object_b, &SetFlag, v8::WeakCallbackType::kParameter); -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - // MarkIndependent is marked deprecated but we still rely on it temporarily. - CHECK(!object_b.handle.IsIndependent()); - object_a.handle.MarkIndependent(); - object_b.handle.MarkIndependent(); - CHECK(object_b.handle.IsIndependent()); -#if __clang__ -#pragma clang diagnostic pop -#endif if (global_gc) { CcTest::CollectAllGarbage(); } else { @@ -8118,19 +8106,6 @@ void v8::internal::heap::HeapTester::ResetWeakHandle(bool global_gc) { v8::WeakCallbackType::kParameter); object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag, v8::WeakCallbackType::kParameter); - if (!global_gc) { -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - // MarkIndependent is marked deprecated but we still rely on it temporarily. - object_a.handle.MarkIndependent(); - object_b.handle.MarkIndependent(); - CHECK(object_b.handle.IsIndependent()); -#if __clang__ -#pragma clang diagnostic pop -#endif - } if (global_gc) { CcTest::PreciseCollectAllGarbage(); } else { @@ -8198,16 +8173,6 @@ THREADED_TEST(GCFromWeakCallbacks) { object.flag = false; object.handle.SetWeak(&object, gc_forcing_callback[inner_gc], v8::WeakCallbackType::kParameter); -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - // MarkIndependent is marked deprecated but we still rely on it - // temporarily. - object.handle.MarkIndependent(); -#if __clang__ -#pragma clang diagnostic pop -#endif invoke_gc[outer_gc](); EmptyMessageQueues(isolate); CHECK(object.flag); diff --git a/test/cctest/test-global-handles.cc b/test/cctest/test-global-handles.cc index 2c620b4963..75ad7035f1 100644 --- a/test/cctest/test-global-handles.cc +++ b/test/cctest/test-global-handles.cc @@ -39,6 +39,25 @@ namespace internal { namespace { +// Empty v8::EmbedderHeapTracer that never keeps objects alive on Scavenge. See +// |IsRootForNonTracingGC|. +class NonRootingEmbedderHeapTracer final : public v8::EmbedderHeapTracer { + public: + NonRootingEmbedderHeapTracer() = default; + + void RegisterV8References( + const std::vector>& embedder_fields) final {} + bool AdvanceTracing(double deadline_in_ms) final { return true; } + bool IsTracingDone() final { return true; } + void TracePrologue() final {} + void TraceEpilogue() final {} + void EnterFinalPause(EmbedderStackState) final {} + + bool IsRootForNonTracingGC(const v8::TracedGlobal& handle) final { + return false; + } +}; + void InvokeScavenge() { CcTest::CollectGarbage(i::NEW_SPACE); } void InvokeMarkSweep() { CcTest::CollectAllGarbage(); } @@ -47,23 +66,23 @@ void SimpleCallback(const v8::FunctionCallbackInfo& info) { info.GetReturnValue().Set(v8_num(0)); } -struct FlagAndPersistent { +struct FlagAndGlobal { bool flag; v8::Global handle; }; -void ResetHandleAndSetFlag( - const v8::WeakCallbackInfo& data) { +struct TracedGlobalWrapper { + v8::TracedGlobal handle; +}; + +void ResetHandleAndSetFlag(const v8::WeakCallbackInfo& data) { data.GetParameter()->handle.Reset(); data.GetParameter()->flag = true; } -using ConstructFunction = void (*)(v8::Isolate* isolate, - v8::Local context, - FlagAndPersistent* flag_and_persistent); - +template void ConstructJSObject(v8::Isolate* isolate, v8::Local context, - FlagAndPersistent* flag_and_persistent) { + HandleContainer* flag_and_persistent) { v8::HandleScope handle_scope(isolate); v8::Local object(v8::Object::New(isolate)); CHECK(!object.IsEmpty()); @@ -79,8 +98,9 @@ void ConstructJSObject(v8::Isolate* isolate, v8::Global* global) { CHECK(!global->IsEmpty()); } +template void ConstructJSApiObject(v8::Isolate* isolate, v8::Local context, - FlagAndPersistent* flag_and_persistent) { + HandleContainer* flag_and_persistent) { v8::HandleScope handle_scope(isolate); v8::Local fun = v8::FunctionTemplate::New(isolate, SimpleCallback); @@ -95,7 +115,8 @@ void ConstructJSApiObject(v8::Isolate* isolate, v8::Local context, enum class SurvivalMode { kSurvives, kDies }; -template +template void WeakHandleTest(v8::Isolate* isolate, ConstructFunction construct_function, ModifierFunction modifier_function, GCFunction gc_function, SurvivalMode survives) { @@ -103,7 +124,7 @@ void WeakHandleTest(v8::Isolate* isolate, ConstructFunction construct_function, v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - FlagAndPersistent fp; + FlagAndGlobal fp; construct_function(isolate, context, &fp); CHECK(heap::InYoungGeneration(isolate, fp.handle)); fp.handle.SetWeak(&fp, &ResetHandleAndSetFlag, @@ -115,6 +136,28 @@ void WeakHandleTest(v8::Isolate* isolate, ConstructFunction construct_function, CHECK_IMPLIES(survives == SurvivalMode::kDies, fp.flag); } +template +void TracedGlobalTest(v8::Isolate* isolate, + ConstructFunction construct_function, + ModifierFunction modifier_function, + GCFunction gc_function, SurvivalMode survives) { + v8::HandleScope scope(isolate); + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + NonRootingEmbedderHeapTracer tracer; + heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + + TracedGlobalWrapper fp; + construct_function(isolate, context, &fp); + CHECK(heap::InYoungGeneration(isolate, fp.handle)); + modifier_function(&fp); + gc_function(); + CHECK_IMPLIES(survives == SurvivalMode::kSurvives, !fp.handle.IsEmpty()); + CHECK_IMPLIES(survives == SurvivalMode::kDies, fp.handle.IsEmpty()); +} + void ResurrectingFinalizer( const v8::WeakCallbackInfo>& data) { data.GetParameter()->ClearWeak(); @@ -277,25 +320,36 @@ TEST(PhatomHandlesWithoutCallbacks) { CHECK_EQ(0u, isolate->NumberOfPhantomHandleResetsSinceLastCall()); } -TEST(WeakHandleToUnmodifiedJSObjectSurvivesScavenge) { +TEST(WeakHandleToUnmodifiedJSObjectDiesOnScavenge) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, [](FlagAndPersistent* fp) {}, - []() { InvokeScavenge(); }, SurvivalMode::kSurvives); + CcTest::isolate(), &ConstructJSObject, + [](FlagAndGlobal* fp) {}, []() { InvokeScavenge(); }, + SurvivalMode::kDies); +} + +TEST(TracedGlobalToUnmodifiedJSObjectSurvivesScavenge) { + ManualGCScope manual_gc; + CcTest::InitializeVM(); + TracedGlobalTest( + CcTest::isolate(), &ConstructJSObject, + [](TracedGlobalWrapper* fp) {}, []() { InvokeScavenge(); }, + SurvivalMode::kSurvives); } TEST(WeakHandleToUnmodifiedJSObjectDiesOnMarkCompact) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, [](FlagAndPersistent* fp) {}, - []() { InvokeMarkSweep(); }, SurvivalMode::kDies); + CcTest::isolate(), &ConstructJSObject, + [](FlagAndGlobal* fp) {}, []() { InvokeMarkSweep(); }, + SurvivalMode::kDies); } TEST(WeakHandleToUnmodifiedJSObjectSurvivesMarkCompactWhenInHandle) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, - [](FlagAndPersistent* fp) { + CcTest::isolate(), &ConstructJSObject, + [](FlagAndGlobal* fp) { v8::Local handle = v8::Local::New(CcTest::isolate(), fp->handle); USE(handle); @@ -306,19 +360,30 @@ TEST(WeakHandleToUnmodifiedJSObjectSurvivesMarkCompactWhenInHandle) { TEST(WeakHandleToUnmodifiedJSApiObjectDiesOnScavenge) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, [](FlagAndPersistent* fp) {}, - []() { InvokeScavenge(); }, SurvivalMode::kDies); + CcTest::isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) {}, []() { InvokeScavenge(); }, + SurvivalMode::kDies); } -TEST(WeakHandleToJSApiObjectWithIdentityHashSurvivesScavenge) { +TEST(TracedGlobalToUnmodifiedJSApiObjectDiesOnScavenge) { + ManualGCScope manual_gc; + CcTest::InitializeVM(); + TracedGlobalTest( + CcTest::isolate(), &ConstructJSApiObject, + [](TracedGlobalWrapper* fp) {}, []() { InvokeScavenge(); }, + SurvivalMode::kDies); +} + +TEST(TracedGlobalToJSApiObjectWithIdentityHashSurvivesScavenge) { + ManualGCScope manual_gc; CcTest::InitializeVM(); Isolate* i_isolate = CcTest::i_isolate(); HandleScope scope(i_isolate); Handle weakmap = i_isolate->factory()->NewJSWeakMap(); - WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [&weakmap, i_isolate](FlagAndPersistent* fp) { + TracedGlobalTest( + CcTest::isolate(), &ConstructJSApiObject, + [&weakmap, i_isolate](TracedGlobalWrapper* fp) { v8::HandleScope scope(CcTest::isolate()); Handle key = Utils::OpenHandle(*fp->handle.Get(CcTest::isolate())); @@ -332,8 +397,8 @@ TEST(WeakHandleToJSApiObjectWithIdentityHashSurvivesScavenge) { TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesScavengeWhenInHandle) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndPersistent* fp) { + CcTest::isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) { v8::Local handle = v8::Local::New(CcTest::isolate(), fp->handle); USE(handle); @@ -344,15 +409,16 @@ TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesScavengeWhenInHandle) { TEST(WeakHandleToUnmodifiedJSApiObjectDiesOnMarkCompact) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, [](FlagAndPersistent* fp) {}, - []() { InvokeMarkSweep(); }, SurvivalMode::kDies); + CcTest::isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) {}, []() { InvokeMarkSweep(); }, + SurvivalMode::kDies); } TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesMarkCompactWhenInHandle) { CcTest::InitializeVM(); WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndPersistent* fp) { + CcTest::isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) { v8::Local handle = v8::Local::New(CcTest::isolate(), fp->handle); USE(handle); @@ -360,58 +426,57 @@ TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesMarkCompactWhenInHandle) { []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives); } -TEST(WeakHandleToActiveUnmodifiedJSApiObjectSurvivesScavenge) { +TEST(TracedGlobalToJSApiObjectWithModifiedMapSurvivesScavenge) { CcTest::InitializeVM(); - WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndPersistent* fp) { -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - fp->handle.MarkActive(); -#if __clang__ -#pragma clang diagnostic pop -#endif - }, - []() { InvokeScavenge(); }, SurvivalMode::kSurvives); + v8::Isolate* isolate = CcTest::isolate(); + LocalContext context; + + TracedGlobal handle; + { + v8::HandleScope scope(isolate); + // Create an API object which does not have the same map as constructor. + auto function_template = FunctionTemplate::New(isolate); + auto instance_t = function_template->InstanceTemplate(); + instance_t->Set( + v8::String::NewFromUtf8(isolate, "a", NewStringType::kNormal) + .ToLocalChecked(), + v8::Number::New(isolate, 10)); + auto function = + function_template->GetFunction(context.local()).ToLocalChecked(); + auto i = function->NewInstance(context.local()).ToLocalChecked(); + handle.Reset(isolate, i); + } + InvokeScavenge(); + CHECK(!handle.IsEmpty()); } -TEST(WeakHandleToActiveUnmodifiedJSApiObjectDiesOnMarkCompact) { +TEST(TracedGlobalTOJsApiObjectWithElementsSurvivesScavenge) { CcTest::InitializeVM(); - WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndPersistent* fp) { -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - fp->handle.MarkActive(); -#if __clang__ -#pragma clang diagnostic pop -#endif - }, - []() { InvokeMarkSweep(); }, SurvivalMode::kDies); -} + v8::Isolate* isolate = CcTest::isolate(); + LocalContext context; -TEST(WeakHandleToActiveUnmodifiedJSApiObjectSurvivesMarkCompactWhenInHandle) { - CcTest::InitializeVM(); - WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndPersistent* fp) { -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - fp->handle.MarkActive(); -#if __clang__ -#pragma clang diagnostic pop -#endif - v8::Local handle = - v8::Local::New(CcTest::isolate(), fp->handle); - USE(handle); - }, - []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives); + TracedGlobal handle; + { + v8::HandleScope scope(isolate); + + // Create an API object which has elements. + auto function_template = FunctionTemplate::New(isolate); + auto instance_t = function_template->InstanceTemplate(); + instance_t->Set( + v8::String::NewFromUtf8(isolate, "1", NewStringType::kNormal) + .ToLocalChecked(), + v8::Number::New(isolate, 10)); + instance_t->Set( + v8::String::NewFromUtf8(isolate, "2", NewStringType::kNormal) + .ToLocalChecked(), + v8::Number::New(isolate, 10)); + auto function = + function_template->GetFunction(context.local()).ToLocalChecked(); + auto i = function->NewInstance(context.local()).ToLocalChecked(); + handle.Reset(isolate, i); + } + InvokeScavenge(); + CHECK(!handle.IsEmpty()); } TEST(FinalizerOnUnmodifiedJSApiObjectDoesNotCrash) { @@ -422,8 +487,7 @@ TEST(FinalizerOnUnmodifiedJSApiObjectDoesNotCrash) { v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - FlagAndPersistent fp; - // Could use a regular object and MarkIndependent too. + FlagAndGlobal fp; ConstructJSApiObject(isolate, context, &fp); fp.handle.SetWeak(&fp, &ResetHandleAndSetFlag, v8::WeakCallbackType::kFinalizer); @@ -495,22 +559,22 @@ TEST(FinalizerDiesAndKeepsPhantomAliveOnMarkCompact) { namespace { -void ForceScavenge2(const v8::WeakCallbackInfo& data) { +void ForceScavenge2(const v8::WeakCallbackInfo& data) { data.GetParameter()->flag = true; InvokeScavenge(); } -void ForceScavenge1(const v8::WeakCallbackInfo& data) { +void ForceScavenge1(const v8::WeakCallbackInfo& data) { data.GetParameter()->handle.Reset(); data.SetSecondPassCallback(ForceScavenge2); } -void ForceMarkSweep2(const v8::WeakCallbackInfo& data) { +void ForceMarkSweep2(const v8::WeakCallbackInfo& data) { data.GetParameter()->flag = true; InvokeMarkSweep(); } -void ForceMarkSweep1(const v8::WeakCallbackInfo& data) { +void ForceMarkSweep1(const v8::WeakCallbackInfo& data) { data.GetParameter()->handle.Reset(); data.SetSecondPassCallback(ForceMarkSweep2); } @@ -525,7 +589,7 @@ TEST(GCFromWeakCallbacks) { v8::Context::Scope context_scope(context); static const int kNumberOfGCTypes = 2; - typedef v8::WeakCallbackInfo::Callback Callback; + typedef v8::WeakCallbackInfo::Callback Callback; Callback gc_forcing_callback[kNumberOfGCTypes] = {&ForceScavenge1, &ForceMarkSweep1}; @@ -534,7 +598,7 @@ TEST(GCFromWeakCallbacks) { for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { - FlagAndPersistent fp; + FlagAndGlobal fp; ConstructJSApiObject(isolate, context, &fp); CHECK(heap::InYoungGeneration(isolate, fp.handle)); fp.flag = false; @@ -549,11 +613,11 @@ TEST(GCFromWeakCallbacks) { namespace { -void SecondPassCallback(const v8::WeakCallbackInfo& data) { +void SecondPassCallback(const v8::WeakCallbackInfo& data) { data.GetParameter()->flag = true; } -void FirstPassCallback(const v8::WeakCallbackInfo& data) { +void FirstPassCallback(const v8::WeakCallbackInfo& data) { data.GetParameter()->handle.Reset(); data.SetSecondPassCallback(SecondPassCallback); } @@ -566,7 +630,7 @@ TEST(SecondPassPhantomCallbacks) { v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - FlagAndPersistent fp; + FlagAndGlobal fp; ConstructJSApiObject(isolate, context, &fp); fp.flag = false; fp.handle.SetWeak(&fp, FirstPassCallback, v8::WeakCallbackType::kParameter);