Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Unified Diff: runtime/vm/precompiler.cc

Issue 1609983002: Precompilation: drop Field objects unless they are an entry point or referenced from a constant poo… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/precompiler.cc
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 4c42e186c2f09801526f9314f97285e5917900c6..843752c1be73ce7cd1da6a250074c50a50f2ae18 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -63,6 +63,7 @@ Precompiler::Precompiler(Thread* thread, bool reset_fields) :
class_count_(0),
selector_count_(0),
dropped_function_count_(0),
+ dropped_field_count_(0),
libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
pending_functions_(
GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
@@ -111,6 +112,7 @@ void Precompiler::DoCompileAll(
}
DropUncompiledFunctions();
+ DropFields();
// TODO(rmacnak): DropEmptyClasses();
@@ -120,11 +122,13 @@ void Precompiler::DoCompileAll(
if (FLAG_trace_precompiler) {
THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
- " %" Pd " dynamic selectors.\n Dropped %" Pd " functions.\n",
+ " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd
+ " fields.\n",
function_count_,
class_count_,
selector_count_,
- dropped_function_count_);
+ dropped_function_count_,
+ dropped_field_count_);
}
I->set_compilation_allowed(false);
@@ -226,6 +230,7 @@ void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
}
Dart_QualifiedFunctionName vm_entry_points[] = {
+ // Functions
{ "dart:async", "::", "_setScheduleImmediateClosure" },
{ "dart:core", "::", "_completeDeferredLoads"},
{ "dart:core", "AbstractClassInstantiationError",
@@ -264,6 +269,9 @@ void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
{ "dart:_vmservice", "::", "_registerIsolate" },
{ "dart:_vmservice", "::", "boot" },
{ "dart:developer", "Metrics", "_printMetrics" },
+ // Fields
+ { "dart:core", "Error", "_stackTrace" },
+ { "dart:math", "_Random", "_state" },
{ NULL, NULL, NULL } // Must be terminated with NULL entries.
};
@@ -276,6 +284,7 @@ void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) {
Library& lib = Library::Handle(Z);
Class& cls = Class::Handle(Z);
Function& func = Function::Handle(Z);
+ Field& field = Field::Handle(Z);
String& library_uri = String::Handle(Z);
String& class_name = String::Handle(Z);
String& function_name = String::Handle(Z);
@@ -295,6 +304,7 @@ void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) {
if (class_name.raw() == Symbols::TopLevel().raw()) {
func = lib.LookupFunctionAllowPrivate(function_name);
+ field = lib.LookupFieldAllowPrivate(function_name);
} else {
cls = lib.LookupClassAllowPrivate(class_name);
if (cls.IsNull()) {
@@ -308,25 +318,31 @@ void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) {
ASSERT(!cls.IsNull());
func = cls.LookupFunctionAllowPrivate(function_name);
+ field = cls.LookupField(function_name);
}
- if (func.IsNull()) {
+ if (func.IsNull() && field.IsNull()) {
if (FLAG_trace_precompiler) {
THR_Print("WARNING: Missing %s %s %s\n",
entry_points[i].library_uri,
entry_points[i].class_name,
entry_points[i].function_name);
}
- continue;
}
- AddFunction(func);
- if (func.IsGenerativeConstructor()) {
- // Allocation stubs are referenced from the call site of the constructor,
- // not in the constructor itself. So compiling the constructor isn't
- // enough for us to discover the class is instantiated if the class isn't
- // otherwise instantiated from Dart code and only instantiated from C++.
- AddInstantiatedClass(cls);
+ if (!func.IsNull()) {
+ AddFunction(func);
+ if (func.IsGenerativeConstructor()) {
+ // Allocation stubs are referenced from the call site of the
+ // constructor, not in the constructor itself. So compiling the
+ // constructor isn't enough for us to discover the class is
+ // instantiated if the class isn't otherwise instantiated from Dart
+ // code and only instantiated from C++.
+ AddInstantiatedClass(cls);
+ }
+ }
+ if (!field.IsNull()) {
+ AddField(field);
}
}
}
@@ -526,6 +542,8 @@ void Precompiler::AddClosureCall(const ICData& call_site) {
void Precompiler::AddField(const Field& field) {
+ fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw()));
+
if (field.is_static()) {
const Object& value = Object::Handle(Z, field.StaticValue());
if (value.IsInstance()) {
@@ -907,12 +925,12 @@ void Precompiler::DropUncompiledFunctions() {
}
}
- functions = Array::New(retained_functions.Length(), Heap::kOld);
- for (intptr_t j = 0; j < retained_functions.Length(); j++) {
- function ^= retained_functions.At(j);
- functions.SetAt(j, function);
+ if (retained_functions.Length() > 0) {
+ functions = Array::MakeArray(retained_functions);
+ cls.SetFunctions(functions);
+ } else {
+ cls.SetFunctions(Object::empty_array());
}
- cls.SetFunctions(functions);
}
}
@@ -934,6 +952,49 @@ void Precompiler::DropUncompiledFunctions() {
}
+void Precompiler::DropFields() {
+ Library& lib = Library::Handle(Z);
+ Class& cls = Class::Handle(Z);
+ Array& fields = Array::Handle(Z);
+ Field& field = Field::Handle(Z);
+ GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
+
+ for (intptr_t i = 0; i < libraries_.Length(); i++) {
+ lib ^= libraries_.At(i);
+ ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+ while (it.HasNext()) {
+ cls = it.GetNextClass();
+ if (cls.IsDynamicClass()) {
+ continue; // class 'dynamic' is in the read-only VM isolate.
+ }
+
+ fields = cls.fields();
+ retained_fields = GrowableObjectArray::New();
+ for (intptr_t j = 0; j < fields.Length(); j++) {
+ field ^= fields.At(j);
+ bool drop = fields_to_retain_.Lookup(&field) == NULL;
+ if (drop) {
+ dropped_field_count_++;
+ if (FLAG_trace_precompiler) {
+ THR_Print("Precompilation dropping %s\n",
+ field.ToCString());
+ }
+ } else {
+ retained_fields.Add(field);
+ }
+ }
+
+ if (retained_fields.Length() > 0) {
+ fields = Array::MakeArray(retained_fields);
+ cls.SetFields(fields);
+ } else {
+ cls.SetFields(Object::empty_array());
+ }
+ }
+ }
+}
+
+
void Precompiler::BindStaticCalls() {
class BindStaticCallsVisitor : public FunctionVisitor {
public:
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698