[vm/snapshots] Finalize and sort all classes in snapshots with compilation trace

This ensures that core-jit snapshots used in Fuchsia (built according
to the compilation trace) would have properly sorted cids without any
gaps with non-finalized classes. This enables merging of cid ranges in
more cases and more efficient cid checks.

Issue: https://github.com/dart-lang/sdk/issues/36428
Change-Id: I7b696ccb7d5ffa80f190bcfc9e1b7229937f16b6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103403
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Alexander Markov
2019-05-22 16:01:07 +00:00
committed by commit-bot@chromium.org
parent 93481167a6
commit e3edfd36b2
6 changed files with 72 additions and 27 deletions
+9 -1
View File
@@ -420,10 +420,18 @@ static void MaybeLoadCode() {
if ((load_compilation_trace_filename != NULL) &&
((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
// Finalize all classes. This ensures that there are no non-finalized
// classes in the gaps between cid ranges. Such classes prevent merging of
// cid ranges.
Dart_Handle result = Dart_FinalizeAllClasses();
CHECK_RESULT(result);
// Sort classes to have better cid ranges.
result = Dart_SortClasses();
CHECK_RESULT(result);
uint8_t* buffer = NULL;
intptr_t size = 0;
ReadFile(load_compilation_trace_filename, &buffer, &size);
Dart_Handle result = Dart_LoadCompilationTrace(buffer, size);
result = Dart_LoadCompilationTrace(buffer, size);
free(buffer);
CHECK_RESULT(result);
}
+5
View File
@@ -170,4 +170,9 @@ DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CompileAll();
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_ReadAllBytecode();
/**
* Finalizes all classes.
*/
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_FinalizeAllClasses();
#endif /* INCLUDE_DART_NATIVE_API_H_ */ /* NOLINT */
+3 -26
View File
@@ -2172,32 +2172,9 @@ void Precompiler::Obfuscate() {
}
void Precompiler::FinalizeAllClasses() {
Library& lib = Library::Handle(Z);
Class& cls = Class::Handle(Z);
for (intptr_t i = 0; i < libraries_.Length(); i++) {
lib ^= libraries_.At(i);
if (!lib.Loaded()) {
String& uri = String::Handle(Z, lib.url());
String& msg = String::Handle(
Z,
String::NewFormatted("Library '%s' is not loaded. "
"Did you forget to call Dart_FinalizeLoading?",
uri.ToCString()));
Jump(Error::Handle(Z, ApiError::New(msg)));
}
ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
while (it.HasNext()) {
cls = it.GetNextClass();
if (cls.IsDynamicClass()) {
continue; // class 'dynamic' is in the read-only VM isolate.
}
error_ = cls.EnsureIsFinalized(T);
if (!error_.IsNull()) {
Jump(error_);
}
}
error_ = Library::FinalizeAllClasses();
if (!error_.IsNull()) {
Jump(error_);
}
I->set_all_classes_finalized(true);
}
+20
View File
@@ -217,4 +217,24 @@ DART_EXPORT Dart_Handle Dart_ReadAllBytecode() {
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
DART_EXPORT Dart_Handle Dart_FinalizeAllClasses() {
#if defined(DART_PRECOMPILED_RUNTIME)
return Api::NewError("%s: All classes are already finalized in AOT runtime.",
CURRENT_FUNC);
#else
DARTSCOPE(Thread::Current());
API_TIMELINE_DURATION(T);
Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
if (Api::IsError(result)) {
return result;
}
CHECK_CALLBACK_STATE(T);
const Error& error = Error::Handle(T->zone(), Library::FinalizeAllClasses());
if (!error.IsNull()) {
return Api::NewHandle(T, error.raw());
}
return Api::Success();
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
} // namespace dart
+33
View File
@@ -12228,6 +12228,39 @@ RawError* Library::CompileAll(bool ignore_error /* = false */) {
}
#if !defined(DART_PRECOMPILED_RUNTIME)
RawError* Library::FinalizeAllClasses() {
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
Zone* zone = thread->zone();
Error& error = Error::Handle(zone);
const GrowableObjectArray& libs = GrowableObjectArray::Handle(
Isolate::Current()->object_store()->libraries());
Library& lib = Library::Handle(zone);
Class& cls = Class::Handle(zone);
for (int i = 0; i < libs.Length(); i++) {
lib ^= libs.At(i);
if (!lib.Loaded()) {
String& uri = String::Handle(zone, lib.url());
String& msg = String::Handle(
zone,
String::NewFormatted("Library '%s' is not loaded. "
"Did you forget to call Dart_FinalizeLoading?",
uri.ToCString()));
return ApiError::New(msg);
}
ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
while (it.HasNext()) {
cls = it.GetNextClass();
error = cls.EnsureIsFinalized(thread);
if (!error.IsNull()) {
return error.raw();
}
}
}
return Error::null();
}
RawError* Library::ReadAllBytecode() {
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
+2
View File
@@ -4024,6 +4024,8 @@ class Library : public Object {
// Eagerly compile all classes and functions in the library.
static RawError* CompileAll(bool ignore_error = false);
#if !defined(DART_PRECOMPILED_RUNTIME)
// Finalize all classes in all libraries.
static RawError* FinalizeAllClasses();
// Eagerly read all bytecode.
static RawError* ReadAllBytecode();
#endif