Skip to content

Commit bf8d6c9

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 bf8d6c9

File tree

11 files changed

+53
-15
lines changed

11 files changed

+53
-15
lines changed

common.gypi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979

8080
# Variables controlling external defines exposed in public headers.
8181
'v8_enable_map_packing%': 0,
82-
'v8_enable_pointer_compression_shared_cage%': 0,
82+
'v8_enable_pointer_compression_multiple_cages%': 0,
8383
'v8_enable_external_code_space%': 0,
8484
'v8_enable_sandbox%': 0,
8585
'v8_enable_v8_checks%': 0,
@@ -112,7 +112,7 @@
112112
# V8 pointer compression only supports 64bit architectures.
113113
['target_arch in "arm ia32 mips mipsel"', {
114114
'v8_enable_pointer_compression': 0,
115-
'v8_enable_pointer_compression_shared_cage': 0,
115+
'v8_enable_pointer_compression_multiple_cages': 0,
116116
'v8_enable_31bit_smis_on_64bit_arch': 0,
117117
'v8_enable_external_code_space': 0,
118118
'v8_enable_sandbox': 0
@@ -443,10 +443,10 @@
443443
['v8_enable_pointer_compression == 1', {
444444
'defines': ['V8_COMPRESS_POINTERS'],
445445
}],
446-
['v8_enable_pointer_compression_shared_cage == 1', {
447-
'defines': ['V8_COMPRESS_POINTERS_IN_SHARED_CAGE'],
446+
['v8_enable_pointer_compression_multiple_cages == 1', {
447+
'defines': ['V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES'],
448448
}],
449-
['v8_enable_pointer_compression == 1 and v8_enable_pointer_compression_shared_cage != 1', {
449+
['v8_enable_pointer_compression == 1 and v8_enable_pointer_compression_multiple_cages != 1', {
450450
'defines': ['V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE'],
451451
}],
452452
['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', {

configure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ def configure_v8(o, configs):
17891789
# Note that enabling pointer compression without enabling sandbox is unsupported by V8,
17901790
# so this can be broken at any time.
17911791
o['variables']['v8_enable_sandbox'] = 0
1792-
o['variables']['v8_enable_pointer_compression_shared_cage'] = 1 if options.enable_pointer_compression else 0
1792+
o['variables']['v8_enable_pointer_compression_multiple_cages'] = 1 if options.enable_pointer_compression else 0
17931793
o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0
17941794
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
17951795
o['variables']['v8_enable_extensible_ro_snapshot'] = 0

src/api/embed_helpers.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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;
@@ -127,7 +128,7 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
127128
if (flags & Flags::kIsForSnapshotting) {
128129
// The isolate must be registered before the SnapshotCreator initializes the
129130
// isolate, so that the memory reducer can be initialized.
130-
isolate = impl_->isolate = Isolate::Allocate();
131+
isolate = impl_->isolate = Isolate::Allocate(GetOrCreateIsolateGroup());
131132
platform->RegisterIsolate(isolate, loop);
132133

133134
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.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "node.h"
2323
#include "node_config_file.h"
2424
#include "node_dotenv.h"
25+
#include "node_options.h"
2526
#include "node_task_runner.h"
2627

2728
// ========== local headers ==========

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/node_options.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@ void PerIsolateOptions::HandleMaxOldSpaceSizePercentage(
128128
}
129129

130130
// Get available memory in bytes
131+
#ifdef V8_COMPRESS_POINTERS
132+
// When pointer compression is enabled, V8 uses a 4 GiB heap limit.
133+
uint64_t total_memory = 4294967296; // 4 GiB
134+
#else
131135
uint64_t total_memory = uv_get_total_memory();
136+
#endif
132137
uint64_t constrained_memory = uv_get_constrained_memory();
133138

134139
// Use constrained memory if available, otherwise use total memory

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

test/parallel/test-max-old-space-size-percentage.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ assert(
122122
);
123123

124124
// Validate heap sizes against system memory
125-
const totalMemoryMB = Math.floor(os.totalmem() / 1024 / 1024);
125+
// When pointer compression is enabled, the maximum total memory is 4 GB
126+
const totalMemoryMB = process.config.variables.v8_enable_pointer_compression
127+
? 4096 : Math.floor(os.totalmem() / 1024 / 1024);
126128
const uint64Max = 2 ** 64 - 1;
127129
const constrainedMemory = process.constrainedMemory();
128130
const constrainedMemoryMB = Math.floor(constrainedMemory / 1024 / 1024);

0 commit comments

Comments
 (0)