Skip to content

Commit 6e01998

Browse files
committed
src: initial enablement of IsolateGroups
This lays the initial groundwork for enabling the use of IsolateGroups. Every isolate in V8 is created within a group. When pointer compression is enabled, all isolates within a single group are limited to a 4 GB shared pointer cage. By default, all isolates in the process share the same group, which means that when running with pointer compression, the entire process would be limited to a single 4 GB shared pointer cage. But, we can create as many IsolateGroups as we want, limited only by the amount of virtual memory available on the machine.
1 parent 0c35aaf commit 6e01998

File tree

6 files changed

+42
-5
lines changed

6 files changed

+42
-5
lines changed

configure.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,12 @@
646646
default=None,
647647
help='[Experimental] Enable V8 pointer compression (limits max heap to 4GB and breaks ABI compatibility)')
648648

649+
parser.add_argument('--experimental-enable-pointer-compression-multicage',
650+
action='store_true',
651+
dest='enable_pointer_compression_multicage',
652+
default=None,
653+
help='[Experimental] When pointer compression is enabled, turns on multi cage mode')
654+
649655
parser.add_argument('--v8-options',
650656
action='store',
651657
dest='v8_options',
@@ -1789,7 +1795,7 @@ def configure_v8(o, configs):
17891795
# Note that enabling pointer compression without enabling sandbox is unsupported by V8,
17901796
# so this can be broken at any time.
17911797
o['variables']['v8_enable_sandbox'] = 0
1792-
o['variables']['v8_enable_pointer_compression_shared_cage'] = 1 if options.enable_pointer_compression else 0
1798+
o['variables']['v8_enable_pointer_compression_shared_cage'] = 1 if options.enable_pointer_compression and not options.enable_pointer_compression_multicage else 0
17931799
o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0
17941800
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
17951801
o['variables']['v8_enable_extensible_ro_snapshot'] = 0

src/api/embed_helpers.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#include "debug_utils-inl.h"
22
#include "env-inl.h"
33
#include "node.h"
4+
#include "node_internals.h"
45
#include "node_snapshot_builder.h"
56

67
using v8::Context;
78
using v8::Function;
89
using v8::Global;
910
using v8::HandleScope;
1011
using v8::Isolate;
12+
using v8::IsolateGroup;
1113
using v8::Just;
1214
using v8::Local;
1315
using v8::Locker;
@@ -127,7 +129,7 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
127129
if (flags & Flags::kIsForSnapshotting) {
128130
// The isolate must be registered before the SnapshotCreator initializes the
129131
// isolate, so that the memory reducer can be initialized.
130-
isolate = impl_->isolate = Isolate::Allocate();
132+
isolate = impl_->isolate = Isolate::Allocate(GetOrCreateIsolateGroup());
131133
platform->RegisterIsolate(isolate, loop);
132134

133135
impl_->snapshot_creator.emplace(isolate, params);

src/api/environment.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ using v8::Function;
3737
using v8::FunctionCallbackInfo;
3838
using v8::HandleScope;
3939
using v8::Isolate;
40+
using v8::IsolateGroup;
4041
using v8::Just;
4142
using v8::JustVoid;
4243
using v8::Local;
@@ -304,14 +305,26 @@ void SetIsolateUpForNode(v8::Isolate* isolate) {
304305
SetIsolateUpForNode(isolate, settings);
305306
}
306307

308+
//
309+
IsolateGroup GetOrCreateIsolateGroup() {
310+
// When pointer compression is disabled, we cannot create new groups,
311+
// in which case we'll always return the default.
312+
if (IsolateGroup::CanCreateNewGroups()) {
313+
return IsolateGroup::Create();
314+
}
315+
316+
return IsolateGroup::GetDefault();
317+
}
318+
307319
// TODO(joyeecheung): we may want to expose this, but then we need to be
308320
// careful about what we override in the params.
309321
Isolate* NewIsolate(Isolate::CreateParams* params,
310322
uv_loop_t* event_loop,
311323
MultiIsolatePlatform* platform,
312324
const SnapshotData* snapshot_data,
313325
const IsolateSettings& settings) {
314-
Isolate* isolate = Isolate::Allocate();
326+
IsolateGroup group = GetOrCreateIsolateGroup();
327+
Isolate* isolate = Isolate::Allocate(group);
315328
if (isolate == nullptr) return nullptr;
316329

317330
if (snapshot_data != nullptr) {

src/node_internals.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,20 @@ void TraceEnvVar(Environment* env,
342342
v8::Local<v8::String> key);
343343

344344
void DefineZlibConstants(v8::Local<v8::Object> target);
345+
346+
// If creating new v8::IsolateGroup instance is supported, this returns a
347+
// new instance. Otherwise, it returns the default instance.
348+
//
349+
// An IsolateGroup is a collection of Isolates that share the same underlying
350+
// pointer cage when pointer compression is enabled. When pointer compression is
351+
// disabled, there is a default IsolateGroup that is used for all isolates, and
352+
// when pointer compression is enabled, all isolates in the app share the
353+
// same pointer cage by default that is limited a maximum of 4GB, not counting
354+
// array buffers and off-heap storage. Multiple IsolateGroups can be used to
355+
// work around the 4GB limit, but each group reserves a range of virtual memory
356+
// addresses, so this should be used with care.
357+
v8::IsolateGroup GetOrCreateIsolateGroup();
358+
345359
v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params,
346360
uv_loop_t* event_loop,
347361
MultiIsolatePlatform* platform,

src/util.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,9 @@ Local<String> UnionBytes::ToStringChecked(Isolate* isolate) const {
736736
}
737737

738738
RAIIIsolateWithoutEntering::RAIIIsolateWithoutEntering(const SnapshotData* data)
739-
: allocator_{ArrayBuffer::Allocator::NewDefaultAllocator()} {
740-
isolate_ = Isolate::Allocate();
739+
: allocator_{ArrayBuffer::Allocator::NewDefaultAllocator()},
740+
isolate_group_(GetOrCreateIsolateGroup()) {
741+
isolate_ = Isolate::Allocate(isolate_group_);
741742
CHECK_NOT_NULL(isolate_);
742743
per_process::v8_platform.Platform()->RegisterIsolate(isolate_,
743744
uv_default_loop());

src/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ class RAIIIsolateWithoutEntering {
990990

991991
private:
992992
std::unique_ptr<v8::ArrayBuffer::Allocator> allocator_;
993+
v8::IsolateGroup isolate_group_;
993994
v8::Isolate* isolate_;
994995
};
995996

0 commit comments

Comments
 (0)