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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/precompiler.h" 5 #include "vm/precompiler.h"
6 6
7 #include "vm/cha.h" 7 #include "vm/cha.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/hash_table.h" 10 #include "vm/hash_table.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 Precompiler::Precompiler(Thread* thread, bool reset_fields) : 56 Precompiler::Precompiler(Thread* thread, bool reset_fields) :
57 thread_(thread), 57 thread_(thread),
58 zone_(thread->zone()), 58 zone_(thread->zone()),
59 isolate_(thread->isolate()), 59 isolate_(thread->isolate()),
60 reset_fields_(reset_fields), 60 reset_fields_(reset_fields),
61 changed_(false), 61 changed_(false),
62 function_count_(0), 62 function_count_(0),
63 class_count_(0), 63 class_count_(0),
64 selector_count_(0), 64 selector_count_(0),
65 dropped_function_count_(0), 65 dropped_function_count_(0),
66 dropped_field_count_(0),
66 libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())), 67 libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
67 pending_functions_( 68 pending_functions_(
68 GrowableObjectArray::Handle(Z, GrowableObjectArray::New())), 69 GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
69 sent_selectors_(), 70 sent_selectors_(),
70 enqueued_functions_(), 71 enqueued_functions_(),
71 error_(Error::Handle(Z)) { 72 error_(Error::Handle(Z)) {
72 } 73 }
73 74
74 75
75 void Precompiler::DoCompileAll( 76 void Precompiler::DoCompileAll(
(...skipping 28 matching lines...) Expand all
104 105
105 // Start with the allocations and invocations that happen from C++. 106 // Start with the allocations and invocations that happen from C++.
106 AddRoots(embedder_entry_points); 107 AddRoots(embedder_entry_points);
107 108
108 // Compile newly found targets and add their callees until we reach a fixed 109 // Compile newly found targets and add their callees until we reach a fixed
109 // point. 110 // point.
110 Iterate(); 111 Iterate();
111 } 112 }
112 113
113 DropUncompiledFunctions(); 114 DropUncompiledFunctions();
115 DropFields();
114 116
115 // TODO(rmacnak): DropEmptyClasses(); 117 // TODO(rmacnak): DropEmptyClasses();
116 118
117 BindStaticCalls(); 119 BindStaticCalls();
118 120
119 DedupStackmaps(); 121 DedupStackmaps();
120 122
121 if (FLAG_trace_precompiler) { 123 if (FLAG_trace_precompiler) {
122 THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types," 124 THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
123 " %" Pd " dynamic selectors.\n Dropped %" Pd " functions.\n", 125 " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd
126 " fields.\n",
124 function_count_, 127 function_count_,
125 class_count_, 128 class_count_,
126 selector_count_, 129 selector_count_,
127 dropped_function_count_); 130 dropped_function_count_,
131 dropped_field_count_);
128 } 132 }
129 133
130 I->set_compilation_allowed(false); 134 I->set_compilation_allowed(false);
131 } 135 }
132 136
133 137
134 void Precompiler::ClearAllCode() { 138 void Precompiler::ClearAllCode() {
135 class ClearCodeFunctionVisitor : public FunctionVisitor { 139 class ClearCodeFunctionVisitor : public FunctionVisitor {
136 void VisitFunction(const Function& function) { 140 void VisitFunction(const Function& function) {
137 function.ClearCode(); 141 function.ClearCode();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 kIllegalCid 223 kIllegalCid
220 }; 224 };
221 225
222 Class& cls = Class::Handle(Z); 226 Class& cls = Class::Handle(Z);
223 for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) { 227 for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) {
224 cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]); 228 cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]);
225 AddInstantiatedClass(cls); 229 AddInstantiatedClass(cls);
226 } 230 }
227 231
228 Dart_QualifiedFunctionName vm_entry_points[] = { 232 Dart_QualifiedFunctionName vm_entry_points[] = {
233 // Functions
229 { "dart:async", "::", "_setScheduleImmediateClosure" }, 234 { "dart:async", "::", "_setScheduleImmediateClosure" },
230 { "dart:core", "::", "_completeDeferredLoads"}, 235 { "dart:core", "::", "_completeDeferredLoads"},
231 { "dart:core", "AbstractClassInstantiationError", 236 { "dart:core", "AbstractClassInstantiationError",
232 "AbstractClassInstantiationError._create" }, 237 "AbstractClassInstantiationError._create" },
233 { "dart:core", "ArgumentError", "ArgumentError." }, 238 { "dart:core", "ArgumentError", "ArgumentError." },
234 { "dart:core", "CyclicInitializationError", 239 { "dart:core", "CyclicInitializationError",
235 "CyclicInitializationError." }, 240 "CyclicInitializationError." },
236 { "dart:core", "FallThroughError", "FallThroughError._create" }, 241 { "dart:core", "FallThroughError", "FallThroughError._create" },
237 { "dart:core", "FormatException", "FormatException." }, 242 { "dart:core", "FormatException", "FormatException." },
238 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, 243 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" },
(...skipping 18 matching lines...) Expand all
257 { "dart:isolate", "::", "_startMainIsolate" }, 262 { "dart:isolate", "::", "_startMainIsolate" },
258 { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" }, 263 { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" },
259 { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" }, 264 { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" },
260 { "dart:isolate", "_SendPortImpl", "send" }, 265 { "dart:isolate", "_SendPortImpl", "send" },
261 { "dart:typed_data", "ByteData", "ByteData." }, 266 { "dart:typed_data", "ByteData", "ByteData." },
262 { "dart:typed_data", "ByteData", "ByteData._view" }, 267 { "dart:typed_data", "ByteData", "ByteData._view" },
263 { "dart:typed_data", "_ByteBuffer", "_ByteBuffer._New" }, 268 { "dart:typed_data", "_ByteBuffer", "_ByteBuffer._New" },
264 { "dart:_vmservice", "::", "_registerIsolate" }, 269 { "dart:_vmservice", "::", "_registerIsolate" },
265 { "dart:_vmservice", "::", "boot" }, 270 { "dart:_vmservice", "::", "boot" },
266 { "dart:developer", "Metrics", "_printMetrics" }, 271 { "dart:developer", "Metrics", "_printMetrics" },
272 // Fields
273 { "dart:core", "Error", "_stackTrace" },
274 { "dart:math", "_Random", "_state" },
267 { NULL, NULL, NULL } // Must be terminated with NULL entries. 275 { NULL, NULL, NULL } // Must be terminated with NULL entries.
268 }; 276 };
269 277
270 AddEntryPoints(vm_entry_points); 278 AddEntryPoints(vm_entry_points);
271 AddEntryPoints(embedder_entry_points); 279 AddEntryPoints(embedder_entry_points);
272 } 280 }
273 281
274 282
275 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) { 283 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) {
276 Library& lib = Library::Handle(Z); 284 Library& lib = Library::Handle(Z);
277 Class& cls = Class::Handle(Z); 285 Class& cls = Class::Handle(Z);
278 Function& func = Function::Handle(Z); 286 Function& func = Function::Handle(Z);
287 Field& field = Field::Handle(Z);
279 String& library_uri = String::Handle(Z); 288 String& library_uri = String::Handle(Z);
280 String& class_name = String::Handle(Z); 289 String& class_name = String::Handle(Z);
281 String& function_name = String::Handle(Z); 290 String& function_name = String::Handle(Z);
282 291
283 for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) { 292 for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) {
284 library_uri = Symbols::New(entry_points[i].library_uri); 293 library_uri = Symbols::New(entry_points[i].library_uri);
285 class_name = Symbols::New(entry_points[i].class_name); 294 class_name = Symbols::New(entry_points[i].class_name);
286 function_name = Symbols::New(entry_points[i].function_name); 295 function_name = Symbols::New(entry_points[i].function_name);
287 296
288 lib = Library::LookupLibrary(library_uri); 297 lib = Library::LookupLibrary(library_uri);
289 if (lib.IsNull()) { 298 if (lib.IsNull()) {
290 if (FLAG_trace_precompiler) { 299 if (FLAG_trace_precompiler) {
291 THR_Print("WARNING: Missing %s\n", entry_points[i].library_uri); 300 THR_Print("WARNING: Missing %s\n", entry_points[i].library_uri);
292 } 301 }
293 continue; 302 continue;
294 } 303 }
295 304
296 if (class_name.raw() == Symbols::TopLevel().raw()) { 305 if (class_name.raw() == Symbols::TopLevel().raw()) {
297 func = lib.LookupFunctionAllowPrivate(function_name); 306 func = lib.LookupFunctionAllowPrivate(function_name);
307 field = lib.LookupFieldAllowPrivate(function_name);
298 } else { 308 } else {
299 cls = lib.LookupClassAllowPrivate(class_name); 309 cls = lib.LookupClassAllowPrivate(class_name);
300 if (cls.IsNull()) { 310 if (cls.IsNull()) {
301 if (FLAG_trace_precompiler) { 311 if (FLAG_trace_precompiler) {
302 THR_Print("WARNING: Missing %s %s\n", 312 THR_Print("WARNING: Missing %s %s\n",
303 entry_points[i].library_uri, 313 entry_points[i].library_uri,
304 entry_points[i].class_name); 314 entry_points[i].class_name);
305 } 315 }
306 continue; 316 continue;
307 } 317 }
308 318
309 ASSERT(!cls.IsNull()); 319 ASSERT(!cls.IsNull());
310 func = cls.LookupFunctionAllowPrivate(function_name); 320 func = cls.LookupFunctionAllowPrivate(function_name);
321 field = cls.LookupField(function_name);
311 } 322 }
312 323
313 if (func.IsNull()) { 324 if (func.IsNull() && field.IsNull()) {
314 if (FLAG_trace_precompiler) { 325 if (FLAG_trace_precompiler) {
315 THR_Print("WARNING: Missing %s %s %s\n", 326 THR_Print("WARNING: Missing %s %s %s\n",
316 entry_points[i].library_uri, 327 entry_points[i].library_uri,
317 entry_points[i].class_name, 328 entry_points[i].class_name,
318 entry_points[i].function_name); 329 entry_points[i].function_name);
319 } 330 }
320 continue;
321 } 331 }
322 332
323 AddFunction(func); 333 if (!func.IsNull()) {
324 if (func.IsGenerativeConstructor()) { 334 AddFunction(func);
325 // Allocation stubs are referenced from the call site of the constructor, 335 if (func.IsGenerativeConstructor()) {
326 // not in the constructor itself. So compiling the constructor isn't 336 // Allocation stubs are referenced from the call site of the
327 // enough for us to discover the class is instantiated if the class isn't 337 // constructor, not in the constructor itself. So compiling the
328 // otherwise instantiated from Dart code and only instantiated from C++. 338 // constructor isn't enough for us to discover the class is
329 AddInstantiatedClass(cls); 339 // instantiated if the class isn't otherwise instantiated from Dart
340 // code and only instantiated from C++.
341 AddInstantiatedClass(cls);
342 }
343 }
344 if (!field.IsNull()) {
345 AddField(field);
330 } 346 }
331 } 347 }
332 } 348 }
333 349
334 350
335 void Precompiler::Iterate() { 351 void Precompiler::Iterate() {
336 Function& function = Function::Handle(Z); 352 Function& function = Function::Handle(Z);
337 353
338 while (changed_) { 354 while (changed_) {
339 changed_ = false; 355 changed_ = false;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 const Function& dispatcher = Function::Handle(Z, 535 const Function& dispatcher = Function::Handle(Z,
520 cache_class.GetInvocationDispatcher(Symbols::Call(), 536 cache_class.GetInvocationDispatcher(Symbols::Call(),
521 arguments_descriptor, 537 arguments_descriptor,
522 RawFunction::kInvokeFieldDispatcher, 538 RawFunction::kInvokeFieldDispatcher,
523 true /* create_if_absent */)); 539 true /* create_if_absent */));
524 AddFunction(dispatcher); 540 AddFunction(dispatcher);
525 } 541 }
526 542
527 543
528 void Precompiler::AddField(const Field& field) { 544 void Precompiler::AddField(const Field& field) {
545 fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw()));
546
529 if (field.is_static()) { 547 if (field.is_static()) {
530 const Object& value = Object::Handle(Z, field.StaticValue()); 548 const Object& value = Object::Handle(Z, field.StaticValue());
531 if (value.IsInstance()) { 549 if (value.IsInstance()) {
532 AddConstObject(Instance::Cast(value)); 550 AddConstObject(Instance::Cast(value));
533 } 551 }
534 552
535 if (field.has_initializer()) { 553 if (field.has_initializer()) {
536 // Should not be in the middle of initialization while precompiling. 554 // Should not be in the middle of initialization while precompiling.
537 ASSERT(value.raw() != Object::transition_sentinel().raw()); 555 ASSERT(value.raw() != Object::transition_sentinel().raw());
538 556
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 function.DropUncompiledImplicitClosureFunction(); 918 function.DropUncompiledImplicitClosureFunction();
901 } else { 919 } else {
902 dropped_function_count_++; 920 dropped_function_count_++;
903 if (FLAG_trace_precompiler) { 921 if (FLAG_trace_precompiler) {
904 THR_Print("Precompilation dropping %s\n", 922 THR_Print("Precompilation dropping %s\n",
905 function.ToLibNamePrefixedQualifiedCString()); 923 function.ToLibNamePrefixedQualifiedCString());
906 } 924 }
907 } 925 }
908 } 926 }
909 927
910 functions = Array::New(retained_functions.Length(), Heap::kOld); 928 if (retained_functions.Length() > 0) {
911 for (intptr_t j = 0; j < retained_functions.Length(); j++) { 929 functions = Array::MakeArray(retained_functions);
912 function ^= retained_functions.At(j); 930 cls.SetFunctions(functions);
913 functions.SetAt(j, function); 931 } else {
932 cls.SetFunctions(Object::empty_array());
914 } 933 }
915 cls.SetFunctions(functions);
916 } 934 }
917 } 935 }
918 936
919 closures = isolate()->object_store()->closure_functions(); 937 closures = isolate()->object_store()->closure_functions();
920 retained_functions = GrowableObjectArray::New(); 938 retained_functions = GrowableObjectArray::New();
921 for (intptr_t j = 0; j < closures.Length(); j++) { 939 for (intptr_t j = 0; j < closures.Length(); j++) {
922 function ^= closures.At(j); 940 function ^= closures.At(j);
923 if (function.HasCode()) { 941 if (function.HasCode()) {
924 retained_functions.Add(function); 942 retained_functions.Add(function);
925 } else { 943 } else {
926 dropped_function_count_++; 944 dropped_function_count_++;
927 if (FLAG_trace_precompiler) { 945 if (FLAG_trace_precompiler) {
928 THR_Print("Precompilation dropping %s\n", 946 THR_Print("Precompilation dropping %s\n",
929 function.ToLibNamePrefixedQualifiedCString()); 947 function.ToLibNamePrefixedQualifiedCString());
930 } 948 }
931 } 949 }
932 } 950 }
933 isolate()->object_store()->set_closure_functions(retained_functions); 951 isolate()->object_store()->set_closure_functions(retained_functions);
934 } 952 }
935 953
936 954
955 void Precompiler::DropFields() {
956 Library& lib = Library::Handle(Z);
957 Class& cls = Class::Handle(Z);
958 Array& fields = Array::Handle(Z);
959 Field& field = Field::Handle(Z);
960 GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
961
962 for (intptr_t i = 0; i < libraries_.Length(); i++) {
963 lib ^= libraries_.At(i);
964 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
965 while (it.HasNext()) {
966 cls = it.GetNextClass();
967 if (cls.IsDynamicClass()) {
968 continue; // class 'dynamic' is in the read-only VM isolate.
969 }
970
971 fields = cls.fields();
972 retained_fields = GrowableObjectArray::New();
973 for (intptr_t j = 0; j < fields.Length(); j++) {
974 field ^= fields.At(j);
975 bool drop = fields_to_retain_.Lookup(&field) == NULL;
976 if (drop) {
977 dropped_field_count_++;
978 if (FLAG_trace_precompiler) {
979 THR_Print("Precompilation dropping %s\n",
980 field.ToCString());
981 }
982 } else {
983 retained_fields.Add(field);
984 }
985 }
986
987 if (retained_fields.Length() > 0) {
988 fields = Array::MakeArray(retained_fields);
989 cls.SetFields(fields);
990 } else {
991 cls.SetFields(Object::empty_array());
992 }
993 }
994 }
995 }
996
997
937 void Precompiler::BindStaticCalls() { 998 void Precompiler::BindStaticCalls() {
938 class BindStaticCallsVisitor : public FunctionVisitor { 999 class BindStaticCallsVisitor : public FunctionVisitor {
939 public: 1000 public:
940 explicit BindStaticCallsVisitor(Zone* zone) : 1001 explicit BindStaticCallsVisitor(Zone* zone) :
941 code_(Code::Handle(zone)), 1002 code_(Code::Handle(zone)),
942 table_(Array::Handle(zone)), 1003 table_(Array::Handle(zone)),
943 pc_offset_(Smi::Handle(zone)), 1004 pc_offset_(Smi::Handle(zone)),
944 target_(Function::Handle(zone)), 1005 target_(Function::Handle(zone)),
945 target_code_(Code::Handle(zone)) { 1006 target_code_(Code::Handle(zone)) {
946 } 1007 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 cls = it.GetNextClass(); 1202 cls = it.GetNextClass();
1142 if (cls.IsDynamicClass()) { 1203 if (cls.IsDynamicClass()) {
1143 continue; // class 'dynamic' is in the read-only VM isolate. 1204 continue; // class 'dynamic' is in the read-only VM isolate.
1144 } 1205 }
1145 cls.set_is_allocated(false); 1206 cls.set_is_allocated(false);
1146 } 1207 }
1147 } 1208 }
1148 } 1209 }
1149 1210
1150 } // namespace dart 1211 } // namespace dart
OLDNEW
« 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