Skip to content

Commit b4ad15b

Browse files
addaleaxMylesBorins
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 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent e1828eb commit b4ad15b

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
@@ -7169,6 +7169,8 @@ class V8_EXPORT Isolate {
71697169

71707170
typedef void (*GCCallback)(Isolate* isolate, GCType type,
71717171
GCCallbackFlags flags);
7172+
typedef void (*GCCallbackWithData)(Isolate* isolate, GCType type,
7173+
GCCallbackFlags flags, void* data);
71727174

71737175
/**
71747176
* Enables the host application to receive a notification before a
@@ -7179,13 +7181,16 @@ class V8_EXPORT Isolate {
71797181
* not possible to register the same callback function two times with
71807182
* different GCType filters.
71817183
*/
7184+
void AddGCPrologueCallback(GCCallbackWithData callback, void* data = nullptr,
7185+
GCType gc_type_filter = kGCTypeAll);
71827186
void AddGCPrologueCallback(GCCallback callback,
71837187
GCType gc_type_filter = kGCTypeAll);
71847188

71857189
/**
71867190
* This function removes callback which was installed by
71877191
* AddGCPrologueCallback function.
71887192
*/
7193+
void RemoveGCPrologueCallback(GCCallbackWithData, void* data = nullptr);
71897194
void RemoveGCPrologueCallback(GCCallback callback);
71907195

71917196
/**
@@ -7202,13 +7207,17 @@ class V8_EXPORT Isolate {
72027207
* not possible to register the same callback function two times with
72037208
* different GCType filters.
72047209
*/
7210+
void AddGCEpilogueCallback(GCCallbackWithData callback, void* data = nullptr,
7211+
GCType gc_type_filter = kGCTypeAll);
72057212
void AddGCEpilogueCallback(GCCallback callback,
72067213
GCType gc_type_filter = kGCTypeAll);
72077214

72087215
/**
72097216
* This function removes callback which was installed by
72107217
* AddGCEpilogueCallback function.
72117218
*/
7219+
void RemoveGCEpilogueCallback(GCCallbackWithData callback,
7220+
void* data = nullptr);
72127221
void RemoveGCEpilogueCallback(GCCallback callback);
72137222

72147223
typedef size_t (*GetExternallyAllocatedMemoryInBytesCallback)();

deps/v8/src/api.cc

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

8341-
void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8341+
void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8342+
GCType gc_type) {
83428343
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8343-
isolate->heap()->AddGCPrologueCallback(callback, gc_type);
8344+
isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
83448345
}
83458346

8346-
8347-
void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8347+
void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8348+
void* data) {
83488349
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8349-
isolate->heap()->RemoveGCPrologueCallback(callback);
8350+
isolate->heap()->RemoveGCPrologueCallback(callback, data);
83508351
}
83518352

8353+
void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8354+
GCType gc_type) {
8355+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8356+
isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8357+
}
83528358

8353-
void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8359+
void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8360+
void* data) {
83548361
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8355-
isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
8362+
isolate->heap()->RemoveGCEpilogueCallback(callback, data);
83568363
}
83578364

8365+
static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8366+
GCCallbackFlags flags, void* data) {
8367+
reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8368+
}
83588369

8359-
void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8360-
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8361-
isolate->heap()->RemoveGCEpilogueCallback(callback);
8370+
void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8371+
void* data = reinterpret_cast<void*>(callback);
8372+
AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
83628373
}
83638374

8375+
void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8376+
void* data = reinterpret_cast<void*>(callback);
8377+
RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8378+
}
83648379

8365-
void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8366-
i::Isolate* isolate = i::Isolate::Current();
8367-
isolate->heap()->AddGCPrologueCallback(
8368-
reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8380+
void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8381+
void* data = reinterpret_cast<void*>(callback);
8382+
AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8383+
}
8384+
8385+
void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8386+
void* data = reinterpret_cast<void*>(callback);
8387+
RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
83698388
}
83708389

8390+
static void CallGCCallbackWithoutIsolate(Isolate* isolate, GCType type,
8391+
GCCallbackFlags flags, void* data) {
8392+
reinterpret_cast<v8::GCCallback>(data)(type, flags);
8393+
}
83718394

8372-
void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8373-
i::Isolate* isolate = i::Isolate::Current();
8374-
isolate->heap()->AddGCEpilogueCallback(
8375-
reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
8395+
void V8::AddGCPrologueCallback(v8::GCCallback callback, GCType gc_type) {
8396+
void* data = reinterpret_cast<void*>(callback);
8397+
Isolate::GetCurrent()->AddGCPrologueCallback(CallGCCallbackWithoutIsolate,
8398+
data, gc_type);
8399+
}
8400+
8401+
void V8::AddGCEpilogueCallback(v8::GCCallback callback, GCType gc_type) {
8402+
void* data = reinterpret_cast<void*>(callback);
8403+
Isolate::GetCurrent()->AddGCEpilogueCallback(CallGCCallbackWithoutIsolate,
8404+
data, gc_type);
83768405
}
83778406

83788407
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
@@ -57,15 +57,16 @@
5757
namespace v8 {
5858
namespace internal {
5959

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

64-
Heap::GCCallbackPair& Heap::GCCallbackPair::operator=(
65-
const Heap::GCCallbackPair& other) {
65+
Heap::GCCallbackTuple& Heap::GCCallbackTuple::operator=(
66+
const Heap::GCCallbackTuple& other) {
6667
callback = other.callback;
6768
gc_type = other.gc_type;
68-
pass_isolate = other.pass_isolate;
69+
data = other.data;
6970
return *this;
7071
}
7172

@@ -1513,35 +1514,21 @@ bool Heap::PerformGarbageCollection(
15131514
void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
15141515
RuntimeCallTimerScope runtime_timer(isolate(),
15151516
&RuntimeCallStats::GCPrologueCallback);
1516-
for (const GCCallbackPair& info : gc_prologue_callbacks_) {
1517+
for (const GCCallbackTuple& info : gc_prologue_callbacks_) {
15171518
if (gc_type & info.gc_type) {
1518-
if (!info.pass_isolate) {
1519-
v8::GCCallback callback =
1520-
reinterpret_cast<v8::GCCallback>(info.callback);
1521-
callback(gc_type, flags);
1522-
} else {
1523-
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1524-
info.callback(isolate, gc_type, flags);
1525-
}
1519+
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1520+
info.callback(isolate, gc_type, flags, info.data);
15261521
}
15271522
}
15281523
}
15291524

1530-
1531-
void Heap::CallGCEpilogueCallbacks(GCType gc_type,
1532-
GCCallbackFlags gc_callback_flags) {
1525+
void Heap::CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags) {
15331526
RuntimeCallTimerScope runtime_timer(isolate(),
15341527
&RuntimeCallStats::GCEpilogueCallback);
1535-
for (const GCCallbackPair& info : gc_epilogue_callbacks_) {
1528+
for (const GCCallbackTuple& info : gc_epilogue_callbacks_) {
15361529
if (gc_type & info.gc_type) {
1537-
if (!info.pass_isolate) {
1538-
v8::GCCallback callback =
1539-
reinterpret_cast<v8::GCCallback>(info.callback);
1540-
callback(gc_type, gc_callback_flags);
1541-
} else {
1542-
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1543-
info.callback(isolate, gc_type, gc_callback_flags);
1544-
}
1530+
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1531+
info.callback(isolate, gc_type, flags, info.data);
15451532
}
15461533
}
15471534
}
@@ -5963,21 +5950,21 @@ void Heap::TearDown() {
59635950
memory_allocator_ = nullptr;
59645951
}
59655952

5966-
5967-
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback,
5968-
GCType gc_type, bool pass_isolate) {
5953+
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
5954+
GCType gc_type, void* data) {
59695955
DCHECK_NOT_NULL(callback);
59705956
DCHECK(gc_prologue_callbacks_.end() ==
59715957
std::find(gc_prologue_callbacks_.begin(), gc_prologue_callbacks_.end(),
5972-
GCCallbackPair(callback, gc_type, pass_isolate)));
5973-
gc_prologue_callbacks_.emplace_back(callback, gc_type, pass_isolate);
5958+
GCCallbackTuple(callback, gc_type, data)));
5959+
gc_prologue_callbacks_.emplace_back(callback, gc_type, data);
59745960
}
59755961

5976-
5977-
void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
5962+
void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
5963+
void* data) {
59785964
DCHECK_NOT_NULL(callback);
59795965
for (size_t i = 0; i < gc_prologue_callbacks_.size(); i++) {
5980-
if (gc_prologue_callbacks_[i].callback == callback) {
5966+
if (gc_prologue_callbacks_[i].callback == callback &&
5967+
gc_prologue_callbacks_[i].data == data) {
59815968
gc_prologue_callbacks_[i] = gc_prologue_callbacks_.back();
59825969
gc_prologue_callbacks_.pop_back();
59835970
return;
@@ -5986,21 +5973,21 @@ void Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
59865973
UNREACHABLE();
59875974
}
59885975

5989-
5990-
void Heap::AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
5991-
GCType gc_type, bool pass_isolate) {
5976+
void Heap::AddGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
5977+
GCType gc_type, void* data) {
59925978
DCHECK_NOT_NULL(callback);
59935979
DCHECK(gc_epilogue_callbacks_.end() ==
59945980
std::find(gc_epilogue_callbacks_.begin(), gc_epilogue_callbacks_.end(),
5995-
GCCallbackPair(callback, gc_type, pass_isolate)));
5996-
gc_epilogue_callbacks_.emplace_back(callback, gc_type, pass_isolate);
5981+
GCCallbackTuple(callback, gc_type, data)));
5982+
gc_epilogue_callbacks_.emplace_back(callback, gc_type, data);
59975983
}
59985984

5999-
6000-
void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
5985+
void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
5986+
void* data) {
60015987
DCHECK_NOT_NULL(callback);
60025988
for (size_t i = 0; i < gc_epilogue_callbacks_.size(); i++) {
6003-
if (gc_epilogue_callbacks_[i].callback == callback) {
5989+
if (gc_epilogue_callbacks_[i].callback == callback &&
5990+
gc_epilogue_callbacks_[i].data == data) {
60045991
gc_epilogue_callbacks_[i] = gc_epilogue_callbacks_.back();
60055992
gc_epilogue_callbacks_.pop_back();
60065993
return;

deps/v8/src/heap/heap.h

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,13 +1414,15 @@ class Heap {
14141414
// Prologue/epilogue callback methods.========================================
14151415
// ===========================================================================
14161416

1417-
void AddGCPrologueCallback(v8::Isolate::GCCallback callback,
1418-
GCType gc_type_filter, bool pass_isolate = true);
1419-
void RemoveGCPrologueCallback(v8::Isolate::GCCallback callback);
1417+
void AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1418+
GCType gc_type_filter, void* data);
1419+
void RemoveGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1420+
void* data);
14201421

1421-
void AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
1422-
GCType gc_type_filter, bool pass_isolate = true);
1423-
void RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback);
1422+
void AddGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1423+
GCType gc_type_filter, void* data);
1424+
void RemoveGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1425+
void* data);
14241426

14251427
void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags);
14261428
void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags);
@@ -1580,17 +1582,17 @@ class Heap {
15801582
RootListIndex index;
15811583
};
15821584

1583-
struct GCCallbackPair {
1584-
GCCallbackPair(v8::Isolate::GCCallback callback, GCType gc_type,
1585-
bool pass_isolate)
1586-
: callback(callback), gc_type(gc_type), pass_isolate(pass_isolate) {}
1585+
struct GCCallbackTuple {
1586+
GCCallbackTuple(v8::Isolate::GCCallbackWithData callback, GCType gc_type,
1587+
void* data)
1588+
: callback(callback), gc_type(gc_type), data(data) {}
15871589

1588-
bool operator==(const GCCallbackPair& other) const;
1589-
GCCallbackPair& operator=(const GCCallbackPair& other);
1590+
bool operator==(const GCCallbackTuple& other) const;
1591+
GCCallbackTuple& operator=(const GCCallbackTuple& other);
15901592

1591-
v8::Isolate::GCCallback callback;
1593+
v8::Isolate::GCCallbackWithData callback;
15921594
GCType gc_type;
1593-
bool pass_isolate;
1595+
void* data;
15941596
};
15951597

15961598
typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap,
@@ -2254,8 +2256,8 @@ class Heap {
22542256

22552257
Object* encountered_transition_arrays_;
22562258

2257-
std::vector<GCCallbackPair> gc_epilogue_callbacks_;
2258-
std::vector<GCCallbackPair> gc_prologue_callbacks_;
2259+
std::vector<GCCallbackTuple> gc_epilogue_callbacks_;
2260+
std::vector<GCCallbackTuple> gc_prologue_callbacks_;
22592261

22602262
GetExternallyAllocatedMemoryInBytesCallback external_memory_callback_;
22612263

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19592,6 +19592,19 @@ void EpilogueCallbackSecond(v8::Isolate* isolate,
1959219592
++epilogue_call_count_second;
1959319593
}
1959419594

19595+
void PrologueCallbackNew(v8::Isolate* isolate, v8::GCType,
19596+
v8::GCCallbackFlags flags, void* data) {
19597+
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
19598+
CHECK_EQ(gc_callbacks_isolate, isolate);
19599+
++*static_cast<int*>(data);
19600+
}
19601+
19602+
void EpilogueCallbackNew(v8::Isolate* isolate, v8::GCType,
19603+
v8::GCCallbackFlags flags, void* data) {
19604+
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
19605+
CHECK_EQ(gc_callbacks_isolate, isolate);
19606+
++*static_cast<int*>(data);
19607+
}
1959519608

1959619609
void PrologueCallbackAlloc(v8::Isolate* isolate,
1959719610
v8::GCType,
@@ -19666,6 +19679,52 @@ TEST(GCCallbacksOld) {
1966619679
CHECK_EQ(2, epilogue_call_count_second);
1966719680
}
1966819681

19682+
TEST(GCCallbacksWithData) {
19683+
LocalContext context;
19684+
19685+
gc_callbacks_isolate = context->GetIsolate();
19686+
int prologue1 = 0;
19687+
int epilogue1 = 0;
19688+
int prologue2 = 0;
19689+
int epilogue2 = 0;
19690+
19691+
context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackNew, &prologue1);
19692+
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackNew, &epilogue1);
19693+
CHECK_EQ(0, prologue1);
19694+
CHECK_EQ(0, epilogue1);
19695+
CHECK_EQ(0, prologue2);
19696+
CHECK_EQ(0, epilogue2);
19697+
CcTest::CollectAllGarbage();
19698+
CHECK_EQ(1, prologue1);
19699+
CHECK_EQ(1, epilogue1);
19700+
CHECK_EQ(0, prologue2);
19701+
CHECK_EQ(0, epilogue2);
19702+
context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackNew, &prologue2);
19703+
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackNew, &epilogue2);
19704+
CcTest::CollectAllGarbage();
19705+
CHECK_EQ(2, prologue1);
19706+
CHECK_EQ(2, epilogue1);
19707+
CHECK_EQ(1, prologue2);
19708+
CHECK_EQ(1, epilogue2);
19709+
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackNew,
19710+
&prologue1);
19711+
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackNew,
19712+
&epilogue1);
19713+
CcTest::CollectAllGarbage();
19714+
CHECK_EQ(2, prologue1);
19715+
CHECK_EQ(2, epilogue1);
19716+
CHECK_EQ(2, prologue2);
19717+
CHECK_EQ(2, epilogue2);
19718+
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackNew,
19719+
&prologue2);
19720+
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackNew,
19721+
&epilogue2);
19722+
CcTest::CollectAllGarbage();
19723+
CHECK_EQ(2, prologue1);
19724+
CHECK_EQ(2, epilogue1);
19725+
CHECK_EQ(2, prologue2);
19726+
CHECK_EQ(2, epilogue2);
19727+
}
1966919728

1967019729
TEST(GCCallbacks) {
1967119730
LocalContext context;

0 commit comments

Comments
 (0)