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

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

Issue 2579413002: Revert "Save and restore feedback from JIT." (Closed)
Patch Set: Created 4 years 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/program_visitor.h » ('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 15 matching lines...) Expand all
26 #include "vm/flow_graph_type_propagator.h" 26 #include "vm/flow_graph_type_propagator.h"
27 #include "vm/hash_table.h" 27 #include "vm/hash_table.h"
28 #include "vm/il_printer.h" 28 #include "vm/il_printer.h"
29 #include "vm/isolate.h" 29 #include "vm/isolate.h"
30 #include "vm/log.h" 30 #include "vm/log.h"
31 #include "vm/longjump.h" 31 #include "vm/longjump.h"
32 #include "vm/object.h" 32 #include "vm/object.h"
33 #include "vm/object_store.h" 33 #include "vm/object_store.h"
34 #include "vm/os.h" 34 #include "vm/os.h"
35 #include "vm/parser.h" 35 #include "vm/parser.h"
36 #include "vm/program_visitor.h"
37 #include "vm/redundancy_elimination.h" 36 #include "vm/redundancy_elimination.h"
38 #include "vm/regexp_assembler.h" 37 #include "vm/regexp_assembler.h"
39 #include "vm/regexp_parser.h" 38 #include "vm/regexp_parser.h"
40 #include "vm/resolver.h" 39 #include "vm/resolver.h"
41 #include "vm/symbols.h" 40 #include "vm/symbols.h"
42 #include "vm/tags.h" 41 #include "vm/tags.h"
43 #include "vm/timeline.h" 42 #include "vm/timeline.h"
44 #include "vm/timer.h" 43 #include "vm/timer.h"
45 #include "vm/type_table.h" 44 #include "vm/type_table.h"
46 #include "vm/version.h"
47 #include "vm/json_parser.h"
48 45
49 namespace dart { 46 namespace dart {
50 47
48
51 #define T (thread()) 49 #define T (thread())
52 #define I (isolate()) 50 #define I (isolate())
53 #define Z (zone()) 51 #define Z (zone())
54 52
55 53
56 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); 54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
57 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); 55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
58 DEFINE_FLAG( 56 DEFINE_FLAG(
59 int, 57 int,
60 max_speculative_inlining_attempts, 58 max_speculative_inlining_attempts,
(...skipping 10 matching lines...) Expand all
71 DECLARE_FLAG(bool, range_analysis); 69 DECLARE_FLAG(bool, range_analysis);
72 DECLARE_FLAG(bool, trace_compiler); 70 DECLARE_FLAG(bool, trace_compiler);
73 DECLARE_FLAG(bool, trace_optimizing_compiler); 71 DECLARE_FLAG(bool, trace_optimizing_compiler);
74 DECLARE_FLAG(bool, trace_bailout); 72 DECLARE_FLAG(bool, trace_bailout);
75 DECLARE_FLAG(bool, use_inlining); 73 DECLARE_FLAG(bool, use_inlining);
76 DECLARE_FLAG(bool, verify_compiler); 74 DECLARE_FLAG(bool, verify_compiler);
77 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); 75 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
78 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 76 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
79 DECLARE_FLAG(bool, trace_inlining_intervals); 77 DECLARE_FLAG(bool, trace_inlining_intervals);
80 DECLARE_FLAG(bool, trace_irregexp); 78 DECLARE_FLAG(bool, trace_irregexp);
81 DECLARE_FLAG(int, inlining_hotness);
82 DECLARE_FLAG(int, inlining_size_threshold);
83 DECLARE_FLAG(int, inlining_callee_size_threshold);
84 DECLARE_FLAG(int, inline_getters_setters_smaller_than);
85 DECLARE_FLAG(int, inlining_depth_threshold);
86 DECLARE_FLAG(int, inlining_caller_size_threshold);
87 DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold);
88 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
89
90 79
91 #ifdef DART_PRECOMPILER 80 #ifdef DART_PRECOMPILER
92 81
93 class DartPrecompilationPipeline : public DartCompilationPipeline { 82 class DartPrecompilationPipeline : public DartCompilationPipeline {
94 public: 83 public:
95 explicit DartPrecompilationPipeline(Zone* zone, 84 explicit DartPrecompilationPipeline(Zone* zone,
96 FieldTypeMap* field_map = NULL) 85 FieldTypeMap* field_map = NULL)
97 : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {} 86 : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {}
98 87
99 virtual void FinalizeCompilation(FlowGraph* flow_graph) { 88 virtual void FinalizeCompilation(FlowGraph* flow_graph) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 178
190 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); 179 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper);
191 }; 180 };
192 181
193 182
194 static void Jump(const Error& error) { 183 static void Jump(const Error& error) {
195 Thread::Current()->long_jump_base()->Jump(1, error); 184 Thread::Current()->long_jump_base()->Jump(1, error);
196 } 185 }
197 186
198 187
199 TypeRangeCache::TypeRangeCache(Precompiler* precompiler,
200 Thread* thread,
201 intptr_t num_cids)
202 : precompiler_(precompiler),
203 thread_(thread),
204 lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)),
205 upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) {
206 for (intptr_t i = 0; i < num_cids; i++) {
207 lower_limits_[i] = kNotComputed;
208 upper_limits_[i] = kNotComputed;
209 }
210 ASSERT(precompiler->type_range_cache() == NULL);
211 precompiler->set_type_range_cache(this);
212 }
213
214
215 TypeRangeCache::~TypeRangeCache() {
216 ASSERT(precompiler_->type_range_cache() == this);
217 precompiler_->set_type_range_cache(NULL);
218 }
219
220
221 RawError* Precompiler::CompileAll( 188 RawError* Precompiler::CompileAll(
222 Dart_QualifiedFunctionName embedder_entry_points[], 189 Dart_QualifiedFunctionName embedder_entry_points[],
223 bool reset_fields, 190 bool reset_fields) {
224 uint8_t* jit_feedback,
225 intptr_t jit_feedback_length) {
226 LongJumpScope jump; 191 LongJumpScope jump;
227 if (setjmp(*jump.Set()) == 0) { 192 if (setjmp(*jump.Set()) == 0) {
228 Precompiler precompiler(Thread::Current(), reset_fields); 193 Precompiler precompiler(Thread::Current(), reset_fields);
229 precompiler.LoadFeedback(jit_feedback, jit_feedback_length);
230 precompiler.DoCompileAll(embedder_entry_points); 194 precompiler.DoCompileAll(embedder_entry_points);
231 return Error::null(); 195 return Error::null();
232 } else { 196 } else {
233 Thread* thread = Thread::Current(); 197 Thread* thread = Thread::Current();
234 const Error& error = Error::Handle(thread->sticky_error()); 198 const Error& error = Error::Handle(thread->sticky_error());
235 thread->clear_sticky_error(); 199 thread->clear_sticky_error();
236 return error.raw(); 200 return error.raw();
237 } 201 }
238 } 202 }
239 203
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 upper_limits_[type_cid] = *upper_limit; 287 upper_limits_[type_cid] = *upper_limit;
324 return true; 288 return true;
325 } 289 }
326 290
327 291
328 Precompiler::Precompiler(Thread* thread, bool reset_fields) 292 Precompiler::Precompiler(Thread* thread, bool reset_fields)
329 : thread_(thread), 293 : thread_(thread),
330 zone_(NULL), 294 zone_(NULL),
331 isolate_(thread->isolate()), 295 isolate_(thread->isolate()),
332 reset_fields_(reset_fields), 296 reset_fields_(reset_fields),
333 jit_feedback_(NULL),
334 changed_(false), 297 changed_(false),
335 function_count_(0), 298 function_count_(0),
336 class_count_(0), 299 class_count_(0),
337 selector_count_(0), 300 selector_count_(0),
338 dropped_function_count_(0), 301 dropped_function_count_(0),
339 dropped_field_count_(0), 302 dropped_field_count_(0),
340 dropped_class_count_(0), 303 dropped_class_count_(0),
341 dropped_typearg_count_(0), 304 dropped_typearg_count_(0),
342 dropped_type_count_(0), 305 dropped_type_count_(0),
343 dropped_library_count_(0), 306 dropped_library_count_(0),
344 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), 307 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())),
345 pending_functions_( 308 pending_functions_(
346 GrowableObjectArray::Handle(GrowableObjectArray::New())), 309 GrowableObjectArray::Handle(GrowableObjectArray::New())),
347 sent_selectors_(), 310 sent_selectors_(),
348 enqueued_functions_(), 311 enqueued_functions_(),
349 fields_to_retain_(), 312 fields_to_retain_(),
350 functions_to_retain_(), 313 functions_to_retain_(),
351 classes_to_retain_(), 314 classes_to_retain_(),
352 typeargs_to_retain_(), 315 typeargs_to_retain_(),
353 types_to_retain_(), 316 types_to_retain_(),
354 consts_to_retain_(), 317 consts_to_retain_(),
355 field_type_map_(), 318 field_type_map_(),
356 type_range_cache_(NULL),
357 error_(Error::Handle()), 319 error_(Error::Handle()),
358 get_runtime_type_is_unique_(false) {} 320 get_runtime_type_is_unique_(false) {}
359 321
360 322
361 void Precompiler::LoadFeedback(uint8_t* buffer, intptr_t length) {
362 if (buffer == NULL) {
363 if (FLAG_trace_precompiler) {
364 THR_Print("Precompiler running without JIT feedback\n");
365 }
366
367 // Flags affecting compilation only:
368 // There is no counter feedback in precompilation, so ignore the counter
369 // when making inlining decisions.
370 FLAG_inlining_hotness = 0;
371 // Use smaller thresholds in precompilation as we are compiling everything
372 // with the optimizing compiler instead of only hot functions.
373 FLAG_inlining_size_threshold = 5;
374 FLAG_inline_getters_setters_smaller_than = 5;
375 FLAG_inlining_callee_size_threshold = 20;
376 FLAG_inlining_depth_threshold = 4;
377 FLAG_inlining_caller_size_threshold = 1000;
378 FLAG_inlining_constant_arguments_max_size_threshold = 100;
379 FLAG_inlining_constant_arguments_min_size_threshold = 30;
380 return;
381 }
382
383 if (FLAG_trace_precompiler) {
384 THR_Print("Loading JIT feedback\n");
385 }
386
387 JSONParser parser(reinterpret_cast<const char*>(buffer), length,
388 Thread::Current()->zone());
389 ParsedJSONValue* root = parser.ParseValue();
390 if (root->IsError()) {
391 ParsedJSONError* error = static_cast<ParsedJSONError*>(root);
392 THR_Print("Error parsing JIT feedback: %s:%" Pd "\n", error->message(),
393 error->position());
394 } else if (!root->IsObject()) {
395 THR_Print("Error parsing JIT feedback: object expected\n");
396 } else {
397 jit_feedback_ = static_cast<ParsedJSONObject*>(root);
398 }
399 }
400
401
402 void Precompiler::DoCompileAll( 323 void Precompiler::DoCompileAll(
403 Dart_QualifiedFunctionName embedder_entry_points[]) { 324 Dart_QualifiedFunctionName embedder_entry_points[]) {
404 ASSERT(I->compilation_allowed()); 325 ASSERT(I->compilation_allowed());
405 326
406 { 327 {
407 StackZone stack_zone(T); 328 StackZone stack_zone(T);
408 zone_ = stack_zone.GetZone(); 329 zone_ = stack_zone.GetZone();
409 330
410 { 331 {
411 HANDLESCOPE(T); 332 HANDLESCOPE(T);
412 // Make sure class hierarchy is stable before compilation so that CHA 333 // Make sure class hierarchy is stable before compilation so that CHA
413 // 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
414 // because their class hasn't been finalized yet. 335 // because their class hasn't been finalized yet.
415 FinalizeAllClasses(); 336 FinalizeAllClasses();
416 337
417 SortClasses(); 338 SortClasses();
418 TypeRangeCache trc(this, T, I->class_table()->NumCids()); 339 TypeRangeCache trc(T, I->class_table()->NumCids());
419 VerifyJITFeedback();
420 340
421 // Precompile static initializers to compute result type information. 341 // Precompile static initializers to compute result type information.
422 PrecompileStaticInitializers(); 342 PrecompileStaticInitializers();
423 343
424 // Precompile constructors to compute type information for final fields. 344 // Precompile constructors to compute type information for final fields.
425 ClearAllCode(); 345 ClearAllCode();
426 PrecompileConstructors(); 346 PrecompileConstructors();
427 347
428 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { 348 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
429 if (FLAG_trace_precompiler) { 349 if (FLAG_trace_precompiler) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 } 471 }
552 472
553 private: 473 private:
554 Array& fields_; 474 Array& fields_;
555 Field& field_; 475 Field& field_;
556 Function& function_; 476 Function& function_;
557 }; 477 };
558 478
559 HANDLESCOPE(T); 479 HANDLESCOPE(T);
560 StaticInitializerVisitor visitor(Z); 480 StaticInitializerVisitor visitor(Z);
561 ProgramVisitor::VisitClasses(&visitor); 481 VisitClasses(&visitor);
562 } 482 }
563 483
564 484
565 void Precompiler::PrecompileConstructors() { 485 void Precompiler::PrecompileConstructors() {
566 class ConstructorVisitor : public FunctionVisitor { 486 class ConstructorVisitor : public FunctionVisitor {
567 public: 487 public:
568 explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone) 488 explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone)
569 : precompiler_(precompiler), zone_(zone) {} 489 : precompiler_(precompiler), zone_(zone) {}
570 void Visit(const Function& function) { 490 void Visit(const Function& function) {
571 if (!function.IsGenerativeConstructor()) return; 491 if (!function.IsGenerativeConstructor()) return;
572 if (function.HasCode()) { 492 if (function.HasCode()) {
573 // Const constructors may have been visited before. Recompile them here 493 // Const constructors may have been visited before. Recompile them here
574 // to collect type information for final fields for them as well. 494 // to collect type information for final fields for them as well.
575 function.ClearCode(); 495 function.ClearCode();
576 } 496 }
577 if (FLAG_trace_precompiler) { 497 if (FLAG_trace_precompiler) {
578 THR_Print("Precompiling constructor %s\n", function.ToCString()); 498 THR_Print("Precompiling constructor %s\n", function.ToCString());
579 } 499 }
580 CompileFunction(precompiler_, Thread::Current(), zone_, function, 500 CompileFunction(precompiler_, Thread::Current(), zone_, function,
581 precompiler_->field_type_map()); 501 precompiler_->field_type_map());
582 } 502 }
583 503
584 private: 504 private:
585 Precompiler* precompiler_; 505 Precompiler* precompiler_;
586 Zone* zone_; 506 Zone* zone_;
587 }; 507 };
588 508
589 HANDLESCOPE(T); 509 HANDLESCOPE(T);
590 ConstructorVisitor visitor(this, zone_); 510 ConstructorVisitor visitor(this, zone_);
591 ProgramVisitor::VisitFunctions(&visitor); 511 VisitFunctions(&visitor);
592 512
593 FieldTypeMap::Iterator it(field_type_map_.GetIterator()); 513 FieldTypeMap::Iterator it(field_type_map_.GetIterator());
594 for (FieldTypePair* current = it.Next(); current != NULL; 514 for (FieldTypePair* current = it.Next(); current != NULL;
595 current = it.Next()) { 515 current = it.Next()) {
596 const intptr_t cid = current->cid_; 516 const intptr_t cid = current->cid_;
597 current->field_->set_guarded_cid(cid); 517 current->field_->set_guarded_cid(cid);
598 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); 518 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid);
599 if (FLAG_trace_precompiler) { 519 if (FLAG_trace_precompiler) {
600 THR_Print( 520 THR_Print(
601 "Field %s <- Type %s\n", current->field_->ToCString(), 521 "Field %s <- Type %s\n", current->field_->ToCString(),
602 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString()); 522 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString());
603 } 523 }
604 } 524 }
605 } 525 }
606 526
607 527
608 void Precompiler::ClearAllCode() { 528 void Precompiler::ClearAllCode() {
609 class ClearCodeFunctionVisitor : public FunctionVisitor { 529 class ClearCodeFunctionVisitor : public FunctionVisitor {
610 void Visit(const Function& function) { 530 void Visit(const Function& function) {
611 function.ClearCode(); 531 function.ClearCode();
612 function.ClearICDataArray(); 532 function.ClearICDataArray();
613 } 533 }
614 }; 534 };
615 ClearCodeFunctionVisitor function_visitor; 535 ClearCodeFunctionVisitor function_visitor;
616 ProgramVisitor::VisitFunctions(&function_visitor); 536 VisitFunctions(&function_visitor);
617 537
618 class ClearCodeClassVisitor : public ClassVisitor { 538 class ClearCodeClassVisitor : public ClassVisitor {
619 void Visit(const Class& cls) { cls.DisableAllocationStub(); } 539 void Visit(const Class& cls) { cls.DisableAllocationStub(); }
620 }; 540 };
621 ClearCodeClassVisitor class_visitor; 541 ClearCodeClassVisitor class_visitor;
622 ProgramVisitor::VisitClasses(&class_visitor); 542 VisitClasses(&class_visitor);
623 } 543 }
624 544
625 545
626 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { 546 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
627 // 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
628 // discovered through _getMainClosure. 548 // discovered through _getMainClosure.
629 549
630 AddSelector(Symbols::NoSuchMethod()); 550 AddSelector(Symbols::NoSuchMethod());
631 551
632 AddSelector(Symbols::Call()); // For speed, not correctness. 552 AddSelector(Symbols::Call()); // For speed, not correctness.
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after
2154 2074
2155 private: 2075 private:
2156 Code& code_; 2076 Code& code_;
2157 Array& table_; 2077 Array& table_;
2158 Smi& pc_offset_; 2078 Smi& pc_offset_;
2159 Function& target_; 2079 Function& target_;
2160 Code& target_code_; 2080 Code& target_code_;
2161 }; 2081 };
2162 2082
2163 BindStaticCallsVisitor visitor(Z); 2083 BindStaticCallsVisitor visitor(Z);
2164 ProgramVisitor::VisitFunctions(&visitor); 2084 VisitFunctions(&visitor);
2165 } 2085 }
2166 2086
2167 2087
2168 void Precompiler::SwitchICCalls() { 2088 void Precompiler::SwitchICCalls() {
2169 #if !defined(TARGET_ARCH_DBC) 2089 #if !defined(TARGET_ARCH_DBC)
2170 // Now that all functions have been compiled, we can switch to an instance 2090 // Now that all functions have been compiled, we can switch to an instance
2171 // call sequence that loads the Code object and entry point directly from 2091 // call sequence that loads the Code object and entry point directly from
2172 // the ic data array instead indirectly through a Function in the ic data 2092 // the ic data array instead indirectly through a Function in the ic data
2173 // array. Iterate all the object pools and rewrite the ic data from 2093 // array. Iterate all the object pools and rewrite the ic data from
2174 // (cid, target function, count) to (cid, target code, entry point), and 2094 // (cid, target function, count) to (cid, target code, entry point), and
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2243 ICData& ic_; 2163 ICData& ic_;
2244 String& target_name_; 2164 String& target_name_;
2245 Array& args_descriptor_; 2165 Array& args_descriptor_;
2246 UnlinkedCall& unlinked_; 2166 UnlinkedCall& unlinked_;
2247 Code& target_code_; 2167 Code& target_code_;
2248 UnlinkedCallSet canonical_unlinked_calls_; 2168 UnlinkedCallSet canonical_unlinked_calls_;
2249 }; 2169 };
2250 2170
2251 ASSERT(!I->compilation_allowed()); 2171 ASSERT(!I->compilation_allowed());
2252 SwitchICCallsVisitor visitor(Z); 2172 SwitchICCallsVisitor visitor(Z);
2253 ProgramVisitor::VisitFunctions(&visitor); 2173 VisitFunctions(&visitor);
2254 #endif 2174 #endif
2255 } 2175 }
2256 2176
2257 2177
2258 void Precompiler::ShareMegamorphicBuckets() { 2178 void Precompiler::ShareMegamorphicBuckets() {
2259 const GrowableObjectArray& table = GrowableObjectArray::Handle( 2179 const GrowableObjectArray& table = GrowableObjectArray::Handle(
2260 Z, I->object_store()->megamorphic_cache_table()); 2180 Z, I->object_store()->megamorphic_cache_table());
2261 if (table.IsNull()) return; 2181 if (table.IsNull()) return;
2262 MegamorphicCache& cache = MegamorphicCache::Handle(Z); 2182 MegamorphicCache& cache = MegamorphicCache::Handle(Z);
2263 2183
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2316 2236
2317 private: 2237 private:
2318 Zone* zone_; 2238 Zone* zone_;
2319 StackMapSet canonical_stackmaps_; 2239 StackMapSet canonical_stackmaps_;
2320 Code& code_; 2240 Code& code_;
2321 Array& stackmaps_; 2241 Array& stackmaps_;
2322 StackMap& stackmap_; 2242 StackMap& stackmap_;
2323 }; 2243 };
2324 2244
2325 DedupStackMapsVisitor visitor(Z); 2245 DedupStackMapsVisitor visitor(Z);
2326 ProgramVisitor::VisitFunctions(&visitor); 2246 VisitFunctions(&visitor);
2327 } 2247 }
2328 2248
2329 2249
2330 void Precompiler::DedupLists() { 2250 void Precompiler::DedupLists() {
2331 class DedupListsVisitor : public FunctionVisitor { 2251 class DedupListsVisitor : public FunctionVisitor {
2332 public: 2252 public:
2333 explicit DedupListsVisitor(Zone* zone) 2253 explicit DedupListsVisitor(Zone* zone)
2334 : zone_(zone), 2254 : zone_(zone),
2335 canonical_lists_(), 2255 canonical_lists_(),
2336 code_(Code::Handle(zone)), 2256 code_(Code::Handle(zone)),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2383 } 2303 }
2384 2304
2385 private: 2305 private:
2386 Zone* zone_; 2306 Zone* zone_;
2387 ArraySet canonical_lists_; 2307 ArraySet canonical_lists_;
2388 Code& code_; 2308 Code& code_;
2389 Array& list_; 2309 Array& list_;
2390 }; 2310 };
2391 2311
2392 DedupListsVisitor visitor(Z); 2312 DedupListsVisitor visitor(Z);
2393 ProgramVisitor::VisitFunctions(&visitor); 2313 VisitFunctions(&visitor);
2394 } 2314 }
2395 2315
2396 2316
2397 void Precompiler::DedupInstructions() { 2317 void Precompiler::DedupInstructions() {
2398 class DedupInstructionsVisitor : public FunctionVisitor { 2318 class DedupInstructionsVisitor : public FunctionVisitor {
2399 public: 2319 public:
2400 explicit DedupInstructionsVisitor(Zone* zone) 2320 explicit DedupInstructionsVisitor(Zone* zone)
2401 : zone_(zone), 2321 : zone_(zone),
2402 canonical_instructions_set_(), 2322 canonical_instructions_set_(),
2403 code_(Code::Handle(zone)), 2323 code_(Code::Handle(zone)),
(...skipping 25 matching lines...) Expand all
2429 } 2349 }
2430 2350
2431 private: 2351 private:
2432 Zone* zone_; 2352 Zone* zone_;
2433 InstructionsSet canonical_instructions_set_; 2353 InstructionsSet canonical_instructions_set_;
2434 Code& code_; 2354 Code& code_;
2435 Instructions& instructions_; 2355 Instructions& instructions_;
2436 }; 2356 };
2437 2357
2438 DedupInstructionsVisitor visitor(Z); 2358 DedupInstructionsVisitor visitor(Z);
2439 ProgramVisitor::VisitFunctions(&visitor); 2359 VisitFunctions(&visitor);
2440 } 2360 }
2441 2361
2442 2362
2363 void Precompiler::VisitClasses(ClassVisitor* visitor) {
2364 Library& lib = Library::Handle(Z);
2365 Class& cls = Class::Handle(Z);
2366
2367 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2368 lib ^= libraries_.At(i);
2369 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
2370 while (it.HasNext()) {
2371 cls = it.GetNextClass();
2372 if (cls.IsDynamicClass()) {
2373 continue; // class 'dynamic' is in the read-only VM isolate.
2374 }
2375 visitor->Visit(cls);
2376 }
2377 }
2378 }
2379
2380
2381 void Precompiler::VisitFunctions(FunctionVisitor* visitor) {
2382 Library& lib = Library::Handle(Z);
2383 Class& cls = Class::Handle(Z);
2384 Array& functions = Array::Handle(Z);
2385 Array& fields = Array::Handle(Z);
2386 Field& field = Field::Handle(Z);
2387 Object& object = Object::Handle(Z);
2388 Function& function = Function::Handle(Z);
2389 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
2390
2391 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2392 lib ^= libraries_.At(i);
2393 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
2394 while (it.HasNext()) {
2395 cls = it.GetNextClass();
2396 if (cls.IsDynamicClass()) {
2397 continue; // class 'dynamic' is in the read-only VM isolate.
2398 }
2399
2400 functions = cls.functions();
2401 for (intptr_t j = 0; j < functions.Length(); j++) {
2402 function ^= functions.At(j);
2403 visitor->Visit(function);
2404 if (function.HasImplicitClosureFunction()) {
2405 function = function.ImplicitClosureFunction();
2406 visitor->Visit(function);
2407 }
2408 }
2409
2410 functions = cls.invocation_dispatcher_cache();
2411 for (intptr_t j = 0; j < functions.Length(); j++) {
2412 object = functions.At(j);
2413 if (object.IsFunction()) {
2414 function ^= functions.At(j);
2415 visitor->Visit(function);
2416 }
2417 }
2418 fields = cls.fields();
2419 for (intptr_t j = 0; j < fields.Length(); j++) {
2420 field ^= fields.At(j);
2421 if (field.is_static() && field.HasPrecompiledInitializer()) {
2422 function ^= field.PrecompiledInitializer();
2423 visitor->Visit(function);
2424 }
2425 }
2426 }
2427 }
2428 closures = isolate()->object_store()->closure_functions();
2429 for (intptr_t j = 0; j < closures.Length(); j++) {
2430 function ^= closures.At(j);
2431 visitor->Visit(function);
2432 ASSERT(!function.HasImplicitClosureFunction());
2433 }
2434 }
2435
2436
2443 void Precompiler::FinalizeAllClasses() { 2437 void Precompiler::FinalizeAllClasses() {
2444 Library& lib = Library::Handle(Z); 2438 Library& lib = Library::Handle(Z);
2445 Class& cls = Class::Handle(Z); 2439 Class& cls = Class::Handle(Z);
2446 2440
2447 for (intptr_t i = 0; i < libraries_.Length(); i++) { 2441 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2448 lib ^= libraries_.At(i); 2442 lib ^= libraries_.At(i);
2449 if (!lib.Loaded()) { 2443 if (!lib.Loaded()) {
2450 String& uri = String::Handle(Z, lib.url()); 2444 String& uri = String::Handle(Z, lib.url());
2451 String& msg = String::Handle( 2445 String& msg = String::Handle(
2452 Z, 2446 Z,
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 } 2600 }
2607 } 2601 }
2608 2602
2609 #if defined(DEBUG) 2603 #if defined(DEBUG)
2610 I->class_table()->Validate(); 2604 I->class_table()->Validate();
2611 I->heap()->Verify(); 2605 I->heap()->Verify();
2612 #endif 2606 #endif
2613 } 2607 }
2614 2608
2615 2609
2616 void Precompiler::VerifyJITFeedback() {
2617 if (jit_feedback_ == NULL) return;
2618
2619 ParsedJSONString* js_vmversion = jit_feedback_->StringAt("vmVersion");
2620 if ((js_vmversion == NULL) ||
2621 strcmp(js_vmversion->value(), Version::CommitString()) != 0) {
2622 THR_Print(
2623 "JIT feedback contains invalid vm version "
2624 "(saw %s, expected %s).\n",
2625 js_vmversion->value(), Version::CommitString());
2626 jit_feedback_ = NULL;
2627 return;
2628 }
2629 ParsedJSONBoolean* js_asserts = jit_feedback_->BooleanAt("asserts");
2630 if ((js_asserts == NULL) || (FLAG_enable_asserts != js_asserts->value())) {
2631 THR_Print("JIT feedback contains invalid FLAG_enable_asserts\n");
2632 jit_feedback_ = NULL;
2633 return;
2634 }
2635 ParsedJSONBoolean* js_typechecks = jit_feedback_->BooleanAt("typeChecks");
2636 if ((js_typechecks == NULL) ||
2637 (FLAG_enable_type_checks != js_typechecks->value())) {
2638 THR_Print("JIT feedback contains invalid FLAG_enable_type_checks\n");
2639 jit_feedback_ = NULL;
2640 return;
2641 }
2642
2643 ParsedJSONArray* js_scripts = jit_feedback_->ArrayAt("scripts");
2644 ASSERT(js_scripts != NULL);
2645 Script& script = Script::Handle(Z);
2646 for (intptr_t i = 0; i < js_scripts->Length(); i++) {
2647 ParsedJSONObject* js_script = js_scripts->ObjectAt(i);
2648 ASSERT(js_script != NULL);
2649 ParsedJSONString* js_uri = js_script->StringAt("uri");
2650 ASSERT(js_uri != NULL);
2651 ParsedJSONNumber* js_fp = js_script->NumberAt("checksum");
2652 ASSERT(js_fp != NULL);
2653 script = LookupScript(js_uri->value());
2654 if (script.IsNull()) {
2655 THR_Print("Cannot find script %s\n", js_uri->value());
2656 continue;
2657 }
2658 intptr_t fp = script.SourceFingerprint();
2659 if (fp != js_fp->value()) {
2660 THR_Print(
2661 "Fingerprint has changed for %s. Continuing without JIT "
2662 "feedback.\n",
2663 js_uri->value());
2664 jit_feedback_ = NULL;
2665 return;
2666 }
2667 }
2668
2669 ParsedJSONArray* js_classes = jit_feedback_->ArrayAt("classes");
2670 ASSERT(js_classes != NULL);
2671 Library& lib = Library::Handle(Z);
2672 Class& cls = Class::Handle(Z);
2673 String& str = String::Handle(Z);
2674 for (intptr_t i = 0; i < js_classes->Length(); i++) {
2675 ParsedJSONObject* js_class = js_classes->ObjectAt(i);
2676 ASSERT(js_class != NULL);
2677 ParsedJSONString* js_uri = js_class->StringAt("uri");
2678 ASSERT(js_uri != NULL);
2679 ParsedJSONString* js_name = js_class->StringAt("name");
2680 ASSERT(js_name != NULL);
2681 ParsedJSONNumber* js_cid = js_class->NumberAt("cid");
2682 ASSERT(js_cid != NULL);
2683
2684 str = String::New(js_uri->value());
2685 lib = Library::LookupLibrary(T, str);
2686 if (lib.IsNull()) {
2687 THR_Print("Cannot find library %s\n", js_uri->value());
2688 continue;
2689 }
2690 str = String::New(js_name->value());
2691 if (str.Equals(Symbols::TopLevel())) {
2692 cls = lib.toplevel_class();
2693 } else {
2694 cls = lib.LookupClassAllowPrivate(str);
2695 }
2696 if (cls.IsNull()) {
2697 THR_Print("Missing class %s\n", js_name->value());
2698 continue;
2699 }
2700
2701 feedback_cid_map_.Insert(IntptrPair(js_cid->value(), cls.id()));
2702 }
2703
2704 ParsedJSONArray* js_functions = jit_feedback_->ArrayAt("functions");
2705 ASSERT(js_functions != NULL);
2706 for (intptr_t i = 0; i < js_functions->Length(); i++) {
2707 ParsedJSONObject* js_function = js_functions->ObjectAt(i);
2708 ASSERT(js_function != NULL);
2709 ParsedJSONString* js_name = js_function->StringAt("name");
2710 ASSERT(js_name != NULL);
2711 ParsedJSONNumber* js_cid = js_function->NumberAt("class");
2712 ASSERT(js_cid != NULL);
2713 ParsedJSONNumber* js_token = js_function->NumberAt("tokenPos");
2714 ASSERT(js_token != NULL);
2715 ParsedJSONNumber* js_kind = js_function->NumberAt("kind");
2716 ASSERT(js_kind != NULL);
2717 function_feedback_map_.Insert(FunctionFeedbackPair(
2718 FunctionFeedbackKey(MapCid(js_cid->value()), js_token->value(),
2719 js_kind->value()),
2720 js_function));
2721 }
2722
2723 class ApplyUsageVisitor : public FunctionVisitor {
2724 public:
2725 explicit ApplyUsageVisitor(Precompiler* precompiler)
2726 : precompiler_(precompiler) {}
2727 void Visit(const Function& function) {
2728 ParsedJSONObject* js_function = precompiler_->LookupFeedback(function);
2729 if (js_function == NULL) {
2730 function.set_usage_counter(0);
2731 } else {
2732 ParsedJSONNumber* js_usage = js_function->NumberAt("usageCounter");
2733 ASSERT(js_usage != NULL);
2734 function.set_usage_counter(js_usage->value());
2735 }
2736 }
2737
2738 private:
2739 Precompiler* precompiler_;
2740 };
2741
2742 ApplyUsageVisitor visitor(this);
2743 ProgramVisitor::VisitFunctions(&visitor);
2744 }
2745
2746
2747 ParsedJSONObject* Precompiler::LookupFeedback(const Function& function) {
2748 const Class& owner = Class::Handle(Z, function.Owner());
2749
2750 FunctionFeedbackKey key(owner.id(), function.token_pos().value(),
2751 function.kind());
2752 FunctionFeedbackPair* pair = function_feedback_map_.Lookup(key);
2753 if (pair == NULL) {
2754 return NULL;
2755 }
2756 return pair->value_;
2757 }
2758
2759
2760 RawScript* Precompiler::LookupScript(const char* uri) {
2761 String& dart_uri = String::Handle(Z, String::New(uri));
2762 Library& lib = Library::Handle(Z);
2763 Script& script = Script::Handle(Z);
2764 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2765 lib ^= libraries_.At(i);
2766 script = lib.LookupScript(dart_uri);
2767 if (!script.IsNull()) {
2768 return script.raw();
2769 }
2770 }
2771 return Script::null();
2772 }
2773
2774
2775 intptr_t Precompiler::MapCid(intptr_t feedback_cid) {
2776 if (feedback_cid < kNumPredefinedCids) {
2777 return feedback_cid;
2778 }
2779 IntptrPair* pair = feedback_cid_map_.Lookup(feedback_cid);
2780 if (pair == NULL) return kIllegalCid;
2781 return pair->value_;
2782 }
2783
2784
2785 void Precompiler::PopulateWithICData(const Function& function,
2786 FlowGraph* graph) {
2787 Zone* zone = Thread::Current()->zone();
2788
2789 for (BlockIterator block_it = graph->reverse_postorder_iterator();
2790 !block_it.Done(); block_it.Advance()) {
2791 ForwardInstructionIterator it(block_it.Current());
2792 for (; !it.Done(); it.Advance()) {
2793 Instruction* instr = it.Current();
2794 if (instr->IsInstanceCall()) {
2795 InstanceCallInstr* call = instr->AsInstanceCall();
2796 if (!call->HasICData()) {
2797 const Array& arguments_descriptor = Array::Handle(
2798 zone, ArgumentsDescriptor::New(call->ArgumentCount(),
2799 call->argument_names()));
2800 const ICData& ic_data = ICData::ZoneHandle(
2801 zone, ICData::New(function, call->function_name(),
2802 arguments_descriptor, call->deopt_id(),
2803 call->checked_argument_count(), false));
2804 call->set_ic_data(&ic_data);
2805 }
2806 } else if (instr->IsStaticCall()) {
2807 StaticCallInstr* call = instr->AsStaticCall();
2808 if (!call->HasICData()) {
2809 const Array& arguments_descriptor = Array::Handle(
2810 zone, ArgumentsDescriptor::New(call->ArgumentCount(),
2811 call->argument_names()));
2812 const Function& target = call->function();
2813 MethodRecognizer::Kind recognized_kind =
2814 MethodRecognizer::RecognizeKind(target);
2815 int num_args_checked = 0;
2816 switch (recognized_kind) {
2817 case MethodRecognizer::kDoubleFromInteger:
2818 case MethodRecognizer::kMathMin:
2819 case MethodRecognizer::kMathMax:
2820 num_args_checked = 2;
2821 break;
2822 default:
2823 break;
2824 }
2825 const ICData& ic_data = ICData::ZoneHandle(
2826 zone, ICData::New(function, String::Handle(zone, target.name()),
2827 arguments_descriptor, call->deopt_id(),
2828 num_args_checked, true));
2829 ic_data.AddTarget(target);
2830 call->set_ic_data(&ic_data);
2831 }
2832 }
2833 }
2834 }
2835 }
2836
2837
2838 void Precompiler::TryApplyFeedback(const Function& function, FlowGraph* graph) {
2839 ParsedJSONObject* js_function = LookupFeedback(function);
2840 if (js_function == NULL) {
2841 if (FLAG_trace_precompiler) {
2842 THR_Print("No feedback available for %s\n",
2843 function.ToQualifiedCString());
2844 }
2845 return;
2846 }
2847
2848 ParsedJSONArray* js_icdatas = js_function->ArrayAt("ics");
2849 ASSERT(js_icdatas != NULL);
2850
2851 for (BlockIterator block_it = graph->reverse_postorder_iterator();
2852 !block_it.Done(); block_it.Advance()) {
2853 ForwardInstructionIterator it(block_it.Current());
2854 for (; !it.Done(); it.Advance()) {
2855 Instruction* instr = it.Current();
2856 if (instr->IsInstanceCall()) {
2857 InstanceCallInstr* call = instr->AsInstanceCall();
2858 TryApplyFeedback(js_icdatas, *call->ic_data());
2859 } else if (instr->IsStaticCall()) {
2860 StaticCallInstr* call = instr->AsStaticCall();
2861 TryApplyFeedback(js_icdatas, *call->ic_data());
2862 }
2863 }
2864 }
2865 }
2866
2867
2868 void Precompiler::TryApplyFeedback(ParsedJSONArray* js_icdatas,
2869 const ICData& ic) {
2870 for (intptr_t j = 0; j < js_icdatas->Length(); j++) {
2871 ParsedJSONObject* js_icdata = js_icdatas->ObjectAt(j);
2872 ASSERT(js_icdata != NULL);
2873
2874 ParsedJSONNumber* js_deoptid = js_icdata->NumberAt("deoptId");
2875 ASSERT(js_deoptid != NULL);
2876 if (js_deoptid->value() != ic.deopt_id()) continue;
2877
2878 ParsedJSONBoolean* js_isstaticcall = js_icdata->BooleanAt("isStaticCall");
2879 ASSERT(js_isstaticcall != NULL);
2880 if (js_isstaticcall->value() != ic.is_static_call()) return;
2881
2882 ParsedJSONNumber* js_argsTested = js_icdata->NumberAt("argsTested");
2883 ASSERT(js_argsTested != NULL);
2884 if (js_argsTested->value() != ic.NumArgsTested()) return;
2885
2886 ParsedJSONString* js_selector = js_icdata->StringAt("selector");
2887 ASSERT(js_selector != NULL);
2888 const String& feedback_selector =
2889 String::Handle(String::New(js_selector->value()));
2890 const String& selector = String::Handle(ic.target_name());
2891 // N.B.: EqualsIgnoringPrivateKey is not symmetric.
2892 if (!String::EqualsIgnoringPrivateKey(selector, feedback_selector)) return;
2893
2894 ParsedJSONArray* js_entries = js_icdata->ArrayAt("entries");
2895 ASSERT(js_entries != NULL);
2896 if (ic.is_static_call()) {
2897 // [cid [cid]] target count
2898 ParsedJSONNumber* entry = js_entries->NumberAt(js_entries->Length() - 1);
2899 ASSERT(entry != NULL);
2900 ic.SetCountAt(0, entry->value());
2901 } else {
2902 // [cid [cid [cid]]] target count
2903 const Array& arguments_descriptor =
2904 Array::Handle(ic.arguments_descriptor());
2905 ArgumentsDescriptor args_desc(arguments_descriptor);
2906
2907 intptr_t num_args_checked = ic.NumArgsTested();
2908 for (intptr_t k = 0; k < js_entries->Length();
2909 k += num_args_checked + 1) {
2910 GrowableArray<intptr_t> class_ids(num_args_checked);
2911 for (intptr_t arg = 0; arg < num_args_checked; arg++) {
2912 ParsedJSONNumber* entry = js_entries->NumberAt(k + arg);
2913 ASSERT(entry != NULL);
2914 class_ids.Add(MapCid(entry->value()));
2915 }
2916 ParsedJSONNumber* entry = js_entries->NumberAt(k + num_args_checked);
2917 ASSERT(entry != NULL);
2918 intptr_t count = entry->value();
2919
2920 bool has_missing_cid = false;
2921 for (intptr_t arg = 0; arg < num_args_checked; arg++) {
2922 if (class_ids[arg] == kIllegalCid) {
2923 has_missing_cid = true;
2924 }
2925 }
2926 if (has_missing_cid) continue;
2927
2928 intptr_t receiver_cid = class_ids[0];
2929 const Class& receiver_cls =
2930 Class::Handle(I->class_table()->At(receiver_cid));
2931 if (receiver_cls.IsClass()) {
2932 const Function& target =
2933 Function::Handle(Resolver::ResolveDynamicForReceiverClass(
2934 receiver_cls, selector, args_desc, false));
2935 // TODO(rmacnak): Create missing dispatchers.
2936 if (!target.IsNull()) {
2937 if (num_args_checked == 1) {
2938 ic.AddReceiverCheck(receiver_cid, target, count);
2939 } else {
2940 ic.AddCheck(class_ids, target, count);
2941 }
2942 }
2943 }
2944 }
2945 }
2946
2947 return;
2948 }
2949 }
2950
2951
2952 void Precompiler::ResetPrecompilerState() { 2610 void Precompiler::ResetPrecompilerState() {
2953 changed_ = false; 2611 changed_ = false;
2954 function_count_ = 0; 2612 function_count_ = 0;
2955 class_count_ = 0; 2613 class_count_ = 0;
2956 selector_count_ = 0; 2614 selector_count_ = 0;
2957 dropped_function_count_ = 0; 2615 dropped_function_count_ = 0;
2958 dropped_field_count_ = 0; 2616 dropped_field_count_ = 0;
2959 ASSERT(pending_functions_.Length() == 0); 2617 ASSERT(pending_functions_.Length() == 0);
2960 sent_selectors_.Clear(); 2618 sent_selectors_.Clear();
2961 enqueued_functions_.Clear(); 2619 enqueued_functions_.Clear();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 ZoneGrowableArray<const ICData*>* ic_data_array = 2750 ZoneGrowableArray<const ICData*>* ic_data_array =
3093 new (zone) ZoneGrowableArray<const ICData*>(); 2751 new (zone) ZoneGrowableArray<const ICData*>();
3094 #ifndef PRODUCT 2752 #ifndef PRODUCT
3095 TimelineDurationScope tds(thread(), compiler_timeline, 2753 TimelineDurationScope tds(thread(), compiler_timeline,
3096 "BuildFlowGraph"); 2754 "BuildFlowGraph");
3097 #endif // !PRODUCT 2755 #endif // !PRODUCT
3098 flow_graph = pipeline->BuildFlowGraph( 2756 flow_graph = pipeline->BuildFlowGraph(
3099 zone, parsed_function(), *ic_data_array, Compiler::kNoOSRDeoptId); 2757 zone, parsed_function(), *ic_data_array, Compiler::kNoOSRDeoptId);
3100 } 2758 }
3101 2759
3102 if (optimized()) {
3103 Precompiler::PopulateWithICData(parsed_function()->function(),
3104 flow_graph);
3105 if (precompiler_ != NULL) {
3106 precompiler_->TryApplyFeedback(parsed_function()->function(),
3107 flow_graph);
3108 }
3109 }
3110
3111 const bool print_flow_graph = 2760 const bool print_flow_graph =
3112 (FLAG_print_flow_graph || 2761 (FLAG_print_flow_graph ||
3113 (optimized() && FLAG_print_flow_graph_optimized)) && 2762 (optimized() && FLAG_print_flow_graph_optimized)) &&
3114 FlowGraphPrinter::ShouldPrint(function); 2763 FlowGraphPrinter::ShouldPrint(function);
3115 2764
3116 if (print_flow_graph) { 2765 if (print_flow_graph) {
3117 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 2766 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
3118 } 2767 }
3119 2768
3120 if (optimized()) { 2769 if (optimized()) {
(...skipping 30 matching lines...) Expand all
3151 // is that the length of |inline_id_to_function| is always larger 2800 // is that the length of |inline_id_to_function| is always larger
3152 // than the length of |inline_id_to_token_pos| by one. 2801 // than the length of |inline_id_to_token_pos| by one.
3153 // Top scope function has no caller (-1). We do this because we expect 2802 // Top scope function has no caller (-1). We do this because we expect
3154 // all token positions to be at an inlined call. 2803 // all token positions to be at an inlined call.
3155 // Top scope function has no caller (-1). 2804 // Top scope function has no caller (-1).
3156 caller_inline_id.Add(-1); 2805 caller_inline_id.Add(-1);
3157 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); 2806 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
3158 2807
3159 AotOptimizer optimizer(precompiler_, flow_graph, 2808 AotOptimizer optimizer(precompiler_, flow_graph,
3160 use_speculative_inlining, &inlining_black_list); 2809 use_speculative_inlining, &inlining_black_list);
2810 optimizer.PopulateWithICData();
3161 2811
3162 optimizer.ApplyClassIds(); 2812 optimizer.ApplyClassIds();
3163 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2813 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3164 2814
3165 FlowGraphTypePropagator::Propagate(flow_graph); 2815 FlowGraphTypePropagator::Propagate(flow_graph);
3166 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2816 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3167 2817
3168 optimizer.ApplyICData(); 2818 optimizer.ApplyICData();
3169 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2819 DEBUG_ASSERT(flow_graph->VerifyUseLists());
3170 2820
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 3299
3650 ASSERT(FLAG_precompiled_mode); 3300 ASSERT(FLAG_precompiled_mode);
3651 const bool optimized = function.IsOptimizable(); // False for natives. 3301 const bool optimized = function.IsOptimizable(); // False for natives.
3652 DartPrecompilationPipeline pipeline(zone, field_type_map); 3302 DartPrecompilationPipeline pipeline(zone, field_type_map);
3653 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); 3303 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized);
3654 } 3304 }
3655 3305
3656 #endif // DART_PRECOMPILER 3306 #endif // DART_PRECOMPILER
3657 3307
3658 } // namespace dart 3308 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/program_visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698