| 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 |