| 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 |