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 |