Skip to content

Commit e8d3389

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
[VM] Expression compilation when loaded from dill (part 2)
Previous version (landed via https://dart-review.googlesource.com/c/sdk/+/135683) only worked if the dill was loaded via Dart_LoadScriptFromKernel where script_kernel_size was set, and when the platform dill could be loaded from a file called the right thing. This CL makes it work for Dart_LoadLibraryFromKernel too and allows the VM to send the platform along (explicitly or implicitly) and only tries to load the platform from a file with the right name if no platform is given in any of the inputs. This should fix http://b/148776866 Change-Id: I62317400a932b7dcd9e126a5a88907d507f9d658 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153609 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent efb1143 commit e8d3389

11 files changed

+199
-116
lines changed

pkg/vm/bin/kernel_service.dart

+79-38
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ class IncrementalCompilerWrapper extends Compiler {
363363
suppressWarnings: suppressWarnings,
364364
enableAsserts: enableAsserts,
365365
experimentalFlags: experimentalFlags,
366-
bytecode: bytecode);
366+
bytecode: bytecode,
367+
packageConfig: packageConfig);
367368
result.generator = new IncrementalCompiler.forExpressionCompilationOnly(
368369
component,
369370
result.options,
@@ -538,27 +539,28 @@ void invalidateSources(IncrementalCompilerWrapper compiler, List sourceFiles) {
538539
Future _processExpressionCompilationRequest(request) async {
539540
final SendPort port = request[1];
540541
final int isolateId = request[2];
541-
final String expression = request[3];
542-
final List<String> definitions = request[4].cast<String>();
543-
final List<String> typeDefinitions = request[5].cast<String>();
544-
final String libraryUri = request[6];
545-
final String klass = request[7]; // might be null
546-
final bool isStatic = request[8];
547-
final List dillData = request[9];
548-
final int hotReloadCount = request[10];
549-
final bool suppressWarnings = request[11];
550-
final bool enableAsserts = request[12];
542+
final dynamic dart_platform_kernel = request[3];
543+
final String expression = request[4];
544+
final List<String> definitions = request[5].cast<String>();
545+
final List<String> typeDefinitions = request[6].cast<String>();
546+
final String libraryUri = request[7];
547+
final String klass = request[8]; // might be null
548+
final bool isStatic = request[9];
549+
final List dillData = request[10];
550+
final int blobLoadCount = request[11];
551+
final bool suppressWarnings = request[12];
552+
final bool enableAsserts = request[13];
551553
final List<String> experimentalFlags =
552-
request[13] != null ? request[13].cast<String>() : null;
553-
final bool bytecode = request[14];
554+
request[14] != null ? request[14].cast<String>() : null;
555+
final bool bytecode = request[15];
554556

555557
IncrementalCompilerWrapper compiler = isolateCompilers[isolateId];
556558

557559
_ExpressionCompilationFromDillSettings isolateLoadDillData =
558560
isolateLoadNotifies[isolateId];
559561
if (isolateLoadDillData != null) {
560562
// Check if we can reuse the compiler.
561-
if (isolateLoadDillData.hotReloadCount != hotReloadCount ||
563+
if (isolateLoadDillData.blobLoadCount != blobLoadCount ||
562564
isolateLoadDillData.prevDillCount != dillData.length) {
563565
compiler = isolateCompilers[isolateId] = null;
564566
}
@@ -571,43 +573,82 @@ Future _processExpressionCompilationRequest(request) async {
571573
}
572574
isolateLoadNotifies[isolateId] =
573575
new _ExpressionCompilationFromDillSettings(
574-
hotReloadCount, dillData.length);
575-
576-
Uri platformUri =
577-
computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
578-
579-
List<List<int>> data = [];
580-
data.add(new File.fromUri(platformUri).readAsBytesSync());
581-
for (int i = 0; i < dillData.length; i++) {
582-
data.add(dillData[i]);
583-
}
576+
blobLoadCount, dillData.length);
584577

585578
// Create Component initialized from the bytes.
586579
Component component = new Component();
587-
for (List<int> bytes in data) {
580+
581+
// First try to just load all "dillData". This *might* include the
582+
// platform (and we might have the (same) platform both here and in
583+
// dart_platform_kernel).
584+
for (List<int> bytes in dillData) {
588585
// TODO(jensj): There might be an issue if main has changed.
589586
new BinaryBuilderWithMetadata(bytes, alwaysCreateNewNamedNodes: true)
590587
.readComponent(component);
591588
}
592589

590+
// Check if the loaded component has the platform.
591+
// If it does not, try to load from dart_platform_kernel or from file.
592+
bool foundDartCore = false;
593+
for (Library library in component.libraries) {
594+
if (library.importUri.scheme == "dart" &&
595+
library.importUri.path == "core" &&
596+
!library.isSynthetic) {
597+
foundDartCore = true;
598+
break;
599+
}
600+
}
601+
if (!foundDartCore) {
602+
List<int> platformKernel = null;
603+
if (dart_platform_kernel is List<int>) {
604+
platformKernel = dart_platform_kernel;
605+
} else {
606+
final Uri platformUri = computePlatformBinariesLocation()
607+
.resolve('vm_platform_strong.dill');
608+
final File platformFile = new File.fromUri(platformUri);
609+
if (platformFile.existsSync()) {
610+
platformKernel = platformFile.readAsBytesSync();
611+
} else {
612+
port.send(new CompilationResult.errors(
613+
["No platform found to initialize incremental compiler."],
614+
null)
615+
.toResponse());
616+
return;
617+
}
618+
}
619+
620+
new BinaryBuilderWithMetadata(platformKernel,
621+
alwaysCreateNewNamedNodes: true)
622+
.readComponent(component);
623+
}
624+
593625
FileSystem fileSystem =
594626
_buildFileSystem([dotPackagesFile, <int>[]], null, null, null);
595627

596628
// TODO(aam): IncrementalCompilerWrapper instance created below have to be
597629
// destroyed when corresponding isolate is shut down. To achieve that
598630
// kernel isolate needs to receive a message indicating that particular
599631
// isolate was shut down. Message should be handled here in this script.
600-
compiler = new IncrementalCompilerWrapper.forExpressionCompilationOnly(
601-
component, isolateId, fileSystem, null,
602-
suppressWarnings: suppressWarnings,
603-
enableAsserts: enableAsserts,
604-
experimentalFlags: experimentalFlags,
605-
bytecode: bytecode,
606-
packageConfig: dotPackagesFile);
607-
isolateCompilers[isolateId] = compiler;
608-
await compiler.compile(
609-
component.mainMethod?.enclosingLibrary?.importUri ??
610-
component.libraries.last.importUri);
632+
try {
633+
compiler = new IncrementalCompilerWrapper.forExpressionCompilationOnly(
634+
component, isolateId, fileSystem, null,
635+
suppressWarnings: suppressWarnings,
636+
enableAsserts: enableAsserts,
637+
experimentalFlags: experimentalFlags,
638+
bytecode: bytecode,
639+
packageConfig: dotPackagesFile);
640+
isolateCompilers[isolateId] = compiler;
641+
await compiler.compile(
642+
component.mainMethod?.enclosingLibrary?.importUri ??
643+
component.libraries.last.importUri);
644+
} catch (e) {
645+
port.send(new CompilationResult.errors([
646+
"Error when trying to create a compiler for expression compilation: "
647+
"'$e'."
648+
], null)
649+
.toResponse());
650+
return;
651+
}
611652
}
612653
}
613654

@@ -1179,9 +1220,9 @@ void _debugDumpKernel(Uint8List bytes) {
11791220
}
11801221

11811222
class _ExpressionCompilationFromDillSettings {
1182-
int hotReloadCount;
1223+
int blobLoadCount;
11831224
int prevDillCount;
11841225

11851226
_ExpressionCompilationFromDillSettings(
1186-
this.hotReloadCount, this.prevDillCount);
1227+
this.blobLoadCount, this.prevDillCount);
11871228
}

runtime/vm/compiler_test.cc

+1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ TEST_CASE(EvalExpression) {
225225

226226
Dart_KernelCompilationResult compilation_result =
227227
KernelIsolate::CompileExpressionToKernel(
228+
/*platform_kernel=*/nullptr, /*platform_kernel_size=*/0,
228229
expr_text.ToCString(), Array::empty_array(), Array::empty_array(),
229230
String::Handle(lib_handle.url()).ToCString(), "A",
230231
/* is_static= */ false);

runtime/vm/dart_api_impl.cc

+3
Original file line numberDiff line numberDiff line change
@@ -5774,6 +5774,9 @@ DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
57745774
kernel::KernelLoader::LoadEntireProgram(program.get(), false);
57755775
program.reset();
57765776

5777+
IsolateGroupSource* source = Isolate::Current()->source();
5778+
source->add_loaded_blob(Z, td);
5779+
57775780
return Api::NewHandle(T, result.raw());
57785781
#endif // defined(DART_PRECOMPILED_RUNTIME)
57795782
}

runtime/vm/debugger_api_impl_test.cc

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ DART_EXPORT Dart_Handle Dart_EvaluateStaticExpr(Dart_Handle lib_handle,
180180
} else {
181181
Dart_KernelCompilationResult compilation_result =
182182
KernelIsolate::CompileExpressionToKernel(
183+
/* platform_kernel= */ nullptr, /* platform_kernel_size= */ 0,
183184
expr.ToCString(),
184185
/* definitions= */ Array::empty_array(),
185186
/* type_defintions= */ Array::empty_array(),

runtime/vm/isolate.cc

+59-2
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,63 @@ static InstancePtr DeserializeMessage(Thread* thread, Message* message) {
153153
}
154154
}
155155

156+
void IsolateGroupSource::add_loaded_blob(
157+
Zone* zone,
158+
const ExternalTypedData& external_typed_data) {
159+
Array& loaded_blobs = Array::Handle();
160+
bool saved_external_typed_data = false;
161+
if (loaded_blobs_ != nullptr) {
162+
loaded_blobs = loaded_blobs_;
163+
164+
// Walk the array, and (if stuff was removed) compact and reuse the space.
165+
// Note that the space has to be compacted as the ordering is important.
166+
WeakProperty& weak_property = WeakProperty::Handle();
167+
WeakProperty& weak_property_tmp = WeakProperty::Handle();
168+
ExternalTypedData& existing_entry = ExternalTypedData::Handle(zone);
169+
intptr_t next_entry_index = 0;
170+
for (intptr_t i = 0; i < loaded_blobs.Length(); i++) {
171+
weak_property ^= loaded_blobs.At(i);
172+
if (weak_property.key() != ExternalTypedData::null()) {
173+
if (i != next_entry_index) {
174+
existing_entry = ExternalTypedData::RawCast(weak_property.key());
175+
weak_property_tmp ^= loaded_blobs.At(next_entry_index);
176+
weak_property_tmp.set_key(existing_entry);
177+
}
178+
next_entry_index++;
179+
}
180+
}
181+
if (next_entry_index < loaded_blobs.Length()) {
182+
// There's now space to re-use.
183+
weak_property ^= loaded_blobs.At(next_entry_index);
184+
weak_property.set_key(external_typed_data);
185+
next_entry_index++;
186+
saved_external_typed_data = true;
187+
}
188+
if (next_entry_index < loaded_blobs.Length()) {
189+
ExternalTypedData& nullExternalTypedData =
190+
ExternalTypedData::Handle(zone);
191+
while (next_entry_index < loaded_blobs.Length()) {
192+
// Null out any extra spaces.
193+
weak_property ^= loaded_blobs.At(next_entry_index);
194+
weak_property.set_key(nullExternalTypedData);
195+
next_entry_index++;
196+
}
197+
}
198+
}
199+
if (!saved_external_typed_data) {
200+
const WeakProperty& weak_property =
201+
WeakProperty::Handle(WeakProperty::New(Heap::kOld));
202+
weak_property.set_key(external_typed_data);
203+
204+
intptr_t length = loaded_blobs.IsNull() ? 0 : loaded_blobs.Length();
205+
Array& new_array =
206+
Array::Handle(Array::Grow(loaded_blobs, length + 1, Heap::kOld));
207+
new_array.SetAt(length, weak_property);
208+
loaded_blobs_ = new_array.raw();
209+
}
210+
num_blob_loads_++;
211+
}
212+
156213
void IdleTimeHandler::InitializeWithHeap(Heap* heap) {
157214
MutexLocker ml(&mutex_);
158215
ASSERT(heap_ == nullptr && heap != nullptr);
@@ -2676,9 +2733,9 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
26762733
visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&deoptimized_code_array_));
26772734
visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
26782735
if (isolate_group_ != nullptr) {
2679-
if (isolate_group_->source()->hot_reload_blobs_ != nullptr) {
2736+
if (isolate_group_->source()->loaded_blobs_ != nullptr) {
26802737
visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(
2681-
&(isolate_group_->source()->hot_reload_blobs_)));
2738+
&(isolate_group_->source()->loaded_blobs_)));
26822739
}
26832740
}
26842741
#if !defined(PRODUCT)

runtime/vm/isolate.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ class IsolateGroupSource {
200200
flags(flags),
201201
script_kernel_buffer(nullptr),
202202
script_kernel_size(-1),
203-
hot_reload_blobs_(nullptr),
204-
num_hot_reloads_(0) {}
203+
loaded_blobs_(nullptr),
204+
num_blob_loads_(0) {}
205205
~IsolateGroupSource() { free(name); }
206206

207+
void add_loaded_blob(Zone* zone_,
208+
const ExternalTypedData& external_typed_data);
209+
207210
// The arguments used for spawning in
208211
// `Dart_CreateIsolateGroupFromKernel` / `Dart_CreateIsolate`.
209212
const char* script_uri;
@@ -223,9 +226,9 @@ class IsolateGroupSource {
223226
// Any newly spawned isolates need to use this permutation map.
224227
std::unique_ptr<intptr_t[]> cid_permutation_map;
225228

226-
// List of weak pointers to external typed data for hot reload blobs.
227-
ArrayPtr hot_reload_blobs_;
228-
intptr_t num_hot_reloads_;
229+
// List of weak pointers to external typed data for loaded blobs.
230+
ArrayPtr loaded_blobs_;
231+
intptr_t num_blob_loads_;
229232
};
230233

231234
// Tracks idle time and notifies heap when idle time expired.

runtime/vm/isolate_reload.cc

+1-53
Original file line numberDiff line numberDiff line change
@@ -619,65 +619,13 @@ bool IsolateGroupReloadContext::Reload(bool force_reload,
619619
const auto& typed_data = ExternalTypedData::Handle(
620620
Z, ExternalTypedData::NewFinalizeWithFree(
621621
const_cast<uint8_t*>(kernel_buffer), kernel_buffer_size));
622-
623622
kernel_program = kernel::Program::ReadFromTypedData(typed_data);
624623
}
625624

626625
ExternalTypedData& external_typed_data =
627626
ExternalTypedData::Handle(Z, kernel_program.get()->typed_data()->raw());
628627
IsolateGroupSource* source = Isolate::Current()->source();
629-
Array& hot_reload_blobs = Array::Handle();
630-
bool saved_external_typed_data = false;
631-
if (source->hot_reload_blobs_ != nullptr) {
632-
hot_reload_blobs = source->hot_reload_blobs_;
633-
634-
// Walk the array, and (if stuff was removed) compact and reuse the space.
635-
// Note that the space has to be compacted as the ordering is important.
636-
WeakProperty& weak_property = WeakProperty::Handle();
637-
WeakProperty& weak_property_tmp = WeakProperty::Handle();
638-
ExternalTypedData& existing_entry = ExternalTypedData::Handle(Z);
639-
intptr_t next_entry_index = 0;
640-
for (intptr_t i = 0; i < hot_reload_blobs.Length(); i++) {
641-
weak_property ^= hot_reload_blobs.At(i);
642-
if (weak_property.key() != ExternalTypedData::null()) {
643-
if (i != next_entry_index) {
644-
existing_entry = ExternalTypedData::RawCast(weak_property.key());
645-
weak_property_tmp ^= hot_reload_blobs.At(next_entry_index);
646-
weak_property_tmp.set_key(existing_entry);
647-
}
648-
next_entry_index++;
649-
}
650-
}
651-
if (next_entry_index < hot_reload_blobs.Length()) {
652-
// There's now space to re-use.
653-
weak_property ^= hot_reload_blobs.At(next_entry_index);
654-
weak_property.set_key(external_typed_data);
655-
next_entry_index++;
656-
saved_external_typed_data = true;
657-
}
658-
if (next_entry_index < hot_reload_blobs.Length()) {
659-
ExternalTypedData& nullExternalTypedData = ExternalTypedData::Handle(Z);
660-
while (next_entry_index < hot_reload_blobs.Length()) {
661-
// Null out any extra spaces.
662-
weak_property ^= hot_reload_blobs.At(next_entry_index);
663-
weak_property.set_key(nullExternalTypedData);
664-
next_entry_index++;
665-
}
666-
}
667-
}
668-
if (!saved_external_typed_data) {
669-
const WeakProperty& weak_property =
670-
WeakProperty::Handle(WeakProperty::New(Heap::kOld));
671-
weak_property.set_key(external_typed_data);
672-
673-
intptr_t length =
674-
hot_reload_blobs.IsNull() ? 0 : hot_reload_blobs.Length();
675-
Array& new_array =
676-
Array::Handle(Array::Grow(hot_reload_blobs, length + 1, Heap::kOld));
677-
new_array.SetAt(length, weak_property);
678-
source->hot_reload_blobs_ = new_array.raw();
679-
}
680-
source->num_hot_reloads_++;
628+
source->add_loaded_blob(Z, external_typed_data);
681629

682630
modified_libs_ = new (Z) BitVector(Z, num_old_libs_);
683631
kernel::KernelLoader::FindModifiedLibraries(

0 commit comments

Comments
 (0)