| OLD | NEW | 
|---|
| 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  Loading... | 
| 46 #include "vm/timer.h" | 46 #include "vm/timer.h" | 
| 47 #include "vm/type_table.h" | 47 #include "vm/type_table.h" | 
| 48 #include "vm/version.h" | 48 #include "vm/version.h" | 
| 49 | 49 | 
| 50 namespace dart { | 50 namespace dart { | 
| 51 | 51 | 
| 52 #define T (thread()) | 52 #define T (thread()) | 
| 53 #define I (isolate()) | 53 #define I (isolate()) | 
| 54 #define Z (zone()) | 54 #define Z (zone()) | 
| 55 | 55 | 
| 56 |  | 
| 57 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynamic targets"); | 56 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynamic targets"); | 
| 58 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); | 57 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); | 
| 59 DEFINE_FLAG( | 58 DEFINE_FLAG( | 
| 60     int, | 59     int, | 
| 61     max_speculative_inlining_attempts, | 60     max_speculative_inlining_attempts, | 
| 62     1, | 61     1, | 
| 63     "Max number of attempts with speculative inlining (precompilation only)"); | 62     "Max number of attempts with speculative inlining (precompilation only)"); | 
| 64 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); | 63 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); | 
| 65 | 64 | 
| 66 DECLARE_FLAG(bool, allocation_sinking); | 65 DECLARE_FLAG(bool, allocation_sinking); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 80 DECLARE_FLAG(bool, trace_inlining_intervals); | 79 DECLARE_FLAG(bool, trace_inlining_intervals); | 
| 81 DECLARE_FLAG(int, inlining_hotness); | 80 DECLARE_FLAG(int, inlining_hotness); | 
| 82 DECLARE_FLAG(int, inlining_size_threshold); | 81 DECLARE_FLAG(int, inlining_size_threshold); | 
| 83 DECLARE_FLAG(int, inlining_callee_size_threshold); | 82 DECLARE_FLAG(int, inlining_callee_size_threshold); | 
| 84 DECLARE_FLAG(int, inline_getters_setters_smaller_than); | 83 DECLARE_FLAG(int, inline_getters_setters_smaller_than); | 
| 85 DECLARE_FLAG(int, inlining_depth_threshold); | 84 DECLARE_FLAG(int, inlining_depth_threshold); | 
| 86 DECLARE_FLAG(int, inlining_caller_size_threshold); | 85 DECLARE_FLAG(int, inlining_caller_size_threshold); | 
| 87 DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold); | 86 DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold); | 
| 88 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold); | 87 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold); | 
| 89 | 88 | 
| 90 |  | 
| 91 #ifdef DART_PRECOMPILER | 89 #ifdef DART_PRECOMPILER | 
| 92 | 90 | 
| 93 class DartPrecompilationPipeline : public DartCompilationPipeline { | 91 class DartPrecompilationPipeline : public DartCompilationPipeline { | 
| 94  public: | 92  public: | 
| 95   explicit DartPrecompilationPipeline(Zone* zone, | 93   explicit DartPrecompilationPipeline(Zone* zone, | 
| 96                                       FieldTypeMap* field_map = NULL) | 94                                       FieldTypeMap* field_map = NULL) | 
| 97       : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {} | 95       : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {} | 
| 98 | 96 | 
| 99   virtual void FinalizeCompilation(FlowGraph* flow_graph) { | 97   virtual void FinalizeCompilation(FlowGraph* flow_graph) { | 
| 100     if ((field_map_ != NULL) && | 98     if ((field_map_ != NULL) && | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 160   } | 158   } | 
| 161 | 159 | 
| 162   CompileType result_type() { return result_type_; } | 160   CompileType result_type() { return result_type_; } | 
| 163 | 161 | 
| 164  private: | 162  private: | 
| 165   Zone* zone_; | 163   Zone* zone_; | 
| 166   CompileType result_type_; | 164   CompileType result_type_; | 
| 167   FieldTypeMap* field_map_; | 165   FieldTypeMap* field_map_; | 
| 168 }; | 166 }; | 
| 169 | 167 | 
| 170 |  | 
| 171 class PrecompileParsedFunctionHelper : public ValueObject { | 168 class PrecompileParsedFunctionHelper : public ValueObject { | 
| 172  public: | 169  public: | 
| 173   PrecompileParsedFunctionHelper(Precompiler* precompiler, | 170   PrecompileParsedFunctionHelper(Precompiler* precompiler, | 
| 174                                  ParsedFunction* parsed_function, | 171                                  ParsedFunction* parsed_function, | 
| 175                                  bool optimized) | 172                                  bool optimized) | 
| 176       : precompiler_(precompiler), | 173       : precompiler_(precompiler), | 
| 177         parsed_function_(parsed_function), | 174         parsed_function_(parsed_function), | 
| 178         optimized_(optimized), | 175         optimized_(optimized), | 
| 179         thread_(Thread::Current()) {} | 176         thread_(Thread::Current()) {} | 
| 180 | 177 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 191                            FlowGraph* flow_graph); | 188                            FlowGraph* flow_graph); | 
| 192 | 189 | 
| 193   Precompiler* precompiler_; | 190   Precompiler* precompiler_; | 
| 194   ParsedFunction* parsed_function_; | 191   ParsedFunction* parsed_function_; | 
| 195   const bool optimized_; | 192   const bool optimized_; | 
| 196   Thread* const thread_; | 193   Thread* const thread_; | 
| 197 | 194 | 
| 198   DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); | 195   DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); | 
| 199 }; | 196 }; | 
| 200 | 197 | 
| 201 |  | 
| 202 static void Jump(const Error& error) { | 198 static void Jump(const Error& error) { | 
| 203   Thread::Current()->long_jump_base()->Jump(1, error); | 199   Thread::Current()->long_jump_base()->Jump(1, error); | 
| 204 } | 200 } | 
| 205 | 201 | 
| 206 |  | 
| 207 TypeRangeCache::TypeRangeCache(Precompiler* precompiler, | 202 TypeRangeCache::TypeRangeCache(Precompiler* precompiler, | 
| 208                                Thread* thread, | 203                                Thread* thread, | 
| 209                                intptr_t num_cids) | 204                                intptr_t num_cids) | 
| 210     : precompiler_(precompiler), | 205     : precompiler_(precompiler), | 
| 211       thread_(thread), | 206       thread_(thread), | 
| 212       lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)), | 207       lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)), | 
| 213       upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) { | 208       upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) { | 
| 214   for (intptr_t i = 0; i < num_cids; i++) { | 209   for (intptr_t i = 0; i < num_cids; i++) { | 
| 215     lower_limits_[i] = kNotComputed; | 210     lower_limits_[i] = kNotComputed; | 
| 216     upper_limits_[i] = kNotComputed; | 211     upper_limits_[i] = kNotComputed; | 
| 217   } | 212   } | 
| 218   ASSERT(precompiler->type_range_cache() == NULL); | 213   ASSERT(precompiler->type_range_cache() == NULL); | 
| 219   precompiler->set_type_range_cache(this); | 214   precompiler->set_type_range_cache(this); | 
| 220 } | 215 } | 
| 221 | 216 | 
| 222 |  | 
| 223 TypeRangeCache::~TypeRangeCache() { | 217 TypeRangeCache::~TypeRangeCache() { | 
| 224   ASSERT(precompiler_->type_range_cache() == this); | 218   ASSERT(precompiler_->type_range_cache() == this); | 
| 225   precompiler_->set_type_range_cache(NULL); | 219   precompiler_->set_type_range_cache(NULL); | 
| 226 } | 220 } | 
| 227 | 221 | 
| 228 |  | 
| 229 RawError* Precompiler::CompileAll( | 222 RawError* Precompiler::CompileAll( | 
| 230     Dart_QualifiedFunctionName embedder_entry_points[], | 223     Dart_QualifiedFunctionName embedder_entry_points[], | 
| 231     uint8_t* jit_feedback, | 224     uint8_t* jit_feedback, | 
| 232     intptr_t jit_feedback_length) { | 225     intptr_t jit_feedback_length) { | 
| 233   LongJumpScope jump; | 226   LongJumpScope jump; | 
| 234   if (setjmp(*jump.Set()) == 0) { | 227   if (setjmp(*jump.Set()) == 0) { | 
| 235     Precompiler precompiler(Thread::Current()); | 228     Precompiler precompiler(Thread::Current()); | 
| 236     precompiler.LoadFeedback(jit_feedback, jit_feedback_length); | 229     precompiler.LoadFeedback(jit_feedback, jit_feedback_length); | 
| 237     precompiler.DoCompileAll(embedder_entry_points); | 230     precompiler.DoCompileAll(embedder_entry_points); | 
| 238     return Error::null(); | 231     return Error::null(); | 
| 239   } else { | 232   } else { | 
| 240     Thread* thread = Thread::Current(); | 233     Thread* thread = Thread::Current(); | 
| 241     const Error& error = Error::Handle(thread->sticky_error()); | 234     const Error& error = Error::Handle(thread->sticky_error()); | 
| 242     thread->clear_sticky_error(); | 235     thread->clear_sticky_error(); | 
| 243     return error.raw(); | 236     return error.raw(); | 
| 244   } | 237   } | 
| 245 } | 238 } | 
| 246 | 239 | 
| 247 |  | 
| 248 bool TypeRangeCache::InstanceOfHasClassRange(const AbstractType& type, | 240 bool TypeRangeCache::InstanceOfHasClassRange(const AbstractType& type, | 
| 249                                              intptr_t* lower_limit, | 241                                              intptr_t* lower_limit, | 
| 250                                              intptr_t* upper_limit) { | 242                                              intptr_t* upper_limit) { | 
| 251   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 243   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 
| 252 | 244 | 
| 253   if (!type.IsInstantiated()) return false; | 245   if (!type.IsInstantiated()) return false; | 
| 254   if (type.IsFunctionType()) return false; | 246   if (type.IsFunctionType()) return false; | 
| 255   if (type.IsDartFunctionType()) return false; | 247   if (type.IsDartFunctionType()) return false; | 
| 256 | 248 | 
| 257   Zone* zone = thread_->zone(); | 249   Zone* zone = thread_->zone(); | 
| 258   const TypeArguments& type_arguments = | 250   const TypeArguments& type_arguments = | 
| 259       TypeArguments::Handle(zone, type.arguments()); | 251       TypeArguments::Handle(zone, type.arguments()); | 
| 260   if (!type_arguments.IsNull() && | 252   if (!type_arguments.IsNull() && | 
| 261       !type_arguments.IsRaw(0, type_arguments.Length())) | 253       !type_arguments.IsRaw(0, type_arguments.Length())) | 
| 262     return false; | 254     return false; | 
| 263 | 255 | 
| 264 |  | 
| 265   intptr_t type_cid = type.type_class_id(); | 256   intptr_t type_cid = type.type_class_id(); | 
| 266   if (lower_limits_[type_cid] == kNotContiguous) return false; | 257   if (lower_limits_[type_cid] == kNotContiguous) return false; | 
| 267   if (lower_limits_[type_cid] != kNotComputed) { | 258   if (lower_limits_[type_cid] != kNotComputed) { | 
| 268     *lower_limit = lower_limits_[type_cid]; | 259     *lower_limit = lower_limits_[type_cid]; | 
| 269     *upper_limit = upper_limits_[type_cid]; | 260     *upper_limit = upper_limits_[type_cid]; | 
| 270     return true; | 261     return true; | 
| 271   } | 262   } | 
| 272 | 263 | 
| 273 |  | 
| 274   *lower_limit = -1; | 264   *lower_limit = -1; | 
| 275   *upper_limit = -1; | 265   *upper_limit = -1; | 
| 276   intptr_t last_matching_cid = -1; | 266   intptr_t last_matching_cid = -1; | 
| 277 | 267 | 
| 278   ClassTable* table = thread_->isolate()->class_table(); | 268   ClassTable* table = thread_->isolate()->class_table(); | 
| 279   Class& cls = Class::Handle(zone); | 269   Class& cls = Class::Handle(zone); | 
| 280   AbstractType& cls_type = AbstractType::Handle(zone); | 270   AbstractType& cls_type = AbstractType::Handle(zone); | 
| 281   for (intptr_t cid = kInstanceCid; cid < table->NumCids(); cid++) { | 271   for (intptr_t cid = kInstanceCid; cid < table->NumCids(); cid++) { | 
| 282     // Create local zone because deep hierarchies may allocate lots of handles | 272     // Create local zone because deep hierarchies may allocate lots of handles | 
| 283     // within one iteration of this loop. | 273     // within one iteration of this loop. | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 331   if (FLAG_trace_precompiler) { | 321   if (FLAG_trace_precompiler) { | 
| 332     THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n", | 322     THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n", | 
| 333               type.ToCString(), *lower_limit, *upper_limit); | 323               type.ToCString(), *lower_limit, *upper_limit); | 
| 334   } | 324   } | 
| 335 | 325 | 
| 336   lower_limits_[type_cid] = *lower_limit; | 326   lower_limits_[type_cid] = *lower_limit; | 
| 337   upper_limits_[type_cid] = *upper_limit; | 327   upper_limits_[type_cid] = *upper_limit; | 
| 338   return true; | 328   return true; | 
| 339 } | 329 } | 
| 340 | 330 | 
| 341 |  | 
| 342 Precompiler::Precompiler(Thread* thread) | 331 Precompiler::Precompiler(Thread* thread) | 
| 343     : thread_(thread), | 332     : thread_(thread), | 
| 344       zone_(NULL), | 333       zone_(NULL), | 
| 345       isolate_(thread->isolate()), | 334       isolate_(thread->isolate()), | 
| 346       jit_feedback_(NULL), | 335       jit_feedback_(NULL), | 
| 347       changed_(false), | 336       changed_(false), | 
| 348       retain_root_library_caches_(false), | 337       retain_root_library_caches_(false), | 
| 349       function_count_(0), | 338       function_count_(0), | 
| 350       class_count_(0), | 339       class_count_(0), | 
| 351       selector_count_(0), | 340       selector_count_(0), | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 364       functions_to_retain_(), | 353       functions_to_retain_(), | 
| 365       classes_to_retain_(), | 354       classes_to_retain_(), | 
| 366       typeargs_to_retain_(), | 355       typeargs_to_retain_(), | 
| 367       types_to_retain_(), | 356       types_to_retain_(), | 
| 368       consts_to_retain_(), | 357       consts_to_retain_(), | 
| 369       field_type_map_(), | 358       field_type_map_(), | 
| 370       type_range_cache_(NULL), | 359       type_range_cache_(NULL), | 
| 371       error_(Error::Handle()), | 360       error_(Error::Handle()), | 
| 372       get_runtime_type_is_unique_(false) {} | 361       get_runtime_type_is_unique_(false) {} | 
| 373 | 362 | 
| 374 |  | 
| 375 void Precompiler::LoadFeedback(uint8_t* buffer, intptr_t length) { | 363 void Precompiler::LoadFeedback(uint8_t* buffer, intptr_t length) { | 
| 376   if (buffer == NULL) { | 364   if (buffer == NULL) { | 
| 377     if (FLAG_trace_precompiler) { | 365     if (FLAG_trace_precompiler) { | 
| 378       THR_Print("Precompiler running without JIT feedback\n"); | 366       THR_Print("Precompiler running without JIT feedback\n"); | 
| 379     } | 367     } | 
| 380 | 368 | 
| 381     // Flags affecting compilation only: | 369     // Flags affecting compilation only: | 
| 382     // There is no counter feedback in precompilation, so ignore the counter | 370     // There is no counter feedback in precompilation, so ignore the counter | 
| 383     // when making inlining decisions. | 371     // when making inlining decisions. | 
| 384     FLAG_inlining_hotness = 0; | 372     FLAG_inlining_hotness = 0; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 405     ParsedJSONError* error = static_cast<ParsedJSONError*>(root); | 393     ParsedJSONError* error = static_cast<ParsedJSONError*>(root); | 
| 406     THR_Print("Error parsing JIT feedback: %s:%" Pd "\n", error->message(), | 394     THR_Print("Error parsing JIT feedback: %s:%" Pd "\n", error->message(), | 
| 407               error->position()); | 395               error->position()); | 
| 408   } else if (!root->IsObject()) { | 396   } else if (!root->IsObject()) { | 
| 409     THR_Print("Error parsing JIT feedback: object expected\n"); | 397     THR_Print("Error parsing JIT feedback: object expected\n"); | 
| 410   } else { | 398   } else { | 
| 411     jit_feedback_ = static_cast<ParsedJSONObject*>(root); | 399     jit_feedback_ = static_cast<ParsedJSONObject*>(root); | 
| 412   } | 400   } | 
| 413 } | 401 } | 
| 414 | 402 | 
| 415 |  | 
| 416 void Precompiler::DoCompileAll( | 403 void Precompiler::DoCompileAll( | 
| 417     Dart_QualifiedFunctionName embedder_entry_points[]) { | 404     Dart_QualifiedFunctionName embedder_entry_points[]) { | 
| 418   ASSERT(I->compilation_allowed()); | 405   ASSERT(I->compilation_allowed()); | 
| 419 | 406 | 
| 420   { | 407   { | 
| 421     StackZone stack_zone(T); | 408     StackZone stack_zone(T); | 
| 422     zone_ = stack_zone.GetZone(); | 409     zone_ = stack_zone.GetZone(); | 
| 423 | 410 | 
| 424     { | 411     { | 
| 425       HANDLESCOPE(T); | 412       HANDLESCOPE(T); | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 526     THR_Print("Dropped %" Pd " functions,", dropped_function_count_); | 513     THR_Print("Dropped %" Pd " functions,", dropped_function_count_); | 
| 527     THR_Print(" %" Pd " fields,", dropped_field_count_); | 514     THR_Print(" %" Pd " fields,", dropped_field_count_); | 
| 528     THR_Print(" %" Pd " symbols,", symbols_before - symbols_after); | 515     THR_Print(" %" Pd " symbols,", symbols_before - symbols_after); | 
| 529     THR_Print(" %" Pd " types,", dropped_type_count_); | 516     THR_Print(" %" Pd " types,", dropped_type_count_); | 
| 530     THR_Print(" %" Pd " type arguments,", dropped_typearg_count_); | 517     THR_Print(" %" Pd " type arguments,", dropped_typearg_count_); | 
| 531     THR_Print(" %" Pd " classes,", dropped_class_count_); | 518     THR_Print(" %" Pd " classes,", dropped_class_count_); | 
| 532     THR_Print(" %" Pd " libraries.\n", dropped_library_count_); | 519     THR_Print(" %" Pd " libraries.\n", dropped_library_count_); | 
| 533   } | 520   } | 
| 534 } | 521 } | 
| 535 | 522 | 
| 536 |  | 
| 537 static void CompileStaticInitializerIgnoreErrors(const Field& field) { | 523 static void CompileStaticInitializerIgnoreErrors(const Field& field) { | 
| 538   LongJumpScope jump; | 524   LongJumpScope jump; | 
| 539   if (setjmp(*jump.Set()) == 0) { | 525   if (setjmp(*jump.Set()) == 0) { | 
| 540     Precompiler::CompileStaticInitializer(field, /* compute_type = */ true); | 526     Precompiler::CompileStaticInitializer(field, /* compute_type = */ true); | 
| 541   } else { | 527   } else { | 
| 542     // Ignore compile-time errors here. If the field is actually used, | 528     // Ignore compile-time errors here. If the field is actually used, | 
| 543     // the error will be reported later during Iterate(). | 529     // the error will be reported later during Iterate(). | 
| 544   } | 530   } | 
| 545 } | 531 } | 
| 546 | 532 | 
| 547 |  | 
| 548 void Precompiler::PrecompileStaticInitializers() { | 533 void Precompiler::PrecompileStaticInitializers() { | 
| 549   class StaticInitializerVisitor : public ClassVisitor { | 534   class StaticInitializerVisitor : public ClassVisitor { | 
| 550    public: | 535    public: | 
| 551     explicit StaticInitializerVisitor(Zone* zone) | 536     explicit StaticInitializerVisitor(Zone* zone) | 
| 552         : fields_(Array::Handle(zone)), | 537         : fields_(Array::Handle(zone)), | 
| 553           field_(Field::Handle(zone)), | 538           field_(Field::Handle(zone)), | 
| 554           function_(Function::Handle(zone)) {} | 539           function_(Function::Handle(zone)) {} | 
| 555     void Visit(const Class& cls) { | 540     void Visit(const Class& cls) { | 
| 556       fields_ = cls.fields(); | 541       fields_ = cls.fields(); | 
| 557       for (intptr_t j = 0; j < fields_.Length(); j++) { | 542       for (intptr_t j = 0; j < fields_.Length(); j++) { | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 570     Array& fields_; | 555     Array& fields_; | 
| 571     Field& field_; | 556     Field& field_; | 
| 572     Function& function_; | 557     Function& function_; | 
| 573   }; | 558   }; | 
| 574 | 559 | 
| 575   HANDLESCOPE(T); | 560   HANDLESCOPE(T); | 
| 576   StaticInitializerVisitor visitor(Z); | 561   StaticInitializerVisitor visitor(Z); | 
| 577   ProgramVisitor::VisitClasses(&visitor); | 562   ProgramVisitor::VisitClasses(&visitor); | 
| 578 } | 563 } | 
| 579 | 564 | 
| 580 |  | 
| 581 void Precompiler::PrecompileConstructors() { | 565 void Precompiler::PrecompileConstructors() { | 
| 582   class ConstructorVisitor : public FunctionVisitor { | 566   class ConstructorVisitor : public FunctionVisitor { | 
| 583    public: | 567    public: | 
| 584     explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone) | 568     explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone) | 
| 585         : precompiler_(precompiler), zone_(zone) {} | 569         : precompiler_(precompiler), zone_(zone) {} | 
| 586     void Visit(const Function& function) { | 570     void Visit(const Function& function) { | 
| 587       if (!function.IsGenerativeConstructor()) return; | 571       if (!function.IsGenerativeConstructor()) return; | 
| 588       if (function.HasCode()) { | 572       if (function.HasCode()) { | 
| 589         // Const constructors may have been visited before. Recompile them here | 573         // Const constructors may have been visited before. Recompile them here | 
| 590         // to collect type information for final fields for them as well. | 574         // to collect type information for final fields for them as well. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 613     current->field_->set_guarded_cid(cid); | 597     current->field_->set_guarded_cid(cid); | 
| 614     current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); | 598     current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); | 
| 615     if (FLAG_trace_precompiler) { | 599     if (FLAG_trace_precompiler) { | 
| 616       THR_Print( | 600       THR_Print( | 
| 617           "Field %s <- Type %s\n", current->field_->ToCString(), | 601           "Field %s <- Type %s\n", current->field_->ToCString(), | 
| 618           Class::Handle(T->isolate()->class_table()->At(cid)).ToCString()); | 602           Class::Handle(T->isolate()->class_table()->At(cid)).ToCString()); | 
| 619     } | 603     } | 
| 620   } | 604   } | 
| 621 } | 605 } | 
| 622 | 606 | 
| 623 |  | 
| 624 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { | 607 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { | 
| 625   // Note that <rootlibrary>.main is not a root. The appropriate main will be | 608   // Note that <rootlibrary>.main is not a root. The appropriate main will be | 
| 626   // discovered through _getMainClosure. | 609   // discovered through _getMainClosure. | 
| 627 | 610 | 
| 628   AddSelector(Symbols::NoSuchMethod()); | 611   AddSelector(Symbols::NoSuchMethod()); | 
| 629 | 612 | 
| 630   AddSelector(Symbols::Call());  // For speed, not correctness. | 613   AddSelector(Symbols::Call());  // For speed, not correctness. | 
| 631 | 614 | 
| 632   // Allocated from C++. | 615   // Allocated from C++. | 
| 633   Class& cls = Class::Handle(Z); | 616   Class& cls = Class::Handle(Z); | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 705   } else if (main_closure.IsError()) { | 688   } else if (main_closure.IsError()) { | 
| 706     const Error& error = Error::Cast(main_closure); | 689     const Error& error = Error::Cast(main_closure); | 
| 707     String& msg = | 690     String& msg = | 
| 708         String::Handle(Z, String::NewFormatted("Cannot find main closure %s\n", | 691         String::Handle(Z, String::NewFormatted("Cannot find main closure %s\n", | 
| 709                                                error.ToErrorCString())); | 692                                                error.ToErrorCString())); | 
| 710     Jump(Error::Handle(Z, ApiError::New(msg))); | 693     Jump(Error::Handle(Z, ApiError::New(msg))); | 
| 711     UNREACHABLE(); | 694     UNREACHABLE(); | 
| 712   } | 695   } | 
| 713 } | 696 } | 
| 714 | 697 | 
| 715 |  | 
| 716 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) { | 698 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) { | 
| 717   Library& lib = Library::Handle(Z); | 699   Library& lib = Library::Handle(Z); | 
| 718   Class& cls = Class::Handle(Z); | 700   Class& cls = Class::Handle(Z); | 
| 719   Function& func = Function::Handle(Z); | 701   Function& func = Function::Handle(Z); | 
| 720   Field& field = Field::Handle(Z); | 702   Field& field = Field::Handle(Z); | 
| 721   String& library_uri = String::Handle(Z); | 703   String& library_uri = String::Handle(Z); | 
| 722   String& class_name = String::Handle(Z); | 704   String& class_name = String::Handle(Z); | 
| 723   String& function_name = String::Handle(Z); | 705   String& function_name = String::Handle(Z); | 
| 724 | 706 | 
| 725   for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) { | 707   for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) { | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 785         // code and only instantiated from C++. | 767         // code and only instantiated from C++. | 
| 786         AddInstantiatedClass(cls); | 768         AddInstantiatedClass(cls); | 
| 787       } | 769       } | 
| 788     } | 770     } | 
| 789     if (!field.IsNull()) { | 771     if (!field.IsNull()) { | 
| 790       AddField(field); | 772       AddField(field); | 
| 791     } | 773     } | 
| 792   } | 774   } | 
| 793 } | 775 } | 
| 794 | 776 | 
| 795 |  | 
| 796 void Precompiler::Iterate() { | 777 void Precompiler::Iterate() { | 
| 797   Function& function = Function::Handle(Z); | 778   Function& function = Function::Handle(Z); | 
| 798 | 779 | 
| 799   while (changed_) { | 780   while (changed_) { | 
| 800     changed_ = false; | 781     changed_ = false; | 
| 801 | 782 | 
| 802     while (pending_functions_.Length() > 0) { | 783     while (pending_functions_.Length() > 0) { | 
| 803       function ^= pending_functions_.RemoveLast(); | 784       function ^= pending_functions_.RemoveLast(); | 
| 804       ProcessFunction(function); | 785       ProcessFunction(function); | 
| 805     } | 786     } | 
| 806 | 787 | 
| 807     CheckForNewDynamicFunctions(); | 788     CheckForNewDynamicFunctions(); | 
| 808     if (!changed_) { | 789     if (!changed_) { | 
| 809       TraceConstFunctions(); | 790       TraceConstFunctions(); | 
| 810     } | 791     } | 
| 811     CollectCallbackFields(); | 792     CollectCallbackFields(); | 
| 812   } | 793   } | 
| 813 } | 794 } | 
| 814 | 795 | 
| 815 |  | 
| 816 void Precompiler::CollectCallbackFields() { | 796 void Precompiler::CollectCallbackFields() { | 
| 817   Library& lib = Library::Handle(Z); | 797   Library& lib = Library::Handle(Z); | 
| 818   Class& cls = Class::Handle(Z); | 798   Class& cls = Class::Handle(Z); | 
| 819   Class& subcls = Class::Handle(Z); | 799   Class& subcls = Class::Handle(Z); | 
| 820   Array& fields = Array::Handle(Z); | 800   Array& fields = Array::Handle(Z); | 
| 821   Field& field = Field::Handle(Z); | 801   Field& field = Field::Handle(Z); | 
| 822   Function& function = Function::Handle(Z); | 802   Function& function = Function::Handle(Z); | 
| 823   Function& dispatcher = Function::Handle(Z); | 803   Function& dispatcher = Function::Handle(Z); | 
| 824   Array& args_desc = Array::Handle(Z); | 804   Array& args_desc = Array::Handle(Z); | 
| 825   AbstractType& field_type = AbstractType::Handle(Z); | 805   AbstractType& field_type = AbstractType::Handle(Z); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 867               } | 847               } | 
| 868               AddFunction(dispatcher); | 848               AddFunction(dispatcher); | 
| 869             } | 849             } | 
| 870           } | 850           } | 
| 871         } | 851         } | 
| 872       } | 852       } | 
| 873     } | 853     } | 
| 874   } | 854   } | 
| 875 } | 855 } | 
| 876 | 856 | 
| 877 |  | 
| 878 void Precompiler::ProcessFunction(const Function& function) { | 857 void Precompiler::ProcessFunction(const Function& function) { | 
| 879   if (!function.HasCode()) { | 858   if (!function.HasCode()) { | 
| 880     function_count_++; | 859     function_count_++; | 
| 881 | 860 | 
| 882     if (FLAG_trace_precompiler) { | 861     if (FLAG_trace_precompiler) { | 
| 883       THR_Print("Precompiling %" Pd " %s (%s, %s)\n", function_count_, | 862       THR_Print("Precompiling %" Pd " %s (%s, %s)\n", function_count_, | 
| 884                 function.ToLibNamePrefixedQualifiedCString(), | 863                 function.ToLibNamePrefixedQualifiedCString(), | 
| 885                 function.token_pos().ToCString(), | 864                 function.token_pos().ToCString(), | 
| 886                 Function::KindToCString(function.kind())); | 865                 Function::KindToCString(function.kind())); | 
| 887     } | 866     } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 903                 function.ToLibNamePrefixedQualifiedCString(), | 882                 function.ToLibNamePrefixedQualifiedCString(), | 
| 904                 function.token_pos().ToCString(), | 883                 function.token_pos().ToCString(), | 
| 905                 Function::KindToCString(function.kind())); | 884                 Function::KindToCString(function.kind())); | 
| 906     } | 885     } | 
| 907   } | 886   } | 
| 908 | 887 | 
| 909   ASSERT(function.HasCode()); | 888   ASSERT(function.HasCode()); | 
| 910   AddCalleesOf(function); | 889   AddCalleesOf(function); | 
| 911 } | 890 } | 
| 912 | 891 | 
| 913 |  | 
| 914 void Precompiler::AddCalleesOf(const Function& function) { | 892 void Precompiler::AddCalleesOf(const Function& function) { | 
| 915   ASSERT(function.HasCode()); | 893   ASSERT(function.HasCode()); | 
| 916 | 894 | 
| 917   const Code& code = Code::Handle(Z, function.CurrentCode()); | 895   const Code& code = Code::Handle(Z, function.CurrentCode()); | 
| 918 | 896 | 
| 919   const Array& table = Array::Handle(Z, code.static_calls_target_table()); | 897   const Array& table = Array::Handle(Z, code.static_calls_target_table()); | 
| 920   Object& entry = Object::Handle(Z); | 898   Object& entry = Object::Handle(Z); | 
| 921   Function& target = Function::Handle(Z); | 899   Function& target = Function::Handle(Z); | 
| 922   for (intptr_t i = 0; i < table.Length(); i++) { | 900   for (intptr_t i = 0; i < table.Length(); i++) { | 
| 923     entry = table.At(i); | 901     entry = table.At(i); | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 995   } | 973   } | 
| 996 | 974 | 
| 997   const Array& inlined_functions = | 975   const Array& inlined_functions = | 
| 998       Array::Handle(Z, code.inlined_id_to_function()); | 976       Array::Handle(Z, code.inlined_id_to_function()); | 
| 999   for (intptr_t i = 0; i < inlined_functions.Length(); i++) { | 977   for (intptr_t i = 0; i < inlined_functions.Length(); i++) { | 
| 1000     target ^= inlined_functions.At(i); | 978     target ^= inlined_functions.At(i); | 
| 1001     AddTypesOf(target); | 979     AddTypesOf(target); | 
| 1002   } | 980   } | 
| 1003 } | 981 } | 
| 1004 | 982 | 
| 1005 |  | 
| 1006 void Precompiler::AddTypesOf(const Class& cls) { | 983 void Precompiler::AddTypesOf(const Class& cls) { | 
| 1007   if (cls.IsNull()) return; | 984   if (cls.IsNull()) return; | 
| 1008   if (classes_to_retain_.HasKey(&cls)) return; | 985   if (classes_to_retain_.HasKey(&cls)) return; | 
| 1009   classes_to_retain_.Insert(&Class::ZoneHandle(Z, cls.raw())); | 986   classes_to_retain_.Insert(&Class::ZoneHandle(Z, cls.raw())); | 
| 1010 | 987 | 
| 1011   Array& interfaces = Array::Handle(Z, cls.interfaces()); | 988   Array& interfaces = Array::Handle(Z, cls.interfaces()); | 
| 1012   AbstractType& type = AbstractType::Handle(Z); | 989   AbstractType& type = AbstractType::Handle(Z); | 
| 1013   for (intptr_t i = 0; i < interfaces.Length(); i++) { | 990   for (intptr_t i = 0; i < interfaces.Length(); i++) { | 
| 1014     type ^= interfaces.At(i); | 991     type ^= interfaces.At(i); | 
| 1015     AddType(type); | 992     AddType(type); | 
| 1016   } | 993   } | 
| 1017 | 994 | 
| 1018   AddTypeArguments(TypeArguments::Handle(Z, cls.type_parameters())); | 995   AddTypeArguments(TypeArguments::Handle(Z, cls.type_parameters())); | 
| 1019 | 996 | 
| 1020   type = cls.super_type(); | 997   type = cls.super_type(); | 
| 1021   AddType(type); | 998   AddType(type); | 
| 1022 | 999 | 
| 1023   type = cls.mixin(); | 1000   type = cls.mixin(); | 
| 1024   AddType(type); | 1001   AddType(type); | 
| 1025 | 1002 | 
| 1026   if (cls.IsTypedefClass()) { | 1003   if (cls.IsTypedefClass()) { | 
| 1027     AddTypesOf(Function::Handle(Z, cls.signature_function())); | 1004     AddTypesOf(Function::Handle(Z, cls.signature_function())); | 
| 1028   } | 1005   } | 
| 1029 } | 1006 } | 
| 1030 | 1007 | 
| 1031 |  | 
| 1032 void Precompiler::AddTypesOf(const Function& function) { | 1008 void Precompiler::AddTypesOf(const Function& function) { | 
| 1033   if (function.IsNull()) return; | 1009   if (function.IsNull()) return; | 
| 1034   if (functions_to_retain_.HasKey(&function)) return; | 1010   if (functions_to_retain_.HasKey(&function)) return; | 
| 1035   // We don't expect to see a reference to a redirecting factory. Only its | 1011   // We don't expect to see a reference to a redirecting factory. Only its | 
| 1036   // target should remain. | 1012   // target should remain. | 
| 1037   ASSERT(!function.IsRedirectingFactory()); | 1013   ASSERT(!function.IsRedirectingFactory()); | 
| 1038   functions_to_retain_.Insert(&Function::ZoneHandle(Z, function.raw())); | 1014   functions_to_retain_.Insert(&Function::ZoneHandle(Z, function.raw())); | 
| 1039 | 1015 | 
| 1040   AbstractType& type = AbstractType::Handle(Z); | 1016   AbstractType& type = AbstractType::Handle(Z); | 
| 1041   type = function.result_type(); | 1017   type = function.result_type(); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1071     type = function.ExistingSignatureType(); | 1047     type = function.ExistingSignatureType(); | 
| 1072     if (!type.IsNull()) { | 1048     if (!type.IsNull()) { | 
| 1073       AddType(type); | 1049       AddType(type); | 
| 1074     } | 1050     } | 
| 1075   } | 1051   } | 
| 1076   // A class may have all functions inlined except a local function. | 1052   // A class may have all functions inlined except a local function. | 
| 1077   const Class& owner = Class::Handle(Z, function.Owner()); | 1053   const Class& owner = Class::Handle(Z, function.Owner()); | 
| 1078   AddTypesOf(owner); | 1054   AddTypesOf(owner); | 
| 1079 } | 1055 } | 
| 1080 | 1056 | 
| 1081 |  | 
| 1082 void Precompiler::AddType(const AbstractType& abstype) { | 1057 void Precompiler::AddType(const AbstractType& abstype) { | 
| 1083   if (abstype.IsNull()) return; | 1058   if (abstype.IsNull()) return; | 
| 1084 | 1059 | 
| 1085   if (types_to_retain_.HasKey(&abstype)) return; | 1060   if (types_to_retain_.HasKey(&abstype)) return; | 
| 1086   types_to_retain_.Insert(&AbstractType::ZoneHandle(Z, abstype.raw())); | 1061   types_to_retain_.Insert(&AbstractType::ZoneHandle(Z, abstype.raw())); | 
| 1087 | 1062 | 
| 1088   if (abstype.IsType()) { | 1063   if (abstype.IsType()) { | 
| 1089     const Type& type = Type::Cast(abstype); | 1064     const Type& type = Type::Cast(abstype); | 
| 1090     const Class& cls = Class::Handle(Z, type.type_class()); | 1065     const Class& cls = Class::Handle(Z, type.type_class()); | 
| 1091     AddTypesOf(cls); | 1066     AddTypesOf(cls); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1108   } else if (abstype.IsTypeParameter()) { | 1083   } else if (abstype.IsTypeParameter()) { | 
| 1109     const AbstractType& type = | 1084     const AbstractType& type = | 
| 1110         AbstractType::Handle(Z, TypeParameter::Cast(abstype).bound()); | 1085         AbstractType::Handle(Z, TypeParameter::Cast(abstype).bound()); | 
| 1111     AddType(type); | 1086     AddType(type); | 
| 1112     const Class& cls = | 1087     const Class& cls = | 
| 1113         Class::Handle(Z, TypeParameter::Cast(abstype).parameterized_class()); | 1088         Class::Handle(Z, TypeParameter::Cast(abstype).parameterized_class()); | 
| 1114     AddTypesOf(cls); | 1089     AddTypesOf(cls); | 
| 1115   } | 1090   } | 
| 1116 } | 1091 } | 
| 1117 | 1092 | 
| 1118 |  | 
| 1119 void Precompiler::AddTypeArguments(const TypeArguments& args) { | 1093 void Precompiler::AddTypeArguments(const TypeArguments& args) { | 
| 1120   if (args.IsNull()) return; | 1094   if (args.IsNull()) return; | 
| 1121 | 1095 | 
| 1122   if (typeargs_to_retain_.HasKey(&args)) return; | 1096   if (typeargs_to_retain_.HasKey(&args)) return; | 
| 1123   typeargs_to_retain_.Insert(&TypeArguments::ZoneHandle(Z, args.raw())); | 1097   typeargs_to_retain_.Insert(&TypeArguments::ZoneHandle(Z, args.raw())); | 
| 1124 | 1098 | 
| 1125   AbstractType& arg = AbstractType::Handle(Z); | 1099   AbstractType& arg = AbstractType::Handle(Z); | 
| 1126   for (intptr_t i = 0; i < args.Length(); i++) { | 1100   for (intptr_t i = 0; i < args.Length(); i++) { | 
| 1127     arg = args.TypeAt(i); | 1101     arg = args.TypeAt(i); | 
| 1128     AddType(arg); | 1102     AddType(arg); | 
| 1129   } | 1103   } | 
| 1130 } | 1104 } | 
| 1131 | 1105 | 
| 1132 |  | 
| 1133 void Precompiler::AddConstObject(const Instance& instance) { | 1106 void Precompiler::AddConstObject(const Instance& instance) { | 
| 1134   const Class& cls = Class::Handle(Z, instance.clazz()); | 1107   const Class& cls = Class::Handle(Z, instance.clazz()); | 
| 1135   AddInstantiatedClass(cls); | 1108   AddInstantiatedClass(cls); | 
| 1136 | 1109 | 
| 1137   if (instance.IsClosure()) { | 1110   if (instance.IsClosure()) { | 
| 1138     // An implicit static closure. | 1111     // An implicit static closure. | 
| 1139     const Function& func = | 1112     const Function& func = | 
| 1140         Function::Handle(Z, Closure::Cast(instance).function()); | 1113         Function::Handle(Z, Closure::Cast(instance).function()); | 
| 1141     ASSERT(func.is_static()); | 1114     ASSERT(func.is_static()); | 
| 1142     AddFunction(func); | 1115     AddFunction(func); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1182 | 1155 | 
| 1183    private: | 1156    private: | 
| 1184     Precompiler* precompiler_; | 1157     Precompiler* precompiler_; | 
| 1185     Object& subinstance_; | 1158     Object& subinstance_; | 
| 1186   }; | 1159   }; | 
| 1187 | 1160 | 
| 1188   ConstObjectVisitor visitor(this, I); | 1161   ConstObjectVisitor visitor(this, I); | 
| 1189   instance.raw()->VisitPointers(&visitor); | 1162   instance.raw()->VisitPointers(&visitor); | 
| 1190 } | 1163 } | 
| 1191 | 1164 | 
| 1192 |  | 
| 1193 void Precompiler::AddClosureCall(const Array& arguments_descriptor) { | 1165 void Precompiler::AddClosureCall(const Array& arguments_descriptor) { | 
| 1194   const Class& cache_class = | 1166   const Class& cache_class = | 
| 1195       Class::Handle(Z, I->object_store()->closure_class()); | 1167       Class::Handle(Z, I->object_store()->closure_class()); | 
| 1196   const Function& dispatcher = Function::Handle( | 1168   const Function& dispatcher = Function::Handle( | 
| 1197       Z, cache_class.GetInvocationDispatcher( | 1169       Z, cache_class.GetInvocationDispatcher( | 
| 1198              Symbols::Call(), arguments_descriptor, | 1170              Symbols::Call(), arguments_descriptor, | 
| 1199              RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */)); | 1171              RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */)); | 
| 1200   AddFunction(dispatcher); | 1172   AddFunction(dispatcher); | 
| 1201 } | 1173 } | 
| 1202 | 1174 | 
| 1203 |  | 
| 1204 void Precompiler::AddField(const Field& field) { | 1175 void Precompiler::AddField(const Field& field) { | 
| 1205   if (fields_to_retain_.HasKey(&field)) return; | 1176   if (fields_to_retain_.HasKey(&field)) return; | 
| 1206 | 1177 | 
| 1207   fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw())); | 1178   fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw())); | 
| 1208 | 1179 | 
| 1209   if (field.is_static()) { | 1180   if (field.is_static()) { | 
| 1210     const Object& value = Object::Handle(Z, field.StaticValue()); | 1181     const Object& value = Object::Handle(Z, field.StaticValue()); | 
| 1211     if (value.IsInstance()) { | 1182     if (value.IsInstance()) { | 
| 1212       AddConstObject(Instance::Cast(value)); | 1183       AddConstObject(Instance::Cast(value)); | 
| 1213     } | 1184     } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 1225         const Function& initializer = Function::Handle( | 1196         const Function& initializer = Function::Handle( | 
| 1226             Z, CompileStaticInitializer(field, /* compute_type = */ true)); | 1197             Z, CompileStaticInitializer(field, /* compute_type = */ true)); | 
| 1227         ASSERT(!initializer.IsNull()); | 1198         ASSERT(!initializer.IsNull()); | 
| 1228         field.SetPrecompiledInitializer(initializer); | 1199         field.SetPrecompiledInitializer(initializer); | 
| 1229         AddCalleesOf(initializer); | 1200         AddCalleesOf(initializer); | 
| 1230       } | 1201       } | 
| 1231     } | 1202     } | 
| 1232   } | 1203   } | 
| 1233 } | 1204 } | 
| 1234 | 1205 | 
| 1235 |  | 
| 1236 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, | 1206 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, | 
| 1237                                                    bool compute_type) { | 1207                                                    bool compute_type) { | 
| 1238   ASSERT(field.is_static()); | 1208   ASSERT(field.is_static()); | 
| 1239   Thread* thread = Thread::Current(); | 1209   Thread* thread = Thread::Current(); | 
| 1240   StackZone stack_zone(thread); | 1210   StackZone stack_zone(thread); | 
| 1241   Zone* zone = stack_zone.GetZone(); | 1211   Zone* zone = stack_zone.GetZone(); | 
| 1242 | 1212 | 
| 1243   ParsedFunction* parsed_function; | 1213   ParsedFunction* parsed_function; | 
| 1244   // Check if this field is coming from the Kernel binary. | 1214   // Check if this field is coming from the Kernel binary. | 
| 1245   if (field.kernel_offset() > 0) { | 1215   if (field.kernel_offset() > 0) { | 
| 1246     parsed_function = kernel::ParseStaticFieldInitializer(zone, field); | 1216     parsed_function = kernel::ParseStaticFieldInitializer(zone, field); | 
| 1247   } else { | 1217   } else { | 
| 1248     parsed_function = Parser::ParseStaticFieldInitializer(field); | 1218     parsed_function = Parser::ParseStaticFieldInitializer(field); | 
| 1249     parsed_function->AllocateVariables(); | 1219     parsed_function->AllocateVariables(); | 
| 1250   } | 1220   } | 
| 1251 | 1221 | 
| 1252 |  | 
| 1253   DartPrecompilationPipeline pipeline(zone); | 1222   DartPrecompilationPipeline pipeline(zone); | 
| 1254   PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL, | 1223   PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL, | 
| 1255                                         parsed_function, | 1224                                         parsed_function, | 
| 1256                                         /* optimized = */ true); | 1225                                         /* optimized = */ true); | 
| 1257   bool success = helper.Compile(&pipeline); | 1226   bool success = helper.Compile(&pipeline); | 
| 1258   ASSERT(success); | 1227   ASSERT(success); | 
| 1259 | 1228 | 
| 1260   if (compute_type && field.is_final()) { | 1229   if (compute_type && field.is_final()) { | 
| 1261     intptr_t result_cid = pipeline.result_type().ToCid(); | 1230     intptr_t result_cid = pipeline.result_type().ToCid(); | 
| 1262     if (result_cid != kDynamicCid) { | 1231     if (result_cid != kDynamicCid) { | 
| 1263 #ifndef PRODUCT | 1232 #ifndef PRODUCT | 
| 1264       if (FLAG_trace_precompiler && FLAG_support_il_printer) { | 1233       if (FLAG_trace_precompiler && FLAG_support_il_printer) { | 
| 1265         THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), | 1234         THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), | 
| 1266                   pipeline.result_type().ToCString()); | 1235                   pipeline.result_type().ToCString()); | 
| 1267       } | 1236       } | 
| 1268 #endif  // !PRODUCT | 1237 #endif  // !PRODUCT | 
| 1269       field.set_guarded_cid(result_cid); | 1238       field.set_guarded_cid(result_cid); | 
| 1270     } | 1239     } | 
| 1271   } | 1240   } | 
| 1272 | 1241 | 
| 1273   if ((FLAG_disassemble || FLAG_disassemble_optimized) && | 1242   if ((FLAG_disassemble || FLAG_disassemble_optimized) && | 
| 1274       FlowGraphPrinter::ShouldPrint(parsed_function->function())) { | 1243       FlowGraphPrinter::ShouldPrint(parsed_function->function())) { | 
| 1275     Code& code = Code::Handle(parsed_function->function().CurrentCode()); | 1244     Code& code = Code::Handle(parsed_function->function().CurrentCode()); | 
| 1276     Disassembler::DisassembleCode(parsed_function->function(), code, | 1245     Disassembler::DisassembleCode(parsed_function->function(), code, | 
| 1277                                   /* optimized = */ true); | 1246                                   /* optimized = */ true); | 
| 1278   } | 1247   } | 
| 1279   return parsed_function->function().raw(); | 1248   return parsed_function->function().raw(); | 
| 1280 } | 1249 } | 
| 1281 | 1250 | 
| 1282 |  | 
| 1283 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { | 1251 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { | 
| 1284   ASSERT(field.is_static()); | 1252   ASSERT(field.is_static()); | 
| 1285   // The VM sets the field's value to transiton_sentinel prior to | 1253   // The VM sets the field's value to transiton_sentinel prior to | 
| 1286   // evaluating the initializer value. | 1254   // evaluating the initializer value. | 
| 1287   ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); | 1255   ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); | 
| 1288   LongJumpScope jump; | 1256   LongJumpScope jump; | 
| 1289   if (setjmp(*jump.Set()) == 0) { | 1257   if (setjmp(*jump.Set()) == 0) { | 
| 1290     // Under precompilation, the initializer may have already been compiled, in | 1258     // Under precompilation, the initializer may have already been compiled, in | 
| 1291     // which case use it. Under lazy compilation or early in precompilation, the | 1259     // which case use it. Under lazy compilation or early in precompilation, the | 
| 1292     // initializer has not yet been created, so create it now, but don't bother | 1260     // initializer has not yet been created, so create it now, but don't bother | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 1303     Thread* const thread = Thread::Current(); | 1271     Thread* const thread = Thread::Current(); | 
| 1304     StackZone zone(thread); | 1272     StackZone zone(thread); | 
| 1305     const Error& error = Error::Handle(thread->zone(), thread->sticky_error()); | 1273     const Error& error = Error::Handle(thread->zone(), thread->sticky_error()); | 
| 1306     thread->clear_sticky_error(); | 1274     thread->clear_sticky_error(); | 
| 1307     return error.raw(); | 1275     return error.raw(); | 
| 1308   } | 1276   } | 
| 1309   UNREACHABLE(); | 1277   UNREACHABLE(); | 
| 1310   return Object::null(); | 1278   return Object::null(); | 
| 1311 } | 1279 } | 
| 1312 | 1280 | 
| 1313 |  | 
| 1314 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) { | 1281 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) { | 
| 1315   LongJumpScope jump; | 1282   LongJumpScope jump; | 
| 1316   if (setjmp(*jump.Set()) == 0) { | 1283   if (setjmp(*jump.Set()) == 0) { | 
| 1317     Thread* const thread = Thread::Current(); | 1284     Thread* const thread = Thread::Current(); | 
| 1318     if (FLAG_support_ast_printer && FLAG_trace_compiler) { | 1285     if (FLAG_support_ast_printer && FLAG_trace_compiler) { | 
| 1319       THR_Print("compiling expression: "); | 1286       THR_Print("compiling expression: "); | 
| 1320       AstPrinter ast_printer; | 1287       AstPrinter ast_printer; | 
| 1321       ast_printer.PrintNode(fragment); | 1288       ast_printer.PrintNode(fragment); | 
| 1322     } | 1289     } | 
| 1323 | 1290 | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1367   } else { | 1334   } else { | 
| 1368     Thread* const thread = Thread::Current(); | 1335     Thread* const thread = Thread::Current(); | 
| 1369     const Object& result = PassiveObject::Handle(thread->sticky_error()); | 1336     const Object& result = PassiveObject::Handle(thread->sticky_error()); | 
| 1370     thread->clear_sticky_error(); | 1337     thread->clear_sticky_error(); | 
| 1371     return result.raw(); | 1338     return result.raw(); | 
| 1372   } | 1339   } | 
| 1373   UNREACHABLE(); | 1340   UNREACHABLE(); | 
| 1374   return Object::null(); | 1341   return Object::null(); | 
| 1375 } | 1342 } | 
| 1376 | 1343 | 
| 1377 |  | 
| 1378 void Precompiler::AddFunction(const Function& function) { | 1344 void Precompiler::AddFunction(const Function& function) { | 
| 1379   if (enqueued_functions_.HasKey(&function)) return; | 1345   if (enqueued_functions_.HasKey(&function)) return; | 
| 1380 | 1346 | 
| 1381   enqueued_functions_.Insert(&Function::ZoneHandle(Z, function.raw())); | 1347   enqueued_functions_.Insert(&Function::ZoneHandle(Z, function.raw())); | 
| 1382   pending_functions_.Add(function); | 1348   pending_functions_.Add(function); | 
| 1383   changed_ = true; | 1349   changed_ = true; | 
| 1384 } | 1350 } | 
| 1385 | 1351 | 
| 1386 |  | 
| 1387 bool Precompiler::IsSent(const String& selector) { | 1352 bool Precompiler::IsSent(const String& selector) { | 
| 1388   if (selector.IsNull()) { | 1353   if (selector.IsNull()) { | 
| 1389     return false; | 1354     return false; | 
| 1390   } | 1355   } | 
| 1391   return sent_selectors_.HasKey(&selector); | 1356   return sent_selectors_.HasKey(&selector); | 
| 1392 } | 1357 } | 
| 1393 | 1358 | 
| 1394 |  | 
| 1395 void Precompiler::AddSelector(const String& selector) { | 1359 void Precompiler::AddSelector(const String& selector) { | 
| 1396   ASSERT(!selector.IsNull()); | 1360   ASSERT(!selector.IsNull()); | 
| 1397 | 1361 | 
| 1398   if (!IsSent(selector)) { | 1362   if (!IsSent(selector)) { | 
| 1399     sent_selectors_.Insert(&String::ZoneHandle(Z, selector.raw())); | 1363     sent_selectors_.Insert(&String::ZoneHandle(Z, selector.raw())); | 
| 1400     selector_count_++; | 1364     selector_count_++; | 
| 1401     changed_ = true; | 1365     changed_ = true; | 
| 1402 | 1366 | 
| 1403     if (FLAG_trace_precompiler) { | 1367     if (FLAG_trace_precompiler) { | 
| 1404       THR_Print("Enqueueing selector %" Pd " %s\n", selector_count_, | 1368       THR_Print("Enqueueing selector %" Pd " %s\n", selector_count_, | 
| 1405                 selector.ToCString()); | 1369                 selector.ToCString()); | 
| 1406     } | 1370     } | 
| 1407   } | 1371   } | 
| 1408 } | 1372 } | 
| 1409 | 1373 | 
| 1410 |  | 
| 1411 void Precompiler::AddInstantiatedClass(const Class& cls) { | 1374 void Precompiler::AddInstantiatedClass(const Class& cls) { | 
| 1412   if (cls.is_allocated()) return; | 1375   if (cls.is_allocated()) return; | 
| 1413 | 1376 | 
| 1414   class_count_++; | 1377   class_count_++; | 
| 1415   cls.set_is_allocated(true); | 1378   cls.set_is_allocated(true); | 
| 1416   error_ = cls.EnsureIsFinalized(T); | 1379   error_ = cls.EnsureIsFinalized(T); | 
| 1417   if (!error_.IsNull()) { | 1380   if (!error_.IsNull()) { | 
| 1418     Jump(error_); | 1381     Jump(error_); | 
| 1419   } | 1382   } | 
| 1420 | 1383 | 
| 1421   changed_ = true; | 1384   changed_ = true; | 
| 1422 | 1385 | 
| 1423   if (FLAG_trace_precompiler) { | 1386   if (FLAG_trace_precompiler) { | 
| 1424     THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); | 1387     THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); | 
| 1425   } | 1388   } | 
| 1426 | 1389 | 
| 1427   const Class& superclass = Class::Handle(cls.SuperClass()); | 1390   const Class& superclass = Class::Handle(cls.SuperClass()); | 
| 1428   if (!superclass.IsNull()) { | 1391   if (!superclass.IsNull()) { | 
| 1429     AddInstantiatedClass(superclass); | 1392     AddInstantiatedClass(superclass); | 
| 1430   } | 1393   } | 
| 1431 } | 1394 } | 
| 1432 | 1395 | 
| 1433 |  | 
| 1434 void Precompiler::CheckForNewDynamicFunctions() { | 1396 void Precompiler::CheckForNewDynamicFunctions() { | 
| 1435   Library& lib = Library::Handle(Z); | 1397   Library& lib = Library::Handle(Z); | 
| 1436   Class& cls = Class::Handle(Z); | 1398   Class& cls = Class::Handle(Z); | 
| 1437   Array& functions = Array::Handle(Z); | 1399   Array& functions = Array::Handle(Z); | 
| 1438   Function& function = Function::Handle(Z); | 1400   Function& function = Function::Handle(Z); | 
| 1439   Function& function2 = Function::Handle(Z); | 1401   Function& function2 = Function::Handle(Z); | 
| 1440   String& selector = String::Handle(Z); | 1402   String& selector = String::Handle(Z); | 
| 1441   String& selector2 = String::Handle(Z); | 1403   String& selector2 = String::Handle(Z); | 
| 1442   String& selector3 = String::Handle(Z); | 1404   String& selector3 = String::Handle(Z); | 
| 1443 | 1405 | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1525             // Add corresponding method extractor get:#foo | 1487             // Add corresponding method extractor get:#foo | 
| 1526             function2 = function.GetMethodExtractor(selector2); | 1488             function2 = function.GetMethodExtractor(selector2); | 
| 1527             AddFunction(function2); | 1489             AddFunction(function2); | 
| 1528           } | 1490           } | 
| 1529         } | 1491         } | 
| 1530       } | 1492       } | 
| 1531     } | 1493     } | 
| 1532   } | 1494   } | 
| 1533 } | 1495 } | 
| 1534 | 1496 | 
| 1535 |  | 
| 1536 class NameFunctionsTraits { | 1497 class NameFunctionsTraits { | 
| 1537  public: | 1498  public: | 
| 1538   static const char* Name() { return "NameFunctionsTraits"; } | 1499   static const char* Name() { return "NameFunctionsTraits"; } | 
| 1539   static bool ReportStats() { return false; } | 1500   static bool ReportStats() { return false; } | 
| 1540 | 1501 | 
| 1541   static bool IsMatch(const Object& a, const Object& b) { | 1502   static bool IsMatch(const Object& a, const Object& b) { | 
| 1542     return a.IsString() && b.IsString() && | 1503     return a.IsString() && b.IsString() && | 
| 1543            String::Cast(a).Equals(String::Cast(b)); | 1504            String::Cast(a).Equals(String::Cast(b)); | 
| 1544   } | 1505   } | 
| 1545   static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } | 1506   static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } | 
| 1546   static RawObject* NewKey(const String& str) { return str.raw(); } | 1507   static RawObject* NewKey(const String& str) { return str.raw(); } | 
| 1547 }; | 1508 }; | 
| 1548 | 1509 | 
| 1549 typedef UnorderedHashMap<NameFunctionsTraits> Table; | 1510 typedef UnorderedHashMap<NameFunctionsTraits> Table; | 
| 1550 | 1511 | 
| 1551 |  | 
| 1552 static void AddNameToFunctionsTable(Zone* zone, | 1512 static void AddNameToFunctionsTable(Zone* zone, | 
| 1553                                     Table* table, | 1513                                     Table* table, | 
| 1554                                     const String& fname, | 1514                                     const String& fname, | 
| 1555                                     const Function& function) { | 1515                                     const Function& function) { | 
| 1556   Array& farray = Array::Handle(zone); | 1516   Array& farray = Array::Handle(zone); | 
| 1557   farray ^= table->InsertNewOrGetValue(fname, Array::empty_array()); | 1517   farray ^= table->InsertNewOrGetValue(fname, Array::empty_array()); | 
| 1558   farray = Array::Grow(farray, farray.Length() + 1); | 1518   farray = Array::Grow(farray, farray.Length() + 1); | 
| 1559   farray.SetAt(farray.Length() - 1, function); | 1519   farray.SetAt(farray.Length() - 1, function); | 
| 1560   table->UpdateValue(fname, farray); | 1520   table->UpdateValue(fname, farray); | 
| 1561 } | 1521 } | 
| 1562 | 1522 | 
| 1563 |  | 
| 1564 void Precompiler::CollectDynamicFunctionNames() { | 1523 void Precompiler::CollectDynamicFunctionNames() { | 
| 1565   if (!FLAG_collect_dynamic_function_names) { | 1524   if (!FLAG_collect_dynamic_function_names) { | 
| 1566     return; | 1525     return; | 
| 1567   } | 1526   } | 
| 1568   Library& lib = Library::Handle(Z); | 1527   Library& lib = Library::Handle(Z); | 
| 1569   Class& cls = Class::Handle(Z); | 1528   Class& cls = Class::Handle(Z); | 
| 1570   Array& functions = Array::Handle(Z); | 1529   Array& functions = Array::Handle(Z); | 
| 1571   Function& function = Function::Handle(Z); | 1530   Function& function = Function::Handle(Z); | 
| 1572   String& fname = String::Handle(Z); | 1531   String& fname = String::Handle(Z); | 
| 1573   Array& farray = Array::Handle(Z); | 1532   Array& farray = Array::Handle(Z); | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1638     } | 1597     } | 
| 1639     THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n", | 1598     THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n", | 
| 1640               functions_set.NumOccupied(), table.NumOccupied()); | 1599               functions_set.NumOccupied(), table.NumOccupied()); | 
| 1641   } | 1600   } | 
| 1642 | 1601 | 
| 1643   isolate()->object_store()->set_unique_dynamic_targets( | 1602   isolate()->object_store()->set_unique_dynamic_targets( | 
| 1644       functions_set.Release()); | 1603       functions_set.Release()); | 
| 1645   table.Release(); | 1604   table.Release(); | 
| 1646 } | 1605 } | 
| 1647 | 1606 | 
| 1648 |  | 
| 1649 void Precompiler::TraceConstFunctions() { | 1607 void Precompiler::TraceConstFunctions() { | 
| 1650   // Compilation of const accessors happens outside of the treeshakers | 1608   // Compilation of const accessors happens outside of the treeshakers | 
| 1651   // queue, so we haven't previously scanned its literal pool. | 1609   // queue, so we haven't previously scanned its literal pool. | 
| 1652 | 1610 | 
| 1653   Library& lib = Library::Handle(Z); | 1611   Library& lib = Library::Handle(Z); | 
| 1654   Class& cls = Class::Handle(Z); | 1612   Class& cls = Class::Handle(Z); | 
| 1655   Array& functions = Array::Handle(Z); | 1613   Array& functions = Array::Handle(Z); | 
| 1656   Function& function = Function::Handle(Z); | 1614   Function& function = Function::Handle(Z); | 
| 1657 | 1615 | 
| 1658   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1616   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1659     lib ^= libraries_.At(i); | 1617     lib ^= libraries_.At(i); | 
| 1660     ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 1618     ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 
| 1661     while (it.HasNext()) { | 1619     while (it.HasNext()) { | 
| 1662       cls = it.GetNextClass(); | 1620       cls = it.GetNextClass(); | 
| 1663       if (cls.IsDynamicClass()) { | 1621       if (cls.IsDynamicClass()) { | 
| 1664         continue;  // class 'dynamic' is in the read-only VM isolate. | 1622         continue;  // class 'dynamic' is in the read-only VM isolate. | 
| 1665       } | 1623       } | 
| 1666 | 1624 | 
| 1667       functions = cls.functions(); | 1625       functions = cls.functions(); | 
| 1668       for (intptr_t j = 0; j < functions.Length(); j++) { | 1626       for (intptr_t j = 0; j < functions.Length(); j++) { | 
| 1669         function ^= functions.At(j); | 1627         function ^= functions.At(j); | 
| 1670         if (function.is_const() && function.HasCode()) { | 1628         if (function.is_const() && function.HasCode()) { | 
| 1671           AddCalleesOf(function); | 1629           AddCalleesOf(function); | 
| 1672         } | 1630         } | 
| 1673       } | 1631       } | 
| 1674     } | 1632     } | 
| 1675   } | 1633   } | 
| 1676 } | 1634 } | 
| 1677 | 1635 | 
| 1678 |  | 
| 1679 void Precompiler::TraceForRetainedFunctions() { | 1636 void Precompiler::TraceForRetainedFunctions() { | 
| 1680   Library& lib = Library::Handle(Z); | 1637   Library& lib = Library::Handle(Z); | 
| 1681   Class& cls = Class::Handle(Z); | 1638   Class& cls = Class::Handle(Z); | 
| 1682   Array& functions = Array::Handle(Z); | 1639   Array& functions = Array::Handle(Z); | 
| 1683   Function& function = Function::Handle(Z); | 1640   Function& function = Function::Handle(Z); | 
| 1684   Function& function2 = Function::Handle(Z); | 1641   Function& function2 = Function::Handle(Z); | 
| 1685   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 1642   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 
| 1686 | 1643 | 
| 1687   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1644   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1688     lib ^= libraries_.At(i); | 1645     lib ^= libraries_.At(i); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1728       // parents and their enclosing classes and libraries. | 1685       // parents and their enclosing classes and libraries. | 
| 1729       function = function.parent_function(); | 1686       function = function.parent_function(); | 
| 1730       while (!function.IsNull()) { | 1687       while (!function.IsNull()) { | 
| 1731         AddTypesOf(function); | 1688         AddTypesOf(function); | 
| 1732         function = function.parent_function(); | 1689         function = function.parent_function(); | 
| 1733       } | 1690       } | 
| 1734     } | 1691     } | 
| 1735   } | 1692   } | 
| 1736 } | 1693 } | 
| 1737 | 1694 | 
| 1738 |  | 
| 1739 void Precompiler::DropFunctions() { | 1695 void Precompiler::DropFunctions() { | 
| 1740   Library& lib = Library::Handle(Z); | 1696   Library& lib = Library::Handle(Z); | 
| 1741   Class& cls = Class::Handle(Z); | 1697   Class& cls = Class::Handle(Z); | 
| 1742   Array& functions = Array::Handle(Z); | 1698   Array& functions = Array::Handle(Z); | 
| 1743   Function& function = Function::Handle(Z); | 1699   Function& function = Function::Handle(Z); | 
| 1744   GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | 1700   GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | 
| 1745   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 1701   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 
| 1746 | 1702 | 
| 1747   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1703   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1748     lib ^= libraries_.At(i); | 1704     lib ^= libraries_.At(i); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1790       dropped_function_count_++; | 1746       dropped_function_count_++; | 
| 1791       if (FLAG_trace_precompiler) { | 1747       if (FLAG_trace_precompiler) { | 
| 1792         THR_Print("Dropping function %s\n", | 1748         THR_Print("Dropping function %s\n", | 
| 1793                   function.ToLibNamePrefixedQualifiedCString()); | 1749                   function.ToLibNamePrefixedQualifiedCString()); | 
| 1794       } | 1750       } | 
| 1795     } | 1751     } | 
| 1796   } | 1752   } | 
| 1797   isolate()->object_store()->set_closure_functions(retained_functions); | 1753   isolate()->object_store()->set_closure_functions(retained_functions); | 
| 1798 } | 1754 } | 
| 1799 | 1755 | 
| 1800 |  | 
| 1801 void Precompiler::DropFields() { | 1756 void Precompiler::DropFields() { | 
| 1802   Library& lib = Library::Handle(Z); | 1757   Library& lib = Library::Handle(Z); | 
| 1803   Class& cls = Class::Handle(Z); | 1758   Class& cls = Class::Handle(Z); | 
| 1804   Array& fields = Array::Handle(Z); | 1759   Array& fields = Array::Handle(Z); | 
| 1805   Field& field = Field::Handle(Z); | 1760   Field& field = Field::Handle(Z); | 
| 1806   GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z); | 1761   GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z); | 
| 1807   AbstractType& type = AbstractType::Handle(Z); | 1762   AbstractType& type = AbstractType::Handle(Z); | 
| 1808 | 1763 | 
| 1809   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1764   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1810     lib ^= libraries_.At(i); | 1765     lib ^= libraries_.At(i); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 1835       if (retained_fields.Length() > 0) { | 1790       if (retained_fields.Length() > 0) { | 
| 1836         fields = Array::MakeFixedLength(retained_fields); | 1791         fields = Array::MakeFixedLength(retained_fields); | 
| 1837         cls.SetFields(fields); | 1792         cls.SetFields(fields); | 
| 1838       } else { | 1793       } else { | 
| 1839         cls.SetFields(Object::empty_array()); | 1794         cls.SetFields(Object::empty_array()); | 
| 1840       } | 1795       } | 
| 1841     } | 1796     } | 
| 1842   } | 1797   } | 
| 1843 } | 1798 } | 
| 1844 | 1799 | 
| 1845 |  | 
| 1846 void Precompiler::DropTypes() { | 1800 void Precompiler::DropTypes() { | 
| 1847   ObjectStore* object_store = I->object_store(); | 1801   ObjectStore* object_store = I->object_store(); | 
| 1848   GrowableObjectArray& retained_types = | 1802   GrowableObjectArray& retained_types = | 
| 1849       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 1803       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 
| 1850   Array& types_array = Array::Handle(Z); | 1804   Array& types_array = Array::Handle(Z); | 
| 1851   Type& type = Type::Handle(Z); | 1805   Type& type = Type::Handle(Z); | 
| 1852   // First drop all the types that are not referenced. | 1806   // First drop all the types that are not referenced. | 
| 1853   { | 1807   { | 
| 1854     CanonicalTypeSet types_table(Z, object_store->canonical_types()); | 1808     CanonicalTypeSet types_table(Z, object_store->canonical_types()); | 
| 1855     types_array = HashTables::ToArray(types_table, false); | 1809     types_array = HashTables::ToArray(types_table, false); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1872   CanonicalTypeSet types_table(Z, types_array.raw()); | 1826   CanonicalTypeSet types_table(Z, types_array.raw()); | 
| 1873   bool present; | 1827   bool present; | 
| 1874   for (intptr_t i = 0; i < retained_types.Length(); i++) { | 1828   for (intptr_t i = 0; i < retained_types.Length(); i++) { | 
| 1875     type ^= retained_types.At(i); | 1829     type ^= retained_types.At(i); | 
| 1876     present = types_table.Insert(type); | 1830     present = types_table.Insert(type); | 
| 1877     ASSERT(!present); | 1831     ASSERT(!present); | 
| 1878   } | 1832   } | 
| 1879   object_store->set_canonical_types(types_table.Release()); | 1833   object_store->set_canonical_types(types_table.Release()); | 
| 1880 } | 1834 } | 
| 1881 | 1835 | 
| 1882 |  | 
| 1883 void Precompiler::DropTypeArguments() { | 1836 void Precompiler::DropTypeArguments() { | 
| 1884   ObjectStore* object_store = I->object_store(); | 1837   ObjectStore* object_store = I->object_store(); | 
| 1885   Array& typeargs_array = Array::Handle(Z); | 1838   Array& typeargs_array = Array::Handle(Z); | 
| 1886   GrowableObjectArray& retained_typeargs = | 1839   GrowableObjectArray& retained_typeargs = | 
| 1887       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 1840       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 
| 1888   TypeArguments& typeargs = TypeArguments::Handle(Z); | 1841   TypeArguments& typeargs = TypeArguments::Handle(Z); | 
| 1889   // First drop all the type arguments that are not referenced. | 1842   // First drop all the type arguments that are not referenced. | 
| 1890   { | 1843   { | 
| 1891     CanonicalTypeArgumentsSet typeargs_table( | 1844     CanonicalTypeArgumentsSet typeargs_table( | 
| 1892         Z, object_store->canonical_type_arguments()); | 1845         Z, object_store->canonical_type_arguments()); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 1911   CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); | 1864   CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); | 
| 1912   bool present; | 1865   bool present; | 
| 1913   for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { | 1866   for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { | 
| 1914     typeargs ^= retained_typeargs.At(i); | 1867     typeargs ^= retained_typeargs.At(i); | 
| 1915     present = typeargs_table.Insert(typeargs); | 1868     present = typeargs_table.Insert(typeargs); | 
| 1916     ASSERT(!present); | 1869     ASSERT(!present); | 
| 1917   } | 1870   } | 
| 1918   object_store->set_canonical_type_arguments(typeargs_table.Release()); | 1871   object_store->set_canonical_type_arguments(typeargs_table.Release()); | 
| 1919 } | 1872 } | 
| 1920 | 1873 | 
| 1921 |  | 
| 1922 void Precompiler::DropScriptData() { | 1874 void Precompiler::DropScriptData() { | 
| 1923   Library& lib = Library::Handle(Z); | 1875   Library& lib = Library::Handle(Z); | 
| 1924   Array& scripts = Array::Handle(Z); | 1876   Array& scripts = Array::Handle(Z); | 
| 1925   Script& script = Script::Handle(Z); | 1877   Script& script = Script::Handle(Z); | 
| 1926   const TokenStream& null_tokens = TokenStream::Handle(Z); | 1878   const TokenStream& null_tokens = TokenStream::Handle(Z); | 
| 1927   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1879   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1928     lib ^= libraries_.At(i); | 1880     lib ^= libraries_.At(i); | 
| 1929     scripts = lib.LoadedScripts(); | 1881     scripts = lib.LoadedScripts(); | 
| 1930     for (intptr_t j = 0; j < scripts.Length(); j++) { | 1882     for (intptr_t j = 0; j < scripts.Length(); j++) { | 
| 1931       script ^= scripts.At(j); | 1883       script ^= scripts.At(j); | 
| 1932       script.set_compile_time_constants(Array::null_array()); | 1884       script.set_compile_time_constants(Array::null_array()); | 
| 1933       script.set_source(String::null_string()); | 1885       script.set_source(String::null_string()); | 
| 1934       script.set_tokens(null_tokens); | 1886       script.set_tokens(null_tokens); | 
| 1935     } | 1887     } | 
| 1936   } | 1888   } | 
| 1937 } | 1889 } | 
| 1938 | 1890 | 
| 1939 |  | 
| 1940 void Precompiler::TraceTypesFromRetainedClasses() { | 1891 void Precompiler::TraceTypesFromRetainedClasses() { | 
| 1941   Library& lib = Library::Handle(Z); | 1892   Library& lib = Library::Handle(Z); | 
| 1942   Class& cls = Class::Handle(Z); | 1893   Class& cls = Class::Handle(Z); | 
| 1943   Array& members = Array::Handle(Z); | 1894   Array& members = Array::Handle(Z); | 
| 1944   Array& constants = Array::Handle(Z); | 1895   Array& constants = Array::Handle(Z); | 
| 1945   GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); | 1896   GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); | 
| 1946   Instance& constant = Instance::Handle(Z); | 1897   Instance& constant = Instance::Handle(Z); | 
| 1947 | 1898 | 
| 1948   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1899   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 1949     lib ^= libraries_.At(i); | 1900     lib ^= libraries_.At(i); | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2003         retain = true; | 1954         retain = true; | 
| 2004       } | 1955       } | 
| 2005 | 1956 | 
| 2006       if (retain) { | 1957       if (retain) { | 
| 2007         AddTypesOf(cls); | 1958         AddTypesOf(cls); | 
| 2008       } | 1959       } | 
| 2009     } | 1960     } | 
| 2010   } | 1961   } | 
| 2011 } | 1962 } | 
| 2012 | 1963 | 
| 2013 |  | 
| 2014 void Precompiler::DropLibraryEntries() { | 1964 void Precompiler::DropLibraryEntries() { | 
| 2015   Library& lib = Library::Handle(Z); | 1965   Library& lib = Library::Handle(Z); | 
| 2016   Array& dict = Array::Handle(Z); | 1966   Array& dict = Array::Handle(Z); | 
| 2017   Object& entry = Object::Handle(Z); | 1967   Object& entry = Object::Handle(Z); | 
| 2018 | 1968 | 
| 2019   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1969   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 2020     lib ^= libraries_.At(i); | 1970     lib ^= libraries_.At(i); | 
| 2021 | 1971 | 
| 2022     dict = lib.dictionary(); | 1972     dict = lib.dictionary(); | 
| 2023     intptr_t dict_size = dict.Length() - 1; | 1973     intptr_t dict_size = dict.Length() - 1; | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 2049       dict.SetAt(j, Object::null_object()); | 1999       dict.SetAt(j, Object::null_object()); | 
| 2050     } | 2000     } | 
| 2051     lib.RehashDictionary(dict, used * 4 / 3 + 1); | 2001     lib.RehashDictionary(dict, used * 4 / 3 + 1); | 
| 2052     if (!(retain_root_library_caches_ && | 2002     if (!(retain_root_library_caches_ && | 
| 2053           (lib.raw() == I->object_store()->root_library()))) { | 2003           (lib.raw() == I->object_store()->root_library()))) { | 
| 2054       lib.DropDependenciesAndCaches(); | 2004       lib.DropDependenciesAndCaches(); | 
| 2055     } | 2005     } | 
| 2056   } | 2006   } | 
| 2057 } | 2007 } | 
| 2058 | 2008 | 
| 2059 |  | 
| 2060 void Precompiler::DropClasses() { | 2009 void Precompiler::DropClasses() { | 
| 2061   Class& cls = Class::Handle(Z); | 2010   Class& cls = Class::Handle(Z); | 
| 2062   Array& constants = Array::Handle(Z); | 2011   Array& constants = Array::Handle(Z); | 
| 2063 | 2012 | 
| 2064 #if defined(DEBUG) | 2013 #if defined(DEBUG) | 
| 2065   // We are about to remove classes from the class table. For this to be safe, | 2014   // We are about to remove classes from the class table. For this to be safe, | 
| 2066   // there must be no instances of these classes on the heap, not even | 2015   // there must be no instances of these classes on the heap, not even | 
| 2067   // corpses because the class table entry may be used to find the size of | 2016   // corpses because the class table entry may be used to find the size of | 
| 2068   // corpses. Request a full GC and wait for the sweeper tasks to finish before | 2017   // corpses. Request a full GC and wait for the sweeper tasks to finish before | 
| 2069   // we continue. | 2018   // we continue. | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2112       THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString()); | 2061       THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString()); | 
| 2113     } | 2062     } | 
| 2114 | 2063 | 
| 2115 #if defined(DEBUG) | 2064 #if defined(DEBUG) | 
| 2116     class_table->Unregister(cid); | 2065     class_table->Unregister(cid); | 
| 2117 #endif | 2066 #endif | 
| 2118     cls.set_id(kIllegalCid);  // We check this when serializing. | 2067     cls.set_id(kIllegalCid);  // We check this when serializing. | 
| 2119   } | 2068   } | 
| 2120 } | 2069 } | 
| 2121 | 2070 | 
| 2122 |  | 
| 2123 void Precompiler::DropLibraries() { | 2071 void Precompiler::DropLibraries() { | 
| 2124   const GrowableObjectArray& retained_libraries = | 2072   const GrowableObjectArray& retained_libraries = | 
| 2125       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 2073       GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 
| 2126   const Library& root_lib = | 2074   const Library& root_lib = | 
| 2127       Library::Handle(Z, I->object_store()->root_library()); | 2075       Library::Handle(Z, I->object_store()->root_library()); | 
| 2128   Library& lib = Library::Handle(Z); | 2076   Library& lib = Library::Handle(Z); | 
| 2129   Class& toplevel_class = Class::Handle(Z); | 2077   Class& toplevel_class = Class::Handle(Z); | 
| 2130 | 2078 | 
| 2131   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2079   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 2132     lib ^= libraries_.At(i); | 2080     lib ^= libraries_.At(i); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2171       if (FLAG_trace_precompiler) { | 2119       if (FLAG_trace_precompiler) { | 
| 2172         THR_Print("Dropping library %s\n", lib.ToCString()); | 2120         THR_Print("Dropping library %s\n", lib.ToCString()); | 
| 2173       } | 2121       } | 
| 2174     } | 2122     } | 
| 2175   } | 2123   } | 
| 2176 | 2124 | 
| 2177   Library::RegisterLibraries(T, retained_libraries); | 2125   Library::RegisterLibraries(T, retained_libraries); | 
| 2178   libraries_ = retained_libraries.raw(); | 2126   libraries_ = retained_libraries.raw(); | 
| 2179 } | 2127 } | 
| 2180 | 2128 | 
| 2181 |  | 
| 2182 void Precompiler::BindStaticCalls() { | 2129 void Precompiler::BindStaticCalls() { | 
| 2183   class BindStaticCallsVisitor : public FunctionVisitor { | 2130   class BindStaticCallsVisitor : public FunctionVisitor { | 
| 2184    public: | 2131    public: | 
| 2185     explicit BindStaticCallsVisitor(Zone* zone) | 2132     explicit BindStaticCallsVisitor(Zone* zone) | 
| 2186         : code_(Code::Handle(zone)), | 2133         : code_(Code::Handle(zone)), | 
| 2187           table_(Array::Handle(zone)), | 2134           table_(Array::Handle(zone)), | 
| 2188           pc_offset_(Smi::Handle(zone)), | 2135           pc_offset_(Smi::Handle(zone)), | 
| 2189           target_(Function::Handle(zone)), | 2136           target_(Function::Handle(zone)), | 
| 2190           target_code_(Code::Handle(zone)) {} | 2137           target_code_(Code::Handle(zone)) {} | 
| 2191 | 2138 | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2228     Array& table_; | 2175     Array& table_; | 
| 2229     Smi& pc_offset_; | 2176     Smi& pc_offset_; | 
| 2230     Function& target_; | 2177     Function& target_; | 
| 2231     Code& target_code_; | 2178     Code& target_code_; | 
| 2232   }; | 2179   }; | 
| 2233 | 2180 | 
| 2234   BindStaticCallsVisitor visitor(Z); | 2181   BindStaticCallsVisitor visitor(Z); | 
| 2235   ProgramVisitor::VisitFunctions(&visitor); | 2182   ProgramVisitor::VisitFunctions(&visitor); | 
| 2236 } | 2183 } | 
| 2237 | 2184 | 
| 2238 |  | 
| 2239 void Precompiler::SwitchICCalls() { | 2185 void Precompiler::SwitchICCalls() { | 
| 2240 #if !defined(TARGET_ARCH_DBC) | 2186 #if !defined(TARGET_ARCH_DBC) | 
| 2241   // Now that all functions have been compiled, we can switch to an instance | 2187   // Now that all functions have been compiled, we can switch to an instance | 
| 2242   // call sequence that loads the Code object and entry point directly from | 2188   // call sequence that loads the Code object and entry point directly from | 
| 2243   // the ic data array instead indirectly through a Function in the ic data | 2189   // the ic data array instead indirectly through a Function in the ic data | 
| 2244   // array. Iterate all the object pools and rewrite the ic data from | 2190   // array. Iterate all the object pools and rewrite the ic data from | 
| 2245   // (cid, target function, count) to (cid, target code, entry point), and | 2191   // (cid, target function, count) to (cid, target code, entry point), and | 
| 2246   // replace the ICCallThroughFunction stub with ICCallThroughCode. | 2192   // replace the ICCallThroughFunction stub with ICCallThroughCode. | 
| 2247 | 2193 | 
| 2248   class SwitchICCallsVisitor : public FunctionVisitor { | 2194   class SwitchICCallsVisitor : public FunctionVisitor { | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2318     Code& target_code_; | 2264     Code& target_code_; | 
| 2319     UnlinkedCallSet canonical_unlinked_calls_; | 2265     UnlinkedCallSet canonical_unlinked_calls_; | 
| 2320   }; | 2266   }; | 
| 2321 | 2267 | 
| 2322   ASSERT(!I->compilation_allowed()); | 2268   ASSERT(!I->compilation_allowed()); | 
| 2323   SwitchICCallsVisitor visitor(Z); | 2269   SwitchICCallsVisitor visitor(Z); | 
| 2324   ProgramVisitor::VisitFunctions(&visitor); | 2270   ProgramVisitor::VisitFunctions(&visitor); | 
| 2325 #endif | 2271 #endif | 
| 2326 } | 2272 } | 
| 2327 | 2273 | 
| 2328 |  | 
| 2329 void Precompiler::FinalizeAllClasses() { | 2274 void Precompiler::FinalizeAllClasses() { | 
| 2330   Library& lib = Library::Handle(Z); | 2275   Library& lib = Library::Handle(Z); | 
| 2331   Class& cls = Class::Handle(Z); | 2276   Class& cls = Class::Handle(Z); | 
| 2332 | 2277 | 
| 2333   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2278   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 2334     lib ^= libraries_.At(i); | 2279     lib ^= libraries_.At(i); | 
| 2335     if (!lib.Loaded()) { | 2280     if (!lib.Loaded()) { | 
| 2336       String& uri = String::Handle(Z, lib.url()); | 2281       String& uri = String::Handle(Z, lib.url()); | 
| 2337       String& msg = String::Handle( | 2282       String& msg = String::Handle( | 
| 2338           Z, | 2283           Z, | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2350       } | 2295       } | 
| 2351       error_ = cls.EnsureIsFinalized(T); | 2296       error_ = cls.EnsureIsFinalized(T); | 
| 2352       if (!error_.IsNull()) { | 2297       if (!error_.IsNull()) { | 
| 2353         Jump(error_); | 2298         Jump(error_); | 
| 2354       } | 2299       } | 
| 2355     } | 2300     } | 
| 2356   } | 2301   } | 
| 2357   I->set_all_classes_finalized(true); | 2302   I->set_all_classes_finalized(true); | 
| 2358 } | 2303 } | 
| 2359 | 2304 | 
| 2360 |  | 
| 2361 |  | 
| 2362 void Precompiler::VerifyJITFeedback() { | 2305 void Precompiler::VerifyJITFeedback() { | 
| 2363   if (jit_feedback_ == NULL) return; | 2306   if (jit_feedback_ == NULL) return; | 
| 2364 | 2307 | 
| 2365   ParsedJSONString* js_vmversion = jit_feedback_->StringAt("vmVersion"); | 2308   ParsedJSONString* js_vmversion = jit_feedback_->StringAt("vmVersion"); | 
| 2366   if ((js_vmversion == NULL) || | 2309   if ((js_vmversion == NULL) || | 
| 2367       strcmp(js_vmversion->value(), Version::CommitString()) != 0) { | 2310       strcmp(js_vmversion->value(), Version::CommitString()) != 0) { | 
| 2368     THR_Print( | 2311     THR_Print( | 
| 2369         "JIT feedback contains invalid vm version " | 2312         "JIT feedback contains invalid vm version " | 
| 2370         "(saw %s, expected %s).\n", | 2313         "(saw %s, expected %s).\n", | 
| 2371         js_vmversion->value(), Version::CommitString()); | 2314         js_vmversion->value(), Version::CommitString()); | 
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2482     } | 2425     } | 
| 2483 | 2426 | 
| 2484    private: | 2427    private: | 
| 2485     Precompiler* precompiler_; | 2428     Precompiler* precompiler_; | 
| 2486   }; | 2429   }; | 
| 2487 | 2430 | 
| 2488   ApplyUsageVisitor visitor(this); | 2431   ApplyUsageVisitor visitor(this); | 
| 2489   ProgramVisitor::VisitFunctions(&visitor); | 2432   ProgramVisitor::VisitFunctions(&visitor); | 
| 2490 } | 2433 } | 
| 2491 | 2434 | 
| 2492 |  | 
| 2493 ParsedJSONObject* Precompiler::LookupFeedback(const Function& function) { | 2435 ParsedJSONObject* Precompiler::LookupFeedback(const Function& function) { | 
| 2494   const Class& owner = Class::Handle(Z, function.Owner()); | 2436   const Class& owner = Class::Handle(Z, function.Owner()); | 
| 2495 | 2437 | 
| 2496   FunctionFeedbackKey key(owner.id(), function.token_pos().value(), | 2438   FunctionFeedbackKey key(owner.id(), function.token_pos().value(), | 
| 2497                           function.kind()); | 2439                           function.kind()); | 
| 2498   FunctionFeedbackPair* pair = function_feedback_map_.Lookup(key); | 2440   FunctionFeedbackPair* pair = function_feedback_map_.Lookup(key); | 
| 2499   if (pair == NULL) { | 2441   if (pair == NULL) { | 
| 2500     return NULL; | 2442     return NULL; | 
| 2501   } | 2443   } | 
| 2502   return pair->value_; | 2444   return pair->value_; | 
| 2503 } | 2445 } | 
| 2504 | 2446 | 
| 2505 |  | 
| 2506 RawScript* Precompiler::LookupScript(const char* uri) { | 2447 RawScript* Precompiler::LookupScript(const char* uri) { | 
| 2507   String& dart_uri = String::Handle(Z, String::New(uri)); | 2448   String& dart_uri = String::Handle(Z, String::New(uri)); | 
| 2508   Library& lib = Library::Handle(Z); | 2449   Library& lib = Library::Handle(Z); | 
| 2509   Script& script = Script::Handle(Z); | 2450   Script& script = Script::Handle(Z); | 
| 2510   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2451   for (intptr_t i = 0; i < libraries_.Length(); i++) { | 
| 2511     lib ^= libraries_.At(i); | 2452     lib ^= libraries_.At(i); | 
| 2512     script = lib.LookupScript(dart_uri); | 2453     script = lib.LookupScript(dart_uri); | 
| 2513     if (!script.IsNull()) { | 2454     if (!script.IsNull()) { | 
| 2514       return script.raw(); | 2455       return script.raw(); | 
| 2515     } | 2456     } | 
| 2516   } | 2457   } | 
| 2517   return Script::null(); | 2458   return Script::null(); | 
| 2518 } | 2459 } | 
| 2519 | 2460 | 
| 2520 |  | 
| 2521 intptr_t Precompiler::MapCid(intptr_t feedback_cid) { | 2461 intptr_t Precompiler::MapCid(intptr_t feedback_cid) { | 
| 2522   if (feedback_cid < kNumPredefinedCids) { | 2462   if (feedback_cid < kNumPredefinedCids) { | 
| 2523     return feedback_cid; | 2463     return feedback_cid; | 
| 2524   } | 2464   } | 
| 2525   IntptrPair* pair = feedback_cid_map_.Lookup(feedback_cid); | 2465   IntptrPair* pair = feedback_cid_map_.Lookup(feedback_cid); | 
| 2526   if (pair == NULL) return kIllegalCid; | 2466   if (pair == NULL) return kIllegalCid; | 
| 2527   return pair->value_; | 2467   return pair->value_; | 
| 2528 } | 2468 } | 
| 2529 | 2469 | 
| 2530 |  | 
| 2531 void Precompiler::PopulateWithICData(const Function& function, | 2470 void Precompiler::PopulateWithICData(const Function& function, | 
| 2532                                      FlowGraph* graph) { | 2471                                      FlowGraph* graph) { | 
| 2533   Zone* zone = Thread::Current()->zone(); | 2472   Zone* zone = Thread::Current()->zone(); | 
| 2534 | 2473 | 
| 2535   for (BlockIterator block_it = graph->reverse_postorder_iterator(); | 2474   for (BlockIterator block_it = graph->reverse_postorder_iterator(); | 
| 2536        !block_it.Done(); block_it.Advance()) { | 2475        !block_it.Done(); block_it.Advance()) { | 
| 2537     ForwardInstructionIterator it(block_it.Current()); | 2476     ForwardInstructionIterator it(block_it.Current()); | 
| 2538     for (; !it.Done(); it.Advance()) { | 2477     for (; !it.Done(); it.Advance()) { | 
| 2539       Instruction* instr = it.Current(); | 2478       Instruction* instr = it.Current(); | 
| 2540       if (instr->IsInstanceCall()) { | 2479       if (instr->IsInstanceCall()) { | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 2571                                 arguments_descriptor, call->deopt_id(), | 2510                                 arguments_descriptor, call->deopt_id(), | 
| 2572                                 num_args_checked, true)); | 2511                                 num_args_checked, true)); | 
| 2573           ic_data.AddTarget(target); | 2512           ic_data.AddTarget(target); | 
| 2574           call->set_ic_data(&ic_data); | 2513           call->set_ic_data(&ic_data); | 
| 2575         } | 2514         } | 
| 2576       } | 2515       } | 
| 2577     } | 2516     } | 
| 2578   } | 2517   } | 
| 2579 } | 2518 } | 
| 2580 | 2519 | 
| 2581 |  | 
| 2582 void Precompiler::TryApplyFeedback(const Function& function, FlowGraph* graph) { | 2520 void Precompiler::TryApplyFeedback(const Function& function, FlowGraph* graph) { | 
| 2583   ParsedJSONObject* js_function = LookupFeedback(function); | 2521   ParsedJSONObject* js_function = LookupFeedback(function); | 
| 2584   if (js_function == NULL) { | 2522   if (js_function == NULL) { | 
| 2585     if (FLAG_trace_precompiler) { | 2523     if (FLAG_trace_precompiler) { | 
| 2586       THR_Print("No feedback available for %s\n", | 2524       THR_Print("No feedback available for %s\n", | 
| 2587                 function.ToQualifiedCString()); | 2525                 function.ToQualifiedCString()); | 
| 2588     } | 2526     } | 
| 2589     return; | 2527     return; | 
| 2590   } | 2528   } | 
| 2591 | 2529 | 
| 2592   ParsedJSONArray* js_icdatas = js_function->ArrayAt("ics"); | 2530   ParsedJSONArray* js_icdatas = js_function->ArrayAt("ics"); | 
| 2593   ASSERT(js_icdatas != NULL); | 2531   ASSERT(js_icdatas != NULL); | 
| 2594 | 2532 | 
| 2595   for (BlockIterator block_it = graph->reverse_postorder_iterator(); | 2533   for (BlockIterator block_it = graph->reverse_postorder_iterator(); | 
| 2596        !block_it.Done(); block_it.Advance()) { | 2534        !block_it.Done(); block_it.Advance()) { | 
| 2597     ForwardInstructionIterator it(block_it.Current()); | 2535     ForwardInstructionIterator it(block_it.Current()); | 
| 2598     for (; !it.Done(); it.Advance()) { | 2536     for (; !it.Done(); it.Advance()) { | 
| 2599       Instruction* instr = it.Current(); | 2537       Instruction* instr = it.Current(); | 
| 2600       if (instr->IsInstanceCall()) { | 2538       if (instr->IsInstanceCall()) { | 
| 2601         InstanceCallInstr* call = instr->AsInstanceCall(); | 2539         InstanceCallInstr* call = instr->AsInstanceCall(); | 
| 2602         TryApplyFeedback(js_icdatas, *call->ic_data()); | 2540         TryApplyFeedback(js_icdatas, *call->ic_data()); | 
| 2603       } else if (instr->IsStaticCall()) { | 2541       } else if (instr->IsStaticCall()) { | 
| 2604         StaticCallInstr* call = instr->AsStaticCall(); | 2542         StaticCallInstr* call = instr->AsStaticCall(); | 
| 2605         TryApplyFeedback(js_icdatas, *call->ic_data()); | 2543         TryApplyFeedback(js_icdatas, *call->ic_data()); | 
| 2606       } | 2544       } | 
| 2607     } | 2545     } | 
| 2608   } | 2546   } | 
| 2609 } | 2547 } | 
| 2610 | 2548 | 
| 2611 |  | 
| 2612 void Precompiler::TryApplyFeedback(ParsedJSONArray* js_icdatas, | 2549 void Precompiler::TryApplyFeedback(ParsedJSONArray* js_icdatas, | 
| 2613                                    const ICData& ic) { | 2550                                    const ICData& ic) { | 
| 2614   for (intptr_t j = 0; j < js_icdatas->Length(); j++) { | 2551   for (intptr_t j = 0; j < js_icdatas->Length(); j++) { | 
| 2615     ParsedJSONObject* js_icdata = js_icdatas->ObjectAt(j); | 2552     ParsedJSONObject* js_icdata = js_icdatas->ObjectAt(j); | 
| 2616     ASSERT(js_icdata != NULL); | 2553     ASSERT(js_icdata != NULL); | 
| 2617 | 2554 | 
| 2618     ParsedJSONNumber* js_deoptid = js_icdata->NumberAt("deoptId"); | 2555     ParsedJSONNumber* js_deoptid = js_icdata->NumberAt("deoptId"); | 
| 2619     ASSERT(js_deoptid != NULL); | 2556     ASSERT(js_deoptid != NULL); | 
| 2620     if (js_deoptid->value() != ic.deopt_id()) continue; | 2557     if (js_deoptid->value() != ic.deopt_id()) continue; | 
| 2621 | 2558 | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2685             } | 2622             } | 
| 2686           } | 2623           } | 
| 2687         } | 2624         } | 
| 2688       } | 2625       } | 
| 2689     } | 2626     } | 
| 2690 | 2627 | 
| 2691     return; | 2628     return; | 
| 2692   } | 2629   } | 
| 2693 } | 2630 } | 
| 2694 | 2631 | 
| 2695 |  | 
| 2696 void Precompiler::ResetPrecompilerState() { | 2632 void Precompiler::ResetPrecompilerState() { | 
| 2697   changed_ = false; | 2633   changed_ = false; | 
| 2698   function_count_ = 0; | 2634   function_count_ = 0; | 
| 2699   class_count_ = 0; | 2635   class_count_ = 0; | 
| 2700   selector_count_ = 0; | 2636   selector_count_ = 0; | 
| 2701   dropped_function_count_ = 0; | 2637   dropped_function_count_ = 0; | 
| 2702   dropped_field_count_ = 0; | 2638   dropped_field_count_ = 0; | 
| 2703   ASSERT(pending_functions_.Length() == 0); | 2639   ASSERT(pending_functions_.Length() == 0); | 
| 2704   sent_selectors_.Clear(); | 2640   sent_selectors_.Clear(); | 
| 2705   enqueued_functions_.Clear(); | 2641   enqueued_functions_.Clear(); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 2720     while (it.HasNext()) { | 2656     while (it.HasNext()) { | 
| 2721       cls = it.GetNextClass(); | 2657       cls = it.GetNextClass(); | 
| 2722       if (cls.IsDynamicClass()) { | 2658       if (cls.IsDynamicClass()) { | 
| 2723         continue;  // class 'dynamic' is in the read-only VM isolate. | 2659         continue;  // class 'dynamic' is in the read-only VM isolate. | 
| 2724       } | 2660       } | 
| 2725       cls.set_is_allocated(false); | 2661       cls.set_is_allocated(false); | 
| 2726     } | 2662     } | 
| 2727   } | 2663   } | 
| 2728 } | 2664 } | 
| 2729 | 2665 | 
| 2730 |  | 
| 2731 void PrecompileParsedFunctionHelper::FinalizeCompilation( | 2666 void PrecompileParsedFunctionHelper::FinalizeCompilation( | 
| 2732     Assembler* assembler, | 2667     Assembler* assembler, | 
| 2733     FlowGraphCompiler* graph_compiler, | 2668     FlowGraphCompiler* graph_compiler, | 
| 2734     FlowGraph* flow_graph) { | 2669     FlowGraph* flow_graph) { | 
| 2735   const Function& function = parsed_function()->function(); | 2670   const Function& function = parsed_function()->function(); | 
| 2736   Zone* const zone = thread()->zone(); | 2671   Zone* const zone = thread()->zone(); | 
| 2737 | 2672 | 
| 2738   CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); | 2673   CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); | 
| 2739   // CreateDeoptInfo uses the object pool and needs to be done before | 2674   // CreateDeoptInfo uses the object pool and needs to be done before | 
| 2740   // FinalizeCode. | 2675   // FinalizeCode. | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 2769     ASSERT(thread()->IsMutatorThread()); | 2704     ASSERT(thread()->IsMutatorThread()); | 
| 2770     function.InstallOptimizedCode(code); | 2705     function.InstallOptimizedCode(code); | 
| 2771   } else {  // not optimized. | 2706   } else {  // not optimized. | 
| 2772     function.set_unoptimized_code(code); | 2707     function.set_unoptimized_code(code); | 
| 2773     function.AttachCode(code); | 2708     function.AttachCode(code); | 
| 2774   } | 2709   } | 
| 2775   ASSERT(!parsed_function()->HasDeferredPrefixes()); | 2710   ASSERT(!parsed_function()->HasDeferredPrefixes()); | 
| 2776   ASSERT(FLAG_load_deferred_eagerly); | 2711   ASSERT(FLAG_load_deferred_eagerly); | 
| 2777 } | 2712 } | 
| 2778 | 2713 | 
| 2779 |  | 
| 2780 // Return false if bailed out. | 2714 // Return false if bailed out. | 
| 2781 // If optimized_result_code is not NULL then it is caller's responsibility | 2715 // If optimized_result_code is not NULL then it is caller's responsibility | 
| 2782 // to install code. | 2716 // to install code. | 
| 2783 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { | 2717 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { | 
| 2784   ASSERT(FLAG_precompiled_mode); | 2718   ASSERT(FLAG_precompiled_mode); | 
| 2785   const Function& function = parsed_function()->function(); | 2719   const Function& function = parsed_function()->function(); | 
| 2786   if (optimized() && !function.IsOptimizable()) { | 2720   if (optimized() && !function.IsOptimizable()) { | 
| 2787     // All functions compiled by precompiler must be optimizable. | 2721     // All functions compiled by precompiler must be optimizable. | 
| 2788     UNREACHABLE(); | 2722     UNREACHABLE(); | 
| 2789     return false; | 2723     return false; | 
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3280         thread()->clear_sticky_error(); | 3214         thread()->clear_sticky_error(); | 
| 3281       } | 3215       } | 
| 3282       is_compiled = false; | 3216       is_compiled = false; | 
| 3283     } | 3217     } | 
| 3284     // Reset global isolate state. | 3218     // Reset global isolate state. | 
| 3285     thread()->set_deopt_id(prev_deopt_id); | 3219     thread()->set_deopt_id(prev_deopt_id); | 
| 3286   } | 3220   } | 
| 3287   return is_compiled; | 3221   return is_compiled; | 
| 3288 } | 3222 } | 
| 3289 | 3223 | 
| 3290 |  | 
| 3291 static RawError* PrecompileFunctionHelper(Precompiler* precompiler, | 3224 static RawError* PrecompileFunctionHelper(Precompiler* precompiler, | 
| 3292                                           CompilationPipeline* pipeline, | 3225                                           CompilationPipeline* pipeline, | 
| 3293                                           const Function& function, | 3226                                           const Function& function, | 
| 3294                                           bool optimized) { | 3227                                           bool optimized) { | 
| 3295   // Check that we optimize, except if the function is not optimizable. | 3228   // Check that we optimize, except if the function is not optimizable. | 
| 3296   ASSERT(FLAG_precompiled_mode); | 3229   ASSERT(FLAG_precompiled_mode); | 
| 3297   ASSERT(!function.IsOptimizable() || optimized); | 3230   ASSERT(!function.IsOptimizable() || optimized); | 
| 3298   ASSERT(!function.HasCode()); | 3231   ASSERT(!function.HasCode()); | 
| 3299   LongJumpScope jump; | 3232   LongJumpScope jump; | 
| 3300   if (setjmp(*jump.Set()) == 0) { | 3233   if (setjmp(*jump.Set()) == 0) { | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3369     thread->clear_sticky_error(); | 3302     thread->clear_sticky_error(); | 
| 3370     // Precompilation may encounter compile-time errors. | 3303     // Precompilation may encounter compile-time errors. | 
| 3371     // Do not attempt to optimize functions that can cause errors. | 3304     // Do not attempt to optimize functions that can cause errors. | 
| 3372     function.set_is_optimizable(false); | 3305     function.set_is_optimizable(false); | 
| 3373     return error.raw(); | 3306     return error.raw(); | 
| 3374   } | 3307   } | 
| 3375   UNREACHABLE(); | 3308   UNREACHABLE(); | 
| 3376   return Error::null(); | 3309   return Error::null(); | 
| 3377 } | 3310 } | 
| 3378 | 3311 | 
| 3379 |  | 
| 3380 RawError* Precompiler::CompileFunction(Precompiler* precompiler, | 3312 RawError* Precompiler::CompileFunction(Precompiler* precompiler, | 
| 3381                                        Thread* thread, | 3313                                        Thread* thread, | 
| 3382                                        Zone* zone, | 3314                                        Zone* zone, | 
| 3383                                        const Function& function, | 3315                                        const Function& function, | 
| 3384                                        FieldTypeMap* field_type_map) { | 3316                                        FieldTypeMap* field_type_map) { | 
| 3385   VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 3317   VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 
| 3386   TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); | 3318   TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); | 
| 3387 | 3319 | 
| 3388   ASSERT(FLAG_precompiled_mode); | 3320   ASSERT(FLAG_precompiled_mode); | 
| 3389   const bool optimized = function.IsOptimizable();  // False for natives. | 3321   const bool optimized = function.IsOptimizable();  // False for natives. | 
| 3390   DartPrecompilationPipeline pipeline(zone, field_type_map); | 3322   DartPrecompilationPipeline pipeline(zone, field_type_map); | 
| 3391   return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | 3323   return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | 
| 3392 } | 3324 } | 
| 3393 | 3325 | 
| 3394 #endif  // DART_PRECOMPILER | 3326 #endif  // DART_PRECOMPILER | 
| 3395 | 3327 | 
| 3396 }  // namespace dart | 3328 }  // namespace dart | 
| OLD | NEW | 
|---|