Skip to content

Commit 56a4d7c

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Support --use_table_dispatch when splitting snapshots.
When reading a secondary snapshot, re-run the dispatch table initialization found in the root snapshot. Since each loading unit's contribution to the dispatch table is scattered, it would take more snapshot size to try to serialize their contributions separately. We'll revisit this when we can defer Class, Function and Code, which will prevent the root snapshot from referencing all Codes. Bug: #41974 Change-Id: Iefd2b98647b96ae59a7efe92897538f5cf8c2426 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/158923 Reviewed-by: Aske Simon Christensen <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 41953c8 commit 56a4d7c

9 files changed

+65
-29
lines changed

pkg/test_runner/lib/src/compiler_configuration.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,19 +705,13 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration
705705
if (_configuration.useElf) ...[
706706
"--snapshot-kind=app-aot-elf",
707707
"--elf=$tempDir/out.aotsnapshot",
708+
// Only splitting with a ELF to avoid having to setup compilation of
709+
// multiple assembly files in the test harness.
710+
"--loading-unit-manifest=$tempDir/ignored.json",
708711
] else ...[
709712
"--snapshot-kind=app-aot-assembly",
710713
"--assembly=$tempDir/out.S",
711714
],
712-
// Only splitting with a ELF to avoid having to setup compilation of
713-
// multiple assembly files in the test harness. Only splitting tests of
714-
// deferred imports because splitting currently requires disable bare
715-
// instructions mode, and we want to continue testing bare instructions
716-
// mode.
717-
if (_configuration.useElf && arguments.last.contains("deferred")) ...[
718-
"--loading-unit-manifest=$tempDir/ignored.json",
719-
"--use-table-dispatch=false",
720-
],
721715
if (_isAndroid && _isArm) '--no-sim-use-hardfp',
722716
if (_configuration.isMinified) '--obfuscate',
723717
// The SIMARM precompiler assumes support for integer division, but the
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// VMOptions=--use_bare_instructions=false
6+
// VMOptions=--use_bare_instructions=true --use_table_dispatch=false
7+
// VMOptions=--use_bare_instructions=true --use_table_dispatch=true
8+
9+
import "splay_test.dart" deferred as splay; // Some non-trivial code.
10+
11+
main() async {
12+
await splay.loadLibrary();
13+
splay.main();
14+
}

runtime/tests/vm/dart/incompatible_loading_unit_test.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ main(List<String> args) async {
7979
// Compile kernel to ELF.
8080
await run(genSnapshot, <String>[
8181
"--snapshot-kind=app-aot-elf",
82-
"--use-table-dispatch=false",
8382
"--elf=$snapshot1",
8483
"--loading-unit-manifest=$manifest1",
8584
dill1,
@@ -95,7 +94,6 @@ main(List<String> args) async {
9594

9695
await run(genSnapshot, <String>[
9796
"--snapshot-kind=app-aot-elf",
98-
"--use-table-dispatch=false",
9997
"--elf=$snapshot2",
10098
"--loading-unit-manifest=$manifest2",
10199
dill2,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// VMOptions=--use_bare_instructions=false
6+
// VMOptions=--use_bare_instructions=true --use_table_dispatch=false
7+
// VMOptions=--use_bare_instructions=true --use_table_dispatch=true
8+
9+
import "splay_test.dart" deferred as splay; // Some non-trivial code.
10+
11+
main() async {
12+
await splay.loadLibrary();
13+
splay.main();
14+
}

runtime/tests/vm/dart_2/incompatible_loading_unit_test.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ main(List<String> args) async {
7979
// Compile kernel to ELF.
8080
await run(genSnapshot, <String>[
8181
"--snapshot-kind=app-aot-elf",
82-
"--use-table-dispatch=false",
8382
"--elf=$snapshot1",
8483
"--loading-unit-manifest=$manifest1",
8584
dill1,
@@ -95,7 +94,6 @@ main(List<String> args) async {
9594

9695
await run(genSnapshot, <String>[
9796
"--snapshot-kind=app-aot-elf",
98-
"--use-table-dispatch=false",
9997
"--elf=$snapshot2",
10098
"--loading-unit-manifest=$manifest2",
10199
dill2,

runtime/vm/clustered_snapshot.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6206,15 +6206,16 @@ DeserializationCluster* Deserializer::ReadCluster() {
62066206
return NULL;
62076207
}
62086208

6209-
void Deserializer::ReadDispatchTable() {
6209+
void Deserializer::ReadDispatchTable(ReadStream* stream) {
62106210
#if defined(DART_PRECOMPILED_RUNTIME)
6211-
const intptr_t length = ReadUnsigned();
6211+
const uint8_t* table_snapshot_start = stream->AddressOfCurrentPosition();
6212+
const intptr_t length = stream->ReadUnsigned();
62126213
if (length == 0) return;
62136214

62146215
// Not all Code objects may be in the code_order_table when instructions can
62156216
// be deduplicated. Thus, we serialize the reference ID of the first code
62166217
// object, from which we can get the reference ID for any code object.
6217-
const intptr_t first_code_id = ReadUnsigned();
6218+
const intptr_t first_code_id = stream->ReadUnsigned();
62186219

62196220
auto const I = isolate();
62206221
auto code = I->object_store()->dispatch_table_null_error_stub();
@@ -6233,7 +6234,7 @@ void Deserializer::ReadDispatchTable() {
62336234
repeat_count--;
62346235
continue;
62356236
}
6236-
auto const encoded = Read<intptr_t>();
6237+
auto const encoded = stream->Read<intptr_t>();
62376238
if (encoded == 0) {
62386239
value = null_entry;
62396240
} else if (encoded < 0) {
@@ -6254,6 +6255,10 @@ void Deserializer::ReadDispatchTable() {
62546255
ASSERT(repeat_count == 0);
62556256

62566257
I->group()->set_dispatch_table(table);
6258+
intptr_t table_snapshot_size =
6259+
stream->AddressOfCurrentPosition() - table_snapshot_start;
6260+
I->group()->set_dispatch_table_snapshot(table_snapshot_start);
6261+
I->group()->set_dispatch_table_snapshot_size(table_snapshot_size);
62576262
#endif
62586263
}
62596264

@@ -6674,7 +6679,7 @@ void Deserializer::ReadProgramSnapshot(ObjectStore* object_store) {
66746679
}
66756680

66766681
// Deserialize dispatch table (when applicable)
6677-
ReadDispatchTable();
6682+
ReadDispatchTable(&stream_);
66786683

66796684
#if defined(DEBUG)
66806685
int32_t section_marker = Read<int32_t>();
@@ -6758,6 +6763,15 @@ ApiErrorPtr Deserializer::ReadUnitSnapshot(const LoadingUnit& unit) {
67586763
code->ptr()->code_source_map_ = static_cast<CodeSourceMapPtr>(ReadRef());
67596764
}
67606765

6766+
// Reinitialize the dispatch table by rereading the table's serialization
6767+
// in the root snapshot.
6768+
IsolateGroup* group = thread()->isolate()->group();
6769+
if (group->dispatch_table_snapshot() != nullptr) {
6770+
ReadStream stream(group->dispatch_table_snapshot(),
6771+
group->dispatch_table_snapshot_size());
6772+
ReadDispatchTable(&stream);
6773+
}
6774+
67616775
#if defined(DEBUG)
67626776
int32_t section_marker = Read<int32_t>();
67636777
ASSERT(section_marker == kSectionMarker);

runtime/vm/clustered_snapshot.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ class Deserializer : public ThreadStackResource {
704704

705705
DeserializationCluster* ReadCluster();
706706

707-
void ReadDispatchTable();
707+
void ReadDispatchTable(ReadStream* stream);
708708

709709
intptr_t next_index() const { return next_ref_index_; }
710710
Heap* heap() const { return heap_; }

runtime/vm/dart_api_impl.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6805,11 +6805,6 @@ DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssemblies(
68056805
return Api::NewError(
68066806
"This VM was built without support for AOT compilation.");
68076807
#else
6808-
if (FLAG_use_bare_instructions && FLAG_use_table_dispatch) {
6809-
return Api::NewError(
6810-
"Splitting is not compatible with --use_table_dispatch.");
6811-
}
6812-
68136808
DARTSCOPE(Thread::Current());
68146809
API_TIMELINE_DURATION(T);
68156810
CHECK_NULL(next_callback);
@@ -6887,11 +6882,6 @@ Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback,
68876882
return Api::NewError(
68886883
"This VM was built without support for AOT compilation.");
68896884
#else
6890-
if (FLAG_use_bare_instructions && FLAG_use_table_dispatch) {
6891-
return Api::NewError(
6892-
"Splitting is not compatible with --use_table_dispatch.");
6893-
}
6894-
68956885
DARTSCOPE(Thread::Current());
68966886
API_TIMELINE_DURATION(T);
68976887
CHECK_NULL(next_callback);

runtime/vm/isolate.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,18 @@ class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
380380
void set_dispatch_table(DispatchTable* table) {
381381
dispatch_table_.reset(table);
382382
}
383+
const uint8_t* dispatch_table_snapshot() const {
384+
return dispatch_table_snapshot_;
385+
}
386+
void set_dispatch_table_snapshot(const uint8_t* snapshot) {
387+
dispatch_table_snapshot_ = snapshot;
388+
}
389+
intptr_t dispatch_table_snapshot_size() const {
390+
return dispatch_table_snapshot_size_;
391+
}
392+
void set_dispatch_table_snapshot_size(intptr_t size) {
393+
dispatch_table_snapshot_size_ = size;
394+
}
383395

384396
SharedClassTable* shared_class_table() const {
385397
return shared_class_table_.get();
@@ -672,6 +684,8 @@ class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
672684
std::unique_ptr<StoreBuffer> store_buffer_;
673685
std::unique_ptr<Heap> heap_;
674686
std::unique_ptr<DispatchTable> dispatch_table_;
687+
const uint8_t* dispatch_table_snapshot_ = nullptr;
688+
intptr_t dispatch_table_snapshot_size_ = 0;
675689
ArrayPtr saved_unlinked_calls_;
676690
std::shared_ptr<FieldTable> saved_initial_field_table_;
677691
uint32_t isolate_group_flags_ = 0;

0 commit comments

Comments
 (0)