[api] Remove APIs for resurrecting finalizers
Removes support for specifying weak handles with finalizers that allow for object resurrection. This CL removes the public facing APIs. Internal support will be removed in a follow up. Bug: v8:12672 Change-Id: Ia6ea269093aaa128caadb7508aca2e5a1254923c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3596174 Auto-Submit: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/main@{#80070}
This commit is contained in:
parent
b25adddb90
commit
2ae2aa92b1
@ -63,13 +63,6 @@ enum class WeakCallbackType {
|
||||
* Passes the first two internal fields of the object back to the callback.
|
||||
*/
|
||||
kInternalFields,
|
||||
/**
|
||||
* Passes a user-defined void* parameter back to the callback. Will do so
|
||||
* before the object is actually reclaimed, allowing it to be resurrected. In
|
||||
* this case it is not possible to set a second-pass callback.
|
||||
*/
|
||||
kFinalizer V8_ENUM_DEPRECATED("Resurrecting finalizers are deprecated "
|
||||
"and will not be supported going forward.")
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/base/sanitizer/asan.h"
|
||||
#include "src/common/allow-deprecated.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/execution/vm-state-inl.h"
|
||||
#include "src/heap/base/stack.h"
|
||||
@ -544,11 +543,6 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> {
|
||||
case v8::WeakCallbackType::kInternalFields:
|
||||
set_weakness_type(PHANTOM_WEAK_2_EMBEDDER_FIELDS);
|
||||
break;
|
||||
START_ALLOW_USE_DEPRECATED()
|
||||
case v8::WeakCallbackType::kFinalizer:
|
||||
set_weakness_type(FINALIZER_WEAK);
|
||||
break;
|
||||
END_ALLOW_USE_DEPRECATED()
|
||||
}
|
||||
set_parameter(parameter);
|
||||
weak_callback_ = phantom_callback;
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "include/v8-function.h"
|
||||
#include "include/v8-locker.h"
|
||||
#include "src/api/api-inl.h"
|
||||
#include "src/common/allow-deprecated.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/handles/global-handles.h"
|
||||
#include "src/heap/factory.h"
|
||||
@ -37,8 +36,6 @@
|
||||
#include "test/cctest/cctest.h"
|
||||
#include "test/cctest/heap/heap-utils.h"
|
||||
|
||||
START_ALLOW_USE_DEPRECATED()
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -191,28 +188,8 @@ void TracedReferenceTestWithScavenge(v8::Isolate* isolate,
|
||||
CHECK_IMPLIES(survives == SurvivalMode::kDies, fp->handle.IsEmpty());
|
||||
}
|
||||
|
||||
void ResurrectingFinalizer(
|
||||
const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) {
|
||||
data.GetParameter()->ClearWeak();
|
||||
}
|
||||
|
||||
void ResettingFinalizer(
|
||||
const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) {
|
||||
data.GetParameter()->Reset();
|
||||
}
|
||||
|
||||
void EmptyWeakCallback(const v8::WeakCallbackInfo<void>& data) {}
|
||||
|
||||
void ResurrectingFinalizerSettingProperty(
|
||||
const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) {
|
||||
data.GetParameter()->ClearWeak();
|
||||
v8::Local<v8::Object> o =
|
||||
v8::Local<v8::Object>::New(data.GetIsolate(), *data.GetParameter());
|
||||
o->Set(data.GetIsolate()->GetCurrentContext(), v8_str("finalizer"),
|
||||
v8_str("was here"))
|
||||
.FromJust();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(EternalHandles) {
|
||||
@ -309,32 +286,7 @@ TEST(WeakPersistentSmi) {
|
||||
v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
|
||||
TEST(FinalizerWeakness) {
|
||||
CcTest::InitializeVM();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
|
||||
v8::Global<v8::Object> g;
|
||||
int identity;
|
||||
|
||||
{
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> o = v8::Object::New(isolate);
|
||||
identity = o->GetIdentityHash();
|
||||
g.Reset(isolate, o);
|
||||
g.SetWeak(&g, &ResurrectingFinalizerSettingProperty,
|
||||
v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
|
||||
CcTest::CollectAllAvailableGarbage();
|
||||
|
||||
CHECK(!g.IsEmpty());
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, g);
|
||||
CHECK_EQ(identity, o->GetIdentityHash());
|
||||
CHECK(o->Has(isolate->GetCurrentContext(), v8_str("finalizer")).FromJust());
|
||||
}
|
||||
|
||||
TEST(PhatomHandlesWithoutCallbacks) {
|
||||
TEST(PhantomHandlesWithoutCallbacks) {
|
||||
CcTest::InitializeVM();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
|
||||
@ -510,84 +462,6 @@ TEST(TracedReferenceTOJsApiObjectWithElementsSurvivesScavenge) {
|
||||
CHECK(!handle.IsEmpty());
|
||||
}
|
||||
|
||||
TEST(FinalizerOnUnmodifiedJSApiObjectDoesNotCrash) {
|
||||
// See crbug.com/v8/8586.
|
||||
CcTest::InitializeVM();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
FlagAndGlobal fp;
|
||||
ConstructJSApiObject(isolate, context, &fp);
|
||||
fp.handle.SetWeak(&fp, &ResetHandleAndSetFlag,
|
||||
v8::WeakCallbackType::kFinalizer);
|
||||
fp.flag = false;
|
||||
{
|
||||
v8::HandleScope inner_scope(isolate);
|
||||
v8::Local<v8::Object> tmp = v8::Local<v8::Object>::New(isolate, fp.handle);
|
||||
USE(tmp);
|
||||
InvokeScavenge();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ConstructFinalizerPointingPhantomHandle(
|
||||
v8::Isolate* isolate, v8::Global<v8::Object>* g1,
|
||||
v8::Global<v8::Object>* g2,
|
||||
typename v8::WeakCallbackInfo<v8::Global<v8::Object>>::Callback
|
||||
finalizer_for_g1) {
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> o1 =
|
||||
v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate));
|
||||
v8::Local<v8::Object> o2 =
|
||||
v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate));
|
||||
o1->Set(isolate->GetCurrentContext(), v8_str("link"), o2).FromJust();
|
||||
g1->Reset(isolate, o1);
|
||||
g2->Reset(isolate, o2);
|
||||
// g1 will be finalized but resurrected.
|
||||
g1->SetWeak(g1, finalizer_for_g1, v8::WeakCallbackType::kFinalizer);
|
||||
// g2 will be a phantom handle that is dependent on the finalizer handle
|
||||
// g1 as it is in its subgraph.
|
||||
g2->SetWeak();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(FinalizerResurrectsAndKeepsPhantomAliveOnMarkCompact) {
|
||||
// See crbug.com/772299.
|
||||
CcTest::InitializeVM();
|
||||
v8::Global<v8::Object> g1, g2;
|
||||
ConstructFinalizerPointingPhantomHandle(CcTest::isolate(), &g1, &g2,
|
||||
ResurrectingFinalizer);
|
||||
InvokeMarkSweep();
|
||||
// Both, g1 and g2, should stay alive as the finalizer resurrects the root
|
||||
// object that transitively keeps the other one alive.
|
||||
CHECK(!g1.IsEmpty());
|
||||
CHECK(!g2.IsEmpty());
|
||||
InvokeMarkSweep();
|
||||
// The finalizer handle is now strong, so it should keep the objects alive.
|
||||
CHECK(!g1.IsEmpty());
|
||||
CHECK(!g2.IsEmpty());
|
||||
}
|
||||
|
||||
TEST(FinalizerDiesAndKeepsPhantomAliveOnMarkCompact) {
|
||||
CcTest::InitializeVM();
|
||||
v8::Global<v8::Object> g1, g2;
|
||||
ConstructFinalizerPointingPhantomHandle(CcTest::isolate(), &g1, &g2,
|
||||
ResettingFinalizer);
|
||||
InvokeMarkSweep();
|
||||
// Finalizer (g1) dies but the phantom handle (g2) is kept alive for one
|
||||
// more round as the underlying object only dies on the next GC.
|
||||
CHECK(g1.IsEmpty());
|
||||
CHECK(!g2.IsEmpty());
|
||||
InvokeMarkSweep();
|
||||
// Phantom handle dies after one more round.
|
||||
CHECK(g1.IsEmpty());
|
||||
CHECK(g2.IsEmpty());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ForceScavenge2(const v8::WeakCallbackInfo<FlagAndGlobal>& data) {
|
||||
@ -748,5 +622,3 @@ TEST(TotalSizeTracedNode) {
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
END_ALLOW_USE_DEPRECATED()
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "include/v8-function.h"
|
||||
#include "include/v8-template.h"
|
||||
#include "src/common/allow-deprecated.h"
|
||||
#include "src/handles/global-handles.h"
|
||||
#include "src/heap/gc-tracer.h"
|
||||
#include "src/heap/heap.h"
|
||||
@ -263,8 +262,6 @@ v8::Local<v8::Object> ConstructTraceableJSApiObject(
|
||||
return scope.Escape(instance);
|
||||
}
|
||||
|
||||
START_ALLOW_USE_DEPRECATED()
|
||||
|
||||
enum class TracePrologueBehavior { kNoop, kCallV8WriteBarrier };
|
||||
|
||||
class TestEmbedderHeapTracer final : public v8::EmbedderHeapTracer {
|
||||
@ -403,47 +400,6 @@ TEST_F(EmbedderTracingTest, EmbedderRegisteringV8Reference) {
|
||||
EXPECT_FALSE(handle->IsEmpty());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ResurrectingFinalizer(
|
||||
const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) {
|
||||
data.GetParameter()->ClearWeak();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(EmbedderTracingTest, TracingInRevivedSubgraph) {
|
||||
// Tests that wrappers are traced when they are contained with in a subgraph
|
||||
// that is revived by a finalizer.
|
||||
ManualGCScope manual_gc(i_isolate());
|
||||
TestEmbedderHeapTracer tracer;
|
||||
heap::TemporaryEmbedderHeapTracerScope tracer_scope(v8_isolate(), &tracer);
|
||||
v8::HandleScope scope(v8_isolate());
|
||||
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
v8::Global<v8::Object> g;
|
||||
void* first_and_second_field = reinterpret_cast<void*>(0x4);
|
||||
{
|
||||
v8::HandleScope inner_scope(v8_isolate());
|
||||
v8::Local<v8::Object> api_object = ConstructTraceableJSApiObject(
|
||||
context, first_and_second_field, first_and_second_field);
|
||||
EXPECT_FALSE(api_object.IsEmpty());
|
||||
v8::Local<v8::Object> o =
|
||||
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
|
||||
o->Set(context,
|
||||
v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "link")
|
||||
.ToLocalChecked(),
|
||||
api_object)
|
||||
.FromJust();
|
||||
g.Reset(v8_isolate(), o);
|
||||
g.SetWeak(&g, ResurrectingFinalizer, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
i_isolate()->heap()->CollectGarbage(i::OLD_SPACE,
|
||||
GarbageCollectionReason::kTesting);
|
||||
EXPECT_TRUE(tracer.IsRegisteredFromV8(first_and_second_field));
|
||||
}
|
||||
|
||||
TEST_F(EmbedderTracingTest, TracingInEphemerons) {
|
||||
// Tests that wrappers that are part of ephemerons are traced.
|
||||
ManualGCScope manual_gc(i_isolate());
|
||||
@ -1231,8 +1187,6 @@ TEST_F(EmbedderTracingTest, NotifyEmptyStack) {
|
||||
TracedReferenceNotifyEmptyStackTest(v8_isolate(), &tracer);
|
||||
}
|
||||
|
||||
END_ALLOW_USE_DEPRECATED()
|
||||
|
||||
} // namespace heap
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user