Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 | 66 |
| 67 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 67 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 68 DECLARE_FLAG(bool, trace_inlining_intervals); | 68 DECLARE_FLAG(bool, trace_inlining_intervals); |
| 69 DECLARE_FLAG(bool, trace_irregexp); | 69 DECLARE_FLAG(bool, trace_irregexp); |
| 70 DECLARE_FLAG(bool, trace_patching); | 70 DECLARE_FLAG(bool, trace_patching); |
| 71 | 71 |
| 72 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove | 72 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove |
| 73 // separate helpers functions & `optimizing` args. | 73 // separate helpers functions & `optimizing` args. |
| 74 class CompilationPipeline : public ZoneAllocated { | 74 class CompilationPipeline : public ZoneAllocated { |
| 75 public: | 75 public: |
| 76 static CompilationPipeline* New(Isolate* isolate, const Function& function); | 76 static CompilationPipeline* New(Zone* zone, const Function& function); |
| 77 | 77 |
| 78 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; | 78 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; |
| 79 virtual FlowGraph* BuildFlowGraph( | 79 virtual FlowGraph* BuildFlowGraph( |
| 80 ParsedFunction* parsed_function, | 80 ParsedFunction* parsed_function, |
| 81 const ZoneGrowableArray<const ICData*>& ic_data_array, | 81 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 82 intptr_t osr_id) = 0; | 82 intptr_t osr_id, |
| 83 Zone* zone) = 0; | |
|
Ivan Posva
2015/03/13 21:56:49
We generally pass Isolate* as the first parameter,
koda
2015/03/14 00:46:36
Done.
| |
| 83 virtual void FinalizeCompilation() = 0; | 84 virtual void FinalizeCompilation() = 0; |
| 84 virtual ~CompilationPipeline() { } | 85 virtual ~CompilationPipeline() { } |
| 85 }; | 86 }; |
| 86 | 87 |
| 87 | 88 |
| 88 class DartCompilationPipeline : public CompilationPipeline { | 89 class DartCompilationPipeline : public CompilationPipeline { |
| 89 public: | 90 public: |
| 90 virtual void ParseFunction(ParsedFunction* parsed_function) { | 91 virtual void ParseFunction(ParsedFunction* parsed_function) { |
| 91 Parser::ParseFunction(parsed_function); | 92 Parser::ParseFunction(parsed_function); |
| 92 parsed_function->AllocateVariables(); | 93 parsed_function->AllocateVariables(); |
| 93 } | 94 } |
| 94 | 95 |
| 95 virtual FlowGraph* BuildFlowGraph( | 96 virtual FlowGraph* BuildFlowGraph( |
| 96 ParsedFunction* parsed_function, | 97 ParsedFunction* parsed_function, |
| 97 const ZoneGrowableArray<const ICData*>& ic_data_array, | 98 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 98 intptr_t osr_id) { | 99 intptr_t osr_id, |
| 100 Zone* zone) { | |
| 99 // Build the flow graph. | 101 // Build the flow graph. |
| 100 FlowGraphBuilder builder(*parsed_function, | 102 FlowGraphBuilder builder(*parsed_function, |
| 101 ic_data_array, | 103 ic_data_array, |
| 102 NULL, // NULL = not inlining. | 104 NULL, // NULL = not inlining. |
| 103 osr_id); | 105 osr_id); |
| 104 | 106 |
| 105 return builder.BuildGraph(); | 107 return builder.BuildGraph(); |
| 106 } | 108 } |
| 107 | 109 |
| 108 virtual void FinalizeCompilation() { } | 110 virtual void FinalizeCompilation() { } |
| 109 }; | 111 }; |
| 110 | 112 |
| 111 | 113 |
| 112 class IrregexpCompilationPipeline : public CompilationPipeline { | 114 class IrregexpCompilationPipeline : public CompilationPipeline { |
| 113 public: | 115 public: |
| 114 explicit IrregexpCompilationPipeline(Isolate* isolate) | 116 IrregexpCompilationPipeline() : backtrack_goto_(NULL) { } |
| 115 : backtrack_goto_(NULL), | |
| 116 isolate_(isolate) { } | |
| 117 | 117 |
| 118 virtual void ParseFunction(ParsedFunction* parsed_function) { | 118 virtual void ParseFunction(ParsedFunction* parsed_function) { |
| 119 RegExpParser::ParseFunction(parsed_function); | 119 RegExpParser::ParseFunction(parsed_function); |
| 120 // Variables are allocated after compilation. | 120 // Variables are allocated after compilation. |
| 121 } | 121 } |
| 122 | 122 |
| 123 virtual FlowGraph* BuildFlowGraph( | 123 virtual FlowGraph* BuildFlowGraph( |
| 124 ParsedFunction* parsed_function, | 124 ParsedFunction* parsed_function, |
| 125 const ZoneGrowableArray<const ICData*>& ic_data_array, | 125 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 126 intptr_t osr_id) { | 126 intptr_t osr_id, |
| 127 Zone* zone) { | |
| 127 // Compile to the dart IR. | 128 // Compile to the dart IR. |
| 128 RegExpEngine::CompilationResult result = | 129 RegExpEngine::CompilationResult result = |
| 129 RegExpEngine::Compile(parsed_function->regexp_compile_data(), | 130 RegExpEngine::Compile(parsed_function->regexp_compile_data(), |
| 130 parsed_function, | 131 parsed_function, |
| 131 ic_data_array); | 132 ic_data_array); |
| 132 backtrack_goto_ = result.backtrack_goto; | 133 backtrack_goto_ = result.backtrack_goto; |
| 133 | 134 |
| 134 // Allocate variables now that we know the number of locals. | 135 // Allocate variables now that we know the number of locals. |
| 135 parsed_function->AllocateIrregexpVariables(result.num_stack_locals); | 136 parsed_function->AllocateIrregexpVariables(result.num_stack_locals); |
| 136 | 137 |
| 137 // Build the flow graph. | 138 // Build the flow graph. |
| 138 FlowGraphBuilder builder(*parsed_function, | 139 FlowGraphBuilder builder(*parsed_function, |
| 139 ic_data_array, | 140 ic_data_array, |
| 140 NULL, // NULL = not inlining. | 141 NULL, // NULL = not inlining. |
| 141 osr_id); | 142 osr_id); |
| 142 | 143 |
| 143 return new(isolate_) FlowGraph(*parsed_function, | 144 return new(zone) FlowGraph(*parsed_function, |
| 144 result.graph_entry, | 145 result.graph_entry, |
| 145 result.num_blocks); | 146 result.num_blocks); |
| 146 } | 147 } |
| 147 | 148 |
| 148 virtual void FinalizeCompilation() { | 149 virtual void FinalizeCompilation() { |
| 149 backtrack_goto_->ComputeOffsetTable(isolate_); | 150 backtrack_goto_->ComputeOffsetTable(); |
| 150 } | 151 } |
| 151 | 152 |
| 152 private: | 153 private: |
| 153 IndirectGotoInstr* backtrack_goto_; | 154 IndirectGotoInstr* backtrack_goto_; |
| 154 Isolate* isolate_; | 155 Zone* zone_; |
|
Ivan Posva
2015/03/13 21:56:49
Where is zone_ being set?
koda
2015/03/14 00:46:36
Removed (leftover from previous version).
| |
| 155 }; | 156 }; |
| 156 | 157 |
| 157 CompilationPipeline* CompilationPipeline::New(Isolate* isolate, | 158 CompilationPipeline* CompilationPipeline::New(Zone* zone, |
| 158 const Function& function) { | 159 const Function& function) { |
| 159 if (function.IsIrregexpFunction()) { | 160 if (function.IsIrregexpFunction()) { |
| 160 return new(isolate) IrregexpCompilationPipeline(isolate); | 161 return new(zone) IrregexpCompilationPipeline(); |
| 161 } else { | 162 } else { |
| 162 return new(isolate) DartCompilationPipeline(); | 163 return new(zone) DartCompilationPipeline(); |
| 163 } | 164 } |
| 164 } | 165 } |
| 165 | 166 |
| 166 | 167 |
| 167 // Compile a function. Should call only if the function has not been compiled. | 168 // Compile a function. Should call only if the function has not been compiled. |
| 168 // Arg0: function object. | 169 // Arg0: function object. |
| 169 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { | 170 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { |
| 170 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 171 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 171 ASSERT(!function.HasCode()); | 172 ASSERT(!function.HasCode()); |
| 172 const Error& error = Error::Handle(Compiler::CompileFunction(isolate, | 173 const Error& error = Error::Handle(Compiler::CompileFunction(thread, |
| 173 function)); | 174 function)); |
| 174 if (!error.IsNull()) { | 175 if (!error.IsNull()) { |
| 175 Exceptions::PropagateError(error); | 176 Exceptions::PropagateError(error); |
| 176 } | 177 } |
| 177 } | 178 } |
| 178 | 179 |
| 179 | 180 |
| 180 RawError* Compiler::Compile(const Library& library, const Script& script) { | 181 RawError* Compiler::Compile(const Library& library, const Script& script) { |
| 181 Isolate* isolate = Isolate::Current(); | 182 Isolate* isolate = Isolate::Current(); |
| 182 StackZone zone(isolate); | 183 StackZone zone(isolate); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, | 368 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, |
| 368 ParsedFunction* parsed_function, | 369 ParsedFunction* parsed_function, |
| 369 bool optimized, | 370 bool optimized, |
| 370 intptr_t osr_id) { | 371 intptr_t osr_id) { |
| 371 const Function& function = parsed_function->function(); | 372 const Function& function = parsed_function->function(); |
| 372 if (optimized && !function.IsOptimizable()) { | 373 if (optimized && !function.IsOptimizable()) { |
| 373 return false; | 374 return false; |
| 374 } | 375 } |
| 375 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); | 376 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); |
| 376 bool is_compiled = false; | 377 bool is_compiled = false; |
| 377 Isolate* isolate = Isolate::Current(); | 378 Thread* thread = Thread::Current(); |
| 379 Zone* zone = thread->zone(); | |
| 380 Isolate* isolate = thread->isolate(); | |
| 378 HANDLESCOPE(isolate); | 381 HANDLESCOPE(isolate); |
| 379 | 382 |
| 380 // We may reattempt compilation if the function needs to be assembled using | 383 // We may reattempt compilation if the function needs to be assembled using |
| 381 // far branches on ARM and MIPS. In the else branch of the setjmp call, | 384 // far branches on ARM and MIPS. In the else branch of the setjmp call, |
| 382 // done is set to false, and use_far_branches is set to true if there is a | 385 // done is set to false, and use_far_branches is set to true if there is a |
| 383 // longjmp from the ARM or MIPS assemblers. In all other paths through this | 386 // longjmp from the ARM or MIPS assemblers. In all other paths through this |
| 384 // while loop, done is set to true. use_far_branches is always false on ia32 | 387 // while loop, done is set to true. use_far_branches is always false on ia32 |
| 385 // and x64. | 388 // and x64. |
| 386 bool done = false; | 389 bool done = false; |
| 387 // volatile because the variable may be clobbered by a longjmp. | 390 // volatile because the variable may be clobbered by a longjmp. |
| 388 volatile bool use_far_branches = false; | 391 volatile bool use_far_branches = false; |
| 389 while (!done) { | 392 while (!done) { |
| 390 const intptr_t prev_deopt_id = isolate->deopt_id(); | 393 const intptr_t prev_deopt_id = isolate->deopt_id(); |
| 391 isolate->set_deopt_id(0); | 394 isolate->set_deopt_id(0); |
| 392 LongJumpScope jump; | 395 LongJumpScope jump; |
| 393 if (setjmp(*jump.Set()) == 0) { | 396 if (setjmp(*jump.Set()) == 0) { |
| 394 FlowGraph* flow_graph = NULL; | 397 FlowGraph* flow_graph = NULL; |
| 395 | 398 |
| 396 // Class hierarchy analysis is registered with the isolate in the | 399 // Class hierarchy analysis is registered with the isolate in the |
| 397 // constructor and unregisters itself upon destruction. | 400 // constructor and unregisters itself upon destruction. |
| 398 CHA cha(isolate); | 401 CHA cha(isolate); |
| 399 | 402 |
| 400 // TimerScope needs an isolate to be properly terminated in case of a | 403 // TimerScope needs an isolate to be properly terminated in case of a |
| 401 // LongJump. | 404 // LongJump. |
| 402 { | 405 { |
| 403 TimerScope timer(FLAG_compiler_stats, | 406 TimerScope timer(FLAG_compiler_stats, |
| 404 &CompilerStats::graphbuilder_timer, | 407 &CompilerStats::graphbuilder_timer, |
| 405 isolate); | 408 isolate); |
| 406 ZoneGrowableArray<const ICData*>* ic_data_array = | 409 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 407 new(isolate) ZoneGrowableArray<const ICData*>(); | 410 new(zone) ZoneGrowableArray<const ICData*>(); |
| 408 if (optimized) { | 411 if (optimized) { |
| 409 ASSERT(function.HasCode()); | 412 ASSERT(function.HasCode()); |
| 410 // Extract type feedback before the graph is built, as the graph | 413 // Extract type feedback before the graph is built, as the graph |
| 411 // builder uses it to attach it to nodes. | 414 // builder uses it to attach it to nodes. |
| 412 ASSERT(function.deoptimization_counter() < | 415 ASSERT(function.deoptimization_counter() < |
| 413 FLAG_deoptimization_counter_threshold); | 416 FLAG_deoptimization_counter_threshold); |
| 414 function.RestoreICDataMap(ic_data_array); | 417 function.RestoreICDataMap(ic_data_array); |
| 415 if (FLAG_print_ic_data_map) { | 418 if (FLAG_print_ic_data_map) { |
| 416 for (intptr_t i = 0; i < ic_data_array->length(); i++) { | 419 for (intptr_t i = 0; i < ic_data_array->length(); i++) { |
| 417 if ((*ic_data_array)[i] != NULL) { | 420 if ((*ic_data_array)[i] != NULL) { |
| 418 ISL_Print("%" Pd " ", i); | 421 ISL_Print("%" Pd " ", i); |
| 419 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); | 422 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); |
| 420 } | 423 } |
| 421 } | 424 } |
| 422 } | 425 } |
| 423 } | 426 } |
| 424 | 427 |
| 425 flow_graph = pipeline->BuildFlowGraph(parsed_function, | 428 flow_graph = pipeline->BuildFlowGraph(parsed_function, |
| 426 *ic_data_array, | 429 *ic_data_array, |
| 427 osr_id); | 430 osr_id, |
| 431 zone); | |
| 428 } | 432 } |
| 429 | 433 |
| 430 const bool print_flow_graph = | 434 const bool print_flow_graph = |
| 431 (FLAG_print_flow_graph || | 435 (FLAG_print_flow_graph || |
| 432 (optimized && FLAG_print_flow_graph_optimized)) && | 436 (optimized && FLAG_print_flow_graph_optimized)) && |
| 433 FlowGraphPrinter::ShouldPrint(function); | 437 FlowGraphPrinter::ShouldPrint(function); |
| 434 | 438 |
| 435 if (print_flow_graph) { | 439 if (print_flow_graph) { |
| 436 if (osr_id == Isolate::kNoDeoptId) { | 440 if (osr_id == Isolate::kNoDeoptId) { |
| 437 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); | 441 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1033 // We got an error during compilation. | 1037 // We got an error during compilation. |
| 1034 error = isolate->object_store()->sticky_error(); | 1038 error = isolate->object_store()->sticky_error(); |
| 1035 isolate->object_store()->clear_sticky_error(); | 1039 isolate->object_store()->clear_sticky_error(); |
| 1036 return error.raw(); | 1040 return error.raw(); |
| 1037 } | 1041 } |
| 1038 UNREACHABLE(); | 1042 UNREACHABLE(); |
| 1039 return Error::null(); | 1043 return Error::null(); |
| 1040 } | 1044 } |
| 1041 | 1045 |
| 1042 | 1046 |
| 1043 RawError* Compiler::CompileFunction(Isolate* isolate, | 1047 RawError* Compiler::CompileFunction(Thread* thread, |
| 1044 const Function& function) { | 1048 const Function& function) { |
| 1045 VMTagScope tagScope(isolate, VMTag::kCompileUnoptimizedTagId); | 1049 VMTagScope tagScope(thread->isolate(), VMTag::kCompileUnoptimizedTagId); |
| 1046 CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function); | 1050 CompilationPipeline* pipeline = |
| 1051 CompilationPipeline::New(thread->zone(), function); | |
| 1047 return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId); | 1052 return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId); |
| 1048 } | 1053 } |
| 1049 | 1054 |
| 1050 | 1055 |
| 1051 RawError* Compiler::CompileOptimizedFunction(Isolate* isolate, | 1056 RawError* Compiler::CompileOptimizedFunction(Thread* thread, |
| 1052 const Function& function, | 1057 const Function& function, |
| 1053 intptr_t osr_id) { | 1058 intptr_t osr_id) { |
| 1054 VMTagScope tagScope(isolate, VMTag::kCompileOptimizedTagId); | 1059 VMTagScope tagScope(thread->isolate(), VMTag::kCompileOptimizedTagId); |
| 1055 CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function); | 1060 CompilationPipeline* pipeline = |
| 1061 CompilationPipeline::New(thread->zone(), function); | |
| 1056 return CompileFunctionHelper(pipeline, function, true, osr_id); | 1062 return CompileFunctionHelper(pipeline, function, true, osr_id); |
| 1057 } | 1063 } |
| 1058 | 1064 |
| 1059 | 1065 |
| 1060 // This is only used from unit tests. | 1066 // This is only used from unit tests. |
| 1061 RawError* Compiler::CompileParsedFunction( | 1067 RawError* Compiler::CompileParsedFunction( |
| 1062 ParsedFunction* parsed_function) { | 1068 ParsedFunction* parsed_function) { |
| 1063 Isolate* isolate = Isolate::Current(); | 1069 Isolate* isolate = Isolate::Current(); |
| 1064 LongJumpScope jump; | 1070 LongJumpScope jump; |
| 1065 if (setjmp(*jump.Set()) == 0) { | 1071 if (setjmp(*jump.Set()) == 0) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1079 error = isolate->object_store()->sticky_error(); | 1085 error = isolate->object_store()->sticky_error(); |
| 1080 isolate->object_store()->clear_sticky_error(); | 1086 isolate->object_store()->clear_sticky_error(); |
| 1081 return error.raw(); | 1087 return error.raw(); |
| 1082 } | 1088 } |
| 1083 UNREACHABLE(); | 1089 UNREACHABLE(); |
| 1084 return Error::null(); | 1090 return Error::null(); |
| 1085 } | 1091 } |
| 1086 | 1092 |
| 1087 | 1093 |
| 1088 RawError* Compiler::CompileAllFunctions(const Class& cls) { | 1094 RawError* Compiler::CompileAllFunctions(const Class& cls) { |
| 1089 Isolate* isolate = Isolate::Current(); | 1095 Thread* thread = Thread::Current(); |
| 1090 Error& error = Error::Handle(isolate); | 1096 Zone* zone = thread->zone(); |
| 1091 Array& functions = Array::Handle(isolate, cls.functions()); | 1097 Error& error = Error::Handle(zone); |
| 1092 Function& func = Function::Handle(isolate); | 1098 Array& functions = Array::Handle(zone, cls.functions()); |
| 1099 Function& func = Function::Handle(zone); | |
| 1093 // Class dynamic lives in the vm isolate. Its array fields cannot be set to | 1100 // Class dynamic lives in the vm isolate. Its array fields cannot be set to |
| 1094 // an empty array. | 1101 // an empty array. |
| 1095 if (functions.IsNull()) { | 1102 if (functions.IsNull()) { |
| 1096 ASSERT(cls.IsDynamicClass()); | 1103 ASSERT(cls.IsDynamicClass()); |
| 1097 return error.raw(); | 1104 return error.raw(); |
| 1098 } | 1105 } |
| 1099 // Compile all the regular functions. | 1106 // Compile all the regular functions. |
| 1100 for (int i = 0; i < functions.Length(); i++) { | 1107 for (int i = 0; i < functions.Length(); i++) { |
| 1101 func ^= functions.At(i); | 1108 func ^= functions.At(i); |
| 1102 ASSERT(!func.IsNull()); | 1109 ASSERT(!func.IsNull()); |
| 1103 if (!func.HasCode() && | 1110 if (!func.HasCode() && |
| 1104 !func.is_abstract() && | 1111 !func.is_abstract() && |
| 1105 !func.IsRedirectingFactory()) { | 1112 !func.IsRedirectingFactory()) { |
| 1106 error = CompileFunction(isolate, func); | 1113 error = CompileFunction(thread, func); |
| 1107 if (!error.IsNull()) { | 1114 if (!error.IsNull()) { |
| 1108 return error.raw(); | 1115 return error.raw(); |
| 1109 } | 1116 } |
| 1110 func.ClearCode(); | 1117 func.ClearCode(); |
| 1111 } | 1118 } |
| 1112 } | 1119 } |
| 1113 // Inner functions get added to the closures array. As part of compilation | 1120 // Inner functions get added to the closures array. As part of compilation |
| 1114 // more closures can be added to the end of the array. Compile all the | 1121 // more closures can be added to the end of the array. Compile all the |
| 1115 // closures until we have reached the end of the "worklist". | 1122 // closures until we have reached the end of the "worklist". |
| 1116 GrowableObjectArray& closures = | 1123 GrowableObjectArray& closures = |
| 1117 GrowableObjectArray::Handle(isolate, cls.closures()); | 1124 GrowableObjectArray::Handle(zone, cls.closures()); |
| 1118 if (!closures.IsNull()) { | 1125 if (!closures.IsNull()) { |
| 1119 for (int i = 0; i < closures.Length(); i++) { | 1126 for (int i = 0; i < closures.Length(); i++) { |
| 1120 func ^= closures.At(i); | 1127 func ^= closures.At(i); |
| 1121 if (!func.HasCode()) { | 1128 if (!func.HasCode()) { |
| 1122 error = CompileFunction(isolate, func); | 1129 error = CompileFunction(thread, func); |
| 1123 if (!error.IsNull()) { | 1130 if (!error.IsNull()) { |
| 1124 return error.raw(); | 1131 return error.raw(); |
| 1125 } | 1132 } |
| 1126 func.ClearCode(); | 1133 func.ClearCode(); |
| 1127 } | 1134 } |
| 1128 } | 1135 } |
| 1129 } | 1136 } |
| 1130 return error.raw(); | 1137 return error.raw(); |
| 1131 } | 1138 } |
| 1132 | 1139 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1225 const Object& result = | 1232 const Object& result = |
| 1226 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1233 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1227 isolate->object_store()->clear_sticky_error(); | 1234 isolate->object_store()->clear_sticky_error(); |
| 1228 return result.raw(); | 1235 return result.raw(); |
| 1229 } | 1236 } |
| 1230 UNREACHABLE(); | 1237 UNREACHABLE(); |
| 1231 return Object::null(); | 1238 return Object::null(); |
| 1232 } | 1239 } |
| 1233 | 1240 |
| 1234 } // namespace dart | 1241 } // namespace dart |
| OLD | NEW |