Skip to content

Commit 3b07865

Browse files
dcharkesCommit Queue
authored andcommitted
[vm/ffi] AOT kernel concatenation with native assets
gen_snapshot can now consume a concatenated dill file. Restrictions: * The first dill file must be the main program. * The subsequent dill files must only contain dummy libraries with objects which are recognized classes in the VM and not treeshaken in the main program. This will enable compiling Dart AOT first, then using the tree-shaking information to tree-shake native assets, and then embedding the native assets mapping in the kernel file before running gen_snapshot. TEST=tests/ffi/native_assets/asset_relative_test.dart Closes: #50152 Bug: #55377 Change-Id: Id562aa39840d5eb467198efaa4cf3152d860f8b5 q-Include-Trybots: dart/try:vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362381 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Daco Harkes <[email protected]>
1 parent 2c95251 commit 3b07865

File tree

3 files changed

+68
-19
lines changed

3 files changed

+68
-19
lines changed

runtime/vm/bootstrap.cc

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "vm/bootstrap.h"
66

77
#include <memory>
8+
#include <utility>
89

910
#include "include/dart_api.h"
1011

@@ -108,22 +109,10 @@ static void Finish(Thread* thread) {
108109
cls.EnsureIsFinalized(thread);
109110
}
110111

111-
static ErrorPtr BootstrapFromKernel(Thread* thread,
112-
const uint8_t* kernel_buffer,
113-
intptr_t kernel_buffer_size) {
112+
static ErrorPtr BootstrapFromKernelSingleProgram(
113+
Thread* thread,
114+
std::unique_ptr<kernel::Program> program) {
114115
Zone* zone = thread->zone();
115-
const char* error = nullptr;
116-
std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
117-
kernel_buffer, kernel_buffer_size, &error);
118-
if (program == nullptr) {
119-
const intptr_t kMessageBufferSize = 512;
120-
char message_buffer[kMessageBufferSize];
121-
Utils::SNPrint(message_buffer, kMessageBufferSize,
122-
"Can't load Kernel binary: %s.", error);
123-
const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
124-
return ApiError::New(msg, Heap::kOld);
125-
}
126-
127116
LongJumpScope jump;
128117
if (setjmp(*jump.Set()) == 0) {
129118
kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
@@ -167,6 +156,66 @@ static ErrorPtr BootstrapFromKernel(Thread* thread,
167156
return Thread::Current()->StealStickyError();
168157
}
169158

159+
static ErrorPtr BootstrapFromKernel(Thread* thread,
160+
const uint8_t* kernel_buffer,
161+
intptr_t kernel_buffer_size) {
162+
Zone* zone = thread->zone();
163+
const char* error = nullptr;
164+
std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
165+
kernel_buffer, kernel_buffer_size, &error);
166+
if (program == nullptr) {
167+
const intptr_t kMessageBufferSize = 512;
168+
char message_buffer[kMessageBufferSize];
169+
Utils::SNPrint(message_buffer, kMessageBufferSize,
170+
"Can't load Kernel binary: %s.", error);
171+
const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
172+
return ApiError::New(msg, Heap::kOld);
173+
}
174+
175+
if (program->is_single_program()) {
176+
return BootstrapFromKernelSingleProgram(thread, std::move(program));
177+
}
178+
179+
GrowableArray<intptr_t> subprogram_file_starts;
180+
{
181+
kernel::Reader reader(program->binary());
182+
kernel::KernelLoader::index_programs(&reader, &subprogram_file_starts);
183+
}
184+
intptr_t subprogram_count = subprogram_file_starts.length() - 1;
185+
186+
// Create "fake programs" for each sub-program.
187+
auto& load_result = Error::Handle(zone);
188+
for (intptr_t i = 0; i < subprogram_count; i++) {
189+
intptr_t subprogram_start = subprogram_file_starts.At(i);
190+
intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
191+
const auto& component = TypedDataBase::Handle(
192+
program->binary().ViewFromTo(subprogram_start, subprogram_end));
193+
kernel::Reader reader(component);
194+
const char* error = nullptr;
195+
std::unique_ptr<kernel::Program> subprogram =
196+
kernel::Program::ReadFrom(&reader, &error);
197+
if (subprogram == nullptr) {
198+
FATAL("Failed to load kernel file: %s", error);
199+
}
200+
ASSERT(subprogram->is_single_program());
201+
if (i == 0) {
202+
// The first subprogram must be the main Dart program.
203+
load_result ^=
204+
BootstrapFromKernelSingleProgram(thread, std::move(subprogram));
205+
} else {
206+
// Restrictions on the subsequent programs: Must contain only
207+
// contain dummy libraries with VM recognized classes (or classes kept
208+
// fully intact by tree-shaking).
209+
// Currently only used for concatenating native assets mappings.
210+
kernel::KernelLoader loader(subprogram.get(),
211+
/*uri_to_source_table=*/nullptr);
212+
load_result ^= loader.LoadProgram(false);
213+
}
214+
if (load_result.IsError()) return load_result.ptr();
215+
}
216+
return Error::null();
217+
}
218+
170219
ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
171220
intptr_t kernel_buffer_size) {
172221
Thread* thread = Thread::Current();

runtime/vm/kernel_loader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ class KernelLoader : public ValueObject {
220220
const Function& parent_function,
221221
const Object& closure_owner);
222222

223+
static void index_programs(kernel::Reader* reader,
224+
GrowableArray<intptr_t>* subprogram_file_starts);
225+
223226
private:
224227
// Pragma bits
225228
using HasPragma = BitField<uint32_t, bool, 0, 1>;
@@ -279,8 +282,6 @@ class KernelLoader : public ValueObject {
279282

280283
uint8_t CharacterAt(StringIndex string_index, intptr_t index);
281284

282-
static void index_programs(kernel::Reader* reader,
283-
GrowableArray<intptr_t>* subprogram_file_starts);
284285
void walk_incremental_kernel(BitVector* modified_libs,
285286
bool* is_empty_program,
286287
intptr_t* p_num_classes,

tests/ffi/native_assets/asset_relative_test.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ Future<void> selfInvokes() async {
6060
await invokeSelf(
6161
selfSourceUri: selfSourceUri,
6262
runtime: Runtime.aot,
63-
// TODO(https://dartbug.com/55377): Support concatenation in AOT.
64-
// kernelCombine: KernelCombine.concatenation,
63+
kernelCombine: KernelCombine.concatenation,
6564
relativePath: RelativePath.up,
6665
arguments: [runTestsArg],
6766
);

0 commit comments

Comments
 (0)