Skip to content

Commit a7fc127

Browse files
addaleaxgibfahn
authored andcommitted
deps: cherry-pick 9b21865822243 from V8 upstream
Original commit message: [api] Add optional data pointer to GC callbacks This can be useful when there may be multiple callbacks attached by code that's not directly tied to a single isolate, e.g. working on a per-context basis. This also allows rephrasing the global non-isolate APIs in terms of this new API, rather than working around it inside `src/heap`. [email protected] Bug: Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: I2e490ec40d1a34ea812f25f41ef9741d2116d965 Reviewed-on: https://chromium-review.googlesource.com/647548 Reviewed-by: Yang Guo <[email protected]> Reviewed-by: Adam Klein <[email protected]> Commit-Queue: Yang Guo <[email protected]> Cr-Commit-Position: refs/heads/master@{#47923} PR-URL: #15391 Backport-PR-URL: #16413 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent aa4f58a commit a7fc127

File tree

5 files changed

+162
-76
lines changed

5 files changed

+162
-76
lines changed

deps/v8/include/v8.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7259,6 +7259,8 @@ class V8_EXPORT Isolate {
72597259

72607260
typedef void (*GCCallback)(Isolate* isolate, GCType type,
72617261
GCCallbackFlags flags);
7262+
typedef void (*GCCallbackWithData)(Isolate* isolate, GCType type,
7263+
GCCallbackFlags flags, void* data);
72627264

72637265
/**
72647266
* Enables the host application to receive a notification before a
@@ -7269,13 +7271,16 @@ class V8_EXPORT Isolate {
72697271
* not possible to register the same callback function two times with
72707272
* different GCType filters.
72717273
*/
7274+
void AddGCPrologueCallback(GCCallbackWithData callback, void* data = nullptr,
7275+
GCType gc_type_filter = kGCTypeAll);
72727276
void AddGCPrologueCallback(GCCallback callback,
72737277
GCType gc_type_filter = kGCTypeAll);
72747278

72757279
/**
72767280
* This function removes callback which was installed by
72777281
* AddGCPrologueCallback function.
72787282
*/
7283+
void RemoveGCPrologueCallback(GCCallbackWithData, void* data = nullptr);
72797284
void RemoveGCPrologueCallback(GCCallback callback);
72807285

72817286
/**
@@ -7292,13 +7297,17 @@ class V8_EXPORT Isolate {
72927297
* not possible to register the same callback function two times with
72937298
* different GCType filters.
72947299
*/
7300+
void AddGCEpilogueCallback(GCCallbackWithData callback, void* data = nullptr,
7301+
GCType gc_type_filter = kGCTypeAll);
72957302
void AddGCEpilogueCallback(GCCallback callback,
72967303
GCType gc_type_filter = kGCTypeAll);
72977304

72987305
/**
72997306
* This function removes callback which was installed by
73007307
* AddGCEpilogueCallback function.
73017308
*/
7309+
void RemoveGCEpilogueCallback(GCCallbackWithData callback,
7310+
void* data = nullptr);
73027311
void RemoveGCEpilogueCallback(GCCallback callback);
73037312

73047313
typedef size_t (*GetExternallyAllocatedMemoryInBytesCallback)();

deps/v8/src/api.cc

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8375,41 +8375,70 @@ v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
83758375
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
83768376
}
83778377

8378-
void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8378+
void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8379+
GCType gc_type) {
83798380
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8380-
isolate->heap()->AddGCPrologueCallback(callback, gc_type);
8381+
isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
83818382
}
83828383

8383-
8384-
void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8384+
void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8385+
void* data) {
83858386
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8386-
isolate->heap()->RemoveGCPrologueCallback(callback);
8387+
isolate->heap()->RemoveGCPrologueCallback(callback, data);
83878388
}
83888389

8390+
void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8391+
GCType gc_type) {
8392+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8393+
isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8394+
}
83898395

8390-
void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8396+
void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8397+
void* data) {
83918398
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8392-
isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
8399+
isolate->heap()->RemoveGCEpilogueCallback(callback, data);
83938400
}
83948401

8402+
static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8403+
GCCallbackFlags flags, void* data) {
8404+
reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8405+
}
83958406

8396-
void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8397-
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8398-
isolate->heap()->RemoveGCEpilogueCallback(callback);
8407+
void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8408+
void* data = reinterpret_cast<void*>(callback);
8409+
AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
83998410
}
84008411

8412+
void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8413+
void* data = reinterpret_cast<void*>(callback);
8414+
RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8415+
}
84018416

8402-
void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8403-
i::Isolate* isolate = i::Isolate::Current();
8404-
isolate->heap()->AddGCPrologueCallback(
8405-
reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8417+
void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8418+
void* data = reinterpret_cast<void*>(callback);
8419+
AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8420+
}
8421+
8422+
void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8423+
void* data = reinterpret_cast<void*>(callback);
8424+
RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
84068425
}
84078426

8427+
static void CallGCCallbackWithoutIsolate(Isolate* isolate, GCType type,
8428+
GCCallbackFlags flags, void* data) {
8429+
reinterpret_cast<v8::GCCallback>(data)(type, flags);
8430+
}
84088431

8409-
void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8410-
i::Isolate* isolate = i::Isolate::Current();
8411-
isolate->heap()->AddGCEpilogueCallback(
8412-
reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8432+
void V8::AddGCPrologueCallback(v8::GCCallback callback, GCType gc_type) {
8433+
void* data = reinterpret_cast<void*>(callback);
8434+
Isolate::GetCurrent()->AddGCPrologueCallback(CallGCCallbackWithoutIsolate,
8435+
data, gc_type);
8436+
}
8437+
8438+
void V8::AddGCEpilogueCallback(v8::GCCallback callback, GCType gc_type) {
8439+
void* data = reinterpret_cast<void*>(callback);
8440+
Isolate::GetCurrent()->AddGCEpilogueCallback(CallGCCallbackWithoutIsolate,
8441+
data, gc_type);
84138442
}
84148443

84158444
void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {

deps/v8/src/heap/heap.cc

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@
5858
namespace v8 {
5959
namespace internal {
6060

61-
bool Heap::GCCallbackPair::operator==(const Heap::GCCallbackPair& other) const {
62-
return other.callback == callback;
61+
bool Heap::GCCallbackTuple::operator==(
62+
const Heap::GCCallbackTuple& other) const {
63+
return other.callback == callback && other.data == data;
6364
}
6465

65-
Heap::GCCallbackPair& Heap::GCCallbackPair::operator=(
66-
const Heap::GCCallbackPair& other) {
66+
Heap::GCCallbackTuple& Heap::GCCallbackTuple::operator=(
67+
const Heap::GCCallbackTuple& other) {
6768
callback = other.callback;
6869
gc_type = other.gc_type;
69-
pass_isolate = other.pass_isolate;
70+
data = other.data;
7071
return *this;
7172
}
7273

@@ -1592,35 +1593,21 @@ bool Heap::PerformGarbageCollection(
15921593
void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
15931594
RuntimeCallTimerScope runtime_timer(isolate(),
15941595
&RuntimeCallStats::GCPrologueCallback);
1595-
for (const GCCallbackPair& info : gc_prologue_callbacks_) {
1596+
for (const GCCallbackTuple& info : gc_prologue_callbacks_) {
15961597
if (gc_type & info.gc_type) {
1597-
if (!info.pass_isolate) {
1598-
v8::GCCallback callback =
1599-
reinterpret_cast<v8::GCCallback>(info.callback);
1600-
callback(gc_type, flags);
1601-
} else {
1602-
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1603-
info.callback(isolate, gc_type, flags);
1604-
}
1598+
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1599+
info.callback(isolate, gc_type, flags, info.data);
16051600
}
16061601
}
16071602
}
16081603

1609-
1610-
void Heap::CallGCEpilogueCallbacks(GCType gc_type,
1611-
GCCallbackFlags gc_callback_flags) {
1604+
void Heap::CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags) {
16121605
RuntimeCallTimerScope runtime_timer(isolate(),
16131606
&RuntimeCallStats::GCEpilogueCallback);
1614-
for (const GCCallbackPair& info : gc_epilogue_callbacks_) {
1607+
for (const GCCallbackTuple& info : gc_epilogue_callbacks_) {
16151608
if (gc_type & info.gc_type) {
1616-
if (!info.pass_isolate) {
1617-
v8::GCCallback callback =
1618-
reinterpret_cast<v8::GCCallback>(info.callback);
1619-
callback(gc_type, gc_callback_flags);
1620-
} else {
1621-
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1622-
info.callback(isolate, gc_type, gc_callback_flags);
1623-
}
1609+
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1610+
info.callback(isolate, gc_type, flags, info.data);
16241611
}
16251612
}
16261613
}
@@ -6192,21 +6179,21 @@ void Heap::TearDown() {
61926179
memory_allocator_ = nullptr;
61936180
}
61946181

6195-
6196-
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback,
6197-
GCType gc_type, bool pass_isolate) {
6182+
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
6183+
GCType gc_type, void* data) {
61986184
DCHECK_NOT_NULL(callback);
61996185
DCHECK(gc_prologue_callbacks_.end() ==
62006186
std::find(gc_prologue_callbacks_.begin(), gc_prologue_callbacks_.end(),
6201-
GCCallbackPair(callback, gc_type, pass_isolate)));
6202-
gc_prologue_callbacks_.emplace_back(callback, gc_type, pass_isolate);
6187+
GCCallbackTuple(callback, gc_type, data)));
6188+
gc_prologue_callbacks_.emplace_back(callback, gc_type, data);
62036189
}
62046190

6205-
6206-
void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
6191+
void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
6192+
void* data) {
62076193
DCHECK_NOT_NULL(callback);
62086194
for (size_t i = 0; i < gc_prologue_callbacks_.size(); i++) {
6209-
if (gc_prologue_callbacks_[i].callback == callback) {
6195+
if (gc_prologue_callbacks_[i].callback == callback &&
6196+
gc_prologue_callbacks_[i].data == data) {
62106197
gc_prologue_callbacks_[i] = gc_prologue_callbacks_.back();
62116198
gc_prologue_callbacks_.pop_back();
62126199
return;
@@ -6215,21 +6202,21 @@ void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
62156202
UNREACHABLE();
62166203
}
62176204

6218-
6219-
void Heap::AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
6220-
GCType gc_type, bool pass_isolate) {
6205+
void Heap::AddGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
6206+
GCType gc_type, void* data) {
62216207
DCHECK_NOT_NULL(callback);
62226208
DCHECK(gc_epilogue_callbacks_.end() ==
62236209
std::find(gc_epilogue_callbacks_.begin(), gc_epilogue_callbacks_.end(),
6224-
GCCallbackPair(callback, gc_type, pass_isolate)));
6225-
gc_epilogue_callbacks_.emplace_back(callback, gc_type, pass_isolate);
6210+
GCCallbackTuple(callback, gc_type, data)));
6211+
gc_epilogue_callbacks_.emplace_back(callback, gc_type, data);
62266212
}
62276213

6228-
6229-
void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
6214+
void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
6215+
void* data) {
62306216
DCHECK_NOT_NULL(callback);
62316217
for (size_t i = 0; i < gc_epilogue_callbacks_.size(); i++) {
6232-
if (gc_epilogue_callbacks_[i].callback == callback) {
6218+
if (gc_epilogue_callbacks_[i].callback == callback &&
6219+
gc_epilogue_callbacks_[i].data == data) {
62336220
gc_epilogue_callbacks_[i] = gc_epilogue_callbacks_.back();
62346221
gc_epilogue_callbacks_.pop_back();
62356222
return;

deps/v8/src/heap/heap.h

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,13 +1435,15 @@ class Heap {
14351435
// Prologue/epilogue callback methods.========================================
14361436
// ===========================================================================
14371437

1438-
void AddGCPrologueCallback(v8::Isolate::GCCallback callback,
1439-
GCType gc_type_filter, bool pass_isolate = true);
1440-
void RemoveGCPrologueCallback(v8::Isolate::GCCallback callback);
1438+
void AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1439+
GCType gc_type_filter, void* data);
1440+
void RemoveGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1441+
void* data);
14411442

1442-
void AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
1443-
GCType gc_type_filter, bool pass_isolate = true);
1444-
void RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback);
1443+
void AddGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1444+
GCType gc_type_filter, void* data);
1445+
void RemoveGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1446+
void* data);
14451447

14461448
void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags);
14471449
void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags);
@@ -1612,17 +1614,17 @@ class Heap {
16121614
RootListIndex index;
16131615
};
16141616

1615-
struct GCCallbackPair {
1616-
GCCallbackPair(v8::Isolate::GCCallback callback, GCType gc_type,
1617-
bool pass_isolate)
1618-
: callback(callback), gc_type(gc_type), pass_isolate(pass_isolate) {}
1617+
struct GCCallbackTuple {
1618+
GCCallbackTuple(v8::Isolate::GCCallbackWithData callback, GCType gc_type,
1619+
void* data)
1620+
: callback(callback), gc_type(gc_type), data(data) {}
16191621

1620-
bool operator==(const GCCallbackPair& other) const;
1621-
GCCallbackPair& operator=(const GCCallbackPair& other);
1622+
bool operator==(const GCCallbackTuple& other) const;
1623+
GCCallbackTuple& operator=(const GCCallbackTuple& other);
16221624

1623-
v8::Isolate::GCCallback callback;
1625+
v8::Isolate::GCCallbackWithData callback;
16241626
GCType gc_type;
1625-
bool pass_isolate;
1627+
void* data;
16261628
};
16271629

16281630
static const int kInitialStringTableSize = 2048;
@@ -2302,8 +2304,8 @@ class Heap {
23022304
// contains Smi(0) while marking is not active.
23032305
Object* encountered_weak_collections_;
23042306

2305-
std::vector<GCCallbackPair> gc_epilogue_callbacks_;
2306-
std::vector<GCCallbackPair> gc_prologue_callbacks_;
2307+
std::vector<GCCallbackTuple> gc_epilogue_callbacks_;
2308+
std::vector<GCCallbackTuple> gc_prologue_callbacks_;
23072309

23082310
GetExternallyAllocatedMemoryInBytesCallback external_memory_callback_;
23092311

deps/v8/test/cctest/test-api.cc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19686,6 +19686,19 @@ void EpilogueCallbackSecond(v8::Isolate* isolate,
1968619686
++epilogue_call_count_second;
1968719687
}
1968819688

19689+
void PrologueCallbackNew(v8::Isolate* isolate, v8::GCType,
19690+
v8::GCCallbackFlags flags, void* data) {
19691+
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
19692+
CHECK_EQ(gc_callbacks_isolate, isolate);
19693+
++*static_cast<int*>(data);
19694+
}
19695+
19696+
void EpilogueCallbackNew(v8::Isolate* isolate, v8::GCType,
19697+
v8::GCCallbackFlags flags, void* data) {
19698+
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
19699+
CHECK_EQ(gc_callbacks_isolate, isolate);
19700+
++*static_cast<int*>(data);
19701+
}
1968919702

1969019703
void PrologueCallbackAlloc(v8::Isolate* isolate,
1969119704
v8::GCType,
@@ -19760,6 +19773,52 @@ TEST(GCCallbacksOld) {
1976019773
CHECK_EQ(2, epilogue_call_count_second);
1976119774
}
1976219775

19776+
TEST(GCCallbacksWithData) {
19777+
LocalContext context;
19778+
19779+
gc_callbacks_isolate = context->GetIsolate();
19780+
int prologue1 = 0;
19781+
int epilogue1 = 0;
19782+
int prologue2 = 0;
19783+
int epilogue2 = 0;
19784+
19785+
context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackNew, &prologue1);
19786+
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackNew, &epilogue1);
19787+
CHECK_EQ(0, prologue1);
19788+
CHECK_EQ(0, epilogue1);
19789+
CHECK_EQ(0, prologue2);
19790+
CHECK_EQ(0, epilogue2);
19791+
CcTest::CollectAllGarbage();
19792+
CHECK_EQ(1, prologue1);
19793+
CHECK_EQ(1, epilogue1);
19794+
CHECK_EQ(0, prologue2);
19795+
CHECK_EQ(0, epilogue2);
19796+
context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackNew, &prologue2);
19797+
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackNew, &epilogue2);
19798+
CcTest::CollectAllGarbage();
19799+
CHECK_EQ(2, prologue1);
19800+
CHECK_EQ(2, epilogue1);
19801+
CHECK_EQ(1, prologue2);
19802+
CHECK_EQ(1, epilogue2);
19803+
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackNew,
19804+
&prologue1);
19805+
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackNew,
19806+
&epilogue1);
19807+
CcTest::CollectAllGarbage();
19808+
CHECK_EQ(2, prologue1);
19809+
CHECK_EQ(2, epilogue1);
19810+
CHECK_EQ(2, prologue2);
19811+
CHECK_EQ(2, epilogue2);
19812+
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackNew,
19813+
&prologue2);
19814+
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackNew,
19815+
&epilogue2);
19816+
CcTest::CollectAllGarbage();
19817+
CHECK_EQ(2, prologue1);
19818+
CHECK_EQ(2, epilogue1);
19819+
CHECK_EQ(2, prologue2);
19820+
CHECK_EQ(2, epilogue2);
19821+
}
1976319822

1976419823
TEST(GCCallbacks) {
1976519824
LocalContext context;

0 commit comments

Comments
 (0)