| 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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 145 |
| 146 private: | 146 private: |
| 147 Zone* zone_; | 147 Zone* zone_; |
| 148 CompileType result_type_; | 148 CompileType result_type_; |
| 149 FieldTypeMap* field_map_; | 149 FieldTypeMap* field_map_; |
| 150 }; | 150 }; |
| 151 | 151 |
| 152 | 152 |
| 153 class PrecompileParsedFunctionHelper : public ValueObject { | 153 class PrecompileParsedFunctionHelper : public ValueObject { |
| 154 public: | 154 public: |
| 155 PrecompileParsedFunctionHelper(Precompiler* precompiler, | 155 PrecompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| 156 ParsedFunction* parsed_function, | |
| 157 bool optimized) | 156 bool optimized) |
| 158 : precompiler_(precompiler), | 157 : parsed_function_(parsed_function), |
| 159 parsed_function_(parsed_function), | |
| 160 optimized_(optimized), | 158 optimized_(optimized), |
| 161 thread_(Thread::Current()) { | 159 thread_(Thread::Current()) { |
| 162 } | 160 } |
| 163 | 161 |
| 164 bool Compile(CompilationPipeline* pipeline); | 162 bool Compile(CompilationPipeline* pipeline); |
| 165 | 163 |
| 166 private: | 164 private: |
| 167 ParsedFunction* parsed_function() const { return parsed_function_; } | 165 ParsedFunction* parsed_function() const { return parsed_function_; } |
| 168 bool optimized() const { return optimized_; } | 166 bool optimized() const { return optimized_; } |
| 169 Thread* thread() const { return thread_; } | 167 Thread* thread() const { return thread_; } |
| 170 Isolate* isolate() const { return thread_->isolate(); } | 168 Isolate* isolate() const { return thread_->isolate(); } |
| 171 | 169 |
| 172 void FinalizeCompilation(Assembler* assembler, | 170 void FinalizeCompilation(Assembler* assembler, |
| 173 FlowGraphCompiler* graph_compiler, | 171 FlowGraphCompiler* graph_compiler, |
| 174 FlowGraph* flow_graph); | 172 FlowGraph* flow_graph); |
| 175 | 173 |
| 176 Precompiler* precompiler_; | |
| 177 ParsedFunction* parsed_function_; | 174 ParsedFunction* parsed_function_; |
| 178 const bool optimized_; | 175 const bool optimized_; |
| 179 Thread* const thread_; | 176 Thread* const thread_; |
| 180 | 177 |
| 181 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); | 178 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); |
| 182 }; | 179 }; |
| 183 | 180 |
| 184 | 181 |
| 185 static void Jump(const Error& error) { | 182 static void Jump(const Error& error) { |
| 186 Thread::Current()->long_jump_base()->Jump(1, error); | 183 Thread::Current()->long_jump_base()->Jump(1, error); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 GrowableObjectArray::Handle(GrowableObjectArray::New())), | 307 GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 311 sent_selectors_(), | 308 sent_selectors_(), |
| 312 enqueued_functions_(), | 309 enqueued_functions_(), |
| 313 fields_to_retain_(), | 310 fields_to_retain_(), |
| 314 functions_to_retain_(), | 311 functions_to_retain_(), |
| 315 classes_to_retain_(), | 312 classes_to_retain_(), |
| 316 typeargs_to_retain_(), | 313 typeargs_to_retain_(), |
| 317 types_to_retain_(), | 314 types_to_retain_(), |
| 318 consts_to_retain_(), | 315 consts_to_retain_(), |
| 319 field_type_map_(), | 316 field_type_map_(), |
| 320 error_(Error::Handle()), | 317 error_(Error::Handle()) { |
| 321 get_runtime_type_is_unique_(false) { | |
| 322 } | 318 } |
| 323 | 319 |
| 324 | 320 |
| 325 void Precompiler::DoCompileAll( | 321 void Precompiler::DoCompileAll( |
| 326 Dart_QualifiedFunctionName embedder_entry_points[]) { | 322 Dart_QualifiedFunctionName embedder_entry_points[]) { |
| 327 ASSERT(I->compilation_allowed()); | 323 ASSERT(I->compilation_allowed()); |
| 328 | 324 |
| 329 { | 325 { |
| 330 StackZone stack_zone(T); | 326 StackZone stack_zone(T); |
| 331 zone_ = stack_zone.GetZone(); | 327 zone_ = stack_zone.GetZone(); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 476 |
| 481 HANDLESCOPE(T); | 477 HANDLESCOPE(T); |
| 482 StaticInitializerVisitor visitor(Z); | 478 StaticInitializerVisitor visitor(Z); |
| 483 VisitClasses(&visitor); | 479 VisitClasses(&visitor); |
| 484 } | 480 } |
| 485 | 481 |
| 486 | 482 |
| 487 void Precompiler::PrecompileConstructors() { | 483 void Precompiler::PrecompileConstructors() { |
| 488 class ConstructorVisitor : public FunctionVisitor { | 484 class ConstructorVisitor : public FunctionVisitor { |
| 489 public: | 485 public: |
| 490 explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone) | 486 explicit ConstructorVisitor(Zone* zone, FieldTypeMap* map) |
| 491 : precompiler_(precompiler), zone_(zone) { | 487 : zone_(zone), field_type_map_(map) { |
| 488 ASSERT(map != NULL); |
| 492 } | 489 } |
| 493 void Visit(const Function& function) { | 490 void Visit(const Function& function) { |
| 494 if (!function.IsGenerativeConstructor()) return; | 491 if (!function.IsGenerativeConstructor()) return; |
| 495 if (function.HasCode()) { | 492 if (function.HasCode()) { |
| 496 // Const constructors may have been visited before. Recompile them here | 493 // Const constructors may have been visited before. Recompile them here |
| 497 // to collect type information for final fields for them as well. | 494 // to collect type information for final fields for them as well. |
| 498 function.ClearCode(); | 495 function.ClearCode(); |
| 499 } | 496 } |
| 500 if (FLAG_trace_precompiler) { | 497 if (FLAG_trace_precompiler) { |
| 501 THR_Print("Precompiling constructor %s\n", function.ToCString()); | 498 THR_Print("Precompiling constructor %s\n", function.ToCString()); |
| 502 } | 499 } |
| 503 CompileFunction(precompiler_, | 500 CompileFunction(Thread::Current(), |
| 504 Thread::Current(), | |
| 505 zone_, | 501 zone_, |
| 506 function); | 502 function, |
| 503 field_type_map_); |
| 507 } | 504 } |
| 508 | |
| 509 private: | 505 private: |
| 510 Precompiler* precompiler_; | |
| 511 Zone* zone_; | 506 Zone* zone_; |
| 507 FieldTypeMap* field_type_map_; |
| 512 }; | 508 }; |
| 513 | 509 |
| 514 HANDLESCOPE(T); | 510 HANDLESCOPE(T); |
| 515 ConstructorVisitor visitor(this, zone_); | 511 ConstructorVisitor visitor(zone_, &field_type_map_); |
| 516 VisitFunctions(&visitor); | 512 VisitFunctions(&visitor); |
| 517 | 513 |
| 518 FieldTypeMap::Iterator it(field_type_map_.GetIterator()); | 514 FieldTypeMap::Iterator it(field_type_map_.GetIterator()); |
| 519 for (FieldTypePair* current = it.Next(); | 515 for (FieldTypePair* current = it.Next(); |
| 520 current != NULL; | 516 current != NULL; |
| 521 current = it.Next()) { | 517 current = it.Next()) { |
| 522 const intptr_t cid = current->cid_; | 518 const intptr_t cid = current->cid_; |
| 523 current->field_->set_guarded_cid(cid); | 519 current->field_->set_guarded_cid(cid); |
| 524 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); | 520 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); |
| 525 if (FLAG_trace_precompiler) { | 521 if (FLAG_trace_precompiler) { |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", | 789 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", |
| 794 function_count_, | 790 function_count_, |
| 795 function.ToLibNamePrefixedQualifiedCString(), | 791 function.ToLibNamePrefixedQualifiedCString(), |
| 796 function.token_pos().ToCString(), | 792 function.token_pos().ToCString(), |
| 797 Function::KindToCString(function.kind())); | 793 Function::KindToCString(function.kind())); |
| 798 } | 794 } |
| 799 | 795 |
| 800 ASSERT(!function.is_abstract()); | 796 ASSERT(!function.is_abstract()); |
| 801 ASSERT(!function.IsRedirectingFactory()); | 797 ASSERT(!function.IsRedirectingFactory()); |
| 802 | 798 |
| 803 error_ = CompileFunction(this, thread_, zone_, function); | 799 error_ = CompileFunction(thread_, zone_, function); |
| 804 if (!error_.IsNull()) { | 800 if (!error_.IsNull()) { |
| 805 Jump(error_); | 801 Jump(error_); |
| 806 } | 802 } |
| 807 // Used in the JIT to save type-feedback across compilations. | 803 // Used in the JIT to save type-feedback across compilations. |
| 808 function.ClearICDataArray(); | 804 function.ClearICDataArray(); |
| 809 } else { | 805 } else { |
| 810 if (FLAG_trace_precompiler) { | 806 if (FLAG_trace_precompiler) { |
| 811 // This function was compiled from somewhere other than Precompiler, | 807 // This function was compiled from somewhere other than Precompiler, |
| 812 // such as const constructors compiled by the parser. | 808 // such as const constructors compiled by the parser. |
| 813 THR_Print("Already has code: %s (%s, %s)\n", | 809 THR_Print("Already has code: %s (%s, %s)\n", |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, | 1127 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, |
| 1132 bool compute_type) { | 1128 bool compute_type) { |
| 1133 ASSERT(field.is_static()); | 1129 ASSERT(field.is_static()); |
| 1134 Thread* thread = Thread::Current(); | 1130 Thread* thread = Thread::Current(); |
| 1135 StackZone zone(thread); | 1131 StackZone zone(thread); |
| 1136 | 1132 |
| 1137 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); | 1133 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); |
| 1138 | 1134 |
| 1139 parsed_function->AllocateVariables(); | 1135 parsed_function->AllocateVariables(); |
| 1140 DartPrecompilationPipeline pipeline(zone.GetZone()); | 1136 DartPrecompilationPipeline pipeline(zone.GetZone()); |
| 1141 PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL, | 1137 PrecompileParsedFunctionHelper helper(parsed_function, |
| 1142 parsed_function, | |
| 1143 /* optimized = */ true); | 1138 /* optimized = */ true); |
| 1144 bool success = helper.Compile(&pipeline); | 1139 bool success = helper.Compile(&pipeline); |
| 1145 ASSERT(success); | 1140 ASSERT(success); |
| 1146 | 1141 |
| 1147 if (compute_type && field.is_final()) { | 1142 if (compute_type && field.is_final()) { |
| 1148 intptr_t result_cid = pipeline.result_type().ToCid(); | 1143 intptr_t result_cid = pipeline.result_type().ToCid(); |
| 1149 if (result_cid != kDynamicCid) { | 1144 if (result_cid != kDynamicCid) { |
| 1150 if (FLAG_trace_precompiler && FLAG_support_il_printer) { | 1145 if (FLAG_trace_precompiler && FLAG_support_il_printer) { |
| 1151 THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), | 1146 THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), |
| 1152 pipeline.result_type().ToCString()); | 1147 pipeline.result_type().ToCString()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 // here. | 1228 // here. |
| 1234 ParsedFunction* parsed_function = new ParsedFunction(thread, func); | 1229 ParsedFunction* parsed_function = new ParsedFunction(thread, func); |
| 1235 parsed_function->SetNodeSequence(fragment); | 1230 parsed_function->SetNodeSequence(fragment); |
| 1236 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); | 1231 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); |
| 1237 fragment->scope()->AddVariable( | 1232 fragment->scope()->AddVariable( |
| 1238 parsed_function->current_context_var()); | 1233 parsed_function->current_context_var()); |
| 1239 parsed_function->AllocateVariables(); | 1234 parsed_function->AllocateVariables(); |
| 1240 | 1235 |
| 1241 // Non-optimized code generator. | 1236 // Non-optimized code generator. |
| 1242 DartPrecompilationPipeline pipeline(Thread::Current()->zone()); | 1237 DartPrecompilationPipeline pipeline(Thread::Current()->zone()); |
| 1243 PrecompileParsedFunctionHelper helper(/* precompiler = */ NULL, | 1238 PrecompileParsedFunctionHelper helper(parsed_function, |
| 1244 parsed_function, | |
| 1245 /* optimized = */ false); | 1239 /* optimized = */ false); |
| 1246 helper.Compile(&pipeline); | 1240 helper.Compile(&pipeline); |
| 1247 Code::Handle(func.unoptimized_code()).set_var_descriptors( | 1241 Code::Handle(func.unoptimized_code()).set_var_descriptors( |
| 1248 Object::empty_var_descriptors()); | 1242 Object::empty_var_descriptors()); |
| 1249 | 1243 |
| 1250 const Object& result = PassiveObject::Handle( | 1244 const Object& result = PassiveObject::Handle( |
| 1251 DartEntry::InvokeFunction(func, Object::empty_array())); | 1245 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 1252 return result.raw(); | 1246 return result.raw(); |
| 1253 } else { | 1247 } else { |
| 1254 Thread* const thread = Thread::Current(); | 1248 Thread* const thread = Thread::Current(); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1510 key ^= table.GetKey(curr_key); | 1504 key ^= table.GetKey(curr_key); |
| 1511 farray ^= table.GetOrNull(key); | 1505 farray ^= table.GetOrNull(key); |
| 1512 ASSERT(!farray.IsNull()); | 1506 ASSERT(!farray.IsNull()); |
| 1513 if (farray.Length() == 1) { | 1507 if (farray.Length() == 1) { |
| 1514 function ^= farray.At(0); | 1508 function ^= farray.At(0); |
| 1515 cls = function.Owner(); | 1509 cls = function.Owner(); |
| 1516 functions_set.Insert(function); | 1510 functions_set.Insert(function); |
| 1517 } | 1511 } |
| 1518 } | 1512 } |
| 1519 | 1513 |
| 1520 farray ^= table.GetOrNull(Symbols::GetRuntimeType()); | |
| 1521 | |
| 1522 get_runtime_type_is_unique_ = !farray.IsNull() && (farray.Length() == 1); | |
| 1523 | |
| 1524 if (FLAG_print_unique_targets) { | 1514 if (FLAG_print_unique_targets) { |
| 1525 UniqueFunctionsSet::Iterator unique_iter(&functions_set); | 1515 UniqueFunctionsSet::Iterator unique_iter(&functions_set); |
| 1526 while (unique_iter.MoveNext()) { | 1516 while (unique_iter.MoveNext()) { |
| 1527 intptr_t curr_key = unique_iter.Current(); | 1517 intptr_t curr_key = unique_iter.Current(); |
| 1528 function ^= functions_set.GetKey(curr_key); | 1518 function ^= functions_set.GetKey(curr_key); |
| 1529 THR_Print("* %s\n", function.ToQualifiedCString()); | 1519 THR_Print("* %s\n", function.ToQualifiedCString()); |
| 1530 } | 1520 } |
| 1531 THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n", | 1521 THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n", |
| 1532 functions_set.NumOccupied(), table.NumOccupied()); | 1522 functions_set.NumOccupied(), table.NumOccupied()); |
| 1533 } | 1523 } |
| (...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 // We do not add the token position now because we don't know the | 2812 // We do not add the token position now because we don't know the |
| 2823 // position of the inlined call until later. A side effect of this | 2813 // position of the inlined call until later. A side effect of this |
| 2824 // is that the length of |inline_id_to_function| is always larger | 2814 // is that the length of |inline_id_to_function| is always larger |
| 2825 // than the length of |inline_id_to_token_pos| by one. | 2815 // than the length of |inline_id_to_token_pos| by one. |
| 2826 // Top scope function has no caller (-1). We do this because we expect | 2816 // Top scope function has no caller (-1). We do this because we expect |
| 2827 // all token positions to be at an inlined call. | 2817 // all token positions to be at an inlined call. |
| 2828 // Top scope function has no caller (-1). | 2818 // Top scope function has no caller (-1). |
| 2829 caller_inline_id.Add(-1); | 2819 caller_inline_id.Add(-1); |
| 2830 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); | 2820 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); |
| 2831 | 2821 |
| 2832 AotOptimizer optimizer(precompiler_, | 2822 AotOptimizer optimizer(flow_graph, |
| 2833 flow_graph, | |
| 2834 use_speculative_inlining, | 2823 use_speculative_inlining, |
| 2835 &inlining_black_list); | 2824 &inlining_black_list); |
| 2836 optimizer.PopulateWithICData(); | 2825 optimizer.PopulateWithICData(); |
| 2837 | 2826 |
| 2838 optimizer.ApplyClassIds(); | 2827 optimizer.ApplyClassIds(); |
| 2839 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 2828 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 2840 | 2829 |
| 2841 FlowGraphTypePropagator::Propagate(flow_graph); | 2830 FlowGraphTypePropagator::Propagate(flow_graph); |
| 2842 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 2831 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 2843 | 2832 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2865 | 2854 |
| 2866 // Use propagated class-ids to create more inlining opportunities. | 2855 // Use propagated class-ids to create more inlining opportunities. |
| 2867 optimizer.ApplyClassIds(); | 2856 optimizer.ApplyClassIds(); |
| 2868 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 2857 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 2869 | 2858 |
| 2870 FlowGraphInliner inliner(flow_graph, | 2859 FlowGraphInliner inliner(flow_graph, |
| 2871 &inline_id_to_function, | 2860 &inline_id_to_function, |
| 2872 &inline_id_to_token_pos, | 2861 &inline_id_to_token_pos, |
| 2873 &caller_inline_id, | 2862 &caller_inline_id, |
| 2874 use_speculative_inlining, | 2863 use_speculative_inlining, |
| 2875 &inlining_black_list, | 2864 &inlining_black_list); |
| 2876 precompiler_); | |
| 2877 inliner.Inline(); | 2865 inliner.Inline(); |
| 2878 // Use lists are maintained and validated by the inliner. | 2866 // Use lists are maintained and validated by the inliner. |
| 2879 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 2867 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 2880 } | 2868 } |
| 2881 | 2869 |
| 2882 // Propagate types and eliminate more type tests. | 2870 // Propagate types and eliminate more type tests. |
| 2883 FlowGraphTypePropagator::Propagate(flow_graph); | 2871 FlowGraphTypePropagator::Propagate(flow_graph); |
| 2884 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 2872 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 2885 | 2873 |
| 2886 { | 2874 { |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3245 } | 3233 } |
| 3246 is_compiled = false; | 3234 is_compiled = false; |
| 3247 } | 3235 } |
| 3248 // Reset global isolate state. | 3236 // Reset global isolate state. |
| 3249 thread()->set_deopt_id(prev_deopt_id); | 3237 thread()->set_deopt_id(prev_deopt_id); |
| 3250 } | 3238 } |
| 3251 return is_compiled; | 3239 return is_compiled; |
| 3252 } | 3240 } |
| 3253 | 3241 |
| 3254 | 3242 |
| 3255 static RawError* PrecompileFunctionHelper(Precompiler* precompiler, | 3243 static RawError* PrecompileFunctionHelper(CompilationPipeline* pipeline, |
| 3256 CompilationPipeline* pipeline, | |
| 3257 const Function& function, | 3244 const Function& function, |
| 3258 bool optimized) { | 3245 bool optimized) { |
| 3259 // Check that we optimize, except if the function is not optimizable. | 3246 // Check that we optimize, except if the function is not optimizable. |
| 3260 ASSERT(FLAG_precompiled_mode); | 3247 ASSERT(FLAG_precompiled_mode); |
| 3261 ASSERT(!function.IsOptimizable() || optimized); | 3248 ASSERT(!function.IsOptimizable() || optimized); |
| 3262 ASSERT(!function.HasCode()); | 3249 ASSERT(!function.HasCode()); |
| 3263 LongJumpScope jump; | 3250 LongJumpScope jump; |
| 3264 if (setjmp(*jump.Set()) == 0) { | 3251 if (setjmp(*jump.Set()) == 0) { |
| 3265 Thread* const thread = Thread::Current(); | 3252 Thread* const thread = Thread::Current(); |
| 3266 StackZone stack_zone(thread); | 3253 StackZone stack_zone(thread); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3288 { | 3275 { |
| 3289 HANDLESCOPE(thread); | 3276 HANDLESCOPE(thread); |
| 3290 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); | 3277 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); |
| 3291 pipeline->ParseFunction(parsed_function); | 3278 pipeline->ParseFunction(parsed_function); |
| 3292 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); | 3279 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); |
| 3293 INC_STAT(thread, | 3280 INC_STAT(thread, |
| 3294 num_func_tokens_compiled, | 3281 num_func_tokens_compiled, |
| 3295 num_tokens_after - num_tokens_before); | 3282 num_tokens_after - num_tokens_before); |
| 3296 } | 3283 } |
| 3297 | 3284 |
| 3298 PrecompileParsedFunctionHelper helper( | 3285 PrecompileParsedFunctionHelper helper(parsed_function, optimized); |
| 3299 precompiler, parsed_function, optimized); | |
| 3300 const bool success = helper.Compile(pipeline); | 3286 const bool success = helper.Compile(pipeline); |
| 3301 if (!success) { | 3287 if (!success) { |
| 3302 // Encountered error. | 3288 // Encountered error. |
| 3303 Error& error = Error::Handle(); | 3289 Error& error = Error::Handle(); |
| 3304 // We got an error during compilation. | 3290 // We got an error during compilation. |
| 3305 error = thread->sticky_error(); | 3291 error = thread->sticky_error(); |
| 3306 thread->clear_sticky_error(); | 3292 thread->clear_sticky_error(); |
| 3307 ASSERT(error.IsLanguageError() && | 3293 ASSERT(error.IsLanguageError() && |
| 3308 LanguageError::Cast(error).kind() != Report::kBailout); | 3294 LanguageError::Cast(error).kind() != Report::kBailout); |
| 3309 return error.raw(); | 3295 return error.raw(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3337 // Precompilation may encounter compile-time errors. | 3323 // Precompilation may encounter compile-time errors. |
| 3338 // Do not attempt to optimize functions that can cause errors. | 3324 // Do not attempt to optimize functions that can cause errors. |
| 3339 function.set_is_optimizable(false); | 3325 function.set_is_optimizable(false); |
| 3340 return error.raw(); | 3326 return error.raw(); |
| 3341 } | 3327 } |
| 3342 UNREACHABLE(); | 3328 UNREACHABLE(); |
| 3343 return Error::null(); | 3329 return Error::null(); |
| 3344 } | 3330 } |
| 3345 | 3331 |
| 3346 | 3332 |
| 3347 RawError* Precompiler::CompileFunction(Precompiler* precompiler, | 3333 RawError* Precompiler::CompileFunction(Thread* thread, |
| 3348 Thread* thread, | |
| 3349 Zone* zone, | 3334 Zone* zone, |
| 3350 const Function& function) { | 3335 const Function& function, |
| 3336 FieldTypeMap* field_type_map) { |
| 3351 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 3337 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); |
| 3352 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); | 3338 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); |
| 3353 | 3339 |
| 3354 ASSERT(FLAG_precompiled_mode); | 3340 ASSERT(FLAG_precompiled_mode); |
| 3355 const bool optimized = function.IsOptimizable(); // False for natives. | 3341 const bool optimized = function.IsOptimizable(); // False for natives. |
| 3356 DartPrecompilationPipeline pipeline(zone, | 3342 DartPrecompilationPipeline pipeline(zone, field_type_map); |
| 3357 (precompiler != NULL) ? precompiler->field_type_map() : NULL); | 3343 return PrecompileFunctionHelper(&pipeline, function, optimized); |
| 3358 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | |
| 3359 } | 3344 } |
| 3360 | 3345 |
| 3361 #endif // DART_PRECOMPILER | 3346 #endif // DART_PRECOMPILER |
| 3362 | 3347 |
| 3363 } // namespace dart | 3348 } // namespace dart |
| OLD | NEW |