Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: runtime/vm/compiler.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/compiler_stats.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); 101 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
102 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); 102 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
103 DEFINE_FLAG(bool, 103 DEFINE_FLAG(bool,
104 verify_compiler, 104 verify_compiler,
105 false, 105 false,
106 "Enable compiler verification assertions"); 106 "Enable compiler verification assertions");
107 107
108 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); 108 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
109 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 109 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
110 110
111
112 #ifndef DART_PRECOMPILED_RUNTIME 111 #ifndef DART_PRECOMPILED_RUNTIME
113 112
114
115 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { 113 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
116 const Function& function = parsed_function->function(); 114 const Function& function = parsed_function->function();
117 return (function.kernel_offset() > 0) || 115 return (function.kernel_offset() > 0) ||
118 (function.kind() == RawFunction::kNoSuchMethodDispatcher) || 116 (function.kind() == RawFunction::kNoSuchMethodDispatcher) ||
119 (function.kind() == RawFunction::kInvokeFieldDispatcher); 117 (function.kind() == RawFunction::kInvokeFieldDispatcher);
120 } 118 }
121 119
122
123 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { 120 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) {
124 if (!UseKernelFrontEndFor(parsed_function)) { 121 if (!UseKernelFrontEndFor(parsed_function)) {
125 Parser::ParseFunction(parsed_function); 122 Parser::ParseFunction(parsed_function);
126 parsed_function->AllocateVariables(); 123 parsed_function->AllocateVariables();
127 } 124 }
128 } 125 }
129 126
130
131 FlowGraph* DartCompilationPipeline::BuildFlowGraph( 127 FlowGraph* DartCompilationPipeline::BuildFlowGraph(
132 Zone* zone, 128 Zone* zone,
133 ParsedFunction* parsed_function, 129 ParsedFunction* parsed_function,
134 const ZoneGrowableArray<const ICData*>& ic_data_array, 130 const ZoneGrowableArray<const ICData*>& ic_data_array,
135 intptr_t osr_id) { 131 intptr_t osr_id) {
136 if (UseKernelFrontEndFor(parsed_function)) { 132 if (UseKernelFrontEndFor(parsed_function)) {
137 kernel::FlowGraphBuilder builder( 133 kernel::FlowGraphBuilder builder(
138 parsed_function->function().kernel_offset(), parsed_function, 134 parsed_function->function().kernel_offset(), parsed_function,
139 ic_data_array, 135 ic_data_array,
140 /* not building var desc */ NULL, 136 /* not building var desc */ NULL,
141 /* not inlining */ NULL, osr_id); 137 /* not inlining */ NULL, osr_id);
142 FlowGraph* graph = builder.BuildGraph(); 138 FlowGraph* graph = builder.BuildGraph();
143 ASSERT(graph != NULL); 139 ASSERT(graph != NULL);
144 return graph; 140 return graph;
145 } 141 }
146 FlowGraphBuilder builder(*parsed_function, ic_data_array, 142 FlowGraphBuilder builder(*parsed_function, ic_data_array,
147 /* not building var desc */ NULL, 143 /* not building var desc */ NULL,
148 /* not inlining */ NULL, osr_id); 144 /* not inlining */ NULL, osr_id);
149 145
150 return builder.BuildGraph(); 146 return builder.BuildGraph();
151 } 147 }
152 148
153
154 void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {} 149 void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {}
155 150
156
157 void IrregexpCompilationPipeline::ParseFunction( 151 void IrregexpCompilationPipeline::ParseFunction(
158 ParsedFunction* parsed_function) { 152 ParsedFunction* parsed_function) {
159 VMTagScope tagScope(parsed_function->thread(), 153 VMTagScope tagScope(parsed_function->thread(),
160 VMTag::kCompileParseRegExpTagId); 154 VMTag::kCompileParseRegExpTagId);
161 Zone* zone = parsed_function->zone(); 155 Zone* zone = parsed_function->zone();
162 RegExp& regexp = RegExp::Handle(parsed_function->function().regexp()); 156 RegExp& regexp = RegExp::Handle(parsed_function->function().regexp());
163 157
164 const String& pattern = String::Handle(regexp.pattern()); 158 const String& pattern = String::Handle(regexp.pattern());
165 const bool multiline = regexp.is_multi_line(); 159 const bool multiline = regexp.is_multi_line();
166 160
167 RegExpCompileData* compile_data = new (zone) RegExpCompileData(); 161 RegExpCompileData* compile_data = new (zone) RegExpCompileData();
168 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) { 162 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) {
169 // Parsing failures are handled in the RegExp factory constructor. 163 // Parsing failures are handled in the RegExp factory constructor.
170 UNREACHABLE(); 164 UNREACHABLE();
171 } 165 }
172 166
173 regexp.set_num_bracket_expressions(compile_data->capture_count); 167 regexp.set_num_bracket_expressions(compile_data->capture_count);
174 if (compile_data->simple) { 168 if (compile_data->simple) {
175 regexp.set_is_simple(); 169 regexp.set_is_simple();
176 } else { 170 } else {
177 regexp.set_is_complex(); 171 regexp.set_is_complex();
178 } 172 }
179 173
180 parsed_function->SetRegExpCompileData(compile_data); 174 parsed_function->SetRegExpCompileData(compile_data);
181 175
182 // Variables are allocated after compilation. 176 // Variables are allocated after compilation.
183 } 177 }
184 178
185
186 FlowGraph* IrregexpCompilationPipeline::BuildFlowGraph( 179 FlowGraph* IrregexpCompilationPipeline::BuildFlowGraph(
187 Zone* zone, 180 Zone* zone,
188 ParsedFunction* parsed_function, 181 ParsedFunction* parsed_function,
189 const ZoneGrowableArray<const ICData*>& ic_data_array, 182 const ZoneGrowableArray<const ICData*>& ic_data_array,
190 intptr_t osr_id) { 183 intptr_t osr_id) {
191 // Compile to the dart IR. 184 // Compile to the dart IR.
192 RegExpEngine::CompilationResult result = 185 RegExpEngine::CompilationResult result =
193 RegExpEngine::CompileIR(parsed_function->regexp_compile_data(), 186 RegExpEngine::CompileIR(parsed_function->regexp_compile_data(),
194 parsed_function, ic_data_array, osr_id); 187 parsed_function, ic_data_array, osr_id);
195 backtrack_goto_ = result.backtrack_goto; 188 backtrack_goto_ = result.backtrack_goto;
196 189
197 // Allocate variables now that we know the number of locals. 190 // Allocate variables now that we know the number of locals.
198 parsed_function->AllocateIrregexpVariables(result.num_stack_locals); 191 parsed_function->AllocateIrregexpVariables(result.num_stack_locals);
199 192
200 // When compiling for OSR, use a depth first search to find the OSR 193 // When compiling for OSR, use a depth first search to find the OSR
201 // entry and make graph entry jump to it instead of normal entry. 194 // entry and make graph entry jump to it instead of normal entry.
202 // Catch entries are always considered reachable, even if they 195 // Catch entries are always considered reachable, even if they
203 // become unreachable after OSR. 196 // become unreachable after OSR.
204 if (osr_id != Compiler::kNoOSRDeoptId) { 197 if (osr_id != Compiler::kNoOSRDeoptId) {
205 result.graph_entry->RelinkToOsrEntry(zone, result.num_blocks); 198 result.graph_entry->RelinkToOsrEntry(zone, result.num_blocks);
206 } 199 }
207 200
208 return new (zone) 201 return new (zone)
209 FlowGraph(*parsed_function, result.graph_entry, result.num_blocks); 202 FlowGraph(*parsed_function, result.graph_entry, result.num_blocks);
210 } 203 }
211 204
212
213 void IrregexpCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) { 205 void IrregexpCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {
214 backtrack_goto_->ComputeOffsetTable(); 206 backtrack_goto_->ComputeOffsetTable();
215 } 207 }
216 208
217
218 CompilationPipeline* CompilationPipeline::New(Zone* zone, 209 CompilationPipeline* CompilationPipeline::New(Zone* zone,
219 const Function& function) { 210 const Function& function) {
220 if (function.IsIrregexpFunction()) { 211 if (function.IsIrregexpFunction()) {
221 return new (zone) IrregexpCompilationPipeline(); 212 return new (zone) IrregexpCompilationPipeline();
222 } else { 213 } else {
223 return new (zone) DartCompilationPipeline(); 214 return new (zone) DartCompilationPipeline();
224 } 215 }
225 } 216 }
226 217
227
228 // Compile a function. Should call only if the function has not been compiled. 218 // Compile a function. Should call only if the function has not been compiled.
229 // Arg0: function object. 219 // Arg0: function object.
230 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { 220 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
231 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 221 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
232 ASSERT(!function.HasCode()); 222 ASSERT(!function.HasCode());
233 const Object& result = 223 const Object& result =
234 Object::Handle(Compiler::CompileFunction(thread, function)); 224 Object::Handle(Compiler::CompileFunction(thread, function));
235 if (result.IsError()) { 225 if (result.IsError()) {
236 if (result.IsLanguageError()) { 226 if (result.IsLanguageError()) {
237 Exceptions::ThrowCompileTimeError(LanguageError::Cast(result)); 227 Exceptions::ThrowCompileTimeError(LanguageError::Cast(result));
238 UNREACHABLE(); 228 UNREACHABLE();
239 } 229 }
240 Exceptions::PropagateError(Error::Cast(result)); 230 Exceptions::PropagateError(Error::Cast(result));
241 } 231 }
242 } 232 }
243 233
244
245 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) { 234 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
246 if (FLAG_support_debugger) { 235 if (FLAG_support_debugger) {
247 Isolate* isolate = thread->isolate(); 236 Isolate* isolate = thread->isolate();
248 if (isolate->debugger()->IsStepping() || 237 if (isolate->debugger()->IsStepping() ||
249 isolate->debugger()->HasBreakpoint(function, thread->zone())) { 238 isolate->debugger()->HasBreakpoint(function, thread->zone())) {
250 // We cannot set breakpoints and single step in optimized code, 239 // We cannot set breakpoints and single step in optimized code,
251 // so do not optimize the function. 240 // so do not optimize the function.
252 function.set_usage_counter(0); 241 function.set_usage_counter(0);
253 return false; 242 return false;
254 } 243 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // non-optimizable only after the code has been generated. 286 // non-optimizable only after the code has been generated.
298 if (FLAG_trace_failed_optimization_attempts) { 287 if (FLAG_trace_failed_optimization_attempts) {
299 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString()); 288 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString());
300 } 289 }
301 function.set_usage_counter(INT_MIN); 290 function.set_usage_counter(INT_MIN);
302 return false; 291 return false;
303 } 292 }
304 return true; 293 return true;
305 } 294 }
306 295
307
308 bool Compiler::IsBackgroundCompilation() { 296 bool Compiler::IsBackgroundCompilation() {
309 // For now: compilation in non mutator thread is the background compoilation. 297 // For now: compilation in non mutator thread is the background compoilation.
310 return !Thread::Current()->IsMutatorThread(); 298 return !Thread::Current()->IsMutatorThread();
311 } 299 }
312 300
313
314 RawError* Compiler::Compile(const Library& library, const Script& script) { 301 RawError* Compiler::Compile(const Library& library, const Script& script) {
315 LongJumpScope jump; 302 LongJumpScope jump;
316 if (setjmp(*jump.Set()) == 0) { 303 if (setjmp(*jump.Set()) == 0) {
317 Thread* const thread = Thread::Current(); 304 Thread* const thread = Thread::Current();
318 StackZone zone(thread); 305 StackZone zone(thread);
319 if (FLAG_trace_compiler) { 306 if (FLAG_trace_compiler) {
320 const String& script_url = String::Handle(script.url()); 307 const String& script_url = String::Handle(script.url());
321 // TODO(iposva): Extract script kind. 308 // TODO(iposva): Extract script kind.
322 THR_Print("Compiling %s '%s'\n", "", script_url.ToCString()); 309 THR_Print("Compiling %s '%s'\n", "", script_url.ToCString());
323 } 310 }
324 const String& library_key = String::Handle(library.private_key()); 311 const String& library_key = String::Handle(library.private_key());
325 script.Tokenize(library_key); 312 script.Tokenize(library_key);
326 Parser::ParseCompilationUnit(library, script); 313 Parser::ParseCompilationUnit(library, script);
327 return Error::null(); 314 return Error::null();
328 } else { 315 } else {
329 Thread* const thread = Thread::Current(); 316 Thread* const thread = Thread::Current();
330 StackZone zone(thread); 317 StackZone zone(thread);
331 Error& error = Error::Handle(); 318 Error& error = Error::Handle();
332 error = thread->sticky_error(); 319 error = thread->sticky_error();
333 thread->clear_sticky_error(); 320 thread->clear_sticky_error();
334 return error.raw(); 321 return error.raw();
335 } 322 }
336 UNREACHABLE(); 323 UNREACHABLE();
337 return Error::null(); 324 return Error::null();
338 } 325 }
339 326
340
341 static void AddRelatedClassesToList( 327 static void AddRelatedClassesToList(
342 const Class& cls, 328 const Class& cls,
343 GrowableHandlePtrArray<const Class>* parse_list, 329 GrowableHandlePtrArray<const Class>* parse_list,
344 GrowableHandlePtrArray<const Class>* patch_list) { 330 GrowableHandlePtrArray<const Class>* patch_list) {
345 Zone* zone = Thread::Current()->zone(); 331 Zone* zone = Thread::Current()->zone();
346 Class& parse_class = Class::Handle(zone); 332 Class& parse_class = Class::Handle(zone);
347 AbstractType& interface_type = Type::Handle(zone); 333 AbstractType& interface_type = Type::Handle(zone);
348 Array& interfaces = Array::Handle(zone); 334 Array& interfaces = Array::Handle(zone);
349 335
350 // Add all the interfaces implemented by the class that have not been 336 // Add all the interfaces implemented by the class that have not been
(...skipping 26 matching lines...) Expand all
377 // recursively add it back into the list. 363 // recursively add it back into the list.
378 parse_class ^= cls.GetPatchClass(); 364 parse_class ^= cls.GetPatchClass();
379 if (!parse_class.IsNull()) { 365 if (!parse_class.IsNull()) {
380 if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) { 366 if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
381 patch_list->Add(parse_class); 367 patch_list->Add(parse_class);
382 parse_class.set_is_marked_for_parsing(); 368 parse_class.set_is_marked_for_parsing();
383 } 369 }
384 } 370 }
385 } 371 }
386 372
387
388 RawError* Compiler::CompileClass(const Class& cls) { 373 RawError* Compiler::CompileClass(const Class& cls) {
389 ASSERT(Thread::Current()->IsMutatorThread()); 374 ASSERT(Thread::Current()->IsMutatorThread());
390 // If class is a top level class it is already parsed. 375 // If class is a top level class it is already parsed.
391 if (cls.IsTopLevel()) { 376 if (cls.IsTopLevel()) {
392 return Error::null(); 377 return Error::null();
393 } 378 }
394 // If the class is already marked for parsing return immediately. 379 // If the class is already marked for parsing return immediately.
395 if (cls.is_marked_for_parsing()) { 380 if (cls.is_marked_for_parsing()) {
396 return Error::null(); 381 return Error::null();
397 } 382 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 Thread* thread = Thread::Current(); 488 Thread* thread = Thread::Current();
504 Error& error = Error::Handle(thread->zone()); 489 Error& error = Error::Handle(thread->zone());
505 error = thread->sticky_error(); 490 error = thread->sticky_error();
506 thread->clear_sticky_error(); 491 thread->clear_sticky_error();
507 return error.raw(); 492 return error.raw();
508 } 493 }
509 UNREACHABLE(); 494 UNREACHABLE();
510 return Error::null(); 495 return Error::null();
511 } 496 }
512 497
513
514 class CompileParsedFunctionHelper : public ValueObject { 498 class CompileParsedFunctionHelper : public ValueObject {
515 public: 499 public:
516 CompileParsedFunctionHelper(ParsedFunction* parsed_function, 500 CompileParsedFunctionHelper(ParsedFunction* parsed_function,
517 bool optimized, 501 bool optimized,
518 intptr_t osr_id) 502 intptr_t osr_id)
519 : parsed_function_(parsed_function), 503 : parsed_function_(parsed_function),
520 optimized_(optimized), 504 optimized_(optimized),
521 osr_id_(osr_id), 505 osr_id_(osr_id),
522 thread_(Thread::Current()), 506 thread_(Thread::Current()),
523 loading_invalidation_gen_at_start_( 507 loading_invalidation_gen_at_start_(
(...skipping 17 matching lines...) Expand all
541 525
542 ParsedFunction* parsed_function_; 526 ParsedFunction* parsed_function_;
543 const bool optimized_; 527 const bool optimized_;
544 const intptr_t osr_id_; 528 const intptr_t osr_id_;
545 Thread* const thread_; 529 Thread* const thread_;
546 const intptr_t loading_invalidation_gen_at_start_; 530 const intptr_t loading_invalidation_gen_at_start_;
547 531
548 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); 532 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
549 }; 533 };
550 534
551
552 RawCode* CompileParsedFunctionHelper::FinalizeCompilation( 535 RawCode* CompileParsedFunctionHelper::FinalizeCompilation(
553 Assembler* assembler, 536 Assembler* assembler,
554 FlowGraphCompiler* graph_compiler, 537 FlowGraphCompiler* graph_compiler,
555 FlowGraph* flow_graph) { 538 FlowGraph* flow_graph) {
556 ASSERT(!FLAG_precompiled_mode); 539 ASSERT(!FLAG_precompiled_mode);
557 const Function& function = parsed_function()->function(); 540 const Function& function = parsed_function()->function();
558 Zone* const zone = thread()->zone(); 541 Zone* const zone = thread()->zone();
559 542
560 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); 543 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer);
561 // CreateDeoptInfo uses the object pool and needs to be done before 544 // CreateDeoptInfo uses the object pool and needs to be done before
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 ASSERT(!FLAG_load_deferred_eagerly); 690 ASSERT(!FLAG_load_deferred_eagerly);
708 ZoneGrowableArray<const LibraryPrefix*>* prefixes = 691 ZoneGrowableArray<const LibraryPrefix*>* prefixes =
709 parsed_function()->deferred_prefixes(); 692 parsed_function()->deferred_prefixes();
710 for (intptr_t i = 0; i < prefixes->length(); i++) { 693 for (intptr_t i = 0; i < prefixes->length(); i++) {
711 (*prefixes)[i]->RegisterDependentCode(code); 694 (*prefixes)[i]->RegisterDependentCode(code);
712 } 695 }
713 } 696 }
714 return code.raw(); 697 return code.raw();
715 } 698 }
716 699
717
718 void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() { 700 void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() {
719 ASSERT(Compiler::IsBackgroundCompilation()); 701 ASSERT(Compiler::IsBackgroundCompilation());
720 if (!isolate()->background_compiler()->is_running()) { 702 if (!isolate()->background_compiler()->is_running()) {
721 // The background compiler is being stopped. 703 // The background compiler is being stopped.
722 Compiler::AbortBackgroundCompilation( 704 Compiler::AbortBackgroundCompilation(
723 Thread::kNoDeoptId, "Background compilation is being stopped"); 705 Thread::kNoDeoptId, "Background compilation is being stopped");
724 } 706 }
725 } 707 }
726 708
727
728 // Return null if bailed out. 709 // Return null if bailed out.
729 // If optimized_result_code is not NULL then it is caller's responsibility 710 // If optimized_result_code is not NULL then it is caller's responsibility
730 // to install code. 711 // to install code.
731 RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { 712 RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
732 ASSERT(!FLAG_precompiled_mode); 713 ASSERT(!FLAG_precompiled_mode);
733 const Function& function = parsed_function()->function(); 714 const Function& function = parsed_function()->function();
734 if (optimized() && !function.IsOptimizable()) { 715 if (optimized() && !function.IsOptimizable()) {
735 return Code::null(); 716 return Code::null();
736 } 717 }
737 Zone* const zone = thread()->zone(); 718 Zone* const zone = thread()->zone();
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 (LanguageError::Cast(error).kind() == Report::kBailout)) { 1214 (LanguageError::Cast(error).kind() == Report::kBailout)) {
1234 thread()->clear_sticky_error(); 1215 thread()->clear_sticky_error();
1235 } 1216 }
1236 } 1217 }
1237 // Reset global isolate state. 1218 // Reset global isolate state.
1238 thread()->set_deopt_id(prev_deopt_id); 1219 thread()->set_deopt_id(prev_deopt_id);
1239 } 1220 }
1240 return result->raw(); 1221 return result->raw();
1241 } 1222 }
1242 1223
1243
1244 static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline, 1224 static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
1245 const Function& function, 1225 const Function& function,
1246 bool optimized, 1226 bool optimized,
1247 intptr_t osr_id) { 1227 intptr_t osr_id) {
1248 ASSERT(!FLAG_precompiled_mode); 1228 ASSERT(!FLAG_precompiled_mode);
1249 ASSERT(!optimized || function.was_compiled()); 1229 ASSERT(!optimized || function.was_compiled());
1250 LongJumpScope jump; 1230 LongJumpScope jump;
1251 if (setjmp(*jump.Set()) == 0) { 1231 if (setjmp(*jump.Set()) == 0) {
1252 Thread* const thread = Thread::Current(); 1232 Thread* const thread = Thread::Current();
1253 Isolate* const isolate = thread->isolate(); 1233 Isolate* const isolate = thread->isolate();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 return Object::null(); 1379 return Object::null();
1400 } 1380 }
1401 // Do not attempt to optimize functions that can cause errors. 1381 // Do not attempt to optimize functions that can cause errors.
1402 function.set_is_optimizable(false); 1382 function.set_is_optimizable(false);
1403 return error.raw(); 1383 return error.raw();
1404 } 1384 }
1405 UNREACHABLE(); 1385 UNREACHABLE();
1406 return Object::null(); 1386 return Object::null();
1407 } 1387 }
1408 1388
1409
1410 static RawError* ParseFunctionHelper(CompilationPipeline* pipeline, 1389 static RawError* ParseFunctionHelper(CompilationPipeline* pipeline,
1411 const Function& function, 1390 const Function& function,
1412 bool optimized, 1391 bool optimized,
1413 intptr_t osr_id) { 1392 intptr_t osr_id) {
1414 ASSERT(!FLAG_precompiled_mode); 1393 ASSERT(!FLAG_precompiled_mode);
1415 ASSERT(!optimized || function.was_compiled()); 1394 ASSERT(!optimized || function.was_compiled());
1416 LongJumpScope jump; 1395 LongJumpScope jump;
1417 if (setjmp(*jump.Set()) == 0) { 1396 if (setjmp(*jump.Set()) == 0) {
1418 Thread* const thread = Thread::Current(); 1397 Thread* const thread = Thread::Current();
1419 StackZone stack_zone(thread); 1398 StackZone stack_zone(thread);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 thread->clear_sticky_error(); 1435 thread->clear_sticky_error();
1457 // Unoptimized compilation or precompilation may encounter compile-time 1436 // Unoptimized compilation or precompilation may encounter compile-time
1458 // errors, but regular optimized compilation should not. 1437 // errors, but regular optimized compilation should not.
1459 ASSERT(!optimized); 1438 ASSERT(!optimized);
1460 return error.raw(); 1439 return error.raw();
1461 } 1440 }
1462 UNREACHABLE(); 1441 UNREACHABLE();
1463 return Error::null(); 1442 return Error::null();
1464 } 1443 }
1465 1444
1466
1467 RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) { 1445 RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
1468 #ifdef DART_PRECOMPILER 1446 #ifdef DART_PRECOMPILER
1469 if (FLAG_precompiled_mode) { 1447 if (FLAG_precompiled_mode) {
1470 return Precompiler::CompileFunction( 1448 return Precompiler::CompileFunction(
1471 /* precompiler = */ NULL, thread, thread->zone(), function); 1449 /* precompiler = */ NULL, thread, thread->zone(), function);
1472 } 1450 }
1473 #endif 1451 #endif
1474 1452
1475 Isolate* isolate = thread->isolate(); 1453 Isolate* isolate = thread->isolate();
1476 1454
1477 #if !defined(PRODUCT) 1455 #if !defined(PRODUCT)
1478 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); 1456 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
1479 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); 1457 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
1480 #endif // !defined(PRODUCT) 1458 #endif // !defined(PRODUCT)
1481 1459
1482 if (!isolate->compilation_allowed()) { 1460 if (!isolate->compilation_allowed()) {
1483 FATAL3("Precompilation missed function %s (%s, %s)\n", 1461 FATAL3("Precompilation missed function %s (%s, %s)\n",
1484 function.ToLibNamePrefixedQualifiedCString(), 1462 function.ToLibNamePrefixedQualifiedCString(),
1485 function.token_pos().ToCString(), 1463 function.token_pos().ToCString(),
1486 Function::KindToCString(function.kind())); 1464 Function::KindToCString(function.kind()));
1487 } 1465 }
1488 1466
1489 CompilationPipeline* pipeline = 1467 CompilationPipeline* pipeline =
1490 CompilationPipeline::New(thread->zone(), function); 1468 CompilationPipeline::New(thread->zone(), function);
1491 1469
1492 return CompileFunctionHelper(pipeline, function, 1470 return CompileFunctionHelper(pipeline, function,
1493 /* optimized = */ false, kNoOSRDeoptId); 1471 /* optimized = */ false, kNoOSRDeoptId);
1494 } 1472 }
1495 1473
1496
1497 RawError* Compiler::ParseFunction(Thread* thread, const Function& function) { 1474 RawError* Compiler::ParseFunction(Thread* thread, const Function& function) {
1498 Isolate* isolate = thread->isolate(); 1475 Isolate* isolate = thread->isolate();
1499 #if !defined(PRODUCT) 1476 #if !defined(PRODUCT)
1500 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); 1477 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
1501 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function); 1478 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function);
1502 #endif // !defined(PRODUCT) 1479 #endif // !defined(PRODUCT)
1503 1480
1504 if (!isolate->compilation_allowed()) { 1481 if (!isolate->compilation_allowed()) {
1505 FATAL3("Precompilation missed function %s (%s, %s)\n", 1482 FATAL3("Precompilation missed function %s (%s, %s)\n",
1506 function.ToLibNamePrefixedQualifiedCString(), 1483 function.ToLibNamePrefixedQualifiedCString(),
1507 function.token_pos().ToCString(), 1484 function.token_pos().ToCString(),
1508 Function::KindToCString(function.kind())); 1485 Function::KindToCString(function.kind()));
1509 } 1486 }
1510 1487
1511 CompilationPipeline* pipeline = 1488 CompilationPipeline* pipeline =
1512 CompilationPipeline::New(thread->zone(), function); 1489 CompilationPipeline::New(thread->zone(), function);
1513 1490
1514 return ParseFunctionHelper(pipeline, function, 1491 return ParseFunctionHelper(pipeline, function,
1515 /* optimized = */ false, kNoOSRDeoptId); 1492 /* optimized = */ false, kNoOSRDeoptId);
1516 } 1493 }
1517 1494
1518
1519 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, 1495 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
1520 const Function& function) { 1496 const Function& function) {
1521 if (function.unoptimized_code() != Object::null()) { 1497 if (function.unoptimized_code() != Object::null()) {
1522 return Error::null(); 1498 return Error::null();
1523 } 1499 }
1524 Code& original_code = Code::ZoneHandle(thread->zone()); 1500 Code& original_code = Code::ZoneHandle(thread->zone());
1525 if (function.HasCode()) { 1501 if (function.HasCode()) {
1526 original_code = function.CurrentCode(); 1502 original_code = function.CurrentCode();
1527 } 1503 }
1528 CompilationPipeline* pipeline = 1504 CompilationPipeline* pipeline =
(...skipping 11 matching lines...) Expand all
1540 function.AttachCode(original_code); 1516 function.AttachCode(original_code);
1541 } 1517 }
1542 ASSERT(function.unoptimized_code() != Object::null()); 1518 ASSERT(function.unoptimized_code() != Object::null());
1543 ASSERT(function.unoptimized_code() == result.raw()); 1519 ASSERT(function.unoptimized_code() == result.raw());
1544 if (FLAG_trace_compiler) { 1520 if (FLAG_trace_compiler) {
1545 THR_Print("Ensure unoptimized code for %s\n", function.ToCString()); 1521 THR_Print("Ensure unoptimized code for %s\n", function.ToCString());
1546 } 1522 }
1547 return Error::null(); 1523 return Error::null();
1548 } 1524 }
1549 1525
1550
1551 RawObject* Compiler::CompileOptimizedFunction(Thread* thread, 1526 RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
1552 const Function& function, 1527 const Function& function,
1553 intptr_t osr_id) { 1528 intptr_t osr_id) {
1554 #if !defined(PRODUCT) 1529 #if !defined(PRODUCT)
1555 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); 1530 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
1556 const char* event_name; 1531 const char* event_name;
1557 if (osr_id != kNoOSRDeoptId) { 1532 if (osr_id != kNoOSRDeoptId) {
1558 event_name = "CompileFunctionOptimizedOSR"; 1533 event_name = "CompileFunctionOptimizedOSR";
1559 } else if (IsBackgroundCompilation()) { 1534 } else if (IsBackgroundCompilation()) {
1560 event_name = "CompileFunctionOptimizedBackground"; 1535 event_name = "CompileFunctionOptimizedBackground";
1561 } else { 1536 } else {
1562 event_name = "CompileFunctionOptimized"; 1537 event_name = "CompileFunctionOptimized";
1563 } 1538 }
1564 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, event_name, function); 1539 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, event_name, function);
1565 #endif // !defined(PRODUCT) 1540 #endif // !defined(PRODUCT)
1566 1541
1567 // If we are in the optimizing in the mutator/Dart thread, then 1542 // If we are in the optimizing in the mutator/Dart thread, then
1568 // this is either an OSR compilation or background compilation is 1543 // this is either an OSR compilation or background compilation is
1569 // not currently allowed. 1544 // not currently allowed.
1570 ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) || 1545 ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) ||
1571 !FLAG_background_compilation || BackgroundCompiler::IsDisabled()); 1546 !FLAG_background_compilation || BackgroundCompiler::IsDisabled());
1572 CompilationPipeline* pipeline = 1547 CompilationPipeline* pipeline =
1573 CompilationPipeline::New(thread->zone(), function); 1548 CompilationPipeline::New(thread->zone(), function);
1574 return CompileFunctionHelper(pipeline, function, true, /* optimized */ 1549 return CompileFunctionHelper(pipeline, function, true, /* optimized */
1575 osr_id); 1550 osr_id);
1576 } 1551 }
1577 1552
1578
1579 // This is only used from unit tests. 1553 // This is only used from unit tests.
1580 RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) { 1554 RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) {
1581 LongJumpScope jump; 1555 LongJumpScope jump;
1582 if (setjmp(*jump.Set()) == 0) { 1556 if (setjmp(*jump.Set()) == 0) {
1583 // Non-optimized code generator. 1557 // Non-optimized code generator.
1584 DartCompilationPipeline pipeline; 1558 DartCompilationPipeline pipeline;
1585 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); 1559 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
1586 helper.Compile(&pipeline); 1560 helper.Compile(&pipeline);
1587 if (FLAG_disassemble) { 1561 if (FLAG_disassemble) {
1588 Code& code = Code::Handle(parsed_function->function().CurrentCode()); 1562 Code& code = Code::Handle(parsed_function->function().CurrentCode());
1589 Disassembler::DisassembleCode(parsed_function->function(), code, false); 1563 Disassembler::DisassembleCode(parsed_function->function(), code, false);
1590 } 1564 }
1591 return Error::null(); 1565 return Error::null();
1592 } else { 1566 } else {
1593 Error& error = Error::Handle(); 1567 Error& error = Error::Handle();
1594 Thread* thread = Thread::Current(); 1568 Thread* thread = Thread::Current();
1595 // We got an error during compilation. 1569 // We got an error during compilation.
1596 error = thread->sticky_error(); 1570 error = thread->sticky_error();
1597 thread->clear_sticky_error(); 1571 thread->clear_sticky_error();
1598 return error.raw(); 1572 return error.raw();
1599 } 1573 }
1600 UNREACHABLE(); 1574 UNREACHABLE();
1601 return Error::null(); 1575 return Error::null();
1602 } 1576 }
1603 1577
1604
1605 void Compiler::ComputeLocalVarDescriptors(const Code& code) { 1578 void Compiler::ComputeLocalVarDescriptors(const Code& code) {
1606 ASSERT(!code.is_optimized()); 1579 ASSERT(!code.is_optimized());
1607 const Function& function = Function::Handle(code.function()); 1580 const Function& function = Function::Handle(code.function());
1608 ParsedFunction* parsed_function = new ParsedFunction( 1581 ParsedFunction* parsed_function = new ParsedFunction(
1609 Thread::Current(), Function::ZoneHandle(function.raw())); 1582 Thread::Current(), Function::ZoneHandle(function.raw()));
1610 ASSERT(code.var_descriptors() == Object::null()); 1583 ASSERT(code.var_descriptors() == Object::null());
1611 // IsIrregexpFunction have eager var descriptors generation. 1584 // IsIrregexpFunction have eager var descriptors generation.
1612 ASSERT(!function.IsIrregexpFunction()); 1585 ASSERT(!function.IsIrregexpFunction());
1613 // In background compilation, parser can produce 'errors": bailouts 1586 // In background compilation, parser can produce 'errors": bailouts
1614 // if state changed while compiling in background. 1587 // if state changed while compiling in background.
(...skipping 27 matching lines...) Expand all
1642 function, context_level_array)); 1615 function, context_level_array));
1643 ASSERT(!var_descs.IsNull()); 1616 ASSERT(!var_descs.IsNull());
1644 code.set_var_descriptors(var_descs); 1617 code.set_var_descriptors(var_descs);
1645 } else { 1618 } else {
1646 // Only possible with background compilation. 1619 // Only possible with background compilation.
1647 ASSERT(Compiler::IsBackgroundCompilation()); 1620 ASSERT(Compiler::IsBackgroundCompilation());
1648 } 1621 }
1649 Thread::Current()->set_deopt_id(prev_deopt_id); 1622 Thread::Current()->set_deopt_id(prev_deopt_id);
1650 } 1623 }
1651 1624
1652
1653 RawError* Compiler::CompileAllFunctions(const Class& cls) { 1625 RawError* Compiler::CompileAllFunctions(const Class& cls) {
1654 Thread* thread = Thread::Current(); 1626 Thread* thread = Thread::Current();
1655 Zone* zone = thread->zone(); 1627 Zone* zone = thread->zone();
1656 Object& result = Object::Handle(zone); 1628 Object& result = Object::Handle(zone);
1657 Array& functions = Array::Handle(zone, cls.functions()); 1629 Array& functions = Array::Handle(zone, cls.functions());
1658 Function& func = Function::Handle(zone); 1630 Function& func = Function::Handle(zone);
1659 // Class dynamic lives in the vm isolate. Its array fields cannot be set to 1631 // Class dynamic lives in the vm isolate. Its array fields cannot be set to
1660 // an empty array. 1632 // an empty array.
1661 if (functions.IsNull()) { 1633 if (functions.IsNull()) {
1662 ASSERT(cls.IsDynamicClass()); 1634 ASSERT(cls.IsDynamicClass());
(...skipping 15 matching lines...) Expand all
1678 return Error::Cast(result).raw(); 1650 return Error::Cast(result).raw();
1679 } 1651 }
1680 ASSERT(!result.IsNull()); 1652 ASSERT(!result.IsNull());
1681 func.ClearICDataArray(); 1653 func.ClearICDataArray();
1682 func.ClearCode(); 1654 func.ClearCode();
1683 } 1655 }
1684 } 1656 }
1685 return Error::null(); 1657 return Error::null();
1686 } 1658 }
1687 1659
1688
1689 RawError* Compiler::ParseAllFunctions(const Class& cls) { 1660 RawError* Compiler::ParseAllFunctions(const Class& cls) {
1690 Thread* thread = Thread::Current(); 1661 Thread* thread = Thread::Current();
1691 Zone* zone = thread->zone(); 1662 Zone* zone = thread->zone();
1692 Error& error = Error::Handle(zone); 1663 Error& error = Error::Handle(zone);
1693 Array& functions = Array::Handle(zone, cls.functions()); 1664 Array& functions = Array::Handle(zone, cls.functions());
1694 Function& func = Function::Handle(zone); 1665 Function& func = Function::Handle(zone);
1695 // Class dynamic lives in the vm isolate. Its array fields cannot be set to 1666 // Class dynamic lives in the vm isolate. Its array fields cannot be set to
1696 // an empty array. 1667 // an empty array.
1697 if (functions.IsNull()) { 1668 if (functions.IsNull()) {
1698 ASSERT(cls.IsDynamicClass()); 1669 ASSERT(cls.IsDynamicClass());
(...skipping 13 matching lines...) Expand all
1712 if (!error.IsNull()) { 1683 if (!error.IsNull()) {
1713 return error.raw(); 1684 return error.raw();
1714 } 1685 }
1715 func.ClearICDataArray(); 1686 func.ClearICDataArray();
1716 func.ClearCode(); 1687 func.ClearCode();
1717 } 1688 }
1718 } 1689 }
1719 return error.raw(); 1690 return error.raw();
1720 } 1691 }
1721 1692
1722
1723 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { 1693 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
1724 #ifdef DART_PRECOMPILER 1694 #ifdef DART_PRECOMPILER
1725 if (FLAG_precompiled_mode) { 1695 if (FLAG_precompiled_mode) {
1726 return Precompiler::EvaluateStaticInitializer(field); 1696 return Precompiler::EvaluateStaticInitializer(field);
1727 } 1697 }
1728 #endif 1698 #endif
1729 ASSERT(field.is_static()); 1699 ASSERT(field.is_static());
1730 // The VM sets the field's value to transiton_sentinel prior to 1700 // The VM sets the field's value to transiton_sentinel prior to
1731 // evaluating the initializer value. 1701 // evaluating the initializer value.
1732 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); 1702 ASSERT(field.StaticValue() == Object::transition_sentinel().raw());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 } 1745 }
1776 } 1746 }
1777 1747
1778 Thread* const thread = Thread::Current(); 1748 Thread* const thread = Thread::Current();
1779 StackZone zone(thread); 1749 StackZone zone(thread);
1780 const Error& error = Error::Handle(thread->zone(), thread->sticky_error()); 1750 const Error& error = Error::Handle(thread->zone(), thread->sticky_error());
1781 thread->clear_sticky_error(); 1751 thread->clear_sticky_error();
1782 return error.raw(); 1752 return error.raw();
1783 } 1753 }
1784 1754
1785
1786 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { 1755 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
1787 #ifdef DART_PRECOMPILER 1756 #ifdef DART_PRECOMPILER
1788 if (FLAG_precompiled_mode) { 1757 if (FLAG_precompiled_mode) {
1789 return Precompiler::ExecuteOnce(fragment); 1758 return Precompiler::ExecuteOnce(fragment);
1790 } 1759 }
1791 #endif 1760 #endif
1792 LongJumpScope jump; 1761 LongJumpScope jump;
1793 if (setjmp(*jump.Set()) == 0) { 1762 if (setjmp(*jump.Set()) == 0) {
1794 Thread* const thread = Thread::Current(); 1763 Thread* const thread = Thread::Current();
1795 1764
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 return result.raw(); 1819 return result.raw();
1851 } 1820 }
1852 } 1821 }
1853 1822
1854 Thread* const thread = Thread::Current(); 1823 Thread* const thread = Thread::Current();
1855 const Object& result = PassiveObject::Handle(thread->sticky_error()); 1824 const Object& result = PassiveObject::Handle(thread->sticky_error());
1856 thread->clear_sticky_error(); 1825 thread->clear_sticky_error();
1857 return result.raw(); 1826 return result.raw();
1858 } 1827 }
1859 1828
1860
1861 void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) { 1829 void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) {
1862 if (FLAG_trace_compiler) { 1830 if (FLAG_trace_compiler) {
1863 THR_Print("ABORT background compilation: %s\n", msg); 1831 THR_Print("ABORT background compilation: %s\n", msg);
1864 } 1832 }
1865 #if !defined(PRODUCT) 1833 #if !defined(PRODUCT)
1866 TimelineStream* stream = Timeline::GetCompilerStream(); 1834 TimelineStream* stream = Timeline::GetCompilerStream();
1867 ASSERT(stream != NULL); 1835 ASSERT(stream != NULL);
1868 TimelineEvent* event = stream->StartEvent(); 1836 TimelineEvent* event = stream->StartEvent();
1869 if (event != NULL) { 1837 if (event != NULL) {
1870 event->Instant("AbortBackgroundCompilation"); 1838 event->Instant("AbortBackgroundCompilation");
1871 event->SetNumArguments(1); 1839 event->SetNumArguments(1);
1872 event->CopyArgument(0, "reason", msg); 1840 event->CopyArgument(0, "reason", msg);
1873 event->Complete(); 1841 event->Complete();
1874 } 1842 }
1875 #endif // !defined(PRODUCT) 1843 #endif // !defined(PRODUCT)
1876 ASSERT(Compiler::IsBackgroundCompilation()); 1844 ASSERT(Compiler::IsBackgroundCompilation());
1877 Thread::Current()->long_jump_base()->Jump( 1845 Thread::Current()->long_jump_base()->Jump(
1878 deopt_id, Object::background_compilation_error()); 1846 deopt_id, Object::background_compilation_error());
1879 } 1847 }
1880 1848
1881
1882 // C-heap allocated background compilation queue element. 1849 // C-heap allocated background compilation queue element.
1883 class QueueElement { 1850 class QueueElement {
1884 public: 1851 public:
1885 explicit QueueElement(const Function& function) 1852 explicit QueueElement(const Function& function)
1886 : next_(NULL), function_(function.raw()) {} 1853 : next_(NULL), function_(function.raw()) {}
1887 1854
1888 virtual ~QueueElement() { 1855 virtual ~QueueElement() {
1889 next_ = NULL; 1856 next_ = NULL;
1890 function_ = Function::null(); 1857 function_ = Function::null();
1891 } 1858 }
1892 1859
1893 RawFunction* Function() const { return function_; } 1860 RawFunction* Function() const { return function_; }
1894 1861
1895
1896 void set_next(QueueElement* elem) { next_ = elem; } 1862 void set_next(QueueElement* elem) { next_ = elem; }
1897 QueueElement* next() const { return next_; } 1863 QueueElement* next() const { return next_; }
1898 1864
1899 RawObject* function() const { return function_; } 1865 RawObject* function() const { return function_; }
1900 RawObject** function_ptr() { 1866 RawObject** function_ptr() {
1901 return reinterpret_cast<RawObject**>(&function_); 1867 return reinterpret_cast<RawObject**>(&function_);
1902 } 1868 }
1903 1869
1904 private: 1870 private:
1905 QueueElement* next_; 1871 QueueElement* next_;
1906 RawFunction* function_; 1872 RawFunction* function_;
1907 1873
1908 DISALLOW_COPY_AND_ASSIGN(QueueElement); 1874 DISALLOW_COPY_AND_ASSIGN(QueueElement);
1909 }; 1875 };
1910 1876
1911
1912 // Allocated in C-heap. Handles both input and output of background compilation. 1877 // Allocated in C-heap. Handles both input and output of background compilation.
1913 // It implements a FIFO queue, using Peek, Add, Remove operations. 1878 // It implements a FIFO queue, using Peek, Add, Remove operations.
1914 class BackgroundCompilationQueue { 1879 class BackgroundCompilationQueue {
1915 public: 1880 public:
1916 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} 1881 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {}
1917 virtual ~BackgroundCompilationQueue() { Clear(); } 1882 virtual ~BackgroundCompilationQueue() { Clear(); }
1918 1883
1919 void VisitObjectPointers(ObjectPointerVisitor* visitor) { 1884 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
1920 ASSERT(visitor != NULL); 1885 ASSERT(visitor != NULL);
1921 QueueElement* p = first_; 1886 QueueElement* p = first_;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 ASSERT((first_ == NULL) && (last_ == NULL)); 1946 ASSERT((first_ == NULL) && (last_ == NULL));
1982 } 1947 }
1983 1948
1984 private: 1949 private:
1985 QueueElement* first_; 1950 QueueElement* first_;
1986 QueueElement* last_; 1951 QueueElement* last_;
1987 1952
1988 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue); 1953 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue);
1989 }; 1954 };
1990 1955
1991
1992 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1956 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1993 : isolate_(isolate), 1957 : isolate_(isolate),
1994 running_(true), 1958 running_(true),
1995 done_(new bool()), 1959 done_(new bool()),
1996 queue_monitor_(new Monitor()), 1960 queue_monitor_(new Monitor()),
1997 done_monitor_(new Monitor()), 1961 done_monitor_(new Monitor()),
1998 function_queue_(new BackgroundCompilationQueue()) { 1962 function_queue_(new BackgroundCompilationQueue()) {
1999 *done_ = false; 1963 *done_ = false;
2000 } 1964 }
2001 1965
2002
2003 // Fields all deleted in ::Stop; here clear them. 1966 // Fields all deleted in ::Stop; here clear them.
2004 BackgroundCompiler::~BackgroundCompiler() { 1967 BackgroundCompiler::~BackgroundCompiler() {
2005 isolate_ = NULL; 1968 isolate_ = NULL;
2006 running_ = false; 1969 running_ = false;
2007 done_ = NULL; 1970 done_ = NULL;
2008 queue_monitor_ = NULL; 1971 queue_monitor_ = NULL;
2009 done_monitor_ = NULL; 1972 done_monitor_ = NULL;
2010 function_queue_ = NULL; 1973 function_queue_ = NULL;
2011 } 1974 }
2012 1975
2013
2014 void BackgroundCompiler::Run() { 1976 void BackgroundCompiler::Run() {
2015 while (running_) { 1977 while (running_) {
2016 // Maybe something is already in the queue, check first before waiting 1978 // Maybe something is already in the queue, check first before waiting
2017 // to be notified. 1979 // to be notified.
2018 bool result = Thread::EnterIsolateAsHelper(isolate_, Thread::kCompilerTask); 1980 bool result = Thread::EnterIsolateAsHelper(isolate_, Thread::kCompilerTask);
2019 ASSERT(result); 1981 ASSERT(result);
2020 { 1982 {
2021 Thread* thread = Thread::Current(); 1983 Thread* thread = Thread::Current();
2022 StackZone stack_zone(thread); 1984 StackZone stack_zone(thread);
2023 Zone* zone = stack_zone.GetZone(); 1985 Zone* zone = stack_zone.GetZone();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 } // while running 2036 } // while running
2075 2037
2076 { 2038 {
2077 // Notify that the thread is done. 2039 // Notify that the thread is done.
2078 MonitorLocker ml_done(done_monitor_); 2040 MonitorLocker ml_done(done_monitor_);
2079 *done_ = true; 2041 *done_ = true;
2080 ml_done.Notify(); 2042 ml_done.Notify();
2081 } 2043 }
2082 } 2044 }
2083 2045
2084
2085 void BackgroundCompiler::CompileOptimized(const Function& function) { 2046 void BackgroundCompiler::CompileOptimized(const Function& function) {
2086 ASSERT(Thread::Current()->IsMutatorThread()); 2047 ASSERT(Thread::Current()->IsMutatorThread());
2087 // TODO(srdjan): Checking different strategy for collecting garbage 2048 // TODO(srdjan): Checking different strategy for collecting garbage
2088 // accumulated by background compiler. 2049 // accumulated by background compiler.
2089 if (isolate_->heap()->NeedsGarbageCollection()) { 2050 if (isolate_->heap()->NeedsGarbageCollection()) {
2090 isolate_->heap()->CollectAllGarbage(); 2051 isolate_->heap()->CollectAllGarbage();
2091 } 2052 }
2092 { 2053 {
2093 MonitorLocker ml(queue_monitor_); 2054 MonitorLocker ml(queue_monitor_);
2094 ASSERT(running_); 2055 ASSERT(running_);
2095 if (function_queue()->ContainsObj(function)) { 2056 if (function_queue()->ContainsObj(function)) {
2096 return; 2057 return;
2097 } 2058 }
2098 QueueElement* elem = new QueueElement(function); 2059 QueueElement* elem = new QueueElement(function);
2099 function_queue()->Add(elem); 2060 function_queue()->Add(elem);
2100 ml.Notify(); 2061 ml.Notify();
2101 } 2062 }
2102 } 2063 }
2103 2064
2104
2105 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) { 2065 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
2106 function_queue_->VisitObjectPointers(visitor); 2066 function_queue_->VisitObjectPointers(visitor);
2107 } 2067 }
2108 2068
2109
2110 void BackgroundCompiler::Stop(Isolate* isolate) { 2069 void BackgroundCompiler::Stop(Isolate* isolate) {
2111 BackgroundCompiler* task = isolate->background_compiler(); 2070 BackgroundCompiler* task = isolate->background_compiler();
2112 if (task == NULL) { 2071 if (task == NULL) {
2113 // Nothing to stop. 2072 // Nothing to stop.
2114 return; 2073 return;
2115 } 2074 }
2116 BackgroundCompilationQueue* function_queue = task->function_queue(); 2075 BackgroundCompilationQueue* function_queue = task->function_queue();
2117 2076
2118 Monitor* queue_monitor = task->queue_monitor_; 2077 Monitor* queue_monitor = task->queue_monitor_;
2119 Monitor* done_monitor = task->done_monitor_; 2078 Monitor* done_monitor = task->done_monitor_;
(...skipping 14 matching lines...) Expand all
2134 ml_done.WaitWithSafepointCheck(Thread::Current()); 2093 ml_done.WaitWithSafepointCheck(Thread::Current());
2135 } 2094 }
2136 } 2095 }
2137 delete task_done; 2096 delete task_done;
2138 delete done_monitor; 2097 delete done_monitor;
2139 delete queue_monitor; 2098 delete queue_monitor;
2140 delete function_queue; 2099 delete function_queue;
2141 isolate->set_background_compiler(NULL); 2100 isolate->set_background_compiler(NULL);
2142 } 2101 }
2143 2102
2144
2145 void BackgroundCompiler::Disable() { 2103 void BackgroundCompiler::Disable() {
2146 Thread* thread = Thread::Current(); 2104 Thread* thread = Thread::Current();
2147 ASSERT(thread != NULL); 2105 ASSERT(thread != NULL);
2148 Isolate* isolate = thread->isolate(); 2106 Isolate* isolate = thread->isolate();
2149 MutexLocker ml(isolate->mutex()); 2107 MutexLocker ml(isolate->mutex());
2150 BackgroundCompiler* task = isolate->background_compiler(); 2108 BackgroundCompiler* task = isolate->background_compiler();
2151 if (task != NULL) { 2109 if (task != NULL) {
2152 // We should only ever have to stop the task if this is the first call to 2110 // We should only ever have to stop the task if this is the first call to
2153 // Disable. 2111 // Disable.
2154 ASSERT(!isolate->is_background_compiler_disabled()); 2112 ASSERT(!isolate->is_background_compiler_disabled());
2155 BackgroundCompiler::Stop(isolate); 2113 BackgroundCompiler::Stop(isolate);
2156 } 2114 }
2157 ASSERT(isolate->background_compiler() == NULL); 2115 ASSERT(isolate->background_compiler() == NULL);
2158 isolate->disable_background_compiler(); 2116 isolate->disable_background_compiler();
2159 } 2117 }
2160 2118
2161
2162 bool BackgroundCompiler::IsDisabled() { 2119 bool BackgroundCompiler::IsDisabled() {
2163 Thread* thread = Thread::Current(); 2120 Thread* thread = Thread::Current();
2164 ASSERT(thread != NULL); 2121 ASSERT(thread != NULL);
2165 Isolate* isolate = thread->isolate(); 2122 Isolate* isolate = thread->isolate();
2166 MutexLocker ml(isolate->mutex()); 2123 MutexLocker ml(isolate->mutex());
2167 return isolate->is_background_compiler_disabled(); 2124 return isolate->is_background_compiler_disabled();
2168 } 2125 }
2169 2126
2170
2171 void BackgroundCompiler::Enable() { 2127 void BackgroundCompiler::Enable() {
2172 Thread* thread = Thread::Current(); 2128 Thread* thread = Thread::Current();
2173 ASSERT(thread != NULL); 2129 ASSERT(thread != NULL);
2174 Isolate* isolate = thread->isolate(); 2130 Isolate* isolate = thread->isolate();
2175 MutexLocker ml(isolate->mutex()); 2131 MutexLocker ml(isolate->mutex());
2176 isolate->enable_background_compiler(); 2132 isolate->enable_background_compiler();
2177 } 2133 }
2178 2134
2179
2180 void BackgroundCompiler::EnsureInit(Thread* thread) { 2135 void BackgroundCompiler::EnsureInit(Thread* thread) {
2181 ASSERT(thread->IsMutatorThread()); 2136 ASSERT(thread->IsMutatorThread());
2182 // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized 2137 // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
2183 // compilation. 2138 // compilation.
2184 Class& cls = Class::Handle( 2139 Class& cls = Class::Handle(
2185 thread->zone(), Library::LookupCoreClass(Symbols::NoSuchMethodError())); 2140 thread->zone(), Library::LookupCoreClass(Symbols::NoSuchMethodError()));
2186 ASSERT(!cls.IsNull()); 2141 ASSERT(!cls.IsNull());
2187 Error& error = Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread)); 2142 Error& error = Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread));
2188 ASSERT(error.IsNull()); 2143 ASSERT(error.IsNull());
2189 cls = Library::LookupCoreClass(Symbols::_Mint()); 2144 cls = Library::LookupCoreClass(Symbols::_Mint());
2190 ASSERT(!cls.IsNull()); 2145 ASSERT(!cls.IsNull());
2191 error = cls.EnsureIsFinalized(thread); 2146 error = cls.EnsureIsFinalized(thread);
2192 ASSERT(error.IsNull()); 2147 ASSERT(error.IsNull());
2193 2148
2194 bool start_task = false; 2149 bool start_task = false;
2195 Isolate* isolate = thread->isolate(); 2150 Isolate* isolate = thread->isolate();
2196 { 2151 {
2197 MutexLocker ml(isolate->mutex()); 2152 MutexLocker ml(isolate->mutex());
2198 if (isolate->background_compiler() == NULL) { 2153 if (isolate->background_compiler() == NULL) {
2199 BackgroundCompiler* task = new BackgroundCompiler(isolate); 2154 BackgroundCompiler* task = new BackgroundCompiler(isolate);
2200 isolate->set_background_compiler(task); 2155 isolate->set_background_compiler(task);
2201 start_task = true; 2156 start_task = true;
2202 } 2157 }
2203 } 2158 }
2204 if (start_task) { 2159 if (start_task) {
2205 Dart::thread_pool()->Run(isolate->background_compiler()); 2160 Dart::thread_pool()->Run(isolate->background_compiler());
2206 } 2161 }
2207 } 2162 }
2208 2163
2209
2210 #else // DART_PRECOMPILED_RUNTIME 2164 #else // DART_PRECOMPILED_RUNTIME
2211 2165
2212
2213 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { 2166 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
2214 UNREACHABLE(); 2167 UNREACHABLE();
2215 return false; 2168 return false;
2216 } 2169 }
2217 2170
2218
2219 CompilationPipeline* CompilationPipeline::New(Zone* zone, 2171 CompilationPipeline* CompilationPipeline::New(Zone* zone,
2220 const Function& function) { 2172 const Function& function) {
2221 UNREACHABLE(); 2173 UNREACHABLE();
2222 return NULL; 2174 return NULL;
2223 } 2175 }
2224 2176
2225
2226 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { 2177 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
2227 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 2178 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
2228 FATAL3("Precompilation missed function %s (%" Pd ", %s)\n", 2179 FATAL3("Precompilation missed function %s (%" Pd ", %s)\n",
2229 function.ToLibNamePrefixedQualifiedCString(), 2180 function.ToLibNamePrefixedQualifiedCString(),
2230 function.token_pos().value(), 2181 function.token_pos().value(),
2231 Function::KindToCString(function.kind())); 2182 Function::KindToCString(function.kind()));
2232 } 2183 }
2233 2184
2234
2235 bool Compiler::IsBackgroundCompilation() { 2185 bool Compiler::IsBackgroundCompilation() {
2236 return false; 2186 return false;
2237 } 2187 }
2238 2188
2239
2240 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) { 2189 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
2241 UNREACHABLE(); 2190 UNREACHABLE();
2242 return false; 2191 return false;
2243 } 2192 }
2244 2193
2245
2246 RawError* Compiler::Compile(const Library& library, const Script& script) { 2194 RawError* Compiler::Compile(const Library& library, const Script& script) {
2247 FATAL1("Attempt to compile script %s", script.ToCString()); 2195 FATAL1("Attempt to compile script %s", script.ToCString());
2248 return Error::null(); 2196 return Error::null();
2249 } 2197 }
2250 2198
2251
2252 RawError* Compiler::CompileClass(const Class& cls) { 2199 RawError* Compiler::CompileClass(const Class& cls) {
2253 FATAL1("Attempt to compile class %s", cls.ToCString()); 2200 FATAL1("Attempt to compile class %s", cls.ToCString());
2254 return Error::null(); 2201 return Error::null();
2255 } 2202 }
2256 2203
2257
2258 RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) { 2204 RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
2259 FATAL1("Attempt to compile function %s", function.ToCString()); 2205 FATAL1("Attempt to compile function %s", function.ToCString());
2260 return Error::null(); 2206 return Error::null();
2261 } 2207 }
2262 2208
2263
2264 RawError* Compiler::ParseFunction(Thread* thread, const Function& function) { 2209 RawError* Compiler::ParseFunction(Thread* thread, const Function& function) {
2265 FATAL1("Attempt to parse function %s", function.ToCString()); 2210 FATAL1("Attempt to parse function %s", function.ToCString());
2266 return Error::null(); 2211 return Error::null();
2267 } 2212 }
2268 2213
2269
2270 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, 2214 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
2271 const Function& function) { 2215 const Function& function) {
2272 FATAL1("Attempt to compile function %s", function.ToCString()); 2216 FATAL1("Attempt to compile function %s", function.ToCString());
2273 return Error::null(); 2217 return Error::null();
2274 } 2218 }
2275 2219
2276
2277 RawObject* Compiler::CompileOptimizedFunction(Thread* thread, 2220 RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
2278 const Function& function, 2221 const Function& function,
2279 intptr_t osr_id) { 2222 intptr_t osr_id) {
2280 FATAL1("Attempt to compile function %s", function.ToCString()); 2223 FATAL1("Attempt to compile function %s", function.ToCString());
2281 return Error::null(); 2224 return Error::null();
2282 } 2225 }
2283 2226
2284
2285 RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) { 2227 RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) {
2286 FATAL1("Attempt to compile function %s", 2228 FATAL1("Attempt to compile function %s",
2287 parsed_function->function().ToCString()); 2229 parsed_function->function().ToCString());
2288 return Error::null(); 2230 return Error::null();
2289 } 2231 }
2290 2232
2291
2292 void Compiler::ComputeLocalVarDescriptors(const Code& code) { 2233 void Compiler::ComputeLocalVarDescriptors(const Code& code) {
2293 UNREACHABLE(); 2234 UNREACHABLE();
2294 } 2235 }
2295 2236
2296
2297 RawError* Compiler::CompileAllFunctions(const Class& cls) { 2237 RawError* Compiler::CompileAllFunctions(const Class& cls) {
2298 FATAL1("Attempt to compile class %s", cls.ToCString()); 2238 FATAL1("Attempt to compile class %s", cls.ToCString());
2299 return Error::null(); 2239 return Error::null();
2300 } 2240 }
2301 2241
2302
2303 RawError* Compiler::ParseAllFunctions(const Class& cls) { 2242 RawError* Compiler::ParseAllFunctions(const Class& cls) {
2304 FATAL1("Attempt to parse class %s", cls.ToCString()); 2243 FATAL1("Attempt to parse class %s", cls.ToCString());
2305 return Error::null(); 2244 return Error::null();
2306 } 2245 }
2307 2246
2308
2309 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { 2247 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
2310 ASSERT(field.HasPrecompiledInitializer()); 2248 ASSERT(field.HasPrecompiledInitializer());
2311 const Function& initializer = 2249 const Function& initializer =
2312 Function::Handle(field.PrecompiledInitializer()); 2250 Function::Handle(field.PrecompiledInitializer());
2313 return DartEntry::InvokeFunction(initializer, Object::empty_array()); 2251 return DartEntry::InvokeFunction(initializer, Object::empty_array());
2314 } 2252 }
2315 2253
2316
2317 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { 2254 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
2318 UNREACHABLE(); 2255 UNREACHABLE();
2319 return Object::null(); 2256 return Object::null();
2320 } 2257 }
2321 2258
2322
2323 void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) { 2259 void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) {
2324 UNREACHABLE(); 2260 UNREACHABLE();
2325 } 2261 }
2326 2262
2327
2328 void BackgroundCompiler::CompileOptimized(const Function& function) { 2263 void BackgroundCompiler::CompileOptimized(const Function& function) {
2329 UNREACHABLE(); 2264 UNREACHABLE();
2330 } 2265 }
2331 2266
2332
2333 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) { 2267 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
2334 UNREACHABLE(); 2268 UNREACHABLE();
2335 } 2269 }
2336 2270
2337
2338 void BackgroundCompiler::Stop(Isolate* isolate) { 2271 void BackgroundCompiler::Stop(Isolate* isolate) {
2339 UNREACHABLE(); 2272 UNREACHABLE();
2340 } 2273 }
2341 2274
2342
2343 void BackgroundCompiler::EnsureInit(Thread* thread) { 2275 void BackgroundCompiler::EnsureInit(Thread* thread) {
2344 UNREACHABLE(); 2276 UNREACHABLE();
2345 } 2277 }
2346 2278
2347
2348 void BackgroundCompiler::Disable() { 2279 void BackgroundCompiler::Disable() {
2349 UNREACHABLE(); 2280 UNREACHABLE();
2350 } 2281 }
2351 2282
2352
2353 void BackgroundCompiler::Enable() { 2283 void BackgroundCompiler::Enable() {
2354 UNREACHABLE(); 2284 UNREACHABLE();
2355 } 2285 }
2356 2286
2357
2358 bool BackgroundCompiler::IsDisabled() { 2287 bool BackgroundCompiler::IsDisabled() {
2359 UNREACHABLE(); 2288 UNREACHABLE();
2360 return true; 2289 return true;
2361 } 2290 }
2362 2291
2363 #endif // DART_PRECOMPILED_RUNTIME 2292 #endif // DART_PRECOMPILED_RUNTIME
2364 2293
2365 } // namespace dart 2294 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/compiler_stats.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698