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

Side by Side Diff: runtime/vm/precompiler.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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/proccpuinfo.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/aot_optimizer.h" 7 #include "vm/aot_optimizer.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/branch_optimizer.h" 10 #include "vm/branch_optimizer.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 namespace dart { 46 namespace dart {
47 47
48 48
49 #define T (thread()) 49 #define T (thread())
50 #define I (isolate()) 50 #define I (isolate())
51 #define Z (zone()) 51 #define Z (zone())
52 52
53 53
54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); 54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); 55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
56 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1, 56 DEFINE_FLAG(
57 int,
58 max_speculative_inlining_attempts,
59 1,
57 "Max number of attempts with speculative inlining (precompilation only)"); 60 "Max number of attempts with speculative inlining (precompilation only)");
58 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); 61 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations");
59 62
60 DECLARE_FLAG(bool, allocation_sinking); 63 DECLARE_FLAG(bool, allocation_sinking);
61 DECLARE_FLAG(bool, common_subexpression_elimination); 64 DECLARE_FLAG(bool, common_subexpression_elimination);
62 DECLARE_FLAG(bool, constant_propagation); 65 DECLARE_FLAG(bool, constant_propagation);
63 DECLARE_FLAG(bool, loop_invariant_code_motion); 66 DECLARE_FLAG(bool, loop_invariant_code_motion);
64 DECLARE_FLAG(bool, print_flow_graph); 67 DECLARE_FLAG(bool, print_flow_graph);
65 DECLARE_FLAG(bool, print_flow_graph_optimized); 68 DECLARE_FLAG(bool, print_flow_graph_optimized);
66 DECLARE_FLAG(bool, range_analysis); 69 DECLARE_FLAG(bool, range_analysis);
67 DECLARE_FLAG(bool, trace_compiler); 70 DECLARE_FLAG(bool, trace_compiler);
68 DECLARE_FLAG(bool, trace_optimizing_compiler); 71 DECLARE_FLAG(bool, trace_optimizing_compiler);
69 DECLARE_FLAG(bool, trace_bailout); 72 DECLARE_FLAG(bool, trace_bailout);
70 DECLARE_FLAG(bool, use_inlining); 73 DECLARE_FLAG(bool, use_inlining);
71 DECLARE_FLAG(bool, verify_compiler); 74 DECLARE_FLAG(bool, verify_compiler);
72 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); 75 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
73 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 76 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
74 DECLARE_FLAG(bool, trace_inlining_intervals); 77 DECLARE_FLAG(bool, trace_inlining_intervals);
75 DECLARE_FLAG(bool, trace_irregexp); 78 DECLARE_FLAG(bool, trace_irregexp);
76 79
77 #ifdef DART_PRECOMPILER 80 #ifdef DART_PRECOMPILER
78 81
79 class DartPrecompilationPipeline : public DartCompilationPipeline { 82 class DartPrecompilationPipeline : public DartCompilationPipeline {
80 public: 83 public:
81 explicit DartPrecompilationPipeline(Zone* zone, 84 explicit DartPrecompilationPipeline(Zone* zone,
82 FieldTypeMap* field_map = NULL) 85 FieldTypeMap* field_map = NULL)
83 : zone_(zone), 86 : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {}
84 result_type_(CompileType::None()),
85 field_map_(field_map) { }
86 87
87 virtual void FinalizeCompilation(FlowGraph* flow_graph) { 88 virtual void FinalizeCompilation(FlowGraph* flow_graph) {
88 if ((field_map_ != NULL )&& 89 if ((field_map_ != NULL) &&
89 flow_graph->function().IsGenerativeConstructor()) { 90 flow_graph->function().IsGenerativeConstructor()) {
90 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator(); 91 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
91 !block_it.Done(); 92 !block_it.Done(); block_it.Advance()) {
92 block_it.Advance()) {
93 ForwardInstructionIterator it(block_it.Current()); 93 ForwardInstructionIterator it(block_it.Current());
94 for (; !it.Done(); it.Advance()) { 94 for (; !it.Done(); it.Advance()) {
95 StoreInstanceFieldInstr* store = it.Current()->AsStoreInstanceField(); 95 StoreInstanceFieldInstr* store = it.Current()->AsStoreInstanceField();
96 if (store != NULL) { 96 if (store != NULL) {
97 if (!store->field().IsNull() && store->field().is_final()) { 97 if (!store->field().IsNull() && store->field().is_final()) {
98 if (FLAG_trace_precompiler && FLAG_support_il_printer) { 98 if (FLAG_trace_precompiler && FLAG_support_il_printer) {
99 THR_Print("Found store to %s <- %s\n", 99 THR_Print("Found store to %s <- %s\n",
100 store->field().ToCString(), 100 store->field().ToCString(),
101 store->value()->Type()->ToCString()); 101 store->value()->Type()->ToCString());
102 } 102 }
103 FieldTypePair* entry = field_map_->Lookup(&store->field()); 103 FieldTypePair* entry = field_map_->Lookup(&store->field());
104 if (entry == NULL) { 104 if (entry == NULL) {
105 field_map_->Insert(FieldTypePair( 105 field_map_->Insert(FieldTypePair(
106 &Field::Handle(zone_, store->field().raw()), // Re-wrap. 106 &Field::Handle(zone_, store->field().raw()), // Re-wrap.
107 store->value()->Type()->ToCid())); 107 store->value()->Type()->ToCid()));
108 if (FLAG_trace_precompiler && FLAG_support_il_printer) { 108 if (FLAG_trace_precompiler && FLAG_support_il_printer) {
109 THR_Print(" initial type = %s\n", 109 THR_Print(" initial type = %s\n",
110 store->value()->Type()->ToCString()); 110 store->value()->Type()->ToCString());
111 } 111 }
112 continue; 112 continue;
113 } 113 }
114 CompileType type = CompileType::FromCid(entry->cid_); 114 CompileType type = CompileType::FromCid(entry->cid_);
115 if (FLAG_trace_precompiler && FLAG_support_il_printer) { 115 if (FLAG_trace_precompiler && FLAG_support_il_printer) {
116 THR_Print(" old type = %s\n", type.ToCString()); 116 THR_Print(" old type = %s\n", type.ToCString());
117 } 117 }
118 type.Union(store->value()->Type()); 118 type.Union(store->value()->Type());
119 if (FLAG_trace_precompiler && FLAG_support_il_printer) { 119 if (FLAG_trace_precompiler && FLAG_support_il_printer) {
120 THR_Print(" new type = %s\n", type.ToCString()); 120 THR_Print(" new type = %s\n", type.ToCString());
121 } 121 }
122 entry->cid_ = type.ToCid(); 122 entry->cid_ = type.ToCid();
123 } 123 }
124 } 124 }
125 } 125 }
126 } 126 }
127 } 127 }
128 128
129 CompileType result_type = CompileType::None(); 129 CompileType result_type = CompileType::None();
130 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator(); 130 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
131 !block_it.Done(); 131 !block_it.Done(); block_it.Advance()) {
132 block_it.Advance()) {
133 ForwardInstructionIterator it(block_it.Current()); 132 ForwardInstructionIterator it(block_it.Current());
134 for (; !it.Done(); it.Advance()) { 133 for (; !it.Done(); it.Advance()) {
135 ReturnInstr* return_instr = it.Current()->AsReturn(); 134 ReturnInstr* return_instr = it.Current()->AsReturn();
136 if (return_instr != NULL) { 135 if (return_instr != NULL) {
137 result_type.Union(return_instr->InputAt(0)->Type()); 136 result_type.Union(return_instr->InputAt(0)->Type());
138 } 137 }
139 } 138 }
140 } 139 }
141 result_type_ = result_type; 140 result_type_ = result_type;
142 } 141 }
143 142
144 CompileType result_type() { return result_type_; } 143 CompileType result_type() { return result_type_; }
145 144
146 private: 145 private:
147 Zone* zone_; 146 Zone* zone_;
148 CompileType result_type_; 147 CompileType result_type_;
149 FieldTypeMap* field_map_; 148 FieldTypeMap* field_map_;
150 }; 149 };
151 150
152 151
153 class PrecompileParsedFunctionHelper : public ValueObject { 152 class PrecompileParsedFunctionHelper : public ValueObject {
154 public: 153 public:
155 PrecompileParsedFunctionHelper(Precompiler* precompiler, 154 PrecompileParsedFunctionHelper(Precompiler* precompiler,
156 ParsedFunction* parsed_function, 155 ParsedFunction* parsed_function,
157 bool optimized) 156 bool optimized)
158 : precompiler_(precompiler), 157 : precompiler_(precompiler),
159 parsed_function_(parsed_function), 158 parsed_function_(parsed_function),
160 optimized_(optimized), 159 optimized_(optimized),
161 thread_(Thread::Current()) { 160 thread_(Thread::Current()) {}
162 }
163 161
164 bool Compile(CompilationPipeline* pipeline); 162 bool Compile(CompilationPipeline* pipeline);
165 163
166 private: 164 private:
167 ParsedFunction* parsed_function() const { return parsed_function_; } 165 ParsedFunction* parsed_function() const { return parsed_function_; }
168 bool optimized() const { return optimized_; } 166 bool optimized() const { return optimized_; }
169 Thread* thread() const { return thread_; } 167 Thread* thread() const { return thread_; }
170 Isolate* isolate() const { return thread_->isolate(); } 168 Isolate* isolate() const { return thread_->isolate(); }
171 169
172 void FinalizeCompilation(Assembler* assembler, 170 void FinalizeCompilation(Assembler* assembler,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 intptr_t* upper_limit) { 207 intptr_t* upper_limit) {
210 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 208 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
211 209
212 if (!type.IsInstantiated()) return false; 210 if (!type.IsInstantiated()) return false;
213 if (type.IsFunctionType()) return false; 211 if (type.IsFunctionType()) return false;
214 212
215 Zone* zone = thread_->zone(); 213 Zone* zone = thread_->zone();
216 const TypeArguments& type_arguments = 214 const TypeArguments& type_arguments =
217 TypeArguments::Handle(zone, type.arguments()); 215 TypeArguments::Handle(zone, type.arguments());
218 if (!type_arguments.IsNull() && 216 if (!type_arguments.IsNull() &&
219 !type_arguments.IsRaw(0, type_arguments.Length())) return false; 217 !type_arguments.IsRaw(0, type_arguments.Length()))
218 return false;
220 219
221 220
222 intptr_t type_cid = type.type_class_id(); 221 intptr_t type_cid = type.type_class_id();
223 if (lower_limits_[type_cid] == kNotContiguous) return false; 222 if (lower_limits_[type_cid] == kNotContiguous) return false;
224 if (lower_limits_[type_cid] != kNotComputed) { 223 if (lower_limits_[type_cid] != kNotComputed) {
225 *lower_limit = lower_limits_[type_cid]; 224 *lower_limit = lower_limits_[type_cid];
226 *upper_limit = upper_limits_[type_cid]; 225 *upper_limit = upper_limits_[type_cid];
227 return true; 226 return true;
228 } 227 }
229 228
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n", 282 THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n",
284 type.ToCString(), *lower_limit, *upper_limit); 283 type.ToCString(), *lower_limit, *upper_limit);
285 } 284 }
286 285
287 lower_limits_[type_cid] = *lower_limit; 286 lower_limits_[type_cid] = *lower_limit;
288 upper_limits_[type_cid] = *upper_limit; 287 upper_limits_[type_cid] = *upper_limit;
289 return true; 288 return true;
290 } 289 }
291 290
292 291
293 Precompiler::Precompiler(Thread* thread, bool reset_fields) : 292 Precompiler::Precompiler(Thread* thread, bool reset_fields)
294 thread_(thread), 293 : thread_(thread),
295 zone_(NULL), 294 zone_(NULL),
296 isolate_(thread->isolate()), 295 isolate_(thread->isolate()),
297 reset_fields_(reset_fields), 296 reset_fields_(reset_fields),
298 changed_(false), 297 changed_(false),
299 function_count_(0), 298 function_count_(0),
300 class_count_(0), 299 class_count_(0),
301 selector_count_(0), 300 selector_count_(0),
302 dropped_function_count_(0), 301 dropped_function_count_(0),
303 dropped_field_count_(0), 302 dropped_field_count_(0),
304 dropped_class_count_(0), 303 dropped_class_count_(0),
305 dropped_typearg_count_(0), 304 dropped_typearg_count_(0),
306 dropped_type_count_(0), 305 dropped_type_count_(0),
307 dropped_library_count_(0), 306 dropped_library_count_(0),
308 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), 307 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())),
309 pending_functions_( 308 pending_functions_(
310 GrowableObjectArray::Handle(GrowableObjectArray::New())), 309 GrowableObjectArray::Handle(GrowableObjectArray::New())),
311 sent_selectors_(), 310 sent_selectors_(),
312 enqueued_functions_(), 311 enqueued_functions_(),
313 fields_to_retain_(), 312 fields_to_retain_(),
314 functions_to_retain_(), 313 functions_to_retain_(),
315 classes_to_retain_(), 314 classes_to_retain_(),
316 typeargs_to_retain_(), 315 typeargs_to_retain_(),
317 types_to_retain_(), 316 types_to_retain_(),
318 consts_to_retain_(), 317 consts_to_retain_(),
319 field_type_map_(), 318 field_type_map_(),
320 error_(Error::Handle()), 319 error_(Error::Handle()),
321 get_runtime_type_is_unique_(false) { 320 get_runtime_type_is_unique_(false) {}
322 }
323 321
324 322
325 void Precompiler::DoCompileAll( 323 void Precompiler::DoCompileAll(
326 Dart_QualifiedFunctionName embedder_entry_points[]) { 324 Dart_QualifiedFunctionName embedder_entry_points[]) {
327 ASSERT(I->compilation_allowed()); 325 ASSERT(I->compilation_allowed());
328 326
329 { 327 {
330 StackZone stack_zone(T); 328 StackZone stack_zone(T);
331 zone_ = stack_zone.GetZone(); 329 zone_ = stack_zone.GetZone();
332 330
333 { HANDLESCOPE(T); 331 {
332 HANDLESCOPE(T);
334 // Make sure class hierarchy is stable before compilation so that CHA 333 // Make sure class hierarchy is stable before compilation so that CHA
335 // can be used. Also ensures lookup of entry points won't miss functions 334 // can be used. Also ensures lookup of entry points won't miss functions
336 // because their class hasn't been finalized yet. 335 // because their class hasn't been finalized yet.
337 FinalizeAllClasses(); 336 FinalizeAllClasses();
338 337
339 SortClasses(); 338 SortClasses();
340 TypeRangeCache trc(T, I->class_table()->NumCids()); 339 TypeRangeCache trc(T, I->class_table()->NumCids());
341 340
342 // Precompile static initializers to compute result type information. 341 // Precompile static initializers to compute result type information.
343 PrecompileStaticInitializers(); 342 PrecompileStaticInitializers();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 // Ignore compile-time errors here. If the field is actually used, 446 // Ignore compile-time errors here. If the field is actually used,
448 // the error will be reported later during Iterate(). 447 // the error will be reported later during Iterate().
449 } 448 }
450 } 449 }
451 450
452 451
453 void Precompiler::PrecompileStaticInitializers() { 452 void Precompiler::PrecompileStaticInitializers() {
454 class StaticInitializerVisitor : public ClassVisitor { 453 class StaticInitializerVisitor : public ClassVisitor {
455 public: 454 public:
456 explicit StaticInitializerVisitor(Zone* zone) 455 explicit StaticInitializerVisitor(Zone* zone)
457 : fields_(Array::Handle(zone)), 456 : fields_(Array::Handle(zone)),
458 field_(Field::Handle(zone)), 457 field_(Field::Handle(zone)),
459 function_(Function::Handle(zone)) { } 458 function_(Function::Handle(zone)) {}
460 void Visit(const Class& cls) { 459 void Visit(const Class& cls) {
461 fields_ = cls.fields(); 460 fields_ = cls.fields();
462 for (intptr_t j = 0; j < fields_.Length(); j++) { 461 for (intptr_t j = 0; j < fields_.Length(); j++) {
463 field_ ^= fields_.At(j); 462 field_ ^= fields_.At(j);
464 if (field_.is_static() && 463 if (field_.is_static() && field_.is_final() &&
465 field_.is_final() &&
466 field_.has_initializer()) { 464 field_.has_initializer()) {
467 if (FLAG_trace_precompiler) { 465 if (FLAG_trace_precompiler) {
468 THR_Print("Precompiling initializer for %s\n", field_.ToCString()); 466 THR_Print("Precompiling initializer for %s\n", field_.ToCString());
469 } 467 }
470 CompileStaticInitializerIgnoreErrors(field_); 468 CompileStaticInitializerIgnoreErrors(field_);
471 } 469 }
472 } 470 }
473 } 471 }
474 472
475 private: 473 private:
476 Array& fields_; 474 Array& fields_;
477 Field& field_; 475 Field& field_;
478 Function& function_; 476 Function& function_;
479 }; 477 };
480 478
481 HANDLESCOPE(T); 479 HANDLESCOPE(T);
482 StaticInitializerVisitor visitor(Z); 480 StaticInitializerVisitor visitor(Z);
483 VisitClasses(&visitor); 481 VisitClasses(&visitor);
484 } 482 }
485 483
486 484
487 void Precompiler::PrecompileConstructors() { 485 void Precompiler::PrecompileConstructors() {
488 class ConstructorVisitor : public FunctionVisitor { 486 class ConstructorVisitor : public FunctionVisitor {
489 public: 487 public:
490 explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone) 488 explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone)
491 : precompiler_(precompiler), zone_(zone) { 489 : precompiler_(precompiler), zone_(zone) {}
492 }
493 void Visit(const Function& function) { 490 void Visit(const Function& function) {
494 if (!function.IsGenerativeConstructor()) return; 491 if (!function.IsGenerativeConstructor()) return;
495 if (function.HasCode()) { 492 if (function.HasCode()) {
496 // Const constructors may have been visited before. Recompile them here 493 // Const constructors may have been visited before. Recompile them here
497 // to collect type information for final fields for them as well. 494 // to collect type information for final fields for them as well.
498 function.ClearCode(); 495 function.ClearCode();
499 } 496 }
500 if (FLAG_trace_precompiler) { 497 if (FLAG_trace_precompiler) {
501 THR_Print("Precompiling constructor %s\n", function.ToCString()); 498 THR_Print("Precompiling constructor %s\n", function.ToCString());
502 } 499 }
503 CompileFunction(precompiler_, 500 CompileFunction(precompiler_, Thread::Current(), zone_, function,
504 Thread::Current(),
505 zone_,
506 function,
507 precompiler_->field_type_map()); 501 precompiler_->field_type_map());
508 } 502 }
509 503
510 private: 504 private:
511 Precompiler* precompiler_; 505 Precompiler* precompiler_;
512 Zone* zone_; 506 Zone* zone_;
513 }; 507 };
514 508
515 HANDLESCOPE(T); 509 HANDLESCOPE(T);
516 ConstructorVisitor visitor(this, zone_); 510 ConstructorVisitor visitor(this, zone_);
517 VisitFunctions(&visitor); 511 VisitFunctions(&visitor);
518 512
519 FieldTypeMap::Iterator it(field_type_map_.GetIterator()); 513 FieldTypeMap::Iterator it(field_type_map_.GetIterator());
520 for (FieldTypePair* current = it.Next(); 514 for (FieldTypePair* current = it.Next(); current != NULL;
521 current != NULL;
522 current = it.Next()) { 515 current = it.Next()) {
523 const intptr_t cid = current->cid_; 516 const intptr_t cid = current->cid_;
524 current->field_->set_guarded_cid(cid); 517 current->field_->set_guarded_cid(cid);
525 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); 518 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid);
526 if (FLAG_trace_precompiler) { 519 if (FLAG_trace_precompiler) {
527 THR_Print("Field %s <- Type %s\n", current->field_->ToCString(), 520 THR_Print(
521 "Field %s <- Type %s\n", current->field_->ToCString(),
528 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString()); 522 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString());
529 } 523 }
530 } 524 }
531 } 525 }
532 526
533 527
534 void Precompiler::ClearAllCode() { 528 void Precompiler::ClearAllCode() {
535 class ClearCodeFunctionVisitor : public FunctionVisitor { 529 class ClearCodeFunctionVisitor : public FunctionVisitor {
536 void Visit(const Function& function) { 530 void Visit(const Function& function) {
537 function.ClearCode(); 531 function.ClearCode();
538 function.ClearICDataArray(); 532 function.ClearICDataArray();
539 } 533 }
540 }; 534 };
541 ClearCodeFunctionVisitor function_visitor; 535 ClearCodeFunctionVisitor function_visitor;
542 VisitFunctions(&function_visitor); 536 VisitFunctions(&function_visitor);
543 537
544 class ClearCodeClassVisitor : public ClassVisitor { 538 class ClearCodeClassVisitor : public ClassVisitor {
545 void Visit(const Class& cls) { 539 void Visit(const Class& cls) { cls.DisableAllocationStub(); }
546 cls.DisableAllocationStub();
547 }
548 }; 540 };
549 ClearCodeClassVisitor class_visitor; 541 ClearCodeClassVisitor class_visitor;
550 VisitClasses(&class_visitor); 542 VisitClasses(&class_visitor);
551 } 543 }
552 544
553 545
554 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { 546 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
555 // Note that <rootlibrary>.main is not a root. The appropriate main will be 547 // Note that <rootlibrary>.main is not a root. The appropriate main will be
556 // discovered through _getMainClosure. 548 // discovered through _getMainClosure.
557 549
558 AddSelector(Symbols::NoSuchMethod()); 550 AddSelector(Symbols::NoSuchMethod());
559 551
560 AddSelector(Symbols::Call()); // For speed, not correctness. 552 AddSelector(Symbols::Call()); // For speed, not correctness.
561 553
562 // Allocated from C++. 554 // Allocated from C++.
563 Class& cls = Class::Handle(Z); 555 Class& cls = Class::Handle(Z);
564 for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) { 556 for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) {
565 ASSERT(isolate()->class_table()->IsValidIndex(cid)); 557 ASSERT(isolate()->class_table()->IsValidIndex(cid));
566 if (!isolate()->class_table()->HasValidClassAt(cid)) { 558 if (!isolate()->class_table()->HasValidClassAt(cid)) {
567 continue; 559 continue;
568 } 560 }
569 if ((cid == kDynamicCid) || 561 if ((cid == kDynamicCid) || (cid == kVoidCid) ||
570 (cid == kVoidCid) || 562 (cid == kFreeListElement) || (cid == kForwardingCorpse)) {
571 (cid == kFreeListElement) ||
572 (cid == kForwardingCorpse)) {
573 continue; 563 continue;
574 } 564 }
575 cls = isolate()->class_table()->At(cid); 565 cls = isolate()->class_table()->At(cid);
576 AddInstantiatedClass(cls); 566 AddInstantiatedClass(cls);
577 } 567 }
578 568
579 Dart_QualifiedFunctionName vm_entry_points[] = { 569 Dart_QualifiedFunctionName vm_entry_points[] = {
580 // Functions 570 // Functions
581 { "dart:async", "::", "_setScheduleImmediateClosure" }, 571 {"dart:async", "::", "_setScheduleImmediateClosure"},
582 { "dart:core", "::", "_completeDeferredLoads" }, 572 {"dart:core", "::", "_completeDeferredLoads"},
583 { "dart:core", "AbstractClassInstantiationError", 573 {"dart:core", "AbstractClassInstantiationError",
584 "AbstractClassInstantiationError._create" }, 574 "AbstractClassInstantiationError._create"},
585 { "dart:core", "ArgumentError", "ArgumentError." }, 575 {"dart:core", "ArgumentError", "ArgumentError."},
586 { "dart:core", "CyclicInitializationError", 576 {"dart:core", "CyclicInitializationError", "CyclicInitializationError."},
587 "CyclicInitializationError." }, 577 {"dart:core", "FallThroughError", "FallThroughError._create"},
588 { "dart:core", "FallThroughError", "FallThroughError._create" }, 578 {"dart:core", "FormatException", "FormatException."},
589 { "dart:core", "FormatException", "FormatException." }, 579 {"dart:core", "NoSuchMethodError", "NoSuchMethodError._withType"},
590 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, 580 {"dart:core", "NullThrownError", "NullThrownError."},
591 { "dart:core", "NullThrownError", "NullThrownError." }, 581 {"dart:core", "OutOfMemoryError", "OutOfMemoryError."},
592 { "dart:core", "OutOfMemoryError", "OutOfMemoryError." }, 582 {"dart:core", "RangeError", "RangeError."},
593 { "dart:core", "RangeError", "RangeError." }, 583 {"dart:core", "RangeError", "RangeError.range"},
594 { "dart:core", "RangeError", "RangeError.range" }, 584 {"dart:core", "StackOverflowError", "StackOverflowError."},
595 { "dart:core", "StackOverflowError", "StackOverflowError." }, 585 {"dart:core", "UnsupportedError", "UnsupportedError."},
596 { "dart:core", "UnsupportedError", "UnsupportedError." }, 586 {"dart:core", "_AssertionError", "_AssertionError._create"},
597 { "dart:core", "_AssertionError", "_AssertionError._create" }, 587 {"dart:core", "_CastError", "_CastError._create"},
598 { "dart:core", "_CastError", "_CastError._create" }, 588 {"dart:core", "_InternalError", "_InternalError."},
599 { "dart:core", "_InternalError", "_InternalError." }, 589 {"dart:core", "_InvocationMirror", "_allocateInvocationMirror"},
600 { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" }, 590 {"dart:core", "_TypeError", "_TypeError._create"},
601 { "dart:core", "_TypeError", "_TypeError._create" }, 591 {"dart:isolate", "IsolateSpawnException", "IsolateSpawnException."},
602 { "dart:isolate", "IsolateSpawnException", "IsolateSpawnException." }, 592 {"dart:isolate", "::", "_getIsolateScheduleImmediateClosure"},
603 { "dart:isolate", "::", "_getIsolateScheduleImmediateClosure" }, 593 {"dart:isolate", "::", "_setupHooks"},
604 { "dart:isolate", "::", "_setupHooks" }, 594 {"dart:isolate", "::", "_startMainIsolate"},
605 { "dart:isolate", "::", "_startMainIsolate" }, 595 {"dart:isolate", "::", "_startIsolate"},
606 { "dart:isolate", "::", "_startIsolate" }, 596 {"dart:isolate", "_RawReceivePortImpl", "_handleMessage"},
607 { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" }, 597 {"dart:isolate", "_RawReceivePortImpl", "_lookupHandler"},
608 { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" }, 598 {"dart:isolate", "_SendPortImpl", "send"},
609 { "dart:isolate", "_SendPortImpl", "send" }, 599 {"dart:typed_data", "ByteData", "ByteData."},
610 { "dart:typed_data", "ByteData", "ByteData." }, 600 {"dart:typed_data", "ByteData", "ByteData._view"},
611 { "dart:typed_data", "ByteData", "ByteData._view" }, 601 {"dart:typed_data", "ByteBuffer", "ByteBuffer._New"},
612 { "dart:typed_data", "ByteBuffer", "ByteBuffer._New" }, 602 {"dart:_vmservice", "::", "_registerIsolate"},
613 { "dart:_vmservice", "::", "_registerIsolate" }, 603 {"dart:_vmservice", "::", "boot"},
614 { "dart:_vmservice", "::", "boot" },
615 #if !defined(PRODUCT) 604 #if !defined(PRODUCT)
616 { "dart:developer", "Metrics", "_printMetrics" }, 605 {"dart:developer", "Metrics", "_printMetrics"},
617 { "dart:developer", "::", "_runExtension" }, 606 {"dart:developer", "::", "_runExtension"},
618 { "dart:isolate", "::", "_runPendingImmediateCallback" }, 607 {"dart:isolate", "::", "_runPendingImmediateCallback"},
619 #endif // !PRODUCT 608 #endif // !PRODUCT
620 // Fields 609 // Fields
621 { "dart:core", "Error", "_stackTrace" }, 610 {"dart:core", "Error", "_stackTrace"},
622 { "dart:math", "_Random", "_state" }, 611 {"dart:math", "_Random", "_state"},
623 { NULL, NULL, NULL } // Must be terminated with NULL entries. 612 {NULL, NULL, NULL} // Must be terminated with NULL entries.
624 }; 613 };
625 614
626 AddEntryPoints(vm_entry_points); 615 AddEntryPoints(vm_entry_points);
627 AddEntryPoints(embedder_entry_points); 616 AddEntryPoints(embedder_entry_points);
628 } 617 }
629 618
630 619
631 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) { 620 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) {
632 Library& lib = Library::Handle(Z); 621 Library& lib = Library::Handle(Z);
633 Class& cls = Class::Handle(Z); 622 Class& cls = Class::Handle(Z);
634 Function& func = Function::Handle(Z); 623 Function& func = Function::Handle(Z);
635 Field& field = Field::Handle(Z); 624 Field& field = Field::Handle(Z);
636 String& library_uri = String::Handle(Z); 625 String& library_uri = String::Handle(Z);
637 String& class_name = String::Handle(Z); 626 String& class_name = String::Handle(Z);
638 String& function_name = String::Handle(Z); 627 String& function_name = String::Handle(Z);
639 628
640 for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) { 629 for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) {
641 library_uri = Symbols::New(thread(), entry_points[i].library_uri); 630 library_uri = Symbols::New(thread(), entry_points[i].library_uri);
642 class_name = Symbols::New(thread(), entry_points[i].class_name); 631 class_name = Symbols::New(thread(), entry_points[i].class_name);
643 function_name = Symbols::New(thread(), entry_points[i].function_name); 632 function_name = Symbols::New(thread(), entry_points[i].function_name);
644 633
645 lib = Library::LookupLibrary(T, library_uri); 634 lib = Library::LookupLibrary(T, library_uri);
646 if (lib.IsNull()) { 635 if (lib.IsNull()) {
647 String& msg = String::Handle(Z, String::NewFormatted( 636 String& msg =
648 "Cannot find entry point %s\n", entry_points[i].library_uri)); 637 String::Handle(Z, String::NewFormatted("Cannot find entry point %s\n",
638 entry_points[i].library_uri));
649 Jump(Error::Handle(Z, ApiError::New(msg))); 639 Jump(Error::Handle(Z, ApiError::New(msg)));
650 UNREACHABLE(); 640 UNREACHABLE();
651 } 641 }
652 642
653 if (class_name.raw() == Symbols::TopLevel().raw()) { 643 if (class_name.raw() == Symbols::TopLevel().raw()) {
654 if (Library::IsPrivate(function_name)) { 644 if (Library::IsPrivate(function_name)) {
655 function_name = lib.PrivateName(function_name); 645 function_name = lib.PrivateName(function_name);
656 } 646 }
657 func = lib.LookupLocalFunction(function_name); 647 func = lib.LookupLocalFunction(function_name);
658 field = lib.LookupLocalField(function_name); 648 field = lib.LookupLocalField(function_name);
659 } else { 649 } else {
660 if (Library::IsPrivate(class_name)) { 650 if (Library::IsPrivate(class_name)) {
661 class_name = lib.PrivateName(class_name); 651 class_name = lib.PrivateName(class_name);
662 } 652 }
663 cls = lib.LookupLocalClass(class_name); 653 cls = lib.LookupLocalClass(class_name);
664 if (cls.IsNull()) { 654 if (cls.IsNull()) {
665 String& msg = String::Handle(Z, String::NewFormatted( 655 String& msg = String::Handle(
666 "Cannot find entry point %s %s\n", 656 Z, String::NewFormatted("Cannot find entry point %s %s\n",
667 entry_points[i].library_uri, 657 entry_points[i].library_uri,
668 entry_points[i].class_name)); 658 entry_points[i].class_name));
669 Jump(Error::Handle(Z, ApiError::New(msg))); 659 Jump(Error::Handle(Z, ApiError::New(msg)));
670 UNREACHABLE(); 660 UNREACHABLE();
671 } 661 }
672 662
673 ASSERT(!cls.IsNull()); 663 ASSERT(!cls.IsNull());
674 func = cls.LookupFunctionAllowPrivate(function_name); 664 func = cls.LookupFunctionAllowPrivate(function_name);
675 field = cls.LookupFieldAllowPrivate(function_name); 665 field = cls.LookupFieldAllowPrivate(function_name);
676 } 666 }
677 667
678 if (func.IsNull() && field.IsNull()) { 668 if (func.IsNull() && field.IsNull()) {
679 String& msg = String::Handle(Z, String::NewFormatted( 669 String& msg = String::Handle(
680 "Cannot find entry point %s %s %s\n", 670 Z, String::NewFormatted("Cannot find entry point %s %s %s\n",
681 entry_points[i].library_uri, 671 entry_points[i].library_uri,
682 entry_points[i].class_name, 672 entry_points[i].class_name,
683 entry_points[i].function_name)); 673 entry_points[i].function_name));
684 Jump(Error::Handle(Z, ApiError::New(msg))); 674 Jump(Error::Handle(Z, ApiError::New(msg)));
685 UNREACHABLE(); 675 UNREACHABLE();
686 } 676 }
687 677
688 if (!func.IsNull()) { 678 if (!func.IsNull()) {
689 AddFunction(func); 679 AddFunction(func);
690 if (func.IsGenerativeConstructor()) { 680 if (func.IsGenerativeConstructor()) {
691 // Allocation stubs are referenced from the call site of the 681 // Allocation stubs are referenced from the call site of the
692 // constructor, not in the constructor itself. So compiling the 682 // constructor, not in the constructor itself. So compiling the
693 // constructor isn't enough for us to discover the class is 683 // constructor isn't enough for us to discover the class is
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 if (!field_type.IsFunctionType()) continue; 742 if (!field_type.IsFunctionType()) continue;
753 field_name = field.name(); 743 field_name = field.name();
754 if (!IsSent(field_name)) continue; 744 if (!IsSent(field_name)) continue;
755 // Create arguments descriptor with fixed parameters from 745 // Create arguments descriptor with fixed parameters from
756 // signature of field_type. 746 // signature of field_type.
757 function = Type::Cast(field_type).signature(); 747 function = Type::Cast(field_type).signature();
758 if (function.HasOptionalParameters()) continue; 748 if (function.HasOptionalParameters()) continue;
759 if (FLAG_trace_precompiler) { 749 if (FLAG_trace_precompiler) {
760 THR_Print("Found callback field %s\n", field_name.ToCString()); 750 THR_Print("Found callback field %s\n", field_name.ToCString());
761 } 751 }
762 args_desc = 752 args_desc = ArgumentsDescriptor::New(function.num_fixed_parameters());
763 ArgumentsDescriptor::New(function.num_fixed_parameters());
764 cids.Clear(); 753 cids.Clear();
765 if (T->cha()->ConcreteSubclasses(cls, &cids)) { 754 if (T->cha()->ConcreteSubclasses(cls, &cids)) {
766 for (intptr_t j = 0; j < cids.length(); ++j) { 755 for (intptr_t j = 0; j < cids.length(); ++j) {
767 subcls ^= I->class_table()->At(cids[j]); 756 subcls ^= I->class_table()->At(cids[j]);
768 if (subcls.is_allocated()) { 757 if (subcls.is_allocated()) {
769 // Add dispatcher to cls. 758 // Add dispatcher to cls.
770 dispatcher = subcls.GetInvocationDispatcher( 759 dispatcher = subcls.GetInvocationDispatcher(
771 field_name, 760 field_name, args_desc, RawFunction::kInvokeFieldDispatcher,
772 args_desc,
773 RawFunction::kInvokeFieldDispatcher,
774 /* create_if_absent = */ true); 761 /* create_if_absent = */ true);
775 if (FLAG_trace_precompiler) { 762 if (FLAG_trace_precompiler) {
776 THR_Print("Added invoke-field-dispatcher for %s to %s\n", 763 THR_Print("Added invoke-field-dispatcher for %s to %s\n",
777 field_name.ToCString(), subcls.ToCString()); 764 field_name.ToCString(), subcls.ToCString());
778 } 765 }
779 AddFunction(dispatcher); 766 AddFunction(dispatcher);
780 } 767 }
781 } 768 }
782 } 769 }
783 } 770 }
784 } 771 }
785 } 772 }
786 } 773 }
787 774
788 775
789 void Precompiler::ProcessFunction(const Function& function) { 776 void Precompiler::ProcessFunction(const Function& function) {
790 if (!function.HasCode()) { 777 if (!function.HasCode()) {
791 function_count_++; 778 function_count_++;
792 779
793 if (FLAG_trace_precompiler) { 780 if (FLAG_trace_precompiler) {
794 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", 781 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", function_count_,
795 function_count_,
796 function.ToLibNamePrefixedQualifiedCString(), 782 function.ToLibNamePrefixedQualifiedCString(),
797 function.token_pos().ToCString(), 783 function.token_pos().ToCString(),
798 Function::KindToCString(function.kind())); 784 Function::KindToCString(function.kind()));
799 } 785 }
800 786
801 ASSERT(!function.is_abstract()); 787 ASSERT(!function.is_abstract());
802 ASSERT(!function.IsRedirectingFactory()); 788 ASSERT(!function.IsRedirectingFactory());
803 789
804 error_ = CompileFunction(this, thread_, zone_, function); 790 error_ = CompileFunction(this, thread_, zone_, function);
805 if (!error_.IsNull()) { 791 if (!error_.IsNull()) {
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 if (!instance.IsCanonical()) return; 1036 if (!instance.IsCanonical()) return;
1051 1037
1052 consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw())); 1038 consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw()));
1053 1039
1054 if (cls.NumTypeArguments() > 0) { 1040 if (cls.NumTypeArguments() > 0) {
1055 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); 1041 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments()));
1056 } 1042 }
1057 1043
1058 class ConstObjectVisitor : public ObjectPointerVisitor { 1044 class ConstObjectVisitor : public ObjectPointerVisitor {
1059 public: 1045 public:
1060 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) : 1046 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate)
1061 ObjectPointerVisitor(isolate), 1047 : ObjectPointerVisitor(isolate),
1062 precompiler_(precompiler), 1048 precompiler_(precompiler),
1063 subinstance_(Object::Handle()) {} 1049 subinstance_(Object::Handle()) {}
1064 1050
1065 virtual void VisitPointers(RawObject** first, RawObject** last) { 1051 virtual void VisitPointers(RawObject** first, RawObject** last) {
1066 for (RawObject** current = first; current <= last; current++) { 1052 for (RawObject** current = first; current <= last; current++) {
1067 subinstance_ = *current; 1053 subinstance_ = *current;
1068 if (subinstance_.IsInstance()) { 1054 if (subinstance_.IsInstance()) {
1069 precompiler_->AddConstObject(Instance::Cast(subinstance_)); 1055 precompiler_->AddConstObject(Instance::Cast(subinstance_));
1070 } 1056 }
1071 } 1057 }
1072 subinstance_ = Object::null(); 1058 subinstance_ = Object::null();
1073 } 1059 }
1074 1060
1075 private: 1061 private:
1076 Precompiler* precompiler_; 1062 Precompiler* precompiler_;
1077 Object& subinstance_; 1063 Object& subinstance_;
1078 }; 1064 };
1079 1065
1080 ConstObjectVisitor visitor(this, I); 1066 ConstObjectVisitor visitor(this, I);
1081 instance.raw()->VisitPointers(&visitor); 1067 instance.raw()->VisitPointers(&visitor);
1082 } 1068 }
1083 1069
1084 1070
1085 void Precompiler::AddClosureCall(const ICData& call_site) { 1071 void Precompiler::AddClosureCall(const ICData& call_site) {
1086 const Array& arguments_descriptor = 1072 const Array& arguments_descriptor =
1087 Array::Handle(Z, call_site.arguments_descriptor()); 1073 Array::Handle(Z, call_site.arguments_descriptor());
1088 const Class& cache_class = 1074 const Class& cache_class =
1089 Class::Handle(Z, I->object_store()->closure_class()); 1075 Class::Handle(Z, I->object_store()->closure_class());
1090 const Function& dispatcher = Function::Handle(Z, 1076 const Function& dispatcher = Function::Handle(
1091 cache_class.GetInvocationDispatcher(Symbols::Call(), 1077 Z, cache_class.GetInvocationDispatcher(
1092 arguments_descriptor, 1078 Symbols::Call(), arguments_descriptor,
1093 RawFunction::kInvokeFieldDispatcher, 1079 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */));
1094 true /* create_if_absent */));
1095 AddFunction(dispatcher); 1080 AddFunction(dispatcher);
1096 } 1081 }
1097 1082
1098 1083
1099 void Precompiler::AddField(const Field& field) { 1084 void Precompiler::AddField(const Field& field) {
1100 fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw())); 1085 fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw()));
1101 1086
1102 if (field.is_static()) { 1087 if (field.is_static()) {
1103 const Object& value = Object::Handle(Z, field.StaticValue()); 1088 const Object& value = Object::Handle(Z, field.StaticValue());
1104 if (value.IsInstance()) { 1089 if (value.IsInstance()) {
1105 AddConstObject(Instance::Cast(value)); 1090 AddConstObject(Instance::Cast(value));
1106 } 1091 }
1107 1092
1108 if (field.has_initializer()) { 1093 if (field.has_initializer()) {
1109 // Should not be in the middle of initialization while precompiling. 1094 // Should not be in the middle of initialization while precompiling.
1110 ASSERT(value.raw() != Object::transition_sentinel().raw()); 1095 ASSERT(value.raw() != Object::transition_sentinel().raw());
1111 1096
1112 const bool is_initialized = value.raw() != Object::sentinel().raw(); 1097 const bool is_initialized = value.raw() != Object::sentinel().raw();
1113 if (is_initialized && !reset_fields_) return; 1098 if (is_initialized && !reset_fields_) return;
1114 1099
1115 if (!field.HasPrecompiledInitializer() || 1100 if (!field.HasPrecompiledInitializer() ||
1116 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) { 1101 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
1117 if (FLAG_trace_precompiler) { 1102 if (FLAG_trace_precompiler) {
1118 THR_Print("Precompiling initializer for %s\n", field.ToCString()); 1103 THR_Print("Precompiling initializer for %s\n", field.ToCString());
1119 } 1104 }
1120 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT); 1105 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
1121 const Function& initializer = Function::Handle(Z, 1106 const Function& initializer = Function::Handle(
1122 CompileStaticInitializer(field, /* compute_type = */ true)); 1107 Z, CompileStaticInitializer(field, /* compute_type = */ true));
1123 ASSERT(!initializer.IsNull()); 1108 ASSERT(!initializer.IsNull());
1124 field.SetPrecompiledInitializer(initializer); 1109 field.SetPrecompiledInitializer(initializer);
1125 AddCalleesOf(initializer); 1110 AddCalleesOf(initializer);
1126 } 1111 }
1127 } 1112 }
1128 } 1113 }
1129 } 1114 }
1130 1115
1131 1116
1132 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, 1117 RawFunction* Precompiler::CompileStaticInitializer(const Field& field,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 if (!field.HasPrecompiledInitializer()) { 1165 if (!field.HasPrecompiledInitializer()) {
1181 initializer = CompileStaticInitializer(field, /* compute_type = */ false); 1166 initializer = CompileStaticInitializer(field, /* compute_type = */ false);
1182 } else { 1167 } else {
1183 initializer ^= field.PrecompiledInitializer(); 1168 initializer ^= field.PrecompiledInitializer();
1184 } 1169 }
1185 // Invoke the function to evaluate the expression. 1170 // Invoke the function to evaluate the expression.
1186 return DartEntry::InvokeFunction(initializer, Object::empty_array()); 1171 return DartEntry::InvokeFunction(initializer, Object::empty_array());
1187 } else { 1172 } else {
1188 Thread* const thread = Thread::Current(); 1173 Thread* const thread = Thread::Current();
1189 StackZone zone(thread); 1174 StackZone zone(thread);
1190 const Error& error = 1175 const Error& error = Error::Handle(thread->zone(), thread->sticky_error());
1191 Error::Handle(thread->zone(), thread->sticky_error());
1192 thread->clear_sticky_error(); 1176 thread->clear_sticky_error();
1193 return error.raw(); 1177 return error.raw();
1194 } 1178 }
1195 UNREACHABLE(); 1179 UNREACHABLE();
1196 return Object::null(); 1180 return Object::null();
1197 } 1181 }
1198 1182
1199 1183
1200 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) { 1184 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) {
1201 LongJumpScope jump; 1185 LongJumpScope jump;
1202 if (setjmp(*jump.Set()) == 0) { 1186 if (setjmp(*jump.Set()) == 0) {
1203 Thread* const thread = Thread::Current(); 1187 Thread* const thread = Thread::Current();
1204 if (FLAG_support_ast_printer && FLAG_trace_compiler) { 1188 if (FLAG_support_ast_printer && FLAG_trace_compiler) {
1205 THR_Print("compiling expression: "); 1189 THR_Print("compiling expression: ");
1206 AstPrinter ast_printer; 1190 AstPrinter ast_printer;
1207 ast_printer.PrintNode(fragment); 1191 ast_printer.PrintNode(fragment);
1208 } 1192 }
1209 1193
1210 // Create a dummy function object for the code generator. 1194 // Create a dummy function object for the code generator.
1211 // The function needs to be associated with a named Class: the interface 1195 // The function needs to be associated with a named Class: the interface
1212 // Function fits the bill. 1196 // Function fits the bill.
1213 const char* kEvalConst = "eval_const"; 1197 const char* kEvalConst = "eval_const";
1214 const Function& func = Function::ZoneHandle(Function::New( 1198 const Function& func = Function::ZoneHandle(Function::New(
1215 String::Handle(Symbols::New(thread, kEvalConst)), 1199 String::Handle(Symbols::New(thread, kEvalConst)),
1216 RawFunction::kRegularFunction, 1200 RawFunction::kRegularFunction,
1217 true, // static function 1201 true, // static function
1218 false, // not const function 1202 false, // not const function
1219 false, // not abstract 1203 false, // not abstract
1220 false, // not external 1204 false, // not external
1221 false, // not native 1205 false, // not native
1222 Class::Handle(Type::Handle(Type::DartFunctionType()).type_class()), 1206 Class::Handle(Type::Handle(Type::DartFunctionType()).type_class()),
1223 fragment->token_pos())); 1207 fragment->token_pos()));
1224 1208
1225 func.set_result_type(Object::dynamic_type()); 1209 func.set_result_type(Object::dynamic_type());
1226 func.set_num_fixed_parameters(0); 1210 func.set_num_fixed_parameters(0);
1227 func.SetNumOptionalParameters(0, true); 1211 func.SetNumOptionalParameters(0, true);
1228 // Manually generated AST, do not recompile. 1212 // Manually generated AST, do not recompile.
1229 func.SetIsOptimizable(false); 1213 func.SetIsOptimizable(false);
1230 func.set_is_debuggable(false); 1214 func.set_is_debuggable(false);
1231 1215
1232 // We compile the function here, even though InvokeFunction() below 1216 // We compile the function here, even though InvokeFunction() below
1233 // would compile func automatically. We are checking fewer invariants 1217 // would compile func automatically. We are checking fewer invariants
1234 // here. 1218 // here.
1235 ParsedFunction* parsed_function = new ParsedFunction(thread, func); 1219 ParsedFunction* parsed_function = new ParsedFunction(thread, func);
1236 parsed_function->SetNodeSequence(fragment); 1220 parsed_function->SetNodeSequence(fragment);
1237 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); 1221 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp());
1238 fragment->scope()->AddVariable( 1222 fragment->scope()->AddVariable(parsed_function->current_context_var());
1239 parsed_function->current_context_var());
1240 parsed_function->AllocateVariables(); 1223 parsed_function->AllocateVariables();
1241 1224
1242 // Non-optimized code generator. 1225 // Non-optimized code generator.
1243 DartPrecompilationPipeline pipeline(Thread::Current()->zone()); 1226 DartPrecompilationPipeline pipeline(Thread::Current()->zone());
1244 PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL, 1227 PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL,
1245 parsed_function, 1228 parsed_function,
1246 /* optimized = */ false); 1229 /* optimized = */ false);
1247 helper.Compile(&pipeline); 1230 helper.Compile(&pipeline);
1248 Code::Handle(func.unoptimized_code()).set_var_descriptors( 1231 Code::Handle(func.unoptimized_code())
1249 Object::empty_var_descriptors()); 1232 .set_var_descriptors(Object::empty_var_descriptors());
1250 1233
1251 const Object& result = PassiveObject::Handle( 1234 const Object& result = PassiveObject::Handle(
1252 DartEntry::InvokeFunction(func, Object::empty_array())); 1235 DartEntry::InvokeFunction(func, Object::empty_array()));
1253 return result.raw(); 1236 return result.raw();
1254 } else { 1237 } else {
1255 Thread* const thread = Thread::Current(); 1238 Thread* const thread = Thread::Current();
1256 const Object& result = 1239 const Object& result = PassiveObject::Handle(thread->sticky_error());
1257 PassiveObject::Handle(thread->sticky_error());
1258 thread->clear_sticky_error(); 1240 thread->clear_sticky_error();
1259 return result.raw(); 1241 return result.raw();
1260 } 1242 }
1261 UNREACHABLE(); 1243 UNREACHABLE();
1262 return Object::null(); 1244 return Object::null();
1263 } 1245 }
1264 1246
1265 1247
1266 void Precompiler::AddFunction(const Function& function) { 1248 void Precompiler::AddFunction(const Function& function) {
1267 if (enqueued_functions_.Lookup(&function) != NULL) return; 1249 if (enqueued_functions_.Lookup(&function) != NULL) return;
(...skipping 14 matching lines...) Expand all
1282 1264
1283 void Precompiler::AddSelector(const String& selector) { 1265 void Precompiler::AddSelector(const String& selector) {
1284 ASSERT(!selector.IsNull()); 1266 ASSERT(!selector.IsNull());
1285 1267
1286 if (!IsSent(selector)) { 1268 if (!IsSent(selector)) {
1287 sent_selectors_.Insert(&String::ZoneHandle(Z, selector.raw())); 1269 sent_selectors_.Insert(&String::ZoneHandle(Z, selector.raw()));
1288 selector_count_++; 1270 selector_count_++;
1289 changed_ = true; 1271 changed_ = true;
1290 1272
1291 if (FLAG_trace_precompiler) { 1273 if (FLAG_trace_precompiler) {
1292 THR_Print("Enqueueing selector %" Pd " %s\n", 1274 THR_Print("Enqueueing selector %" Pd " %s\n", selector_count_,
1293 selector_count_,
1294 selector.ToCString()); 1275 selector.ToCString());
1295 } 1276 }
1296 } 1277 }
1297 } 1278 }
1298 1279
1299 1280
1300 void Precompiler::AddInstantiatedClass(const Class& cls) { 1281 void Precompiler::AddInstantiatedClass(const Class& cls) {
1301 if (cls.is_allocated()) return; 1282 if (cls.is_allocated()) return;
1302 1283
1303 class_count_++; 1284 class_count_++;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 1336
1356 // Handle the implicit call type conversions. 1337 // Handle the implicit call type conversions.
1357 if (Field::IsGetterName(selector)) { 1338 if (Field::IsGetterName(selector)) {
1358 selector2 = Field::NameFromGetter(selector); 1339 selector2 = Field::NameFromGetter(selector);
1359 selector3 = Symbols::Lookup(thread(), selector2); 1340 selector3 = Symbols::Lookup(thread(), selector2);
1360 if (IsSent(selector2)) { 1341 if (IsSent(selector2)) {
1361 // Call-through-getter. 1342 // Call-through-getter.
1362 // Function is get:foo and somewhere foo is called. 1343 // Function is get:foo and somewhere foo is called.
1363 AddFunction(function); 1344 AddFunction(function);
1364 } 1345 }
1365 selector3 = Symbols::LookupFromConcat(thread(), 1346 selector3 = Symbols::LookupFromConcat(
1366 Symbols::ClosurizePrefix(), selector2); 1347 thread(), Symbols::ClosurizePrefix(), selector2);
1367 if (IsSent(selector3)) { 1348 if (IsSent(selector3)) {
1368 // Hash-closurization. 1349 // Hash-closurization.
1369 // Function is get:foo and somewhere get:#foo is called. 1350 // Function is get:foo and somewhere get:#foo is called.
1370 AddFunction(function); 1351 AddFunction(function);
1371 1352
1372 function2 = function.ImplicitClosureFunction(); 1353 function2 = function.ImplicitClosureFunction();
1373 AddFunction(function2); 1354 AddFunction(function2);
1374 1355
1375 // Add corresponding method extractor get:#foo. 1356 // Add corresponding method extractor get:#foo.
1376 function2 = function.GetMethodExtractor(selector3); 1357 function2 = function.GetMethodExtractor(selector3);
1377 AddFunction(function2); 1358 AddFunction(function2);
1378 } 1359 }
1379 } else if (Field::IsSetterName(selector)) { 1360 } else if (Field::IsSetterName(selector)) {
1380 selector2 = Symbols::LookupFromConcat(thread(), 1361 selector2 = Symbols::LookupFromConcat(
1381 Symbols::ClosurizePrefix(), selector); 1362 thread(), Symbols::ClosurizePrefix(), selector);
1382 if (IsSent(selector2)) { 1363 if (IsSent(selector2)) {
1383 // Hash-closurization. 1364 // Hash-closurization.
1384 // Function is set:foo and somewhere get:#set:foo is called. 1365 // Function is set:foo and somewhere get:#set:foo is called.
1385 AddFunction(function); 1366 AddFunction(function);
1386 1367
1387 function2 = function.ImplicitClosureFunction(); 1368 function2 = function.ImplicitClosureFunction();
1388 AddFunction(function2); 1369 AddFunction(function2);
1389 1370
1390 // Add corresponding method extractor get:#set:foo. 1371 // Add corresponding method extractor get:#set:foo.
1391 function2 = function.GetMethodExtractor(selector2); 1372 function2 = function.GetMethodExtractor(selector2);
1392 AddFunction(function2); 1373 AddFunction(function2);
1393 } 1374 }
1394 } else if (function.kind() == RawFunction::kRegularFunction) { 1375 } else if (function.kind() == RawFunction::kRegularFunction) {
1395 selector2 = Field::LookupGetterSymbol(selector); 1376 selector2 = Field::LookupGetterSymbol(selector);
1396 if (IsSent(selector2)) { 1377 if (IsSent(selector2)) {
1397 // Closurization. 1378 // Closurization.
1398 // Function is foo and somewhere get:foo is called. 1379 // Function is foo and somewhere get:foo is called.
1399 function2 = function.ImplicitClosureFunction(); 1380 function2 = function.ImplicitClosureFunction();
1400 AddFunction(function2); 1381 AddFunction(function2);
1401 1382
1402 // Add corresponding method extractor. 1383 // Add corresponding method extractor.
1403 function2 = function.GetMethodExtractor(selector2); 1384 function2 = function.GetMethodExtractor(selector2);
1404 AddFunction(function2); 1385 AddFunction(function2);
1405 } 1386 }
1406 selector2 = Symbols::LookupFromConcat(thread(), 1387 selector2 = Symbols::LookupFromConcat(
1407 Symbols::ClosurizePrefix(), selector); 1388 thread(), Symbols::ClosurizePrefix(), selector);
1408 if (IsSent(selector2)) { 1389 if (IsSent(selector2)) {
1409 // Hash-closurization. 1390 // Hash-closurization.
1410 // Function is foo and somewhere get:#foo is called. 1391 // Function is foo and somewhere get:#foo is called.
1411 function2 = function.ImplicitClosureFunction(); 1392 function2 = function.ImplicitClosureFunction();
1412 AddFunction(function2); 1393 AddFunction(function2);
1413 1394
1414 // Add corresponding method extractor get:#foo 1395 // Add corresponding method extractor get:#foo
1415 function2 = function.GetMethodExtractor(selector2); 1396 function2 = function.GetMethodExtractor(selector2);
1416 AddFunction(function2); 1397 AddFunction(function2);
1417 } 1398 }
1418 } 1399 }
1419 } 1400 }
1420 } 1401 }
1421 } 1402 }
1422 } 1403 }
1423 1404
1424 1405
1425 class NameFunctionsTraits { 1406 class NameFunctionsTraits {
1426 public: 1407 public:
1427 static const char* Name() { return "NameFunctionsTraits"; } 1408 static const char* Name() { return "NameFunctionsTraits"; }
1428 static bool ReportStats() { return false; } 1409 static bool ReportStats() { return false; }
1429 1410
1430 static bool IsMatch(const Object& a, const Object& b) { 1411 static bool IsMatch(const Object& a, const Object& b) {
1431 return a.IsString() && b.IsString() && 1412 return a.IsString() && b.IsString() &&
1432 String::Cast(a).Equals(String::Cast(b)); 1413 String::Cast(a).Equals(String::Cast(b));
1433 } 1414 }
1434 static uword Hash(const Object& obj) { 1415 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }
1435 return String::Cast(obj).Hash(); 1416 static RawObject* NewKey(const String& str) { return str.raw(); }
1436 }
1437 static RawObject* NewKey(const String& str) {
1438 return str.raw();
1439 }
1440 }; 1417 };
1441 1418
1442 typedef UnorderedHashMap<NameFunctionsTraits> Table; 1419 typedef UnorderedHashMap<NameFunctionsTraits> Table;
1443 1420
1444 1421
1445 static void AddNameToFunctionsTable(Zone* zone, 1422 static void AddNameToFunctionsTable(Zone* zone,
1446 Table* table, 1423 Table* table,
1447 const String& fname, 1424 const String& fname,
1448 const Function& function) { 1425 const Function& function) {
1449 Array& farray = Array::Handle(zone); 1426 Array& farray = Array::Handle(zone);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 get_runtime_type_is_unique_ = !farray.IsNull() && (farray.Length() == 1); 1500 get_runtime_type_is_unique_ = !farray.IsNull() && (farray.Length() == 1);
1524 1501
1525 if (FLAG_print_unique_targets) { 1502 if (FLAG_print_unique_targets) {
1526 UniqueFunctionsSet::Iterator unique_iter(&functions_set); 1503 UniqueFunctionsSet::Iterator unique_iter(&functions_set);
1527 while (unique_iter.MoveNext()) { 1504 while (unique_iter.MoveNext()) {
1528 intptr_t curr_key = unique_iter.Current(); 1505 intptr_t curr_key = unique_iter.Current();
1529 function ^= functions_set.GetKey(curr_key); 1506 function ^= functions_set.GetKey(curr_key);
1530 THR_Print("* %s\n", function.ToQualifiedCString()); 1507 THR_Print("* %s\n", function.ToQualifiedCString());
1531 } 1508 }
1532 THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n", 1509 THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n",
1533 functions_set.NumOccupied(), table.NumOccupied()); 1510 functions_set.NumOccupied(), table.NumOccupied());
1534 } 1511 }
1535 1512
1536 isolate()->object_store()->set_unique_dynamic_targets( 1513 isolate()->object_store()->set_unique_dynamic_targets(
1537 functions_set.Release()); 1514 functions_set.Release());
1538 table.Release(); 1515 table.Release();
1539 } 1516 }
1540 1517
1541 1518
1542 void Precompiler::TraceConstFunctions() { 1519 void Precompiler::TraceConstFunctions() {
1543 // Compilation of const accessors happens outside of the treeshakers 1520 // Compilation of const accessors happens outside of the treeshakers
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 type = field.type(); 1706 type = field.type();
1730 AddType(type); 1707 AddType(type);
1731 } else { 1708 } else {
1732 bool top_level = cls.IsTopLevel(); 1709 bool top_level = cls.IsTopLevel();
1733 if (top_level) { 1710 if (top_level) {
1734 name = field.DictionaryName(); 1711 name = field.DictionaryName();
1735 lib.RemoveObject(field, name); 1712 lib.RemoveObject(field, name);
1736 } 1713 }
1737 dropped_field_count_++; 1714 dropped_field_count_++;
1738 if (FLAG_trace_precompiler) { 1715 if (FLAG_trace_precompiler) {
1739 THR_Print("Dropping field %s\n", 1716 THR_Print("Dropping field %s\n", field.ToCString());
1740 field.ToCString());
1741 } 1717 }
1742 } 1718 }
1743 } 1719 }
1744 1720
1745 if (retained_fields.Length() > 0) { 1721 if (retained_fields.Length() > 0) {
1746 fields = Array::MakeArray(retained_fields); 1722 fields = Array::MakeArray(retained_fields);
1747 cls.SetFields(fields); 1723 cls.SetFields(fields);
1748 } else { 1724 } else {
1749 cls.SetFields(Object::empty_array()); 1725 cls.SetFields(Object::empty_array());
1750 } 1726 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 } else { 1785 } else {
1810 dropped_typearg_count_++; 1786 dropped_typearg_count_++;
1811 } 1787 }
1812 } 1788 }
1813 typeargs_table.Release(); 1789 typeargs_table.Release();
1814 } 1790 }
1815 1791
1816 // Now construct a new type arguments table and save in the object store. 1792 // Now construct a new type arguments table and save in the object store.
1817 const intptr_t dict_size = 1793 const intptr_t dict_size =
1818 Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3); 1794 Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3);
1819 typeargs_array = HashTables::New<CanonicalTypeArgumentsSet>(dict_size, 1795 typeargs_array =
1820 Heap::kOld); 1796 HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld);
1821 CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); 1797 CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw());
1822 bool present; 1798 bool present;
1823 for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { 1799 for (intptr_t i = 0; i < retained_typeargs.Length(); i++) {
1824 typeargs ^= retained_typeargs.At(i); 1800 typeargs ^= retained_typeargs.At(i);
1825 present = typeargs_table.Insert(typeargs); 1801 present = typeargs_table.Insert(typeargs);
1826 ASSERT(!present); 1802 ASSERT(!present);
1827 } 1803 }
1828 object_store->set_canonical_type_arguments(typeargs_table.Release()); 1804 object_store->set_canonical_type_arguments(typeargs_table.Release());
1829 } 1805 }
1830 1806
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 ASSERT(!cls.is_allocated()); 1938 ASSERT(!cls.is_allocated());
1963 constants = cls.constants(); 1939 constants = cls.constants();
1964 ASSERT(constants.Length() == 0); 1940 ASSERT(constants.Length() == 0);
1965 1941
1966 #if defined(DEBUG) 1942 #if defined(DEBUG)
1967 intptr_t instances = 1943 intptr_t instances =
1968 class_table->StatsWithUpdatedSize(cid)->post_gc.new_count + 1944 class_table->StatsWithUpdatedSize(cid)->post_gc.new_count +
1969 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; 1945 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count;
1970 if (instances != 0) { 1946 if (instances != 0) {
1971 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", 1947 FATAL2("Want to drop class %s, but it has %" Pd " instances\n",
1972 cls.ToCString(), 1948 cls.ToCString(), instances);
1973 instances);
1974 } 1949 }
1975 #endif 1950 #endif
1976 1951
1977 dropped_class_count_++; 1952 dropped_class_count_++;
1978 if (FLAG_trace_precompiler) { 1953 if (FLAG_trace_precompiler) {
1979 THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString()); 1954 THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString());
1980 } 1955 }
1981 1956
1982 #if defined(DEBUG) 1957 #if defined(DEBUG)
1983 class_table->Unregister(cid); 1958 class_table->Unregister(cid);
1984 #endif 1959 #endif
1985 cls.set_id(kIllegalCid); // We check this when serializing. 1960 cls.set_id(kIllegalCid); // We check this when serializing.
1986 1961
1987 lib = cls.library(); 1962 lib = cls.library();
1988 name = cls.DictionaryName(); 1963 name = cls.DictionaryName();
1989 lib.RemoveObject(cls, name); 1964 lib.RemoveObject(cls, name);
1990 } 1965 }
1991 } 1966 }
1992 1967
1993 1968
1994 void Precompiler::DropLibraries() { 1969 void Precompiler::DropLibraries() {
1995 const GrowableObjectArray& retained_libraries = 1970 const GrowableObjectArray& retained_libraries =
1996 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); 1971 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
1997 const Library& root_lib = Library::Handle(Z, 1972 const Library& root_lib =
1998 I->object_store()->root_library()); 1973 Library::Handle(Z, I->object_store()->root_library());
1999 Library& lib = Library::Handle(Z); 1974 Library& lib = Library::Handle(Z);
2000 1975
2001 for (intptr_t i = 0; i < libraries_.Length(); i++) { 1976 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2002 lib ^= libraries_.At(i); 1977 lib ^= libraries_.At(i);
2003 lib.DropDependencies(); 1978 lib.DropDependencies();
2004 intptr_t entries = 0; 1979 intptr_t entries = 0;
2005 DictionaryIterator it(lib); 1980 DictionaryIterator it(lib);
2006 while (it.HasNext()) { 1981 while (it.HasNext()) {
2007 it.GetNext(); 1982 it.GetNext();
2008 entries++; 1983 entries++;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 } 2015 }
2041 2016
2042 Library::RegisterLibraries(T, retained_libraries); 2017 Library::RegisterLibraries(T, retained_libraries);
2043 libraries_ = retained_libraries.raw(); 2018 libraries_ = retained_libraries.raw();
2044 } 2019 }
2045 2020
2046 2021
2047 void Precompiler::BindStaticCalls() { 2022 void Precompiler::BindStaticCalls() {
2048 class BindStaticCallsVisitor : public FunctionVisitor { 2023 class BindStaticCallsVisitor : public FunctionVisitor {
2049 public: 2024 public:
2050 explicit BindStaticCallsVisitor(Zone* zone) : 2025 explicit BindStaticCallsVisitor(Zone* zone)
2051 code_(Code::Handle(zone)), 2026 : code_(Code::Handle(zone)),
2052 table_(Array::Handle(zone)), 2027 table_(Array::Handle(zone)),
2053 pc_offset_(Smi::Handle(zone)), 2028 pc_offset_(Smi::Handle(zone)),
2054 target_(Function::Handle(zone)), 2029 target_(Function::Handle(zone)),
2055 target_code_(Code::Handle(zone)) { 2030 target_code_(Code::Handle(zone)) {}
2056 }
2057 2031
2058 void Visit(const Function& function) { 2032 void Visit(const Function& function) {
2059 if (!function.HasCode()) { 2033 if (!function.HasCode()) {
2060 return; 2034 return;
2061 } 2035 }
2062 code_ = function.CurrentCode(); 2036 code_ = function.CurrentCode();
2063 table_ = code_.static_calls_target_table(); 2037 table_ = code_.static_calls_target_table();
2064 2038
2065 for (intptr_t i = 0; 2039 for (intptr_t i = 0; i < table_.Length();
2066 i < table_.Length();
2067 i += Code::kSCallTableEntryLength) { 2040 i += Code::kSCallTableEntryLength) {
2068 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); 2041 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry);
2069 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry); 2042 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry);
2070 if (target_.IsNull()) { 2043 if (target_.IsNull()) {
2071 target_code_ ^= table_.At(i + Code::kSCallTableCodeEntry); 2044 target_code_ ^= table_.At(i + Code::kSCallTableCodeEntry);
2072 ASSERT(!target_code_.IsNull()); 2045 ASSERT(!target_code_.IsNull());
2073 ASSERT(!target_code_.IsFunctionCode()); 2046 ASSERT(!target_code_.IsFunctionCode());
2074 // Allocation stub or AllocateContext or AllocateArray or ... 2047 // Allocation stub or AllocateContext or AllocateArray or ...
2075 } else { 2048 } else {
2076 // Static calls initially call the CallStaticFunction stub because 2049 // Static calls initially call the CallStaticFunction stub because
(...skipping 30 matching lines...) Expand all
2107 #if !defined(TARGET_ARCH_DBC) 2080 #if !defined(TARGET_ARCH_DBC)
2108 // Now that all functions have been compiled, we can switch to an instance 2081 // Now that all functions have been compiled, we can switch to an instance
2109 // call sequence that loads the Code object and entry point directly from 2082 // call sequence that loads the Code object and entry point directly from
2110 // the ic data array instead indirectly through a Function in the ic data 2083 // the ic data array instead indirectly through a Function in the ic data
2111 // array. Iterate all the object pools and rewrite the ic data from 2084 // array. Iterate all the object pools and rewrite the ic data from
2112 // (cid, target function, count) to (cid, target code, entry point), and 2085 // (cid, target function, count) to (cid, target code, entry point), and
2113 // replace the ICCallThroughFunction stub with ICCallThroughCode. 2086 // replace the ICCallThroughFunction stub with ICCallThroughCode.
2114 2087
2115 class SwitchICCallsVisitor : public FunctionVisitor { 2088 class SwitchICCallsVisitor : public FunctionVisitor {
2116 public: 2089 public:
2117 explicit SwitchICCallsVisitor(Zone* zone) : 2090 explicit SwitchICCallsVisitor(Zone* zone)
2118 zone_(zone), 2091 : zone_(zone),
2119 code_(Code::Handle(zone)), 2092 code_(Code::Handle(zone)),
2120 pool_(ObjectPool::Handle(zone)), 2093 pool_(ObjectPool::Handle(zone)),
2121 entry_(Object::Handle(zone)), 2094 entry_(Object::Handle(zone)),
2122 ic_(ICData::Handle(zone)), 2095 ic_(ICData::Handle(zone)),
2123 target_name_(String::Handle(zone)), 2096 target_name_(String::Handle(zone)),
2124 args_descriptor_(Array::Handle(zone)), 2097 args_descriptor_(Array::Handle(zone)),
2125 unlinked_(UnlinkedCall::Handle(zone)), 2098 unlinked_(UnlinkedCall::Handle(zone)),
2126 target_code_(Code::Handle(zone)), 2099 target_code_(Code::Handle(zone)),
2127 canonical_unlinked_calls_() { 2100 canonical_unlinked_calls_() {}
2128 }
2129 2101
2130 void Visit(const Function& function) { 2102 void Visit(const Function& function) {
2131 if (!function.HasCode()) { 2103 if (!function.HasCode()) {
2132 return; 2104 return;
2133 } 2105 }
2134 2106
2135 code_ = function.CurrentCode(); 2107 code_ = function.CurrentCode();
2136 pool_ = code_.object_pool(); 2108 pool_ = code_.object_pool();
2137 for (intptr_t i = 0; i < pool_.Length(); i++) { 2109 for (intptr_t i = 0; i < pool_.Length(); i++) {
2138 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; 2110 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 }; 2156 };
2185 2157
2186 ASSERT(!I->compilation_allowed()); 2158 ASSERT(!I->compilation_allowed());
2187 SwitchICCallsVisitor visitor(Z); 2159 SwitchICCallsVisitor visitor(Z);
2188 VisitFunctions(&visitor); 2160 VisitFunctions(&visitor);
2189 #endif 2161 #endif
2190 } 2162 }
2191 2163
2192 2164
2193 void Precompiler::ShareMegamorphicBuckets() { 2165 void Precompiler::ShareMegamorphicBuckets() {
2194 const GrowableObjectArray& table = GrowableObjectArray::Handle(Z, 2166 const GrowableObjectArray& table = GrowableObjectArray::Handle(
2195 I->object_store()->megamorphic_cache_table()); 2167 Z, I->object_store()->megamorphic_cache_table());
2196 if (table.IsNull()) return; 2168 if (table.IsNull()) return;
2197 MegamorphicCache& cache = MegamorphicCache::Handle(Z); 2169 MegamorphicCache& cache = MegamorphicCache::Handle(Z);
2198 2170
2199 const intptr_t capacity = 1; 2171 const intptr_t capacity = 1;
2200 const Array& buckets = Array::Handle(Z, 2172 const Array& buckets = Array::Handle(
2201 Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld)); 2173 Z, Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld));
2202 const Function& handler = 2174 const Function& handler =
2203 Function::Handle(Z, MegamorphicCacheTable::miss_handler(I)); 2175 Function::Handle(Z, MegamorphicCacheTable::miss_handler(I));
2204 MegamorphicCache::SetEntry(buckets, 0, 2176 MegamorphicCache::SetEntry(buckets, 0, MegamorphicCache::smi_illegal_cid(),
2205 MegamorphicCache::smi_illegal_cid(), handler); 2177 handler);
2206 2178
2207 for (intptr_t i = 0; i < table.Length(); i++) { 2179 for (intptr_t i = 0; i < table.Length(); i++) {
2208 cache ^= table.At(i); 2180 cache ^= table.At(i);
2209 cache.set_buckets(buckets); 2181 cache.set_buckets(buckets);
2210 cache.set_mask(capacity - 1); 2182 cache.set_mask(capacity - 1);
2211 cache.set_filled_entry_count(0); 2183 cache.set_filled_entry_count(0);
2212 } 2184 }
2213 } 2185 }
2214 2186
2215 2187
2216 void Precompiler::DedupStackmaps() { 2188 void Precompiler::DedupStackmaps() {
2217 class DedupStackmapsVisitor : public FunctionVisitor { 2189 class DedupStackmapsVisitor : public FunctionVisitor {
2218 public: 2190 public:
2219 explicit DedupStackmapsVisitor(Zone* zone) : 2191 explicit DedupStackmapsVisitor(Zone* zone)
2220 zone_(zone), 2192 : zone_(zone),
2221 canonical_stackmaps_(), 2193 canonical_stackmaps_(),
2222 code_(Code::Handle(zone)), 2194 code_(Code::Handle(zone)),
2223 stackmaps_(Array::Handle(zone)), 2195 stackmaps_(Array::Handle(zone)),
2224 stackmap_(Stackmap::Handle(zone)) { 2196 stackmap_(Stackmap::Handle(zone)) {}
2225 }
2226 2197
2227 void Visit(const Function& function) { 2198 void Visit(const Function& function) {
2228 if (!function.HasCode()) { 2199 if (!function.HasCode()) {
2229 return; 2200 return;
2230 } 2201 }
2231 code_ = function.CurrentCode(); 2202 code_ = function.CurrentCode();
2232 stackmaps_ = code_.stackmaps(); 2203 stackmaps_ = code_.stackmaps();
2233 if (stackmaps_.IsNull()) return; 2204 if (stackmaps_.IsNull()) return;
2234 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { 2205 for (intptr_t i = 0; i < stackmaps_.Length(); i++) {
2235 stackmap_ ^= stackmaps_.At(i); 2206 stackmap_ ^= stackmaps_.At(i);
(...skipping 23 matching lines...) Expand all
2259 }; 2230 };
2260 2231
2261 DedupStackmapsVisitor visitor(Z); 2232 DedupStackmapsVisitor visitor(Z);
2262 VisitFunctions(&visitor); 2233 VisitFunctions(&visitor);
2263 } 2234 }
2264 2235
2265 2236
2266 void Precompiler::DedupLists() { 2237 void Precompiler::DedupLists() {
2267 class DedupListsVisitor : public FunctionVisitor { 2238 class DedupListsVisitor : public FunctionVisitor {
2268 public: 2239 public:
2269 explicit DedupListsVisitor(Zone* zone) : 2240 explicit DedupListsVisitor(Zone* zone)
2270 zone_(zone), 2241 : zone_(zone),
2271 canonical_lists_(), 2242 canonical_lists_(),
2272 code_(Code::Handle(zone)), 2243 code_(Code::Handle(zone)),
2273 list_(Array::Handle(zone)) { 2244 list_(Array::Handle(zone)) {}
2274 }
2275 2245
2276 void Visit(const Function& function) { 2246 void Visit(const Function& function) {
2277 code_ = function.CurrentCode(); 2247 code_ = function.CurrentCode();
2278 if (!code_.IsNull()) { 2248 if (!code_.IsNull()) {
2279 list_ = code_.stackmaps(); 2249 list_ = code_.stackmaps();
2280 if (!list_.IsNull()) { 2250 if (!list_.IsNull()) {
2281 list_ = DedupList(list_); 2251 list_ = DedupList(list_);
2282 code_.set_stackmaps(list_); 2252 code_.set_stackmaps(list_);
2283 } 2253 }
2284 } 2254 }
2285 2255
2286 list_ = function.parameter_types(); 2256 list_ = function.parameter_types();
2287 if (!list_.IsNull()) { 2257 if (!list_.IsNull()) {
2288 if (!function.IsSignatureFunction() && 2258 if (!function.IsSignatureFunction() && !function.IsClosureFunction() &&
2289 !function.IsClosureFunction() && 2259 (function.name() != Symbols::Call().raw()) && !list_.InVMHeap()) {
2290 (function.name() != Symbols::Call().raw()) &&
2291 !list_.InVMHeap()) {
2292 // Parameter types not needed for function type tests. 2260 // Parameter types not needed for function type tests.
2293 for (intptr_t i = 0; i < list_.Length(); i++) { 2261 for (intptr_t i = 0; i < list_.Length(); i++) {
2294 list_.SetAt(i, Object::dynamic_type()); 2262 list_.SetAt(i, Object::dynamic_type());
2295 } 2263 }
2296 } 2264 }
2297 list_ = DedupList(list_); 2265 list_ = DedupList(list_);
2298 function.set_parameter_types(list_); 2266 function.set_parameter_types(list_);
2299 } 2267 }
2300 2268
2301 list_ = function.parameter_names(); 2269 list_ = function.parameter_names();
2302 if (!list_.IsNull()) { 2270 if (!list_.IsNull()) {
2303 if (!function.HasOptionalNamedParameters() && 2271 if (!function.HasOptionalNamedParameters() && !list_.InVMHeap()) {
2304 !list_.InVMHeap()) {
2305 // Parameter names not needed for resolution. 2272 // Parameter names not needed for resolution.
2306 for (intptr_t i = 0; i < list_.Length(); i++) { 2273 for (intptr_t i = 0; i < list_.Length(); i++) {
2307 list_.SetAt(i, Symbols::OptimizedOut()); 2274 list_.SetAt(i, Symbols::OptimizedOut());
2308 } 2275 }
2309 } 2276 }
2310 list_ = DedupList(list_); 2277 list_ = DedupList(list_);
2311 function.set_parameter_names(list_); 2278 function.set_parameter_names(list_);
2312 } 2279 }
2313 } 2280 }
2314 2281
(...skipping 15 matching lines...) Expand all
2330 }; 2297 };
2331 2298
2332 DedupListsVisitor visitor(Z); 2299 DedupListsVisitor visitor(Z);
2333 VisitFunctions(&visitor); 2300 VisitFunctions(&visitor);
2334 } 2301 }
2335 2302
2336 2303
2337 void Precompiler::DedupInstructions() { 2304 void Precompiler::DedupInstructions() {
2338 class DedupInstructionsVisitor : public FunctionVisitor { 2305 class DedupInstructionsVisitor : public FunctionVisitor {
2339 public: 2306 public:
2340 explicit DedupInstructionsVisitor(Zone* zone) : 2307 explicit DedupInstructionsVisitor(Zone* zone)
2341 zone_(zone), 2308 : zone_(zone),
2342 canonical_instructions_set_(), 2309 canonical_instructions_set_(),
2343 code_(Code::Handle(zone)), 2310 code_(Code::Handle(zone)),
2344 instructions_(Instructions::Handle(zone)) { 2311 instructions_(Instructions::Handle(zone)) {}
2345 }
2346 2312
2347 void Visit(const Function& function) { 2313 void Visit(const Function& function) {
2348 if (!function.HasCode()) { 2314 if (!function.HasCode()) {
2349 ASSERT(function.HasImplicitClosureFunction()); 2315 ASSERT(function.HasImplicitClosureFunction());
2350 return; 2316 return;
2351 } 2317 }
2352 code_ = function.CurrentCode(); 2318 code_ = function.CurrentCode();
2353 instructions_ = code_.instructions(); 2319 instructions_ = code_.instructions();
2354 instructions_ = DedupOneInstructions(instructions_); 2320 instructions_ = DedupOneInstructions(instructions_);
2355 code_.SetActiveInstructions(instructions_); 2321 code_.SetActiveInstructions(instructions_);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2422
2457 2423
2458 void Precompiler::FinalizeAllClasses() { 2424 void Precompiler::FinalizeAllClasses() {
2459 Library& lib = Library::Handle(Z); 2425 Library& lib = Library::Handle(Z);
2460 Class& cls = Class::Handle(Z); 2426 Class& cls = Class::Handle(Z);
2461 2427
2462 for (intptr_t i = 0; i < libraries_.Length(); i++) { 2428 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2463 lib ^= libraries_.At(i); 2429 lib ^= libraries_.At(i);
2464 if (!lib.Loaded()) { 2430 if (!lib.Loaded()) {
2465 String& uri = String::Handle(Z, lib.url()); 2431 String& uri = String::Handle(Z, lib.url());
2466 String& msg = String::Handle(Z, String::NewFormatted( 2432 String& msg = String::Handle(
2467 "Library '%s' is not loaded. " 2433 Z,
2468 "Did you forget to call Dart_FinalizeLoading?", uri.ToCString())); 2434 String::NewFormatted("Library '%s' is not loaded. "
2435 "Did you forget to call Dart_FinalizeLoading?",
2436 uri.ToCString()));
2469 Jump(Error::Handle(Z, ApiError::New(msg))); 2437 Jump(Error::Handle(Z, ApiError::New(msg)));
2470 } 2438 }
2471 2439
2472 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); 2440 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
2473 while (it.HasNext()) { 2441 while (it.HasNext()) {
2474 cls = it.GetNextClass(); 2442 cls = it.GetNextClass();
2475 if (cls.IsDynamicClass()) { 2443 if (cls.IsDynamicClass()) {
2476 continue; // class 'dynamic' is in the read-only VM isolate. 2444 continue; // class 'dynamic' is in the read-only VM isolate.
2477 } 2445 }
2478 error_ = cls.EnsureIsFinalized(T); 2446 error_ = cls.EnsureIsFinalized(T);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2516 } 2484 }
2517 2485
2518 while (dfs_stack.length() > 0) { 2486 while (dfs_stack.length() > 0) {
2519 intptr_t cid = dfs_stack.RemoveLast(); 2487 intptr_t cid = dfs_stack.RemoveLast();
2520 ASSERT(table->HasValidClassAt(cid)); 2488 ASSERT(table->HasValidClassAt(cid));
2521 cls = table->At(cid); 2489 cls = table->At(cid);
2522 ASSERT(!cls.IsNull()); 2490 ASSERT(!cls.IsNull());
2523 if (old_to_new_cid[cid] == -1) { 2491 if (old_to_new_cid[cid] == -1) {
2524 old_to_new_cid[cid] = next_new_cid++; 2492 old_to_new_cid[cid] = next_new_cid++;
2525 if (FLAG_trace_precompiler) { 2493 if (FLAG_trace_precompiler) {
2526 THR_Print("%" Pd ": %s, was %" Pd "\n", 2494 THR_Print("%" Pd ": %s, was %" Pd "\n", old_to_new_cid[cid],
2527 old_to_new_cid[cid], cls.ToCString(), cid); 2495 cls.ToCString(), cid);
2528 } 2496 }
2529 } 2497 }
2530 subclasses = cls.direct_subclasses(); 2498 subclasses = cls.direct_subclasses();
2531 if (!subclasses.IsNull()) { 2499 if (!subclasses.IsNull()) {
2532 for (intptr_t i = 0; i < subclasses.Length(); i++) { 2500 for (intptr_t i = 0; i < subclasses.Length(); i++) {
2533 cls ^= subclasses.At(i); 2501 cls ^= subclasses.At(i);
2534 ASSERT(!cls.IsNull()); 2502 ASSERT(!cls.IsNull());
2535 dfs_stack.Add(cls.id()); 2503 dfs_stack.Add(cls.id());
2536 } 2504 }
2537 } 2505 }
2538 } 2506 }
2539 2507
2540 // Top-level classes, typedefs, patch classes, etc. 2508 // Top-level classes, typedefs, patch classes, etc.
2541 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { 2509 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
2542 if (old_to_new_cid[cid] == -1) { 2510 if (old_to_new_cid[cid] == -1) {
2543 old_to_new_cid[cid] = next_new_cid++; 2511 old_to_new_cid[cid] = next_new_cid++;
2544 if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) { 2512 if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) {
2545 cls = table->At(cid); 2513 cls = table->At(cid);
2546 THR_Print("%" Pd ": %s, was %" Pd "\n", 2514 THR_Print("%" Pd ": %s, was %" Pd "\n", old_to_new_cid[cid],
2547 old_to_new_cid[cid], cls.ToCString(), cid); 2515 cls.ToCString(), cid);
2548 } 2516 }
2549 } 2517 }
2550 } 2518 }
2551 ASSERT(next_new_cid == num_cids); 2519 ASSERT(next_new_cid == num_cids);
2552 2520
2553 RemapClassIds(old_to_new_cid); 2521 RemapClassIds(old_to_new_cid);
2554 delete[] old_to_new_cid; 2522 delete[] old_to_new_cid;
2555 } 2523 }
2556 2524
2557 2525
2558 class CidRewriteVisitor : public ObjectVisitor { 2526 class CidRewriteVisitor : public ObjectVisitor {
2559 public: 2527 public:
2560 explicit CidRewriteVisitor(intptr_t* old_to_new_cids) 2528 explicit CidRewriteVisitor(intptr_t* old_to_new_cids)
2561 : old_to_new_cids_(old_to_new_cids) { } 2529 : old_to_new_cids_(old_to_new_cids) {}
2562 2530
2563 intptr_t Map(intptr_t cid) { 2531 intptr_t Map(intptr_t cid) {
2564 ASSERT(cid != -1); 2532 ASSERT(cid != -1);
2565 return old_to_new_cids_[cid]; 2533 return old_to_new_cids_[cid];
2566 } 2534 }
2567 2535
2568 void VisitObject(RawObject* obj) { 2536 void VisitObject(RawObject* obj) {
2569 if (obj->IsClass()) { 2537 if (obj->IsClass()) {
2570 RawClass* cls = Class::RawCast(obj); 2538 RawClass* cls = Class::RawCast(obj);
2571 cls->ptr()->id_ = Map(cls->ptr()->id_); 2539 cls->ptr()->id_ = Map(cls->ptr()->id_);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 2631
2664 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); 2632 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer);
2665 // CreateDeoptInfo uses the object pool and needs to be done before 2633 // CreateDeoptInfo uses the object pool and needs to be done before
2666 // FinalizeCode. 2634 // FinalizeCode.
2667 const Array& deopt_info_array = 2635 const Array& deopt_info_array =
2668 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler)); 2636 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler));
2669 INC_STAT(thread(), total_code_size, 2637 INC_STAT(thread(), total_code_size,
2670 deopt_info_array.Length() * sizeof(uword)); 2638 deopt_info_array.Length() * sizeof(uword));
2671 // Allocates instruction object. Since this occurs only at safepoint, 2639 // Allocates instruction object. Since this occurs only at safepoint,
2672 // there can be no concurrent access to the instruction page. 2640 // there can be no concurrent access to the instruction page.
2673 const Code& code = Code::Handle( 2641 const Code& code =
2674 Code::FinalizeCode(function, assembler, optimized())); 2642 Code::Handle(Code::FinalizeCode(function, assembler, optimized()));
2675 code.set_is_optimized(optimized()); 2643 code.set_is_optimized(optimized());
2676 code.set_owner(function); 2644 code.set_owner(function);
2677 if (!function.IsOptimizable()) { 2645 if (!function.IsOptimizable()) {
2678 // A function with huge unoptimized code can become non-optimizable 2646 // A function with huge unoptimized code can become non-optimizable
2679 // after generating unoptimized code. 2647 // after generating unoptimized code.
2680 function.set_usage_counter(INT_MIN); 2648 function.set_usage_counter(INT_MIN);
2681 } 2649 }
2682 2650
2683 const Array& intervals = graph_compiler->inlined_code_intervals(); 2651 const Array& intervals = graph_compiler->inlined_code_intervals();
2684 INC_STAT(thread(), total_code_size, 2652 INC_STAT(thread(), total_code_size, intervals.Length() * sizeof(uword));
2685 intervals.Length() * sizeof(uword));
2686 code.SetInlinedIntervals(intervals); 2653 code.SetInlinedIntervals(intervals);
2687 2654
2688 const Array& inlined_id_array = 2655 const Array& inlined_id_array =
2689 Array::Handle(zone, graph_compiler->InliningIdToFunction()); 2656 Array::Handle(zone, graph_compiler->InliningIdToFunction());
2690 INC_STAT(thread(), total_code_size, 2657 INC_STAT(thread(), total_code_size,
2691 inlined_id_array.Length() * sizeof(uword)); 2658 inlined_id_array.Length() * sizeof(uword));
2692 code.SetInlinedIdToFunction(inlined_id_array); 2659 code.SetInlinedIdToFunction(inlined_id_array);
2693 2660
2694 const Array& caller_inlining_id_map_array = 2661 const Array& caller_inlining_id_map_array =
2695 Array::Handle(zone, graph_compiler->CallerInliningIdMap()); 2662 Array::Handle(zone, graph_compiler->CallerInliningIdMap());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2760 2727
2761 // Class hierarchy analysis is registered with the thread in the 2728 // Class hierarchy analysis is registered with the thread in the
2762 // constructor and unregisters itself upon destruction. 2729 // constructor and unregisters itself upon destruction.
2763 CHA cha(thread()); 2730 CHA cha(thread());
2764 2731
2765 // TimerScope needs an isolate to be properly terminated in case of a 2732 // TimerScope needs an isolate to be properly terminated in case of a
2766 // LongJump. 2733 // LongJump.
2767 { 2734 {
2768 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer); 2735 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer);
2769 ZoneGrowableArray<const ICData*>* ic_data_array = 2736 ZoneGrowableArray<const ICData*>* ic_data_array =
2770 new(zone) ZoneGrowableArray<const ICData*>(); 2737 new (zone) ZoneGrowableArray<const ICData*>();
2771 #ifndef PRODUCT 2738 #ifndef PRODUCT
2772 TimelineDurationScope tds(thread(), 2739 TimelineDurationScope tds(thread(), compiler_timeline,
2773 compiler_timeline,
2774 "BuildFlowGraph"); 2740 "BuildFlowGraph");
2775 #endif // !PRODUCT 2741 #endif // !PRODUCT
2776 flow_graph = pipeline->BuildFlowGraph(zone, 2742 flow_graph = pipeline->BuildFlowGraph(
2777 parsed_function(), 2743 zone, parsed_function(), *ic_data_array, Compiler::kNoOSRDeoptId);
2778 *ic_data_array,
2779 Compiler::kNoOSRDeoptId);
2780 } 2744 }
2781 2745
2782 const bool print_flow_graph = 2746 const bool print_flow_graph =
2783 (FLAG_print_flow_graph || 2747 (FLAG_print_flow_graph ||
2784 (optimized() && FLAG_print_flow_graph_optimized)) && 2748 (optimized() && FLAG_print_flow_graph_optimized)) &&
2785 FlowGraphPrinter::ShouldPrint(function); 2749 FlowGraphPrinter::ShouldPrint(function);
2786 2750
2787 if (print_flow_graph) { 2751 if (print_flow_graph) {
2788 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 2752 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
2789 } 2753 }
2790 2754
2791 if (optimized()) { 2755 if (optimized()) {
2792 #ifndef PRODUCT 2756 #ifndef PRODUCT
2793 TimelineDurationScope tds(thread(), 2757 TimelineDurationScope tds(thread(), compiler_timeline, "ComputeSSA");
2794 compiler_timeline,
2795 "ComputeSSA");
2796 #endif // !PRODUCT 2758 #endif // !PRODUCT
2797 CSTAT_TIMER_SCOPE(thread(), ssa_timer); 2759 CSTAT_TIMER_SCOPE(thread(), ssa_timer);
2798 // Transform to SSA (virtual register 0 and no inlining arguments). 2760 // Transform to SSA (virtual register 0 and no inlining arguments).
2799 flow_graph->ComputeSSA(0, NULL); 2761 flow_graph->ComputeSSA(0, NULL);
2800 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2762 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2801 if (print_flow_graph) { 2763 if (print_flow_graph) {
2802 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); 2764 FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
2803 } 2765 }
2804 } 2766 }
2805 2767
2806 // Maps inline_id_to_function[inline_id] -> function. Top scope 2768 // Maps inline_id_to_function[inline_id] -> function. Top scope
2807 // function has inline_id 0. The map is populated by the inliner. 2769 // function has inline_id 0. The map is populated by the inliner.
2808 GrowableArray<const Function*> inline_id_to_function; 2770 GrowableArray<const Function*> inline_id_to_function;
2809 // Token position where inlining occured. 2771 // Token position where inlining occured.
2810 GrowableArray<TokenPosition> inline_id_to_token_pos; 2772 GrowableArray<TokenPosition> inline_id_to_token_pos;
2811 // For a given inlining-id(index) specifies the caller's inlining-id. 2773 // For a given inlining-id(index) specifies the caller's inlining-id.
2812 GrowableArray<intptr_t> caller_inline_id; 2774 GrowableArray<intptr_t> caller_inline_id;
2813 // Collect all instance fields that are loaded in the graph and 2775 // Collect all instance fields that are loaded in the graph and
2814 // have non-generic type feedback attached to them that can 2776 // have non-generic type feedback attached to them that can
2815 // potentially affect optimizations. 2777 // potentially affect optimizations.
2816 if (optimized()) { 2778 if (optimized()) {
2817 #ifndef PRODUCT 2779 #ifndef PRODUCT
2818 TimelineDurationScope tds(thread(), 2780 TimelineDurationScope tds(thread(), compiler_timeline,
2819 compiler_timeline,
2820 "OptimizationPasses"); 2781 "OptimizationPasses");
2821 #endif // !PRODUCT 2782 #endif // !PRODUCT
2822 inline_id_to_function.Add(&function); 2783 inline_id_to_function.Add(&function);
2823 // We do not add the token position now because we don't know the 2784 // We do not add the token position now because we don't know the
2824 // position of the inlined call until later. A side effect of this 2785 // position of the inlined call until later. A side effect of this
2825 // is that the length of |inline_id_to_function| is always larger 2786 // is that the length of |inline_id_to_function| is always larger
2826 // than the length of |inline_id_to_token_pos| by one. 2787 // than the length of |inline_id_to_token_pos| by one.
2827 // Top scope function has no caller (-1). We do this because we expect 2788 // Top scope function has no caller (-1). We do this because we expect
2828 // all token positions to be at an inlined call. 2789 // all token positions to be at an inlined call.
2829 // Top scope function has no caller (-1). 2790 // Top scope function has no caller (-1).
2830 caller_inline_id.Add(-1); 2791 caller_inline_id.Add(-1);
2831 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); 2792 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
2832 2793
2833 AotOptimizer optimizer(precompiler_, 2794 AotOptimizer optimizer(precompiler_, flow_graph,
2834 flow_graph, 2795 use_speculative_inlining, &inlining_black_list);
2835 use_speculative_inlining,
2836 &inlining_black_list);
2837 optimizer.PopulateWithICData(); 2796 optimizer.PopulateWithICData();
2838 2797
2839 optimizer.ApplyClassIds(); 2798 optimizer.ApplyClassIds();
2840 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2799 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2841 2800
2842 FlowGraphTypePropagator::Propagate(flow_graph); 2801 FlowGraphTypePropagator::Propagate(flow_graph);
2843 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2802 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2844 2803
2845 optimizer.ApplyICData(); 2804 optimizer.ApplyICData();
2846 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2805 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2847 2806
2848 // Optimize (a << b) & c patterns, merge operations. 2807 // Optimize (a << b) & c patterns, merge operations.
2849 // Run early in order to have more opportunity to optimize left shifts. 2808 // Run early in order to have more opportunity to optimize left shifts.
2850 flow_graph->TryOptimizePatterns(); 2809 flow_graph->TryOptimizePatterns();
2851 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2810 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2852 2811
2853 FlowGraphInliner::SetInliningId(flow_graph, 0); 2812 FlowGraphInliner::SetInliningId(flow_graph, 0);
2854 2813
2855 // Inlining (mutates the flow graph) 2814 // Inlining (mutates the flow graph)
2856 if (FLAG_use_inlining) { 2815 if (FLAG_use_inlining) {
2857 #ifndef PRODUCT 2816 #ifndef PRODUCT
2858 TimelineDurationScope tds2(thread(), 2817 TimelineDurationScope tds2(thread(), compiler_timeline, "Inlining");
2859 compiler_timeline,
2860 "Inlining");
2861 #endif // !PRODUCT 2818 #endif // !PRODUCT
2862 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer); 2819 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer);
2863 // Propagate types to create more inlining opportunities. 2820 // Propagate types to create more inlining opportunities.
2864 FlowGraphTypePropagator::Propagate(flow_graph); 2821 FlowGraphTypePropagator::Propagate(flow_graph);
2865 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2822 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2866 2823
2867 // Use propagated class-ids to create more inlining opportunities. 2824 // Use propagated class-ids to create more inlining opportunities.
2868 optimizer.ApplyClassIds(); 2825 optimizer.ApplyClassIds();
2869 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2826 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2870 2827
2871 FlowGraphInliner inliner(flow_graph, 2828 FlowGraphInliner inliner(flow_graph, &inline_id_to_function,
2872 &inline_id_to_function, 2829 &inline_id_to_token_pos, &caller_inline_id,
2873 &inline_id_to_token_pos,
2874 &caller_inline_id,
2875 use_speculative_inlining, 2830 use_speculative_inlining,
2876 &inlining_black_list, 2831 &inlining_black_list, precompiler_);
2877 precompiler_);
2878 inliner.Inline(); 2832 inliner.Inline();
2879 // Use lists are maintained and validated by the inliner. 2833 // Use lists are maintained and validated by the inliner.
2880 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2834 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2881 } 2835 }
2882 2836
2883 // Propagate types and eliminate more type tests. 2837 // Propagate types and eliminate more type tests.
2884 FlowGraphTypePropagator::Propagate(flow_graph); 2838 FlowGraphTypePropagator::Propagate(flow_graph);
2885 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2839 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2886 2840
2887 { 2841 {
2888 #ifndef PRODUCT 2842 #ifndef PRODUCT
2889 TimelineDurationScope tds2(thread(), 2843 TimelineDurationScope tds2(thread(), compiler_timeline,
2890 compiler_timeline,
2891 "ApplyClassIds"); 2844 "ApplyClassIds");
2892 #endif // !PRODUCT 2845 #endif // !PRODUCT
2893 // Use propagated class-ids to optimize further. 2846 // Use propagated class-ids to optimize further.
2894 optimizer.ApplyClassIds(); 2847 optimizer.ApplyClassIds();
2895 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2848 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2896 } 2849 }
2897 2850
2898 // Propagate types for potentially newly added instructions by 2851 // Propagate types for potentially newly added instructions by
2899 // ApplyClassIds(). Must occur before canonicalization. 2852 // ApplyClassIds(). Must occur before canonicalization.
2900 FlowGraphTypePropagator::Propagate(flow_graph); 2853 FlowGraphTypePropagator::Propagate(flow_graph);
2901 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2854 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2902 2855
2903 // Do optimizations that depend on the propagated type information. 2856 // Do optimizations that depend on the propagated type information.
2904 if (flow_graph->Canonicalize()) { 2857 if (flow_graph->Canonicalize()) {
2905 // Invoke Canonicalize twice in order to fully canonicalize patterns 2858 // Invoke Canonicalize twice in order to fully canonicalize patterns
2906 // like "if (a & const == 0) { }". 2859 // like "if (a & const == 0) { }".
2907 flow_graph->Canonicalize(); 2860 flow_graph->Canonicalize();
2908 } 2861 }
2909 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2862 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2910 2863
2911 { 2864 {
2912 #ifndef PRODUCT 2865 #ifndef PRODUCT
2913 TimelineDurationScope tds2(thread(), 2866 TimelineDurationScope tds2(thread(), compiler_timeline,
2914 compiler_timeline,
2915 "BranchSimplifier"); 2867 "BranchSimplifier");
2916 #endif // !PRODUCT 2868 #endif // !PRODUCT
2917 BranchSimplifier::Simplify(flow_graph); 2869 BranchSimplifier::Simplify(flow_graph);
2918 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2870 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2919 2871
2920 IfConverter::Simplify(flow_graph); 2872 IfConverter::Simplify(flow_graph);
2921 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2873 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2922 } 2874 }
2923 2875
2924 if (FLAG_constant_propagation) { 2876 if (FLAG_constant_propagation) {
2925 #ifndef PRODUCT 2877 #ifndef PRODUCT
2926 TimelineDurationScope tds2(thread(), 2878 TimelineDurationScope tds2(thread(), compiler_timeline,
2927 compiler_timeline,
2928 "ConstantPropagation"); 2879 "ConstantPropagation");
2929 #endif // !PRODUCT 2880 #endif // !PRODUCT
2930 ConstantPropagator::Optimize(flow_graph); 2881 ConstantPropagator::Optimize(flow_graph);
2931 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2882 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2932 // A canonicalization pass to remove e.g. smi checks on smi constants. 2883 // A canonicalization pass to remove e.g. smi checks on smi constants.
2933 flow_graph->Canonicalize(); 2884 flow_graph->Canonicalize();
2934 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2885 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2935 // Canonicalization introduced more opportunities for constant 2886 // Canonicalization introduced more opportunities for constant
2936 // propagation. 2887 // propagation.
2937 ConstantPropagator::Optimize(flow_graph); 2888 ConstantPropagator::Optimize(flow_graph);
2938 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2889 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2939 } 2890 }
2940 2891
2941 // Optimistically convert loop phis that have a single non-smi input 2892 // Optimistically convert loop phis that have a single non-smi input
2942 // coming from the loop pre-header into smi-phis. 2893 // coming from the loop pre-header into smi-phis.
2943 if (FLAG_loop_invariant_code_motion) { 2894 if (FLAG_loop_invariant_code_motion) {
2944 LICM licm(flow_graph); 2895 LICM licm(flow_graph);
2945 licm.OptimisticallySpecializeSmiPhis(); 2896 licm.OptimisticallySpecializeSmiPhis();
2946 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2897 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2947 } 2898 }
2948 2899
2949 // Propagate types and eliminate even more type tests. 2900 // Propagate types and eliminate even more type tests.
2950 // Recompute types after constant propagation to infer more precise 2901 // Recompute types after constant propagation to infer more precise
2951 // types for uses that were previously reached by now eliminated phis. 2902 // types for uses that were previously reached by now eliminated phis.
2952 FlowGraphTypePropagator::Propagate(flow_graph); 2903 FlowGraphTypePropagator::Propagate(flow_graph);
2953 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2904 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2954 2905
2955 { 2906 {
2956 #ifndef PRODUCT 2907 #ifndef PRODUCT
2957 TimelineDurationScope tds2(thread(), 2908 TimelineDurationScope tds2(thread(), compiler_timeline,
2958 compiler_timeline,
2959 "SelectRepresentations"); 2909 "SelectRepresentations");
2960 #endif // !PRODUCT 2910 #endif // !PRODUCT
2961 // Where beneficial convert Smi operations into Int32 operations. 2911 // Where beneficial convert Smi operations into Int32 operations.
2962 // Only meanigful for 32bit platforms right now. 2912 // Only meanigful for 32bit platforms right now.
2963 flow_graph->WidenSmiToInt32(); 2913 flow_graph->WidenSmiToInt32();
2964 2914
2965 // Unbox doubles. Performed after constant propagation to minimize 2915 // Unbox doubles. Performed after constant propagation to minimize
2966 // interference from phis merging double values and tagged 2916 // interference from phis merging double values and tagged
2967 // values coming from dead paths. 2917 // values coming from dead paths.
2968 flow_graph->SelectRepresentations(); 2918 flow_graph->SelectRepresentations();
2969 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2919 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2970 } 2920 }
2971 2921
2972 { 2922 {
2973 #ifndef PRODUCT 2923 #ifndef PRODUCT
2974 TimelineDurationScope tds2(thread(), 2924 TimelineDurationScope tds2(thread(), compiler_timeline,
2975 compiler_timeline,
2976 "CommonSubexpressionElinination"); 2925 "CommonSubexpressionElinination");
2977 #endif // !PRODUCT 2926 #endif // !PRODUCT
2978 if (FLAG_common_subexpression_elimination || 2927 if (FLAG_common_subexpression_elimination ||
2979 FLAG_loop_invariant_code_motion) { 2928 FLAG_loop_invariant_code_motion) {
2980 flow_graph->ComputeBlockEffects(); 2929 flow_graph->ComputeBlockEffects();
2981 } 2930 }
2982 2931
2983 if (FLAG_common_subexpression_elimination) { 2932 if (FLAG_common_subexpression_elimination) {
2984 if (DominatorBasedCSE::Optimize(flow_graph)) { 2933 if (DominatorBasedCSE::Optimize(flow_graph)) {
2985 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2934 DEBUG_ASSERT(flow_graph->VerifyUseLists());
(...skipping 20 matching lines...) Expand all
3006 } 2955 }
3007 2956
3008 // Optimize (a << b) & c patterns, merge operations. 2957 // Optimize (a << b) & c patterns, merge operations.
3009 // Run after CSE in order to have more opportunity to merge 2958 // Run after CSE in order to have more opportunity to merge
3010 // instructions that have same inputs. 2959 // instructions that have same inputs.
3011 flow_graph->TryOptimizePatterns(); 2960 flow_graph->TryOptimizePatterns();
3012 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2961 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3013 2962
3014 { 2963 {
3015 #ifndef PRODUCT 2964 #ifndef PRODUCT
3016 TimelineDurationScope tds2(thread(), 2965 TimelineDurationScope tds2(thread(), compiler_timeline,
3017 compiler_timeline,
3018 "DeadStoreElimination"); 2966 "DeadStoreElimination");
3019 #endif // !PRODUCT 2967 #endif // !PRODUCT
3020 DeadStoreElimination::Optimize(flow_graph); 2968 DeadStoreElimination::Optimize(flow_graph);
3021 } 2969 }
3022 2970
3023 if (FLAG_range_analysis) { 2971 if (FLAG_range_analysis) {
3024 #ifndef PRODUCT 2972 #ifndef PRODUCT
3025 TimelineDurationScope tds2(thread(), 2973 TimelineDurationScope tds2(thread(), compiler_timeline,
3026 compiler_timeline,
3027 "RangeAnalysis"); 2974 "RangeAnalysis");
3028 #endif // !PRODUCT 2975 #endif // !PRODUCT
3029 // Propagate types after store-load-forwarding. Some phis may have 2976 // Propagate types after store-load-forwarding. Some phis may have
3030 // become smi phis that can be processed by range analysis. 2977 // become smi phis that can be processed by range analysis.
3031 FlowGraphTypePropagator::Propagate(flow_graph); 2978 FlowGraphTypePropagator::Propagate(flow_graph);
3032 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2979 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3033 2980
3034 // We have to perform range analysis after LICM because it 2981 // We have to perform range analysis after LICM because it
3035 // optimistically moves CheckSmi through phis into loop preheaders 2982 // optimistically moves CheckSmi through phis into loop preheaders
3036 // making some phis smi. 2983 // making some phis smi.
3037 RangeAnalysis range_analysis(flow_graph); 2984 RangeAnalysis range_analysis(flow_graph);
3038 range_analysis.Analyze(); 2985 range_analysis.Analyze();
3039 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2986 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3040 } 2987 }
3041 2988
3042 if (FLAG_constant_propagation) { 2989 if (FLAG_constant_propagation) {
3043 #ifndef PRODUCT 2990 #ifndef PRODUCT
3044 TimelineDurationScope tds2(thread(), 2991 TimelineDurationScope tds2(thread(), compiler_timeline,
3045 compiler_timeline,
3046 "ConstantPropagator::OptimizeBranches"); 2992 "ConstantPropagator::OptimizeBranches");
3047 #endif // !PRODUCT 2993 #endif // !PRODUCT
3048 // Constant propagation can use information from range analysis to 2994 // Constant propagation can use information from range analysis to
3049 // find unreachable branch targets and eliminate branches that have 2995 // find unreachable branch targets and eliminate branches that have
3050 // the same true- and false-target. 2996 // the same true- and false-target.
3051 ConstantPropagator::OptimizeBranches(flow_graph); 2997 ConstantPropagator::OptimizeBranches(flow_graph);
3052 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2998 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3053 } 2999 }
3054 3000
3055 // Recompute types after code movement was done to ensure correct 3001 // Recompute types after code movement was done to ensure correct
3056 // reaching types for hoisted values. 3002 // reaching types for hoisted values.
3057 FlowGraphTypePropagator::Propagate(flow_graph); 3003 FlowGraphTypePropagator::Propagate(flow_graph);
3058 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3004 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3059 3005
3060 { 3006 {
3061 #ifndef PRODUCT 3007 #ifndef PRODUCT
3062 TimelineDurationScope tds2(thread(), 3008 TimelineDurationScope tds2(thread(), compiler_timeline,
3063 compiler_timeline,
3064 "TryCatchAnalyzer::Optimize"); 3009 "TryCatchAnalyzer::Optimize");
3065 #endif // !PRODUCT 3010 #endif // !PRODUCT
3066 // Optimize try-blocks. 3011 // Optimize try-blocks.
3067 TryCatchAnalyzer::Optimize(flow_graph); 3012 TryCatchAnalyzer::Optimize(flow_graph);
3068 } 3013 }
3069 3014
3070 // Detach environments from the instructions that can't deoptimize. 3015 // Detach environments from the instructions that can't deoptimize.
3071 // Do it before we attempt to perform allocation sinking to minimize 3016 // Do it before we attempt to perform allocation sinking to minimize
3072 // amount of materializations it has to perform. 3017 // amount of materializations it has to perform.
3073 flow_graph->EliminateEnvironments(); 3018 flow_graph->EliminateEnvironments();
3074 3019
3075 { 3020 {
3076 #ifndef PRODUCT 3021 #ifndef PRODUCT
3077 TimelineDurationScope tds2(thread(), 3022 TimelineDurationScope tds2(thread(), compiler_timeline,
3078 compiler_timeline,
3079 "EliminateDeadPhis"); 3023 "EliminateDeadPhis");
3080 #endif // !PRODUCT 3024 #endif // !PRODUCT
3081 DeadCodeElimination::EliminateDeadPhis(flow_graph); 3025 DeadCodeElimination::EliminateDeadPhis(flow_graph);
3082 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3026 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3083 } 3027 }
3084 3028
3085 if (flow_graph->Canonicalize()) { 3029 if (flow_graph->Canonicalize()) {
3086 flow_graph->Canonicalize(); 3030 flow_graph->Canonicalize();
3087 } 3031 }
3088 3032
3089 // Attempt to sink allocations of temporary non-escaping objects to 3033 // Attempt to sink allocations of temporary non-escaping objects to
3090 // the deoptimization path. 3034 // the deoptimization path.
3091 AllocationSinking* sinking = NULL; 3035 AllocationSinking* sinking = NULL;
3092 if (FLAG_allocation_sinking && 3036 if (FLAG_allocation_sinking &&
3093 (flow_graph->graph_entry()->SuccessorCount() == 1)) { 3037 (flow_graph->graph_entry()->SuccessorCount() == 1)) {
3094 #ifndef PRODUCT 3038 #ifndef PRODUCT
3095 TimelineDurationScope tds2(thread(), 3039 TimelineDurationScope tds2(thread(), compiler_timeline,
3096 compiler_timeline,
3097 "AllocationSinking::Optimize"); 3040 "AllocationSinking::Optimize");
3098 #endif // !PRODUCT 3041 #endif // !PRODUCT
3099 // TODO(fschneider): Support allocation sinking with try-catch. 3042 // TODO(fschneider): Support allocation sinking with try-catch.
3100 sinking = new AllocationSinking(flow_graph); 3043 sinking = new AllocationSinking(flow_graph);
3101 sinking->Optimize(); 3044 sinking->Optimize();
3102 } 3045 }
3103 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3046 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3104 3047
3105 DeadCodeElimination::EliminateDeadPhis(flow_graph); 3048 DeadCodeElimination::EliminateDeadPhis(flow_graph);
3106 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3049 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3107 3050
3108 FlowGraphTypePropagator::Propagate(flow_graph); 3051 FlowGraphTypePropagator::Propagate(flow_graph);
3109 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3052 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3110 3053
3111 { 3054 {
3112 #ifndef PRODUCT 3055 #ifndef PRODUCT
3113 TimelineDurationScope tds2(thread(), 3056 TimelineDurationScope tds2(thread(), compiler_timeline,
3114 compiler_timeline,
3115 "SelectRepresentations"); 3057 "SelectRepresentations");
3116 #endif // !PRODUCT 3058 #endif // !PRODUCT
3117 // Ensure that all phis inserted by optimization passes have 3059 // Ensure that all phis inserted by optimization passes have
3118 // consistent representations. 3060 // consistent representations.
3119 flow_graph->SelectRepresentations(); 3061 flow_graph->SelectRepresentations();
3120 } 3062 }
3121 3063
3122 if (flow_graph->Canonicalize()) { 3064 if (flow_graph->Canonicalize()) {
3123 // To fully remove redundant boxing (e.g. BoxDouble used only in 3065 // To fully remove redundant boxing (e.g. BoxDouble used only in
3124 // environments and UnboxDouble instructions) instruction we 3066 // environments and UnboxDouble instructions) instruction we
3125 // first need to replace all their uses and then fold them away. 3067 // first need to replace all their uses and then fold them away.
3126 // For now we just repeat Canonicalize twice to do that. 3068 // For now we just repeat Canonicalize twice to do that.
3127 // TODO(vegorov): implement a separate representation folding pass. 3069 // TODO(vegorov): implement a separate representation folding pass.
3128 flow_graph->Canonicalize(); 3070 flow_graph->Canonicalize();
3129 } 3071 }
3130 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 3072 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3131 3073
3132 if (sinking != NULL) { 3074 if (sinking != NULL) {
3133 #ifndef PRODUCT 3075 #ifndef PRODUCT
3134 TimelineDurationScope tds2( 3076 TimelineDurationScope tds2(
3135 thread(), 3077 thread(), compiler_timeline,
3136 compiler_timeline,
3137 "AllocationSinking::DetachMaterializations"); 3078 "AllocationSinking::DetachMaterializations");
3138 #endif // !PRODUCT 3079 #endif // !PRODUCT
3139 // Remove all MaterializeObject instructions inserted by allocation 3080 // Remove all MaterializeObject instructions inserted by allocation
3140 // sinking from the flow graph and let them float on the side 3081 // sinking from the flow graph and let them float on the side
3141 // referenced only from environments. Register allocator will consider 3082 // referenced only from environments. Register allocator will consider
3142 // them as part of a deoptimization environment. 3083 // them as part of a deoptimization environment.
3143 sinking->DetachMaterializations(); 3084 sinking->DetachMaterializations();
3144 } 3085 }
3145 3086
3146 // Replace bounds check instruction with a generic one. 3087 // Replace bounds check instruction with a generic one.
3147 optimizer.ReplaceArrayBoundChecks(); 3088 optimizer.ReplaceArrayBoundChecks();
3148 3089
3149 // Compute and store graph informations (call & instruction counts) 3090 // Compute and store graph informations (call & instruction counts)
3150 // to be later used by the inliner. 3091 // to be later used by the inliner.
3151 FlowGraphInliner::CollectGraphInfo(flow_graph, true); 3092 FlowGraphInliner::CollectGraphInfo(flow_graph, true);
3152 3093
3153 { 3094 {
3154 #ifndef PRODUCT 3095 #ifndef PRODUCT
3155 TimelineDurationScope tds2(thread(), 3096 TimelineDurationScope tds2(thread(), compiler_timeline,
3156 compiler_timeline,
3157 "AllocateRegisters"); 3097 "AllocateRegisters");
3158 #endif // !PRODUCT 3098 #endif // !PRODUCT
3159 // Perform register allocation on the SSA graph. 3099 // Perform register allocation on the SSA graph.
3160 FlowGraphAllocator allocator(*flow_graph); 3100 FlowGraphAllocator allocator(*flow_graph);
3161 allocator.AllocateRegisters(); 3101 allocator.AllocateRegisters();
3162 } 3102 }
3163 3103
3164 if (print_flow_graph) { 3104 if (print_flow_graph) {
3165 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 3105 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
3166 } 3106 }
3167 } 3107 }
3168 3108
3169 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); 3109 ASSERT(inline_id_to_function.length() == caller_inline_id.length());
3170 Assembler assembler(use_far_branches); 3110 Assembler assembler(use_far_branches);
3171 FlowGraphCompiler graph_compiler(&assembler, flow_graph, 3111 FlowGraphCompiler graph_compiler(
3172 *parsed_function(), optimized(), 3112 &assembler, flow_graph, *parsed_function(), optimized(),
3173 inline_id_to_function, 3113 inline_id_to_function, inline_id_to_token_pos, caller_inline_id);
3174 inline_id_to_token_pos,
3175 caller_inline_id);
3176 { 3114 {
3177 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); 3115 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
3178 #ifndef PRODUCT 3116 #ifndef PRODUCT
3179 TimelineDurationScope tds(thread(), 3117 TimelineDurationScope tds(thread(), compiler_timeline, "CompileGraph");
3180 compiler_timeline,
3181 "CompileGraph");
3182 #endif // !PRODUCT 3118 #endif // !PRODUCT
3183 graph_compiler.CompileGraph(); 3119 graph_compiler.CompileGraph();
3184 pipeline->FinalizeCompilation(flow_graph); 3120 pipeline->FinalizeCompilation(flow_graph);
3185 } 3121 }
3186 { 3122 {
3187 #ifndef PRODUCT 3123 #ifndef PRODUCT
3188 TimelineDurationScope tds(thread(), 3124 TimelineDurationScope tds(thread(), compiler_timeline,
3189 compiler_timeline,
3190 "FinalizeCompilation"); 3125 "FinalizeCompilation");
3191 #endif // !PRODUCT 3126 #endif // !PRODUCT
3192 ASSERT(thread()->IsMutatorThread()); 3127 ASSERT(thread()->IsMutatorThread());
3193 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); 3128 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
3194 } 3129 }
3195 // Mark that this isolate now has compiled code. 3130 // Mark that this isolate now has compiled code.
3196 isolate()->set_has_compiled_code(true); 3131 isolate()->set_has_compiled_code(true);
3197 // Exit the loop and the function with the correct result value. 3132 // Exit the loop and the function with the correct result value.
3198 is_compiled = true; 3133 is_compiled = true;
3199 done = true; 3134 done = true;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 // Check that we optimize, except if the function is not optimizable. 3195 // Check that we optimize, except if the function is not optimizable.
3261 ASSERT(FLAG_precompiled_mode); 3196 ASSERT(FLAG_precompiled_mode);
3262 ASSERT(!function.IsOptimizable() || optimized); 3197 ASSERT(!function.IsOptimizable() || optimized);
3263 ASSERT(!function.HasCode()); 3198 ASSERT(!function.HasCode());
3264 LongJumpScope jump; 3199 LongJumpScope jump;
3265 if (setjmp(*jump.Set()) == 0) { 3200 if (setjmp(*jump.Set()) == 0) {
3266 Thread* const thread = Thread::Current(); 3201 Thread* const thread = Thread::Current();
3267 StackZone stack_zone(thread); 3202 StackZone stack_zone(thread);
3268 Zone* const zone = stack_zone.GetZone(); 3203 Zone* const zone = stack_zone.GetZone();
3269 const bool trace_compiler = 3204 const bool trace_compiler =
3270 FLAG_trace_compiler || 3205 FLAG_trace_compiler || (FLAG_trace_optimizing_compiler && optimized);
3271 (FLAG_trace_optimizing_compiler && optimized);
3272 Timer per_compile_timer(trace_compiler, "Compilation time"); 3206 Timer per_compile_timer(trace_compiler, "Compilation time");
3273 per_compile_timer.Start(); 3207 per_compile_timer.Start();
3274 3208
3275 ParsedFunction* parsed_function = new(zone) ParsedFunction( 3209 ParsedFunction* parsed_function = new (zone)
3276 thread, Function::ZoneHandle(zone, function.raw())); 3210 ParsedFunction(thread, Function::ZoneHandle(zone, function.raw()));
3277 if (trace_compiler) { 3211 if (trace_compiler) {
3278 THR_Print( 3212 THR_Print("Precompiling %sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
3279 "Precompiling %sfunction: '%s' @ token %" Pd ", size %" Pd "\n", 3213 (optimized ? "optimized " : ""),
3280 (optimized ? "optimized " : ""), 3214 function.ToFullyQualifiedCString(), function.token_pos().Pos(),
3281 function.ToFullyQualifiedCString(), 3215 (function.end_token_pos().Pos() - function.token_pos().Pos()));
3282 function.token_pos().Pos(),
3283 (function.end_token_pos().Pos() - function.token_pos().Pos()));
3284 } 3216 }
3285 INC_STAT(thread, num_functions_compiled, 1); 3217 INC_STAT(thread, num_functions_compiled, 1);
3286 if (optimized) { 3218 if (optimized) {
3287 INC_STAT(thread, num_functions_optimized, 1); 3219 INC_STAT(thread, num_functions_optimized, 1);
3288 } 3220 }
3289 { 3221 {
3290 HANDLESCOPE(thread); 3222 HANDLESCOPE(thread);
3291 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); 3223 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed);
3292 pipeline->ParseFunction(parsed_function); 3224 pipeline->ParseFunction(parsed_function);
3293 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); 3225 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed);
3294 INC_STAT(thread, 3226 INC_STAT(thread, num_func_tokens_compiled,
3295 num_func_tokens_compiled,
3296 num_tokens_after - num_tokens_before); 3227 num_tokens_after - num_tokens_before);
3297 } 3228 }
3298 3229
3299 PrecompileParsedFunctionHelper helper( 3230 PrecompileParsedFunctionHelper helper(precompiler, parsed_function,
3300 precompiler, parsed_function, optimized); 3231 optimized);
3301 const bool success = helper.Compile(pipeline); 3232 const bool success = helper.Compile(pipeline);
3302 if (!success) { 3233 if (!success) {
3303 // Encountered error. 3234 // Encountered error.
3304 Error& error = Error::Handle(); 3235 Error& error = Error::Handle();
3305 // We got an error during compilation. 3236 // We got an error during compilation.
3306 error = thread->sticky_error(); 3237 error = thread->sticky_error();
3307 thread->clear_sticky_error(); 3238 thread->clear_sticky_error();
3308 ASSERT(error.IsLanguageError() && 3239 ASSERT(error.IsLanguageError() &&
3309 LanguageError::Cast(error).kind() != Report::kBailout); 3240 LanguageError::Cast(error).kind() != Report::kBailout);
3310 return error.raw(); 3241 return error.raw();
3311 } 3242 }
3312 3243
3313 per_compile_timer.Stop(); 3244 per_compile_timer.Stop();
3314 3245
3315 if (trace_compiler) { 3246 if (trace_compiler) {
3316 THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", 3247 THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
3317 function.ToFullyQualifiedCString(), 3248 function.ToFullyQualifiedCString(),
3318 Code::Handle(function.CurrentCode()).PayloadStart(), 3249 Code::Handle(function.CurrentCode()).PayloadStart(),
3319 Code::Handle(function.CurrentCode()).Size(), 3250 Code::Handle(function.CurrentCode()).Size(),
3320 per_compile_timer.TotalElapsedTime()); 3251 per_compile_timer.TotalElapsedTime());
3321 } 3252 }
3322 3253
3323 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { 3254 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
3324 Disassembler::DisassembleCode(function, optimized); 3255 Disassembler::DisassembleCode(function, optimized);
3325 } else if (FLAG_disassemble_optimized && 3256 } else if (FLAG_disassemble_optimized && optimized &&
3326 optimized &&
3327 FlowGraphPrinter::ShouldPrint(function)) { 3257 FlowGraphPrinter::ShouldPrint(function)) {
3328 Disassembler::DisassembleCode(function, true); 3258 Disassembler::DisassembleCode(function, true);
3329 } 3259 }
3330 return Error::null(); 3260 return Error::null();
3331 } else { 3261 } else {
3332 Thread* const thread = Thread::Current(); 3262 Thread* const thread = Thread::Current();
3333 StackZone stack_zone(thread); 3263 StackZone stack_zone(thread);
3334 Error& error = Error::Handle(); 3264 Error& error = Error::Handle();
3335 // We got an error during compilation. 3265 // We got an error during compilation.
3336 error = thread->sticky_error(); 3266 error = thread->sticky_error();
(...skipping 18 matching lines...) Expand all
3355 3285
3356 ASSERT(FLAG_precompiled_mode); 3286 ASSERT(FLAG_precompiled_mode);
3357 const bool optimized = function.IsOptimizable(); // False for natives. 3287 const bool optimized = function.IsOptimizable(); // False for natives.
3358 DartPrecompilationPipeline pipeline(zone, field_type_map); 3288 DartPrecompilationPipeline pipeline(zone, field_type_map);
3359 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); 3289 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized);
3360 } 3290 }
3361 3291
3362 #endif // DART_PRECOMPILER 3292 #endif // DART_PRECOMPILER
3363 3293
3364 } // namespace dart 3294 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/proccpuinfo.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698