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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 const Code& code = | 542 const Code& code = |
543 Code::Handle(Code::FinalizeCode(function, assembler, optimized())); | 543 Code::Handle(Code::FinalizeCode(function, assembler, optimized())); |
544 code.set_is_optimized(optimized()); | 544 code.set_is_optimized(optimized()); |
545 code.set_owner(function); | 545 code.set_owner(function); |
546 if (!function.IsOptimizable()) { | 546 if (!function.IsOptimizable()) { |
547 // A function with huge unoptimized code can become non-optimizable | 547 // A function with huge unoptimized code can become non-optimizable |
548 // after generating unoptimized code. | 548 // after generating unoptimized code. |
549 function.set_usage_counter(INT_MIN); | 549 function.set_usage_counter(INT_MIN); |
550 } | 550 } |
551 | 551 |
552 const Array& intervals = graph_compiler->inlined_code_intervals(); | |
553 INC_STAT(thread(), total_code_size, intervals.Length() * sizeof(uword)); | |
554 code.SetInlinedIntervals(intervals); | |
555 | |
556 const Array& inlined_id_array = | |
557 Array::Handle(zone, graph_compiler->InliningIdToFunction()); | |
558 INC_STAT(thread(), total_code_size, | |
559 inlined_id_array.Length() * sizeof(uword)); | |
560 code.SetInlinedIdToFunction(inlined_id_array); | |
561 | |
562 const Array& caller_inlining_id_map_array = | |
563 Array::Handle(zone, graph_compiler->CallerInliningIdMap()); | |
564 INC_STAT(thread(), total_code_size, | |
565 caller_inlining_id_map_array.Length() * sizeof(uword)); | |
566 code.SetInlinedCallerIdMap(caller_inlining_id_map_array); | |
567 | |
568 const Array& inlined_id_to_token_pos = | |
569 Array::Handle(zone, graph_compiler->InliningIdToTokenPos()); | |
570 INC_STAT(thread(), total_code_size, | |
571 inlined_id_to_token_pos.Length() * sizeof(uword)); | |
572 code.SetInlinedIdToTokenPos(inlined_id_to_token_pos); | |
573 | |
574 graph_compiler->FinalizePcDescriptors(code); | 552 graph_compiler->FinalizePcDescriptors(code); |
575 code.set_deopt_info_array(deopt_info_array); | 553 code.set_deopt_info_array(deopt_info_array); |
576 | 554 |
577 graph_compiler->FinalizeStackMaps(code); | 555 graph_compiler->FinalizeStackMaps(code); |
578 graph_compiler->FinalizeVarDescriptors(code); | 556 graph_compiler->FinalizeVarDescriptors(code); |
579 graph_compiler->FinalizeExceptionHandlers(code); | 557 graph_compiler->FinalizeExceptionHandlers(code); |
580 graph_compiler->FinalizeStaticCallTargetsTable(code); | 558 graph_compiler->FinalizeStaticCallTargetsTable(code); |
581 | 559 graph_compiler->FinalizeCodeSourceMap(code); |
582 #if !defined(PRODUCT) | |
583 // Set the code source map after setting the inlined information because | |
584 // we use the inlined information when printing. | |
585 const CodeSourceMap& code_source_map = CodeSourceMap::Handle( | |
586 zone, graph_compiler->code_source_map_builder()->Finalize()); | |
587 code.set_code_source_map(code_source_map); | |
588 if (FLAG_print_code_source_map) { | |
589 CodeSourceMap::Dump(code_source_map, code, function); | |
590 } | |
591 #endif // !defined(PRODUCT) | |
592 | 560 |
593 if (optimized()) { | 561 if (optimized()) { |
594 bool code_was_installed = false; | 562 bool code_was_installed = false; |
595 // Installs code while at safepoint. | 563 // Installs code while at safepoint. |
596 if (thread()->IsMutatorThread()) { | 564 if (thread()->IsMutatorThread()) { |
597 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; | 565 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; |
598 function.InstallOptimizedCode(code, is_osr); | 566 function.InstallOptimizedCode(code, is_osr); |
599 code_was_installed = true; | 567 code_was_installed = true; |
600 } else { | 568 } else { |
601 // Background compilation. | 569 // Background compilation. |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 } | 1164 } |
1197 is_compiled = false; | 1165 is_compiled = false; |
1198 } | 1166 } |
1199 // Reset global isolate state. | 1167 // Reset global isolate state. |
1200 thread()->set_deopt_id(prev_deopt_id); | 1168 thread()->set_deopt_id(prev_deopt_id); |
1201 } | 1169 } |
1202 return is_compiled; | 1170 return is_compiled; |
1203 } | 1171 } |
1204 | 1172 |
1205 | 1173 |
1206 #if defined(DEBUG) | |
1207 // Verifies that the inliner is always in the list of inlined functions. | |
1208 // If this fails run with --trace-inlining-intervals to get more information. | |
1209 static void CheckInliningIntervals(const Function& function) { | |
1210 const Code& code = Code::Handle(function.CurrentCode()); | |
1211 const Array& intervals = Array::Handle(code.GetInlinedIntervals()); | |
1212 if (intervals.IsNull() || (intervals.Length() == 0)) return; | |
1213 Smi& start = Smi::Handle(); | |
1214 GrowableArray<Function*> inlined_functions; | |
1215 for (intptr_t i = 0; i < intervals.Length(); i += Code::kInlIntNumEntries) { | |
1216 start ^= intervals.At(i + Code::kInlIntStart); | |
1217 ASSERT(!start.IsNull()); | |
1218 if (start.IsNull()) continue; | |
1219 code.GetInlinedFunctionsAt(start.Value(), &inlined_functions); | |
1220 ASSERT(inlined_functions[inlined_functions.length() - 1]->raw() == | |
1221 function.raw()); | |
1222 } | |
1223 } | |
1224 #endif // defined(DEBUG) | |
1225 | |
1226 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, | 1174 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
1227 const Function& function, | 1175 const Function& function, |
1228 bool optimized, | 1176 bool optimized, |
1229 intptr_t osr_id) { | 1177 intptr_t osr_id) { |
1230 ASSERT(!FLAG_precompiled_mode); | 1178 ASSERT(!FLAG_precompiled_mode); |
1231 ASSERT(!optimized || function.was_compiled()); | 1179 ASSERT(!optimized || function.was_compiled()); |
1232 LongJumpScope jump; | 1180 LongJumpScope jump; |
1233 if (setjmp(*jump.Set()) == 0) { | 1181 if (setjmp(*jump.Set()) == 0) { |
1234 Thread* const thread = Thread::Current(); | 1182 Thread* const thread = Thread::Current(); |
1235 Isolate* const isolate = thread->isolate(); | 1183 Isolate* const isolate = thread->isolate(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1354 isolate->debugger()->NotifyCompilation(function); | 1302 isolate->debugger()->NotifyCompilation(function); |
1355 } | 1303 } |
1356 | 1304 |
1357 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { | 1305 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { |
1358 Disassembler::DisassembleCode(function, optimized); | 1306 Disassembler::DisassembleCode(function, optimized); |
1359 } else if (FLAG_disassemble_optimized && optimized && | 1307 } else if (FLAG_disassemble_optimized && optimized && |
1360 FlowGraphPrinter::ShouldPrint(function)) { | 1308 FlowGraphPrinter::ShouldPrint(function)) { |
1361 Disassembler::DisassembleCode(function, true); | 1309 Disassembler::DisassembleCode(function, true); |
1362 } | 1310 } |
1363 | 1311 |
1364 DEBUG_ONLY(CheckInliningIntervals(function)); | |
1365 return Error::null(); | 1312 return Error::null(); |
1366 } else { | 1313 } else { |
1367 Thread* const thread = Thread::Current(); | 1314 Thread* const thread = Thread::Current(); |
1368 StackZone stack_zone(thread); | 1315 StackZone stack_zone(thread); |
1369 Error& error = Error::Handle(); | 1316 Error& error = Error::Handle(); |
1370 // We got an error during compilation or it is a bailout from background | 1317 // We got an error during compilation or it is a bailout from background |
1371 // compilation (e.g., during parsing with EnsureIsFinalized). | 1318 // compilation (e.g., during parsing with EnsureIsFinalized). |
1372 error = thread->sticky_error(); | 1319 error = thread->sticky_error(); |
1373 thread->clear_sticky_error(); | 1320 thread->clear_sticky_error(); |
1374 if (error.raw() == Object::background_compilation_error().raw()) { | 1321 if (error.raw() == Object::background_compilation_error().raw()) { |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2318 | 2265 |
2319 | 2266 |
2320 bool BackgroundCompiler::IsDisabled() { | 2267 bool BackgroundCompiler::IsDisabled() { |
2321 UNREACHABLE(); | 2268 UNREACHABLE(); |
2322 return true; | 2269 return true; |
2323 } | 2270 } |
2324 | 2271 |
2325 #endif // DART_PRECOMPILED_RUNTIME | 2272 #endif // DART_PRECOMPILED_RUNTIME |
2326 | 2273 |
2327 } // namespace dart | 2274 } // namespace dart |
OLD | NEW |