[vm/concurrency] Make clustered snapshot serializer independent of current isolate
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Mainly refactoring, stress tests for --enable-isolate-groups with JIT will come in the future.
Change-Id: Iebb2fb8bd144cb9abd21916856a04f49f85541c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183680
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 897e24a..1849a38 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -59,9 +59,10 @@
GrowableArray<CodePtr>* code_objects,
GrowableArray<ImageWriterCommand>* image_writer_commands) {
auto thread = Thread::Current();
- auto isolate = is_vm ? Dart::vm_isolate() : thread->isolate();
+ auto isolate_group =
+ is_vm ? Dart::vm_isolate()->group() : thread->isolate_group();
- WritableCodePages writable_code_pages(thread, isolate);
+ WritableCodePages writable_code_pages(thread, isolate_group);
CodeRelocator::Relocate(thread, code_objects, image_writer_commands, is_vm);
}
@@ -146,8 +147,7 @@
Serializer* s,
intptr_t class_id) {
const auto unboxed_fields_bitmap_host =
- s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
- class_id);
+ s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
UnboxedFieldBitmap unboxed_fields_bitmap;
if (unboxed_fields_bitmap_host.IsEmpty() ||
@@ -358,7 +358,7 @@
}
}
- auto shared_class_table = d->isolate()->group()->shared_class_table();
+ auto shared_class_table = d->isolate_group()->shared_class_table();
for (intptr_t id = start_index_; id < stop_index_; id++) {
ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize());
@@ -498,7 +498,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalTypeArgumentsSet table(
d->zone(),
d->isolate_group()->object_store()->canonical_type_arguments());
@@ -2367,7 +2367,7 @@
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
if (is_canonical && IsStringClassId(cid_) &&
- (d->isolate() != Dart::vm_isolate())) {
+ (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalStringSet table(
d->zone(), d->isolate_group()->object_store()->symbol_table());
String& str = String::Handle(d->zone());
@@ -3165,8 +3165,7 @@
const intptr_t next_field_offset = host_next_field_offset_in_words_
<< kWordSizeLog2;
const auto unboxed_fields_bitmap =
- s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
- cid_);
+ s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
intptr_t offset = Instance::NextFieldOffset();
while (offset < next_field_offset) {
// Skips unboxed fields
@@ -3203,8 +3202,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned64(CalculateTargetUnboxedFieldsBitmap(s, cid_).Value());
const auto unboxed_fields_bitmap =
- s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
- cid_);
+ s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
for (intptr_t i = 0; i < count; i++) {
InstancePtr instance = objects_[i];
@@ -3458,7 +3456,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalTypeSet table(
d->zone(), d->isolate_group()->object_store()->canonical_types());
Type& type = Type::Handle(d->zone());
@@ -3578,7 +3576,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalFunctionTypeSet table(
d->zone(),
d->isolate_group()->object_store()->canonical_function_types());
@@ -3785,7 +3783,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalTypeParameterSet table(
d->zone(),
d->isolate_group()->object_store()->canonical_type_parameters());
@@ -3955,7 +3953,7 @@
void ReadFill(Deserializer* d, bool is_canonical) {}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
const Class& mint_cls = Class::Handle(
d->zone(), IsolateGroup::Current()->object_store()->mint_class());
mint_cls.set_constants(Object::null_array());
@@ -4843,7 +4841,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalStringSet table(
d->zone(), d->isolate_group()->object_store()->symbol_table());
String& str = String::Handle(d->zone());
@@ -4940,7 +4938,7 @@
}
void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
- if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ if (is_canonical && (d->isolate_group() != Dart::vm_isolate()->group())) {
CanonicalStringSet table(
d->zone(), d->isolate_group()->object_store()->symbol_table());
String& str = String::Handle(d->zone());
@@ -5274,7 +5272,6 @@
}
void PostLoad(Deserializer* d, const Array& refs) {
- auto isolate = d->thread()->isolate();
auto isolate_group = d->thread()->isolate_group();
isolate_group->class_table()->CopySizesFromClassObjects();
d->heap()->old_space()->EvaluateAfterLoading();
@@ -5286,7 +5283,6 @@
unit ^= units.At(LoadingUnit::kRootId);
unit.set_base_objects(refs);
}
- isolate->isolate_object_store()->PreallocateObjects();
// Setup native resolver for bootstrap impl.
Bootstrap::SetupNativeResolver();
@@ -5392,7 +5388,7 @@
// Reinitialize the dispatch table by rereading the table's serialization
// in the root snapshot.
- IsolateGroup* group = d->thread()->isolate()->group();
+ IsolateGroup* group = d->thread()->isolate_group();
if (group->dispatch_table_snapshot() != nullptr) {
ReadStream stream(group->dispatch_table_snapshot(),
group->dispatch_table_snapshot_size());
@@ -6005,7 +6001,7 @@
WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
const char* expected_features =
- Dart::FeaturesString(Isolate::Current(), is_vm_snapshot, kind_);
+ Dart::FeaturesString(IsolateGroup::Current(), is_vm_snapshot, kind_);
ASSERT(expected_features != NULL);
const intptr_t features_len = strlen(expected_features);
WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
@@ -6522,7 +6518,6 @@
// object, from which we can get the reference ID for any code object.
const intptr_t first_code_id = stream->ReadUnsigned();
- auto const I = isolate();
auto const IG = isolate_group();
auto code = IG->object_store()->dispatch_table_null_error_stub();
ASSERT(code != Code::null());
@@ -6560,11 +6555,11 @@
}
ASSERT(repeat_count == 0);
- I->group()->set_dispatch_table(table);
+ IG->set_dispatch_table(table);
intptr_t table_snapshot_size =
stream->AddressOfCurrentPosition() - table_snapshot_start;
- I->group()->set_dispatch_table_snapshot(table_snapshot_start);
- I->group()->set_dispatch_table_snapshot_size(table_snapshot_size);
+ IG->set_dispatch_table_snapshot(table_snapshot_start);
+ IG->set_dispatch_table_snapshot_size(table_snapshot_size);
#endif
}
@@ -6575,11 +6570,12 @@
return ApiError::null();
}
-char* SnapshotHeaderReader::VerifyVersionAndFeatures(Isolate* isolate,
- intptr_t* offset) {
+char* SnapshotHeaderReader::VerifyVersionAndFeatures(
+ IsolateGroup* isolate_group,
+ intptr_t* offset) {
char* error = VerifyVersion();
if (error == nullptr) {
- error = VerifyFeatures(isolate);
+ error = VerifyFeatures(isolate_group);
}
if (error == nullptr) {
*offset = stream_.Position();
@@ -6622,9 +6618,9 @@
return nullptr;
}
-char* SnapshotHeaderReader::VerifyFeatures(Isolate* isolate) {
+char* SnapshotHeaderReader::VerifyFeatures(IsolateGroup* isolate_group) {
const char* expected_features =
- Dart::FeaturesString(isolate, (isolate == NULL), kind_);
+ Dart::FeaturesString(isolate_group, (isolate_group == NULL), kind_);
ASSERT(expected_features != NULL);
const intptr_t expected_len = strlen(expected_features);
@@ -6912,10 +6908,10 @@
roots->PostLoad(this, refs);
#if defined(DEBUG)
- Isolate* isolate = thread()->isolate();
- isolate->ValidateClassTable();
- if (isolate != Dart::vm_isolate()) {
- isolate->group()->heap()->Verify();
+ auto isolate_group = thread()->isolate_group();
+ isolate_group->ValidateClassTable();
+ if (isolate_group != Dart::vm_isolate()->group()) {
+ isolate_group->heap()->Verify();
}
#endif
@@ -6956,13 +6952,13 @@
clustered_isolate_size_(0),
mapped_data_size_(0),
mapped_text_size_(0) {
- ASSERT(isolate() != NULL);
+ ASSERT(isolate_group() != NULL);
ASSERT(heap() != NULL);
ObjectStore* object_store = isolate_group()->object_store();
ASSERT(object_store != NULL);
#if defined(DEBUG)
- isolate()->ValidateClassTable();
+ isolate_group()->ValidateClassTable();
isolate_group()->ValidateConstants();
#endif // DEBUG
@@ -7289,8 +7285,8 @@
SnapshotHeaderReader header_reader(kind_, buffer_, size_);
intptr_t offset = 0;
- char* error =
- header_reader.VerifyVersionAndFeatures(/*isolate=*/NULL, &offset);
+ char* error = header_reader.VerifyVersionAndFeatures(
+ /*isolate_group=*/nullptr, &offset);
if (error != nullptr) {
return ConvertToApiError(error);
}
@@ -7305,11 +7301,11 @@
if (Snapshot::IncludesCode(kind_)) {
ASSERT(data_image_ != NULL);
- thread_->isolate()->SetupImagePage(data_image_,
- /* is_executable */ false);
+ thread_->isolate_group()->SetupImagePage(data_image_,
+ /* is_executable */ false);
ASSERT(instructions_image_ != NULL);
- thread_->isolate()->SetupImagePage(instructions_image_,
- /* is_executable */ true);
+ thread_->isolate_group()->SetupImagePage(instructions_image_,
+ /* is_executable */ true);
}
VMDeserializationRoots roots;
@@ -7331,7 +7327,7 @@
SnapshotHeaderReader header_reader(kind_, buffer_, size_);
intptr_t offset = 0;
char* error =
- header_reader.VerifyVersionAndFeatures(thread_->isolate(), &offset);
+ header_reader.VerifyVersionAndFeatures(thread_->isolate_group(), &offset);
if (error != nullptr) {
return ConvertToApiError(error);
}
@@ -7346,11 +7342,11 @@
if (Snapshot::IncludesCode(kind_)) {
ASSERT(data_image_ != NULL);
- thread_->isolate()->SetupImagePage(data_image_,
- /* is_executable */ false);
+ thread_->isolate_group()->SetupImagePage(data_image_,
+ /* is_executable */ false);
ASSERT(instructions_image_ != NULL);
- thread_->isolate()->SetupImagePage(instructions_image_,
- /* is_executable */ true);
+ thread_->isolate_group()->SetupImagePage(instructions_image_,
+ /* is_executable */ true);
}
ProgramDeserializationRoots roots(thread_->isolate_group()->object_store());
@@ -7366,7 +7362,7 @@
SnapshotHeaderReader header_reader(kind_, buffer_, size_);
intptr_t offset = 0;
char* error =
- header_reader.VerifyVersionAndFeatures(thread_->isolate(), &offset);
+ header_reader.VerifyVersionAndFeatures(thread_->isolate_group(), &offset);
if (error != nullptr) {
return ConvertToApiError(error);
}
@@ -7392,11 +7388,11 @@
if (Snapshot::IncludesCode(kind_)) {
ASSERT(data_image_ != NULL);
- thread_->isolate()->SetupImagePage(data_image_,
- /* is_executable */ false);
+ thread_->isolate_group()->SetupImagePage(data_image_,
+ /* is_executable */ false);
ASSERT(instructions_image_ != NULL);
- thread_->isolate()->SetupImagePage(instructions_image_,
- /* is_executable */ true);
+ thread_->isolate_group()->SetupImagePage(instructions_image_,
+ /* is_executable */ true);
}
UnitDeserializationRoots roots(unit);
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index fcd5d90..c4bd073 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -537,12 +537,12 @@
// Returns null on success and a malloc()ed error on failure.
// The [offset] will be the next position in the snapshot stream after the
// features.
- char* VerifyVersionAndFeatures(Isolate* isolate, intptr_t* offset);
+ char* VerifyVersionAndFeatures(IsolateGroup* isolate_group, intptr_t* offset);
private:
char* VerifyVersion();
char* ReadFeatures(const char** features, intptr_t* features_length);
- char* VerifyFeatures(Isolate* isolate);
+ char* VerifyFeatures(IsolateGroup* isolate_group);
char* BuildError(const char* message);
Snapshot::Kind kind_;
@@ -685,7 +685,6 @@
Thread* thread() const { return thread_; }
Zone* zone() const { return thread_->zone(); }
- Isolate* isolate() const { return thread_->isolate(); }
IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
Heap* heap() const { return isolate_group()->heap(); }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index c1259f2..51a197c 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -879,9 +879,6 @@
HandleScope handle_scope(T);
bool was_child_cloned_into_existing_isolate = false;
if (source_isolate_group != nullptr) {
- I->isolate_object_store()->Init();
- I->isolate_object_store()->PreallocateObjects();
-
// If a static field gets registered in [IsolateGroup::RegisterStaticField]:
//
// * before this block it will ignore this isolate. The [Clone] of the
@@ -938,16 +935,16 @@
I->set_ic_miss_code(StubCode::SwitchableCallMiss());
- if ((snapshot_data == NULL) || (kernel_buffer != NULL)) {
- Error& error = Error::Handle();
+ Error& error = Error::Handle();
+ if (snapshot_data == nullptr || kernel_buffer != nullptr) {
error ^= IG->object_store()->PreallocateObjects();
if (!error.IsNull()) {
return error.ptr();
}
- error ^= I->isolate_object_store()->PreallocateObjects();
- if (!error.IsNull()) {
- return error.ptr();
- }
+ }
+ error ^= I->isolate_object_store()->PreallocateObjects();
+ if (!error.IsNull()) {
+ return error.ptr();
}
if (!was_child_cloned_into_existing_isolate) {
@@ -983,11 +980,9 @@
return Error::null();
}
-const char* Dart::FeaturesString(Isolate* isolate,
+const char* Dart::FeaturesString(IsolateGroup* isolate_group,
bool is_vm_isolate,
Snapshot::Kind kind) {
- auto isolate_group = isolate != nullptr ? isolate->group() : nullptr;
-
TextBuffer buffer(64);
// Different fields are included for DEBUG/RELEASE/PRODUCT.
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index b7406c1..fa95787 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -101,7 +101,7 @@
static uword AllocateReadOnlyHandle();
static bool IsReadOnlyHandle(uword address);
- static const char* FeaturesString(Isolate* isolate,
+ static const char* FeaturesString(IsolateGroup* isolate_group,
bool is_vm_snapshot,
Snapshot::Kind kind);
static Snapshot::Kind vm_snapshot_kind() { return vm_snapshot_kind_; }
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 9757a28..2422e51 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -1210,13 +1210,14 @@
}
}
-WritableCodePages::WritableCodePages(Thread* thread, Isolate* isolate)
- : StackResource(thread), isolate_(isolate) {
- isolate_->group()->heap()->WriteProtectCode(false);
+WritableCodePages::WritableCodePages(Thread* thread,
+ IsolateGroup* isolate_group)
+ : StackResource(thread), isolate_group_(isolate_group) {
+ isolate_group_->heap()->WriteProtectCode(false);
}
WritableCodePages::~WritableCodePages() {
- isolate_->group()->heap()->WriteProtectCode(true);
+ isolate_group_->heap()->WriteProtectCode(true);
}
} // namespace dart
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index ac1f0ff..6ec7705 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -484,11 +484,11 @@
class WritableCodePages : StackResource {
public:
- explicit WritableCodePages(Thread* thread, Isolate* isolate);
+ WritableCodePages(Thread* thread, IsolateGroup* isolate_group);
~WritableCodePages();
private:
- Isolate* isolate_;
+ IsolateGroup* isolate_group_;
};
#if defined(TESTING)
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3799f2c..5b8ffb7 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -905,8 +905,8 @@
}
#if defined(DEBUG)
-void Isolate::ValidateClassTable() {
- group()->class_table()->Validate();
+void IsolateGroup::ValidateClassTable() {
+ class_table()->Validate();
}
#endif // DEBUG
@@ -1918,10 +1918,11 @@
return Api::UnwrapHandle(api_result);
}
-void Isolate::SetupImagePage(const uint8_t* image_buffer, bool is_executable) {
+void IsolateGroup::SetupImagePage(const uint8_t* image_buffer,
+ bool is_executable) {
Image image(image_buffer);
- group()->heap()->SetupImagePage(image.object_start(), image.object_size(),
- is_executable);
+ heap()->SetupImagePage(image.object_start(), image.object_size(),
+ is_executable);
}
void Isolate::ScheduleInterrupts(uword interrupt_bits) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 1ec4245..b73263d 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -344,6 +344,7 @@
void RehashConstants();
#if defined(DEBUG)
void ValidateConstants();
+ void ValidateClassTable();
#endif
IsolateGroupSource* source() const { return source_.get(); }
@@ -384,6 +385,7 @@
SafepointHandler* safepoint_handler() { return safepoint_handler_.get(); }
void CreateHeap(bool is_vm_isolate, bool is_service_or_kernel_isolate);
+ void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
void Shutdown();
#define ISOLATE_METRIC_ACCESSOR(type, variable, name, unit) \
@@ -979,9 +981,6 @@
// Register a newly introduced class.
void RegisterClass(const Class& cls);
-#if defined(DEBUG)
- void ValidateClassTable();
-#endif
ThreadRegistry* thread_registry() const { return group()->thread_registry(); }
@@ -1100,8 +1099,6 @@
}
ObjectPtr CallDeferredLoadHandler(intptr_t id);
- void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
-
void ScheduleInterrupts(uword interrupt_bits);
const char* MakeRunnable();
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 5202079..f90b098 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -710,7 +710,8 @@
return NULL;
}
-ApiErrorPtr SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
+ApiErrorPtr SnapshotReader::VerifyVersionAndFeatures(
+ IsolateGroup* isolate_group) {
// If the version string doesn't match, return an error.
// Note: New things are allocated only if we're going to return an error.
@@ -747,7 +748,8 @@
}
Advance(version_len);
- const char* expected_features = Dart::FeaturesString(isolate, false, kind_);
+ const char* expected_features =
+ Dart::FeaturesString(isolate_group, false, kind_);
ASSERT(expected_features != NULL);
const intptr_t expected_len = strlen(expected_features);
@@ -1566,7 +1568,7 @@
WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
const char* expected_features =
- Dart::FeaturesString(Isolate::Current(), false, kind_);
+ Dart::FeaturesString(IsolateGroup::Current(), false, kind_);
ASSERT(expected_features != NULL);
const intptr_t features_len = strlen(expected_features);
WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index d526847..8ad3cb1 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -289,7 +289,7 @@
Object* GetBackRef(intptr_t id);
// Read version number of snapshot and verify.
- ApiErrorPtr VerifyVersionAndFeatures(Isolate* isolate);
+ ApiErrorPtr VerifyVersionAndFeatures(IsolateGroup* isolate_group);
ObjectPtr NewInteger(int64_t value);