Version 2.12.0-274.0.dev
Merge commit '27deca1457ad6b79eb3d22f16ab45b30b754e2eb' into 'dev'
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 2579d39..b960315 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -441,6 +441,11 @@
CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
errorNode,
);
+ } else if (errorNode is BlockFunctionBody) {
+ errorReporter.reportErrorForToken(
+ CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
+ errorNode.block.leftBracket,
+ );
} else {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
diff --git a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
index b366a0d..b46c519 100644
--- a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
@@ -171,23 +171,23 @@
test_functionExpression_future_int_blockBody_async() async {
await assertErrorsInCode(r'''
-main() {
+void f() {
Future<int> Function() foo = () async {};
foo;
}
''', [
- error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 43, 8),
+ error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 51, 1),
]);
}
test_functionExpression_future_void_blockBody() async {
await assertErrorsInCode(r'''
-main() {
+void f() {
Future<void> Function() foo = () {};
foo;
}
''', [
- error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 44, 2),
+ error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 46, 1),
]);
}
@@ -202,13 +202,13 @@
test_functionExpression_notNullable_blockBody() async {
await assertErrorsInCode(r'''
-main() {
+void f() {
int Function() foo = () {
};
foo;
}
''', [
- error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 35, 5),
+ error(CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY, 37, 1),
]);
}
diff --git a/runtime/tests/vm/dart/split_literals.dart b/runtime/tests/vm/dart/split_literals.dart
deleted file mode 100644
index b71e9bd..0000000
--- a/runtime/tests/vm/dart/split_literals.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "split_literals_deferred.dart" deferred as lib;
-
-class Box {
- final contents;
- const Box(this.contents);
- String toString() => "Box($contents)";
-}
-
-main() async {
- print("Root literal!");
- print(const <String>["Root literal in a list!"]);
- print(const <String, String>{"key": "Root literal in a map!"});
- print(const Box("Root literal in a box!"));
-
- await lib.loadLibrary();
- lib.foo();
-}
diff --git a/runtime/tests/vm/dart/split_literals_deferred.dart b/runtime/tests/vm/dart/split_literals_deferred.dart
deleted file mode 100644
index 015ae1d..0000000
--- a/runtime/tests/vm/dart/split_literals_deferred.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "split_literals.dart";
-
-void foo() {
- print("Deferred literal!");
- print(const <String>["Deferred literal in a list!"]);
- print(const <String, String>{"key": "Deferred literal in a map!"});
- print(const Box("Deferred literal in a box!"));
-}
diff --git a/runtime/tests/vm/dart/split_literals_test.dart b/runtime/tests/vm/dart/split_literals_test.dart
deleted file mode 100644
index 6cbc01b..0000000
--- a/runtime/tests/vm/dart/split_literals_test.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:convert";
-import "dart:io";
-
-import "package:expect/expect.dart";
-import "package:path/path.dart" as path;
-
-import "use_flag_test_helper.dart";
-
-main(List<String> args) async {
- if (!isAOTRuntime) {
- return; // Running in JIT: AOT binaries not available.
- }
-
- if (Platform.isAndroid) {
- return; // SDK tree not available on the test device.
- }
-
- // These are the tools we need to be available to run on a given platform:
- if (!File(platformDill).existsSync()) {
- throw "Cannot run test as $platformDill does not exist";
- }
- if (!await testExecutable(genSnapshot)) {
- throw "Cannot run test as $genSnapshot not available";
- }
-
- sanitizedPartitioning(manifest) {
- // Filter core libraries, relativize URIs, and sort to make the results less
- // sensitive to compiler or test harness changes.
- print(manifest);
- var units = <List<String>>[];
- for (var unit in manifest['loadingUnits']) {
- var uris = <String>[];
- for (var uri in unit['libraries']) {
- if (uri.startsWith("dart:")) continue;
- uris.add(Uri.parse(uri).pathSegments.last);
- }
- uris.sort((a, b) => a.compareTo(b));
- units.add(uris);
- }
- units.sort((a, b) => a.first.compareTo(b.first));
- print(units);
- return units;
- }
-
- await withTempDir("split-literals-test", (String tempDir) async {
- final source =
- path.join(sdkDir, "runtime/tests/vm/dart_2/split_literals.dart");
- final dill = path.join(tempDir, "split_literals.dart.dill");
- final snapshot = path.join(tempDir, "split_literals.so");
- final manifest = path.join(tempDir, "split_literals.txt");
- final deferredSnapshot = snapshot + "-2.part.so";
-
- // Compile source to kernel.
- await run(genKernel, <String>[
- "--aot",
- "--platform=$platformDill",
- "-o",
- dill,
- source,
- ]);
-
- // Compile kernel to ELF.
- await run(genSnapshot, <String>[
- "--use_bare_instructions=false", //# object: ok
- "--use_bare_instructions=true", //# bare: ok
- "--snapshot-kind=app-aot-elf",
- "--elf=$snapshot",
- "--loading-unit-manifest=$manifest",
- dill,
- ]);
- var manifestContent = jsonDecode(await new File(manifest).readAsString());
- Expect.equals(2, manifestContent["loadingUnits"].length);
- // Note package:expect doesn't do deep equals on collections.
- Expect.equals(
- "[[split_literals.dart],"
- " [split_literals_deferred.dart]]",
- sanitizedPartitioning(manifestContent).toString());
- Expect.isTrue(await new File(deferredSnapshot).exists());
-
- bool containsSubsequence(haystack, needle) {
- outer:
- for (var i = 0, n = haystack.length - needle.length; i < n; i++) {
- for (var j = 0; j < needle.length; j++) {
- if (haystack[i + j] != needle.codeUnitAt(j)) continue outer;
- }
- return true;
- }
- return false;
- }
-
- var unit_1 = await new File(snapshot).readAsBytes();
- Expect.isTrue(containsSubsequence(unit_1, "Root literal!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a list!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a map!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a box!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a list!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a map!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a box!"));
-
- var unit_2 = await new File(deferredSnapshot).readAsBytes();
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a list!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a map!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a box!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a list!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a map!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a box!"));
- });
-}
diff --git a/runtime/tests/vm/dart_2/split_literals.dart b/runtime/tests/vm/dart_2/split_literals.dart
deleted file mode 100644
index b71e9bd..0000000
--- a/runtime/tests/vm/dart_2/split_literals.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "split_literals_deferred.dart" deferred as lib;
-
-class Box {
- final contents;
- const Box(this.contents);
- String toString() => "Box($contents)";
-}
-
-main() async {
- print("Root literal!");
- print(const <String>["Root literal in a list!"]);
- print(const <String, String>{"key": "Root literal in a map!"});
- print(const Box("Root literal in a box!"));
-
- await lib.loadLibrary();
- lib.foo();
-}
diff --git a/runtime/tests/vm/dart_2/split_literals_deferred.dart b/runtime/tests/vm/dart_2/split_literals_deferred.dart
deleted file mode 100644
index 015ae1d..0000000
--- a/runtime/tests/vm/dart_2/split_literals_deferred.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "split_literals.dart";
-
-void foo() {
- print("Deferred literal!");
- print(const <String>["Deferred literal in a list!"]);
- print(const <String, String>{"key": "Deferred literal in a map!"});
- print(const Box("Deferred literal in a box!"));
-}
diff --git a/runtime/tests/vm/dart_2/split_literals_test.dart b/runtime/tests/vm/dart_2/split_literals_test.dart
deleted file mode 100644
index 6cbc01b..0000000
--- a/runtime/tests/vm/dart_2/split_literals_test.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:convert";
-import "dart:io";
-
-import "package:expect/expect.dart";
-import "package:path/path.dart" as path;
-
-import "use_flag_test_helper.dart";
-
-main(List<String> args) async {
- if (!isAOTRuntime) {
- return; // Running in JIT: AOT binaries not available.
- }
-
- if (Platform.isAndroid) {
- return; // SDK tree not available on the test device.
- }
-
- // These are the tools we need to be available to run on a given platform:
- if (!File(platformDill).existsSync()) {
- throw "Cannot run test as $platformDill does not exist";
- }
- if (!await testExecutable(genSnapshot)) {
- throw "Cannot run test as $genSnapshot not available";
- }
-
- sanitizedPartitioning(manifest) {
- // Filter core libraries, relativize URIs, and sort to make the results less
- // sensitive to compiler or test harness changes.
- print(manifest);
- var units = <List<String>>[];
- for (var unit in manifest['loadingUnits']) {
- var uris = <String>[];
- for (var uri in unit['libraries']) {
- if (uri.startsWith("dart:")) continue;
- uris.add(Uri.parse(uri).pathSegments.last);
- }
- uris.sort((a, b) => a.compareTo(b));
- units.add(uris);
- }
- units.sort((a, b) => a.first.compareTo(b.first));
- print(units);
- return units;
- }
-
- await withTempDir("split-literals-test", (String tempDir) async {
- final source =
- path.join(sdkDir, "runtime/tests/vm/dart_2/split_literals.dart");
- final dill = path.join(tempDir, "split_literals.dart.dill");
- final snapshot = path.join(tempDir, "split_literals.so");
- final manifest = path.join(tempDir, "split_literals.txt");
- final deferredSnapshot = snapshot + "-2.part.so";
-
- // Compile source to kernel.
- await run(genKernel, <String>[
- "--aot",
- "--platform=$platformDill",
- "-o",
- dill,
- source,
- ]);
-
- // Compile kernel to ELF.
- await run(genSnapshot, <String>[
- "--use_bare_instructions=false", //# object: ok
- "--use_bare_instructions=true", //# bare: ok
- "--snapshot-kind=app-aot-elf",
- "--elf=$snapshot",
- "--loading-unit-manifest=$manifest",
- dill,
- ]);
- var manifestContent = jsonDecode(await new File(manifest).readAsString());
- Expect.equals(2, manifestContent["loadingUnits"].length);
- // Note package:expect doesn't do deep equals on collections.
- Expect.equals(
- "[[split_literals.dart],"
- " [split_literals_deferred.dart]]",
- sanitizedPartitioning(manifestContent).toString());
- Expect.isTrue(await new File(deferredSnapshot).exists());
-
- bool containsSubsequence(haystack, needle) {
- outer:
- for (var i = 0, n = haystack.length - needle.length; i < n; i++) {
- for (var j = 0; j < needle.length; j++) {
- if (haystack[i + j] != needle.codeUnitAt(j)) continue outer;
- }
- return true;
- }
- return false;
- }
-
- var unit_1 = await new File(snapshot).readAsBytes();
- Expect.isTrue(containsSubsequence(unit_1, "Root literal!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a list!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a map!"));
- Expect.isTrue(containsSubsequence(unit_1, "Root literal in a box!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a list!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a map!"));
- Expect.isTrue(!containsSubsequence(unit_1, "Deferred literal in a box!"));
-
- var unit_2 = await new File(deferredSnapshot).readAsBytes();
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a list!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a map!"));
- Expect.isTrue(!containsSubsequence(unit_2, "Root literal in a box!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a list!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a map!"));
- Expect.isTrue(containsSubsequence(unit_2, "Deferred literal in a box!"));
- });
-}
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 12ec76e..ef22f90 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -289,7 +289,7 @@
ClassDeserializationCluster() : DeserializationCluster("Class") {}
~ClassDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
predefined_start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
intptr_t count = d->ReadUnsigned();
@@ -311,7 +311,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
ClassTable* table = d->isolate_group()->class_table();
for (intptr_t id = predefined_start_index_; id < predefined_stop_index_;
@@ -464,7 +464,7 @@
: DeserializationCluster("TypeArguments") {}
~TypeArgumentsDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -476,13 +476,13 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
TypeArguments::InstanceSize(length),
- stamp_canonical);
+ is_canonical);
type_args->untag()->length_ = Smi::New(length);
type_args->untag()->hash_ = Smi::New(d->Read<int32_t>());
type_args->untag()->nullability_ = Smi::New(d->ReadUnsigned());
@@ -494,15 +494,22 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- Thread* thread = Thread::Current();
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalTypeArgumentsSet table(
+ d->zone(),
+ d->isolate_group()->object_store()->canonical_type_arguments());
TypeArguments& type_arg = TypeArguments::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
type_arg ^= refs.At(i);
- type_arg = type_arg.Canonicalize(thread, nullptr);
- refs.SetAt(i, type_arg);
+ ASSERT(type_arg.IsCanonical());
+ bool present = table.Insert(type_arg);
+ // Two recursive types with different topology (and hashes) may be
+ // equal.
+ ASSERT(!present || type_arg.IsRecursive());
}
+ d->isolate_group()->object_store()->set_canonical_type_arguments(
+ table.Release());
}
}
};
@@ -551,7 +558,7 @@
PatchClassDeserializationCluster() : DeserializationCluster("PatchClass") {}
~PatchClassDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -562,8 +569,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
PatchClassPtr cls = static_cast<PatchClassPtr>(d->Ref(id));
Deserializer::InitializeHeader(cls, kPatchClassCid,
@@ -661,7 +667,7 @@
FunctionDeserializationCluster() : DeserializationCluster("Function") {}
~FunctionDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -671,8 +677,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
Snapshot::Kind kind = d->kind();
for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -720,7 +725,7 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
if (d->kind() == Snapshot::kFullAOT) {
Function& func = Function::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
@@ -811,7 +816,7 @@
ClosureDataDeserializationCluster() : DeserializationCluster("ClosureData") {}
~ClosureDataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -822,8 +827,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ClosureDataPtr data = static_cast<ClosureDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kClosureDataCid,
@@ -893,7 +897,7 @@
: DeserializationCluster("FfiTrampolineData") {}
~FfiTrampolineDataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -904,8 +908,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kFfiTrampolineDataCid,
@@ -1012,7 +1015,7 @@
FieldDeserializationCluster() : DeserializationCluster("Field") {}
~FieldDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1022,8 +1025,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
Snapshot::Kind kind = d->kind();
for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -1079,7 +1081,7 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
Field& field = Field::Handle(d->zone());
if (!IsolateGroup::Current()->use_field_guards()) {
for (intptr_t i = start_index_; i < stop_index_; i++) {
@@ -1155,7 +1157,7 @@
ScriptDeserializationCluster() : DeserializationCluster("Script") {}
~ScriptDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1165,8 +1167,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ScriptPtr script = static_cast<ScriptPtr>(d->Ref(id));
Deserializer::InitializeHeader(script, kScriptCid,
@@ -1231,7 +1232,7 @@
LibraryDeserializationCluster() : DeserializationCluster("Library") {}
~LibraryDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1241,8 +1242,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
LibraryPtr lib = static_cast<LibraryPtr>(d->Ref(id));
Deserializer::InitializeHeader(lib, kLibraryCid, Library::InstanceSize());
@@ -1304,7 +1304,7 @@
NamespaceDeserializationCluster() : DeserializationCluster("Namespace") {}
~NamespaceDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1314,8 +1314,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
NamespacePtr ns = static_cast<NamespacePtr>(d->Ref(id));
Deserializer::InitializeHeader(ns, kNamespaceCid,
@@ -1371,7 +1370,7 @@
: DeserializationCluster("KernelProgramInfo") {}
~KernelProgramInfoDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1382,8 +1381,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
KernelProgramInfoPtr info = static_cast<KernelProgramInfoPtr>(d->Ref(id));
Deserializer::InitializeHeader(info, kKernelProgramInfoCid,
@@ -1393,7 +1391,7 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
Array& array = Array::Handle(d->zone());
KernelProgramInfo& info = KernelProgramInfo::Handle(d->zone());
for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -1419,26 +1417,9 @@
objects_.Add(code);
}
- if (s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions) {
- if (FLAG_retain_function_objects) {
- ObjectPoolPtr pool = code->untag()->object_pool_;
- if ((pool != ObjectPool::null()) && s->InCurrentLoadingUnit(code)) {
- const intptr_t length = pool->untag()->length_;
- uint8_t* entry_bits = pool->untag()->entry_bits();
- for (intptr_t i = 0; i < length; i++) {
- auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
- if (entry_type == ObjectPool::EntryType::kTaggedObject) {
- s->Push(pool->untag()->data()[i].raw_obj_);
- }
- }
- }
- }
- } else {
- if (s->InCurrentLoadingUnit(code->untag()->object_pool_)) {
- s->Push(code->untag()->object_pool_);
- }
+ if (!(s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
+ s->Push(code->untag()->object_pool_);
}
-
s->Push(code->untag()->owner_);
s->Push(code->untag()->exception_handlers_);
s->Push(code->untag()->pc_descriptors_);
@@ -1550,6 +1531,20 @@
}
void WriteAlloc(Serializer* s) {
+ Sort(&objects_);
+ auto loading_units = s->loading_units();
+ if (loading_units != nullptr) {
+ for (intptr_t i = LoadingUnit::kRootId + 1; i < loading_units->length();
+ i++) {
+ auto unit_objects = loading_units->At(i)->deferred_objects();
+ Sort(unit_objects);
+ for (intptr_t j = 0; j < unit_objects->length(); j++) {
+ deferred_objects_.Add(unit_objects->At(j)->ptr());
+ }
+ }
+ }
+ s->PrepareInstructions(&objects_);
+
s->WriteCid(kCodeCid);
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
@@ -1610,11 +1605,7 @@
// No need to write object pool out if we are producing full AOT
// snapshot with bare instructions.
if (!(kind == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
- if (s->InCurrentLoadingUnit(code->untag()->object_pool_)) {
- WriteField(code, object_pool_);
- } else {
- WriteFieldValue(object_pool_, ObjectPool::null());
- }
+ WriteField(code, object_pool_);
#if defined(DART_PRECOMPILER)
} else if (FLAG_write_v8_snapshot_profile_to != nullptr &&
code->untag()->object_pool_ != ObjectPool::null()) {
@@ -1695,8 +1686,7 @@
s->Write<int32_t>(code->untag()->state_bits_);
}
- GrowableArray<CodePtr>* objects() { return &objects_; }
- GrowableArray<CodePtr>* deferred_objects() { return &deferred_objects_; }
+ GrowableArray<CodePtr>* discovered_objects() { return &objects_; }
// Some code objects would have their owners dropped from the snapshot,
// which makes it is impossible to recover program structure when
@@ -1742,7 +1732,7 @@
CodeDeserializationCluster() : DeserializationCluster("Code") {}
~CodeDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
PageSpace* old_space = d->heap()->old_space();
start_index_ = d->next_index();
const intptr_t count = d->ReadUnsigned();
@@ -1760,8 +1750,7 @@
deferred_stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ReadFill(d, id, false);
}
@@ -1816,7 +1805,7 @@
code->untag()->state_bits_ = d->Read<int32_t>();
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
d->EndInstructions(refs, start_index_, stop_index_);
#if !defined(PRODUCT)
@@ -1864,17 +1853,12 @@
ObjectPoolPtr pool = ObjectPool::RawCast(object);
objects_.Add(pool);
- if (s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions &&
- FLAG_retain_function_objects) {
- // Treat pool as weak.
- } else {
- const intptr_t length = pool->untag()->length_;
- uint8_t* entry_bits = pool->untag()->entry_bits();
- for (intptr_t i = 0; i < length; i++) {
- auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
- if (entry_type == ObjectPool::EntryType::kTaggedObject) {
- s->Push(pool->untag()->data()[i].raw_obj_);
- }
+ const intptr_t length = pool->untag()->length_;
+ uint8_t* entry_bits = pool->untag()->entry_bits();
+ for (intptr_t i = 0; i < length; i++) {
+ auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
+ if (entry_type == ObjectPool::EntryType::kTaggedObject) {
+ s->Push(pool->untag()->data()[i].raw_obj_);
}
}
}
@@ -1893,9 +1877,6 @@
}
void WriteFill(Serializer* s) {
- bool weak = s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions &&
- FLAG_retain_function_objects;
-
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
ObjectPoolPtr pool = objects_[i];
@@ -1916,12 +1897,7 @@
s->WriteElementRef(StubCode::CallBootstrapNative().ptr(), j);
break;
}
- if (weak && !s->HasRef(entry.raw_obj_)) {
- // Any value will do, but null has the shortest id.
- s->WriteElementRef(Object::null(), j);
- } else {
- s->WriteElementRef(entry.raw_obj_, j);
- }
+ s->WriteElementRef(entry.raw_obj_, j);
break;
}
case ObjectPool::EntryType::kImmediate: {
@@ -1950,7 +1926,7 @@
ObjectPoolDeserializationCluster() : DeserializationCluster("ObjectPool") {}
~ObjectPoolDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -1962,10 +1938,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
- fill_position_ = d->position();
-
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
const intptr_t length = d->ReadUnsigned();
ObjectPoolPtr pool = static_cast<ObjectPoolPtr>(d->Ref(id + 0));
@@ -1995,41 +1968,6 @@
}
}
}
-
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- intptr_t restore_position = d->position();
- d->set_position(fill_position_);
-
- ObjectPool& pool = ObjectPool::Handle();
- Object& entry = Object::Handle();
- for (intptr_t id = start_index_; id < stop_index_; id += 1) {
- pool ^= refs.At(id);
- const intptr_t length = d->ReadUnsigned();
- for (intptr_t j = 0; j < length; j++) {
- const uint8_t entry_bits = d->Read<uint8_t>();
- switch (ObjectPool::TypeBits::decode(entry_bits)) {
- case ObjectPool::EntryType::kTaggedObject:
- entry = refs.At(d->ReadUnsigned());
- pool.SetObjectAt(j, entry);
- break;
- case ObjectPool::EntryType::kImmediate:
- d->Read<intptr_t>();
- break;
- case ObjectPool::EntryType::kNativeFunction: {
- // Read nothing.
- break;
- }
- default:
- UNREACHABLE();
- }
- }
- }
-
- d->set_position(restore_position);
- }
-
- private:
- intptr_t fill_position_ = 0;
};
#if defined(DART_PRECOMPILER)
@@ -2152,7 +2090,7 @@
: DeserializationCluster("WeakSerializationReference") {}
~WeakSerializationReferenceDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2166,8 +2104,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
auto const ref = static_cast<WeakSerializationReferencePtr>(d->Ref(id));
Deserializer::InitializeHeader(
@@ -2226,7 +2163,7 @@
: DeserializationCluster("PcDescriptors") {}
~PcDescriptorsDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2238,8 +2175,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
const intptr_t length = d->ReadUnsigned();
PcDescriptorsPtr desc = static_cast<PcDescriptorsPtr>(d->Ref(id));
@@ -2321,7 +2257,7 @@
: DeserializationCluster("ROData"), cid_(cid) {}
~RODataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
intptr_t count = d->ReadUnsigned();
uint32_t running_offset = 0;
@@ -2332,25 +2268,21 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
// No-op.
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize && IsStringClassId(cid_)) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && IsStringClassId(cid_) &&
+ (d->isolate() != Dart::vm_isolate())) {
CanonicalStringSet table(
d->zone(), d->isolate_group()->object_store()->symbol_table());
String& str = String::Handle(d->zone());
- String& str2 = String::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
str ^= refs.At(i);
- str2 ^= table.InsertOrGet(str);
- if (str.ptr() == str2.ptr()) {
- // str.SetCanonical();
- } else {
- FATAL("Lost canonicalization race");
- refs.SetAt(i, str2);
- }
+ ASSERT(str.IsCanonical());
+ bool present = table.Insert(str);
+ ASSERT(!present);
}
d->isolate_group()->object_store()->set_symbol_table(table.Release());
}
@@ -2417,7 +2349,7 @@
: DeserializationCluster("ExceptionHandlers") {}
~ExceptionHandlersDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2429,8 +2361,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ExceptionHandlersPtr handlers =
static_cast<ExceptionHandlersPtr>(d->Ref(id));
@@ -2506,7 +2437,7 @@
ContextDeserializationCluster() : DeserializationCluster("Context") {}
~ContextDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2518,8 +2449,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ContextPtr context = static_cast<ContextPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
@@ -2584,7 +2514,7 @@
: DeserializationCluster("ContextScope") {}
~ContextScopeDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2596,8 +2526,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ContextScopePtr scope = static_cast<ContextScopePtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
@@ -2653,7 +2582,7 @@
: DeserializationCluster("UnlinkedCall") {}
~UnlinkedCallDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2664,8 +2593,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
UnlinkedCallPtr unlinked = static_cast<UnlinkedCallPtr>(d->Ref(id));
Deserializer::InitializeHeader(unlinked, kUnlinkedCallCid,
@@ -2722,7 +2650,7 @@
ICDataDeserializationCluster() : DeserializationCluster("ICData") {}
~ICDataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2732,8 +2660,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ICDataPtr ic = static_cast<ICDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(ic, kICDataCid, ICData::InstanceSize());
@@ -2788,7 +2715,7 @@
: DeserializationCluster("MegamorphicCache") {}
~MegamorphicCacheDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2799,8 +2726,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
MegamorphicCachePtr cache = static_cast<MegamorphicCachePtr>(d->Ref(id));
Deserializer::InitializeHeader(cache, kMegamorphicCacheCid,
@@ -2811,7 +2737,7 @@
}
#if defined(DART_PRECOMPILED_RUNTIME)
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
if (FLAG_use_bare_instructions) {
// By default, every megamorphic call site will load the target
// [Function] from the hash table and call indirectly via loading the
@@ -2880,7 +2806,7 @@
: DeserializationCluster("SubtypeTestCache") {}
~SubtypeTestCacheDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2891,8 +2817,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
SubtypeTestCachePtr cache = static_cast<SubtypeTestCachePtr>(d->Ref(id));
Deserializer::InitializeHeader(cache, kSubtypeTestCacheCid,
@@ -2944,7 +2869,7 @@
LoadingUnitDeserializationCluster() : DeserializationCluster("LoadingUnit") {}
~LoadingUnitDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -2955,8 +2880,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
LoadingUnitPtr unit = static_cast<LoadingUnitPtr>(d->Ref(id));
Deserializer::InitializeHeader(unit, kLoadingUnitCid,
@@ -3015,7 +2939,7 @@
: DeserializationCluster("LanguageError") {}
~LanguageErrorDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3026,8 +2950,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
LanguageErrorPtr error = static_cast<LanguageErrorPtr>(d->Ref(id));
Deserializer::InitializeHeader(error, kLanguageErrorCid,
@@ -3083,7 +3006,7 @@
: DeserializationCluster("UnhandledException") {}
~UnhandledExceptionDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3094,8 +3017,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
UnhandledExceptionPtr exception =
static_cast<UnhandledExceptionPtr>(d->Ref(id));
@@ -3204,35 +3126,13 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class AbstractInstanceDeserializationCluster : public DeserializationCluster {
- protected:
- explicit AbstractInstanceDeserializationCluster(const char* name)
- : DeserializationCluster(name) {}
-
- public:
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- Thread* thread = Thread::Current();
- SafepointMutexLocker ml(
- thread->isolate_group()->constant_canonicalization_mutex());
- Instance& instance = Instance::Handle(d->zone());
- for (intptr_t i = start_index_; i < stop_index_; i++) {
- instance ^= refs.At(i);
- instance = instance.CanonicalizeLocked(thread);
- refs.SetAt(i, instance);
- }
- }
- }
-};
-
-class InstanceDeserializationCluster
- : public AbstractInstanceDeserializationCluster {
+class InstanceDeserializationCluster : public DeserializationCluster {
public:
explicit InstanceDeserializationCluster(intptr_t cid)
- : AbstractInstanceDeserializationCluster("Instance"), cid_(cid) {}
+ : DeserializationCluster("Instance"), cid_(cid) {}
~InstanceDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3246,7 +3146,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
intptr_t instance_size =
Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
@@ -3255,7 +3155,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
InstancePtr instance = static_cast<InstancePtr>(d->Ref(id));
Deserializer::InitializeHeader(instance, cid_, instance_size,
- stamp_canonical);
+ is_canonical);
intptr_t offset = Instance::NextFieldOffset();
while (offset < next_field_offset) {
if (unboxed_fields_bitmap.Get(offset / kWordSize)) {
@@ -3330,7 +3230,7 @@
: DeserializationCluster("LibraryPrefix") {}
~LibraryPrefixDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3341,8 +3241,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
LibraryPrefixPtr prefix = static_cast<LibraryPrefixPtr>(d->Ref(id));
Deserializer::InitializeHeader(prefix, kLibraryPrefixCid,
@@ -3425,7 +3324,7 @@
TypeDeserializationCluster() : DeserializationCluster("Type") {}
~TypeDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3435,11 +3334,11 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypePtr type = static_cast<TypePtr>(d->Ref(id));
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
- stamp_canonical);
+ is_canonical);
ReadFromTo(type);
const uint8_t combined = d->Read<uint8_t>();
type->untag()->type_state_ = combined >> kNullabilityBitSize;
@@ -3447,15 +3346,20 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- Thread* thread = Thread::Current();
- AbstractType& type = AbstractType::Handle(d->zone());
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalTypeSet table(
+ d->zone(), d->isolate_group()->object_store()->canonical_types());
+ Type& type = Type::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
type ^= refs.At(i);
- type = type.Canonicalize(thread, nullptr);
- refs.SetAt(i, type);
+ ASSERT(type.IsCanonical());
+ bool present = table.Insert(type);
+ // Two recursive types with different topology (and hashes) may be
+ // equal.
+ ASSERT(!present || type.IsRecursive());
}
+ d->isolate_group()->object_store()->set_canonical_types(table.Release());
}
Type& type = Type::Handle(d->zone());
@@ -3536,7 +3440,7 @@
: DeserializationCluster("FunctionType") {}
~FunctionTypeDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3547,12 +3451,11 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
FunctionTypePtr type = static_cast<FunctionTypePtr>(d->Ref(id));
- Deserializer::InitializeHeader(type, kFunctionTypeCid,
- FunctionType::InstanceSize(),
- stamp_canonical);
+ Deserializer::InitializeHeader(
+ type, kFunctionTypeCid, FunctionType::InstanceSize(), is_canonical);
ReadFromTo(type);
const uint8_t combined = d->Read<uint8_t>();
type->untag()->type_state_ = combined >> kNullabilityBitSize;
@@ -3561,15 +3464,22 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- Thread* thread = Thread::Current();
- AbstractType& type = AbstractType::Handle(d->zone());
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalFunctionTypeSet table(
+ d->zone(),
+ d->isolate_group()->object_store()->canonical_function_types());
+ FunctionType& type = FunctionType::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
type ^= refs.At(i);
- type = type.Canonicalize(thread, nullptr);
- refs.SetAt(i, type);
+ ASSERT(type.IsCanonical());
+ bool present = table.Insert(type);
+ // Two recursive types with different topology (and hashes) may be
+ // equal.
+ ASSERT(!present || type.IsRecursive());
}
+ d->isolate_group()->object_store()->set_canonical_function_types(
+ table.Release());
}
FunctionType& type = FunctionType::Handle(d->zone());
@@ -3632,7 +3542,7 @@
TypeRefDeserializationCluster() : DeserializationCluster("TypeRef") {}
~TypeRefDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3642,16 +3552,16 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
- Deserializer::InitializeHeader(type, kTypeRefCid, TypeRef::InstanceSize(),
- stamp_canonical);
+ Deserializer::InitializeHeader(type, kTypeRefCid,
+ TypeRef::InstanceSize());
ReadFromTo(type);
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
TypeRef& type_ref = TypeRef::Handle(d->zone());
Code& stub = Code::Handle(d->zone());
@@ -3731,7 +3641,7 @@
: DeserializationCluster("TypeParameter") {}
~TypeParameterDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3742,12 +3652,11 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
- Deserializer::InitializeHeader(type, kTypeParameterCid,
- TypeParameter::InstanceSize(),
- stamp_canonical);
+ Deserializer::InitializeHeader(
+ type, kTypeParameterCid, TypeParameter::InstanceSize(), is_canonical);
ReadFromTo(type);
type->untag()->parameterized_class_id_ = d->Read<int32_t>();
type->untag()->base_ = d->Read<uint16_t>();
@@ -3758,15 +3667,20 @@
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- Thread* thread = Thread::Current();
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalTypeParameterSet table(
+ d->zone(),
+ d->isolate_group()->object_store()->canonical_type_parameters());
TypeParameter& type_param = TypeParameter::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
type_param ^= refs.At(i);
- type_param ^= type_param.Canonicalize(thread, nullptr);
- refs.SetAt(i, type_param);
+ ASSERT(type_param.IsCanonical());
+ bool present = table.Insert(type_param);
+ ASSERT(!present);
}
+ d->isolate_group()->object_store()->set_canonical_type_parameters(
+ table.Release());
}
TypeParameter& type_param = TypeParameter::Handle(d->zone());
@@ -3825,14 +3739,12 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class ClosureDeserializationCluster
- : public AbstractInstanceDeserializationCluster {
+class ClosureDeserializationCluster : public DeserializationCluster {
public:
- ClosureDeserializationCluster()
- : AbstractInstanceDeserializationCluster("Closure") {}
+ ClosureDeserializationCluster() : DeserializationCluster("Closure") {}
~ClosureDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3842,11 +3754,11 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ClosurePtr closure = static_cast<ClosurePtr>(d->Ref(id));
Deserializer::InitializeHeader(closure, kClosureCid,
- Closure::InstanceSize(), stamp_canonical);
+ Closure::InstanceSize(), is_canonical);
ReadFromTo(closure);
}
}
@@ -3899,7 +3811,7 @@
MintDeserializationCluster() : DeserializationCluster("int") {}
~MintDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
PageSpace* old_space = d->heap()->old_space();
start_index_ = d->next_index();
@@ -3912,7 +3824,7 @@
MintPtr mint = static_cast<MintPtr>(
AllocateUninitialized(old_space, Mint::InstanceSize()));
Deserializer::InitializeHeader(mint, kMintCid, Mint::InstanceSize(),
- stamp_canonical);
+ is_canonical);
mint->untag()->value_ = value;
d->AssignRef(mint);
}
@@ -3920,24 +3832,19 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {}
+ void ReadFill(Deserializer* d, bool is_canonical) {}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
const Class& mint_cls = Class::Handle(
- d->zone(), d->isolate_group()->object_store()->mint_class());
+ d->zone(), IsolateGroup::Current()->object_store()->mint_class());
+ mint_cls.set_constants(Object::null_array());
Object& number = Object::Handle(d->zone());
- Mint& number2 = Mint::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
number = refs.At(i);
- if (!number.IsMint()) continue;
- number2 =
- mint_cls.LookupCanonicalMint(d->zone(), Mint::Cast(number).value());
- if (number2.IsNull()) {
- number.SetCanonical();
+ if (number.IsMint()) {
+ ASSERT(number.IsCanonical());
mint_cls.InsertCanonicalMint(d->zone(), Mint::Cast(number));
- } else {
- refs.SetAt(i, number2);
}
}
}
@@ -3984,7 +3891,7 @@
DoubleDeserializationCluster() : DeserializationCluster("double") {}
~DoubleDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -3994,35 +3901,14 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
DoublePtr dbl = static_cast<DoublePtr>(d->Ref(id));
Deserializer::InitializeHeader(dbl, kDoubleCid, Double::InstanceSize(),
- stamp_canonical);
+ is_canonical);
dbl->untag()->value_ = d->Read<double>();
}
}
-
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- const Class& cls = Class::Handle(
- d->zone(), d->isolate_group()->object_store()->double_class());
- SafepointMutexLocker ml(
- d->isolate_group()->constant_canonicalization_mutex());
- Double& dbl = Double::Handle(d->zone());
- Double& dbl2 = Double::Handle(d->zone());
- for (intptr_t i = start_index_; i < stop_index_; i++) {
- dbl ^= refs.At(i);
- dbl2 = cls.LookupCanonicalDouble(d->zone(), dbl.value());
- if (dbl2.IsNull()) {
- dbl.SetCanonical();
- cls.InsertCanonicalDouble(d->zone(), dbl);
- } else {
- refs.SetAt(i, dbl2);
- }
- }
- }
- }
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -4069,7 +3955,7 @@
: DeserializationCluster("GrowableObjectArray") {}
~GrowableObjectArrayDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4080,13 +3966,13 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
GrowableObjectArrayPtr list =
static_cast<GrowableObjectArrayPtr>(d->Ref(id));
Deserializer::InitializeHeader(list, kGrowableObjectArrayCid,
GrowableObjectArray::InstanceSize(),
- stamp_canonical);
+ is_canonical);
ReadFromTo(list);
}
}
@@ -4142,7 +4028,7 @@
: DeserializationCluster("TypedData"), cid_(cid) {}
~TypedDataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4155,17 +4041,15 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypedDataPtr data = static_cast<TypedDataPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
const intptr_t length_in_bytes = length * element_size;
- Deserializer::InitializeHeader(data, cid_,
- TypedData::InstanceSize(length_in_bytes),
- stamp_canonical);
+ Deserializer::InitializeHeader(
+ data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
data->untag()->length_ = Smi::New(length);
data->untag()->RecomputeDataField();
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data());
@@ -4222,7 +4106,7 @@
: DeserializationCluster("TypedDataView"), cid_(cid) {}
~TypedDataViewDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4233,17 +4117,16 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
- Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize());
+ Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize(),
+ is_canonical);
ReadFromTo(view);
}
}
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- ASSERT(!canonicalize);
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
auto& view = TypedDataView::Handle(d->zone());
for (intptr_t id = start_index_; id < stop_index_; id++) {
view ^= refs.At(id);
@@ -4303,7 +4186,7 @@
: DeserializationCluster("ExternalTypedData"), cid_(cid) {}
~ExternalTypedDataDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4314,8 +4197,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -4376,7 +4258,7 @@
StackTraceDeserializationCluster() : DeserializationCluster("StackTrace") {}
~StackTraceDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4387,8 +4269,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
StackTracePtr trace = static_cast<StackTracePtr>(d->Ref(id));
Deserializer::InitializeHeader(trace, kStackTraceCid,
@@ -4442,7 +4323,7 @@
RegExpDeserializationCluster() : DeserializationCluster("RegExp") {}
~RegExpDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4452,8 +4333,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RegExpPtr regexp = static_cast<RegExpPtr>(d->Ref(id));
Deserializer::InitializeHeader(regexp, kRegExpCid,
@@ -4508,7 +4388,7 @@
: DeserializationCluster("WeakProperty") {}
~WeakPropertyDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4519,8 +4399,7 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
- ASSERT(!stamp_canonical); // Never canonical.
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d->Ref(id));
Deserializer::InitializeHeader(property, kWeakPropertyCid,
@@ -4599,14 +4478,13 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class LinkedHashMapDeserializationCluster
- : public AbstractInstanceDeserializationCluster {
+class LinkedHashMapDeserializationCluster : public DeserializationCluster {
public:
LinkedHashMapDeserializationCluster()
- : AbstractInstanceDeserializationCluster("LinkedHashMap") {}
+ : DeserializationCluster("LinkedHashMap") {}
~LinkedHashMapDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4617,14 +4495,13 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
PageSpace* old_space = d->heap()->old_space();
for (intptr_t id = start_index_; id < stop_index_; id++) {
LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
- Deserializer::InitializeHeader(map, kLinkedHashMapCid,
- LinkedHashMap::InstanceSize(),
- stamp_canonical);
+ Deserializer::InitializeHeader(
+ map, kLinkedHashMapCid, LinkedHashMap::InstanceSize(), is_canonical);
map->untag()->type_arguments_ =
static_cast<TypeArgumentsPtr>(d->ReadRef());
@@ -4708,14 +4585,13 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class ArrayDeserializationCluster
- : public AbstractInstanceDeserializationCluster {
+class ArrayDeserializationCluster : public DeserializationCluster {
public:
explicit ArrayDeserializationCluster(intptr_t cid)
- : AbstractInstanceDeserializationCluster("Array"), cid_(cid) {}
+ : DeserializationCluster("Array"), cid_(cid) {}
~ArrayDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4727,12 +4603,12 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
- stamp_canonical);
+ is_canonical);
array->untag()->type_arguments_ =
static_cast<TypeArgumentsPtr>(d->ReadRef());
array->untag()->length_ = Smi::New(length);
@@ -4787,40 +4663,13 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class StringDeserializationCluster : public DeserializationCluster {
- protected:
- explicit StringDeserializationCluster(const char* name)
- : DeserializationCluster(name) {}
-
- public:
- void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
- if (canonicalize) {
- CanonicalStringSet table(
- d->zone(), d->isolate_group()->object_store()->symbol_table());
- String& str = String::Handle(d->zone());
- String& str2 = String::Handle(d->zone());
- for (intptr_t i = start_index_; i < stop_index_; i++) {
- str ^= refs.At(i);
- str2 ^= table.InsertOrGet(str);
- if (str.ptr() == str2.ptr()) {
- str.SetCanonical();
- } else {
- refs.SetAt(i, str2);
- }
- }
- d->isolate_group()->object_store()->set_symbol_table(table.Release());
- }
- }
-};
-
-class OneByteStringDeserializationCluster
- : public StringDeserializationCluster {
+class OneByteStringDeserializationCluster : public DeserializationCluster {
public:
OneByteStringDeserializationCluster()
- : StringDeserializationCluster("OneByteString") {}
+ : DeserializationCluster("OneByteString") {}
~OneByteStringDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4832,13 +4681,13 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
OneByteStringPtr str = static_cast<OneByteStringPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(str, kOneByteStringCid,
OneByteString::InstanceSize(length),
- stamp_canonical);
+ is_canonical);
str->untag()->length_ = Smi::New(length);
StringHasher hasher;
for (intptr_t j = 0; j < length; j++) {
@@ -4849,6 +4698,21 @@
String::SetCachedHash(str, hasher.Finalize());
}
}
+
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalStringSet table(
+ d->zone(), d->isolate_group()->object_store()->symbol_table());
+ String& str = String::Handle(d->zone());
+ for (intptr_t i = start_index_; i < stop_index_; i++) {
+ str ^= refs.At(i);
+ ASSERT(str.IsCanonical());
+ bool present = table.Insert(str);
+ ASSERT(!present);
+ }
+ d->isolate_group()->object_store()->set_symbol_table(table.Release());
+ }
+ }
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -4893,14 +4757,13 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
-class TwoByteStringDeserializationCluster
- : public StringDeserializationCluster {
+class TwoByteStringDeserializationCluster : public DeserializationCluster {
public:
TwoByteStringDeserializationCluster()
- : StringDeserializationCluster("TwoByteString") {}
+ : DeserializationCluster("TwoByteString") {}
~TwoByteStringDeserializationCluster() {}
- void ReadAlloc(Deserializer* d, bool stamp_canonical) {
+ void ReadAlloc(Deserializer* d, bool is_canonical) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
const intptr_t count = d->ReadUnsigned();
@@ -4912,13 +4775,13 @@
stop_index_ = d->next_index();
}
- void ReadFill(Deserializer* d, bool stamp_canonical) {
+ void ReadFill(Deserializer* d, bool is_canonical) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
TwoByteStringPtr str = static_cast<TwoByteStringPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(str, kTwoByteStringCid,
TwoByteString::InstanceSize(length),
- stamp_canonical);
+ is_canonical);
str->untag()->length_ = Smi::New(length);
StringHasher hasher;
for (intptr_t j = 0; j < length; j++) {
@@ -4930,6 +4793,21 @@
String::SetCachedHash(str, hasher.Finalize());
}
}
+
+ void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) {
+ if (is_canonical && (d->isolate() != Dart::vm_isolate())) {
+ CanonicalStringSet table(
+ d->zone(), d->isolate_group()->object_store()->symbol_table());
+ String& str = String::Handle(d->zone());
+ for (intptr_t i = start_index_; i < stop_index_; i++) {
+ str ^= refs.At(i);
+ ASSERT(str.IsCanonical());
+ bool present = table.Insert(str);
+ ASSERT(!present);
+ }
+ d->isolate_group()->object_store()->set_symbol_table(table.Release());
+ }
+ }
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -5309,26 +5187,16 @@
const Object* deferred_object = (*unit_->deferred_objects())[i];
ASSERT(deferred_object->IsCode());
CodePtr code = static_cast<CodePtr>(deferred_object->ptr());
- if (FLAG_use_bare_instructions) {
- if (FLAG_retain_function_objects) {
- ObjectPoolPtr pool = code->untag()->object_pool_;
- if (pool != ObjectPool::null()) {
- const intptr_t length = pool->untag()->length_;
- uint8_t* entry_bits = pool->untag()->entry_bits();
- for (intptr_t i = 0; i < length; i++) {
- auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
- if (entry_type == ObjectPool::EntryType::kTaggedObject) {
- s->Push(pool->untag()->data()[i].raw_obj_);
- }
- }
- }
- }
- } else {
- s->Push(code->untag()->object_pool_);
- }
s->Push(code->untag()->compressed_stackmaps_);
s->Push(code->untag()->code_source_map_);
}
+ {
+ GrowableArray<CodePtr> raw_codes(num_deferred_objects);
+ for (intptr_t i = 0; i < num_deferred_objects; i++) {
+ raw_codes.Add((*unit_->deferred_objects())[i]->ptr());
+ }
+ s->PrepareInstructions(&raw_codes);
+ }
}
void WriteRoots(Serializer* s) {
@@ -5348,33 +5216,9 @@
ASSERT(s->RefId(code) == (start_index + i));
s->WriteInstructions(code->untag()->instructions_,
code->untag()->unchecked_offset_, code, false);
- if (!FLAG_use_bare_instructions) {
- s->WriteRootRef(code->untag()->object_pool_, "deferred-code");
- }
s->WriteRootRef(code->untag()->compressed_stackmaps_, "deferred-code");
s->WriteRootRef(code->untag()->code_source_map_, "deferred-code");
}
-
- if (FLAG_use_bare_instructions && FLAG_retain_function_objects) {
- ObjectPoolPtr pool =
- s->isolate_group()->object_store()->global_object_pool();
- const intptr_t length = pool->untag()->length_;
- uint8_t* entry_bits = pool->untag()->entry_bits();
- intptr_t last_write = 0;
- for (intptr_t i = 0; i < length; i++) {
- auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
- if (entry_type == ObjectPool::EntryType::kTaggedObject) {
- if (s->IsWritten(pool->untag()->data()[i].raw_obj_)) {
- intptr_t skip = i - last_write;
- s->WriteUnsigned(skip);
- s->WriteRootRef(pool->untag()->data()[i].raw_obj_,
- "deferred-literal");
- last_write = i;
- }
- }
- }
- s->WriteUnsigned(length - last_write);
- }
#endif
}
@@ -5410,29 +5254,12 @@
ASSERT(unchecked_entry_point != 0);
func->untag()->unchecked_entry_point_ = unchecked_entry_point;
}
- if (!FLAG_use_bare_instructions) {
- code->untag()->object_pool_ = static_cast<ObjectPoolPtr>(d->ReadRef());
- }
code->untag()->compressed_stackmaps_ =
static_cast<CompressedStackMapsPtr>(d->ReadRef());
code->untag()->code_source_map_ =
static_cast<CodeSourceMapPtr>(d->ReadRef());
}
- if (FLAG_use_bare_instructions && FLAG_retain_function_objects) {
- ObjectPoolPtr pool =
- d->isolate_group()->object_store()->global_object_pool();
- const intptr_t length = pool->untag()->length_;
- uint8_t* entry_bits = pool->untag()->entry_bits();
- for (intptr_t i = d->ReadUnsigned(); i < length; i += d->ReadUnsigned()) {
- auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
- ASSERT(entry_type == ObjectPool::EntryType::kTaggedObject);
- // The existing entry will usually be null, but it might also be an
- // equivalent object that was duplicated in another loading unit.
- pool->untag()->data()[i].raw_obj_ = d->ReadRef();
- }
- }
-
// Reinitialize the dispatch table by rereading the table's serialization
// in the root snapshot.
IsolateGroup* group = d->thread()->isolate()->group();
@@ -5845,9 +5672,6 @@
// TODO(41974): Are these always type testing stubs?
unit_id = LoadingUnit::kRootId;
}
- if (unit_id == LoadingUnit::kRootId) {
- return true;
- }
if (unit_id != current_loading_unit_id_) {
if (record) {
(*loading_units_)[unit_id]->AddDeferredObject(static_cast<CodePtr>(obj));
@@ -5858,58 +5682,11 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-void Serializer::PrepareInstructions() {
- if (!Snapshot::IncludesCode(kind())) return;
-
- CodeSerializationCluster* cluster =
- static_cast<CodeSerializationCluster*>(clusters_by_cid_[kCodeCid]);
-
- // Code objects that have identical/duplicate instructions must be adjacent in
- // the order that Code objects are written because the encoding of the
- // reference from the Code to the Instructions assumes monotonically
- // increasing offsets as part of a delta encoding. Also the code order table
- // that allows for mapping return addresses back to Code objects depends on
- // this sorting.
- if (cluster != nullptr) {
- CodeSerializationCluster::Sort(cluster->objects());
- }
- if ((loading_units_ != nullptr) &&
- (current_loading_unit_id_ == LoadingUnit::kRootId)) {
- for (intptr_t i = LoadingUnit::kRootId + 1; i < loading_units_->length();
- i++) {
- auto unit_objects = loading_units_->At(i)->deferred_objects();
- CodeSerializationCluster::Sort(unit_objects);
- for (intptr_t j = 0; j < unit_objects->length(); j++) {
- cluster->deferred_objects()->Add(unit_objects->At(j)->ptr());
- }
- }
- }
-
+void Serializer::PrepareInstructions(GrowableArray<CodePtr>* code_objects) {
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
if ((kind() == Snapshot::kFullAOT) && FLAG_use_bare_instructions) {
- // Group the code objects whose instructions are not being deferred in this
- // snapshot unit in the order they will be written: first the code objects
- // encountered for this first time in this unit being written by the
- // CodeSerializationCluster, then code object previously deferred whose
- // instructions are now written by UnitSerializationRoots. This order needs
- // to be known to finalize bare-instructions-mode's PC-relative calls.
- GrowableArray<CodePtr> code_objects;
- if (cluster != nullptr) {
- auto in = cluster->objects();
- for (intptr_t i = 0; i < in->length(); i++) {
- code_objects.Add(in->At(i));
- }
- }
- if (loading_units_ != nullptr) {
- auto in =
- loading_units_->At(current_loading_unit_id_)->deferred_objects();
- for (intptr_t i = 0; i < in->length(); i++) {
- code_objects.Add(in->At(i)->ptr());
- }
- }
-
GrowableArray<ImageWriterCommand> writer_commands;
- RelocateCodeObjects(vm_, &code_objects, &writer_commands);
+ RelocateCodeObjects(vm_, code_objects, &writer_commands);
image_writer_->PrepareForSerialization(&writer_commands);
}
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
@@ -6117,22 +5894,6 @@
}
GrowableArray<SerializationCluster*> canonical_clusters;
- // The order that PostLoad runs matters for some classes. Explicitly place
- // these clusters first, then add the rest ordered by class id.
-#define ADD_NEXT(cid) \
- if (canonical_clusters_by_cid_[cid] != nullptr) { \
- canonical_clusters.Add(canonical_clusters_by_cid_[cid]); \
- canonical_clusters_by_cid_[cid] = nullptr; \
- }
- ADD_NEXT(kOneByteStringCid)
- ADD_NEXT(kTwoByteStringCid)
- ADD_NEXT(kMintCid)
- ADD_NEXT(kDoubleCid)
- ADD_NEXT(kTypeParameterCid)
- ADD_NEXT(kTypeCid)
- ADD_NEXT(kTypeArgumentsCid)
- ADD_NEXT(kClosureCid)
-#undef ADD_NEXT
for (intptr_t cid = 0; cid < num_cids_; cid++) {
if (canonical_clusters_by_cid_[cid] != nullptr) {
canonical_clusters.Add(canonical_clusters_by_cid_[cid]);
@@ -6159,8 +5920,6 @@
}
#endif
- PrepareInstructions();
-
intptr_t num_objects = num_base_objects_ + num_written_objects_;
#if defined(ARCH_IS_64_BIT)
if (!Utils::IsInt(32, num_objects)) {
@@ -6278,7 +6037,8 @@
ASSERT(code_cluster != nullptr);
// Reference IDs in a cluster are allocated sequentially, so we can use the
// first code object's reference ID to calculate the cluster index.
- const intptr_t first_code_id = RefId(code_cluster->objects()->At(0));
+ const intptr_t first_code_id =
+ RefId(code_cluster->discovered_objects()->At(0));
// The first object in the code cluster must have its reference ID allocated.
ASSERT(IsAllocatedReference(first_code_id));
@@ -6968,17 +6728,18 @@
ASSERT_EQUAL(next_ref_index_ - kFirstReference, num_objects_);
{
- TIMELINE_DURATION(thread(), Isolate, "PostLoad");
+ TIMELINE_DURATION(thread(), Isolate, "ReadFill");
for (intptr_t i = 0; i < num_canonical_clusters_; i++) {
- bool stamp_canonical = isolate() == Dart::vm_isolate();
- canonical_clusters_[i]->ReadFill(this, stamp_canonical);
+ TIMELINE_DURATION(thread(), Isolate, canonical_clusters_[i]->name());
+ canonical_clusters_[i]->ReadFill(this, /*is_canonical*/ true);
#if defined(DEBUG)
int32_t section_marker = Read<int32_t>();
ASSERT(section_marker == kSectionMarker);
#endif
}
for (intptr_t i = 0; i < num_clusters_; i++) {
- clusters_[i]->ReadFill(this, /*stamp_canonical*/ false);
+ TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
+ clusters_[i]->ReadFill(this, /*is_canonical*/ false);
#if defined(DEBUG)
int32_t section_marker = Read<int32_t>();
ASSERT(section_marker == kSectionMarker);
@@ -6999,22 +6760,26 @@
roots->PostLoad(this, refs);
#if defined(DEBUG)
- isolate()->ValidateClassTable();
- if (isolate() != Dart::vm_isolate()) {
- isolate_group()->heap()->Verify();
+ Isolate* isolate = thread()->isolate();
+ isolate->ValidateClassTable();
+ if (isolate != Dart::vm_isolate()) {
+ isolate->group()->heap()->Verify();
}
#endif
+ // TODO(rmacnak): When splitting literals, load clusters requiring
+ // canonicalization first, canonicalize and update the ref array, the load
+ // the remaining clusters to avoid a full heap walk to update references to
+ // the losers of any canonicalization races.
{
TIMELINE_DURATION(thread(), Isolate, "PostLoad");
for (intptr_t i = 0; i < num_canonical_clusters_; i++) {
TIMELINE_DURATION(thread(), Isolate, canonical_clusters_[i]->name());
- bool canonicalize = isolate() != Dart::vm_isolate();
- canonical_clusters_[i]->PostLoad(this, refs, canonicalize);
+ canonical_clusters_[i]->PostLoad(this, refs, /*is_canonical*/ true);
}
for (intptr_t i = 0; i < num_clusters_; i++) {
TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
- clusters_[i]->PostLoad(this, refs, /*canonicalize*/ false);
+ clusters_[i]->PostLoad(this, refs, /*is_canonical*/ false);
}
}
}
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index d35b83a..ac72aed 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -116,20 +116,16 @@
// Allocate memory for all objects in the cluster and write their addresses
// into the ref array. Do not touch this memory.
- virtual void ReadAlloc(Deserializer* deserializer, bool stamp_canonical) = 0;
+ virtual void ReadAlloc(Deserializer* deserializer, bool is_canonical) = 0;
// Initialize the cluster's objects. Do not touch the memory of other objects.
- virtual void ReadFill(Deserializer* deserializer, bool stamp_canonical) = 0;
+ virtual void ReadFill(Deserializer* deserializer, bool is_canonical) = 0;
// Complete any action that requires the full graph to be deserialized, such
// as rehashing.
virtual void PostLoad(Deserializer* deserializer,
const Array& refs,
- bool canonicalize) {
- if (canonicalize) {
- FATAL1("%s needs canonicalization but doesn't define PostLoad", name());
- }
- }
+ bool is_canonical) {}
const char* name() const { return name_; }
@@ -351,7 +347,7 @@
Write<int32_t>(cid);
}
- void PrepareInstructions();
+ void PrepareInstructions(GrowableArray<CodePtr>* codes);
void WriteInstructions(InstructionsPtr instr,
uint32_t unchecked_offset,
CodePtr code,
@@ -384,7 +380,6 @@
void set_loading_units(GrowableArray<LoadingUnitSerializationData*>* units) {
loading_units_ = units;
}
- intptr_t current_loading_unit_id() { return current_loading_unit_id_; }
void set_current_loading_unit_id(intptr_t id) {
current_loading_unit_id_ = id;
}
@@ -419,13 +414,6 @@
FATAL("Missing ref");
}
- bool HasRef(ObjectPtr object) const {
- return heap_->GetObjectId(object) != kUnreachableReference;
- }
- bool IsWritten(ObjectPtr object) const {
- return heap_->GetObjectId(object) > num_base_objects_;
- }
-
private:
const char* ReadOnlyObjectType(intptr_t cid);
@@ -585,8 +573,6 @@
uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
- intptr_t position() const { return stream_.Position(); }
- void set_position(intptr_t p) { stream_.SetPosition(p); }
const uint8_t* CurrentBufferAddress() const {
return stream_.AddressOfCurrentPosition();
}
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index ff5ea61..f19bbbd 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -71,15 +71,8 @@
// We're guaranteed to have all calls resolved, since
// * backwards calls are resolved eagerly
// * forward calls are resolved once the target is written
- if (!all_unresolved_calls_.IsEmpty()) {
- for (auto call : all_unresolved_calls_) {
- OS::PrintErr("Unresolved call to %s from %s\n",
- Object::Handle(call->callee).ToCString(),
- Object::Handle(call->caller).ToCString());
- }
- }
- RELEASE_ASSERT(all_unresolved_calls_.IsEmpty());
- RELEASE_ASSERT(unresolved_calls_by_destination_.IsEmpty());
+ ASSERT(all_unresolved_calls_.IsEmpty());
+ ASSERT(unresolved_calls_by_destination_.IsEmpty());
// Any trampolines we created must be patched with the right offsets.
auto it = trampolines_by_destination_.GetIterator();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 9694444..5bdddc8 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -86,7 +86,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 48;
+ 52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
@@ -611,7 +611,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 96;
+ 104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
164;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
@@ -1140,7 +1140,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 48;
+ 52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
@@ -1662,7 +1662,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 96;
+ 104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
164;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
@@ -2194,7 +2194,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 48;
+ 52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
@@ -2713,7 +2713,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 96;
+ 104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
164;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
@@ -3236,7 +3236,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 48;
+ 52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
@@ -3752,7 +3752,7 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 96;
+ 104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
164;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
@@ -4280,7 +4280,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
4;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 48;
+ AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 88;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
@@ -4864,7 +4864,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 96;
+ AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 164;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
@@ -5454,7 +5454,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 96;
+ AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 164;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
@@ -6043,7 +6043,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
4;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 48;
+ AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 88;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
@@ -6620,7 +6620,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 96;
+ AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 164;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
@@ -7203,7 +7203,7 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 96;
+ AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 164;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
diff --git a/runtime/vm/compiler/type_testing_stubs_arm.cc b/runtime/vm/compiler/type_testing_stubs_arm.cc
index ccd9d36..ed1ace2 100644
--- a/runtime/vm/compiler/type_testing_stubs_arm.cc
+++ b/runtime/vm/compiler/type_testing_stubs_arm.cc
@@ -20,8 +20,16 @@
const Type& type,
const Class& type_class) {
BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
- __ Branch(compiler::Address(
- THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+ if (!compiler::IsSameObject(
+ compiler::NullObject(),
+ compiler::CastHandle<Object>(slow_type_test_stub))) {
+ __ GenerateUnRelocatedPcRelativeTailCall();
+ unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+ __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+ } else {
+ __ Branch(compiler::Address(
+ THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+ }
}
} // namespace dart
diff --git a/runtime/vm/compiler/type_testing_stubs_arm64.cc b/runtime/vm/compiler/type_testing_stubs_arm64.cc
index 850b198..0540b01 100644
--- a/runtime/vm/compiler/type_testing_stubs_arm64.cc
+++ b/runtime/vm/compiler/type_testing_stubs_arm64.cc
@@ -20,11 +20,19 @@
const Type& type,
const Class& type_class) {
BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
- __ ldr(
- TMP,
- compiler::Address(
- THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
- __ br(TMP);
+ if (!compiler::IsSameObject(
+ compiler::NullObject(),
+ compiler::CastHandle<Object>(slow_type_test_stub))) {
+ __ GenerateUnRelocatedPcRelativeTailCall();
+ unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+ __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+ } else {
+ __ ldr(TMP,
+ compiler::Address(
+ THR,
+ compiler::target::Thread::slow_type_test_entry_point_offset()));
+ __ br(TMP);
+ }
}
} // namespace dart
diff --git a/runtime/vm/compiler/type_testing_stubs_x64.cc b/runtime/vm/compiler/type_testing_stubs_x64.cc
index 7722cee..f7a974c 100644
--- a/runtime/vm/compiler/type_testing_stubs_x64.cc
+++ b/runtime/vm/compiler/type_testing_stubs_x64.cc
@@ -20,8 +20,16 @@
const Type& type,
const Class& type_class) {
BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
- __ jmp(compiler::Address(
- THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+ if (!compiler::IsSameObject(
+ compiler::NullObject(),
+ compiler::CastHandle<Object>(slow_type_test_stub))) {
+ __ GenerateUnRelocatedPcRelativeTailCall();
+ unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+ __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+ } else {
+ __ jmp(compiler::Address(
+ THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+ }
}
} // namespace dart
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index fae18df..d98aa2d 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -20212,11 +20212,9 @@
}
}
ASSERT(this->Equals(type));
- // TODO(rmacnak): Revisit immediately returning type after to changes to
- // recanonicalization on load for literal splitting.
- if (type.IsCanonical()) {
- return type.ptr();
- }
+ ASSERT(type.IsCanonical());
+ ASSERT(type.IsOld());
+ return type.ptr();
}
Type& type = Type::Handle(zone);
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index b8e3de1..9082979 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -1371,15 +1371,9 @@
MergeAssignment(obj_, id);
obj_ = code.compressed_stackmaps();
MergeAssignment(obj_, id);
- if (!FLAG_use_bare_instructions) {
- obj_ = code.object_pool();
- MergeAssignment(obj_, id);
- }
}
void MergeAssignment(const Object& obj, intptr_t id) {
- if (obj.IsNull()) return;
-
intptr_t old_id = heap_->GetLoadingUnit(obj_.ptr());
if (old_id == WeakTable::kNoValue) {
heap_->SetLoadingUnit(obj_.ptr(), id);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 8a02e59..d209ad2 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -28,8 +28,8 @@
// * Target architecture
// * DART_PRECOMPILED_RUNTIME (i.e, AOT vs. JIT)
//
-// That is, fields in UntaggedObject and its subclasses should only be included or
-// excluded conditionally based on these factors. Otherwise, the generated
+// That is, fields in UntaggedObject and its subclasses should only be included
+// or excluded conditionally based on these factors. Otherwise, the generated
// offsets can be wrong (which should be caught by offset checking in dart.cc).
//
// TODO(dartbug.com/43646): Add DART_PRECOMPILER as another axis.
@@ -819,6 +819,8 @@
POINTER_FIELD(LibraryPtr, library)
POINTER_FIELD(TypeArgumentsPtr, type_parameters) // Array of TypeParameter.
POINTER_FIELD(AbstractTypePtr, super_type)
+ POINTER_FIELD(ArrayPtr,
+ constants) // Canonicalized const instances of this class.
POINTER_FIELD(TypePtr, declaration_type) // Declaration type for this class.
POINTER_FIELD(ArrayPtr,
invocation_dispatcher_cache) // Cache for dispatcher functions.
@@ -828,9 +830,7 @@
direct_implementors) // Array of Class.
POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses) // Array of Class.
POINTER_FIELD(ArrayPtr, dependent_code) // CHA optimized codes.
- POINTER_FIELD(ArrayPtr,
- constants) // Canonicalized const instances of this class.
- VISIT_TO(ObjectPtr, constants)
+ VISIT_TO(ObjectPtr, dependent_code)
ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
@@ -1642,8 +1642,6 @@
friend class Object;
friend class CodeSerializationCluster;
- friend class UnitSerializationRoots;
- friend class UnitDeserializationRoots;
};
class UntaggedInstructions : public UntaggedObject {
diff --git a/tools/VERSION b/tools/VERSION
index 41eeca7..0f13953 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 273
+PRERELEASE 274
PRERELEASE_PATCH 0
\ No newline at end of file