Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 | 175 |
| 176 FlowGraphCompiler::FlowGraphCompiler( | 176 FlowGraphCompiler::FlowGraphCompiler( |
| 177 Assembler* assembler, | 177 Assembler* assembler, |
| 178 FlowGraph* flow_graph, | 178 FlowGraph* flow_graph, |
| 179 const ParsedFunction& parsed_function, | 179 const ParsedFunction& parsed_function, |
| 180 bool is_optimizing, | 180 bool is_optimizing, |
| 181 const GrowableArray<const Function*>& inline_id_to_function, | 181 const GrowableArray<const Function*>& inline_id_to_function, |
| 182 const GrowableArray<TokenPosition>& inline_id_to_token_pos, | |
| 182 const GrowableArray<intptr_t>& caller_inline_id) | 183 const GrowableArray<intptr_t>& caller_inline_id) |
| 183 : thread_(Thread::Current()), | 184 : thread_(Thread::Current()), |
| 184 zone_(Thread::Current()->zone()), | 185 zone_(Thread::Current()->zone()), |
| 185 assembler_(assembler), | 186 assembler_(assembler), |
| 186 parsed_function_(parsed_function), | 187 parsed_function_(parsed_function), |
| 187 flow_graph_(*flow_graph), | 188 flow_graph_(*flow_graph), |
| 188 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)), | 189 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)), |
| 189 current_block_(NULL), | 190 current_block_(NULL), |
| 190 exception_handlers_list_(NULL), | 191 exception_handlers_list_(NULL), |
| 191 pc_descriptors_list_(NULL), | 192 pc_descriptors_list_(NULL), |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 209 list_class_(Class::ZoneHandle( | 210 list_class_(Class::ZoneHandle( |
| 210 Library::Handle(Library::CoreLibrary()). | 211 Library::Handle(Library::CoreLibrary()). |
| 211 LookupClass(Symbols::List()))), | 212 LookupClass(Symbols::List()))), |
| 212 parallel_move_resolver_(this), | 213 parallel_move_resolver_(this), |
| 213 pending_deoptimization_env_(NULL), | 214 pending_deoptimization_env_(NULL), |
| 214 lazy_deopt_pc_offset_(Code::kInvalidPc), | 215 lazy_deopt_pc_offset_(Code::kInvalidPc), |
| 215 deopt_id_to_ic_data_(NULL), | 216 deopt_id_to_ic_data_(NULL), |
| 216 edge_counters_array_(Array::ZoneHandle()), | 217 edge_counters_array_(Array::ZoneHandle()), |
| 217 inlined_code_intervals_(Array::ZoneHandle(Object::empty_array().raw())), | 218 inlined_code_intervals_(Array::ZoneHandle(Object::empty_array().raw())), |
| 218 inline_id_to_function_(inline_id_to_function), | 219 inline_id_to_function_(inline_id_to_function), |
| 220 inline_id_to_token_pos_(inline_id_to_token_pos), | |
| 219 caller_inline_id_(caller_inline_id) { | 221 caller_inline_id_(caller_inline_id) { |
| 220 ASSERT(flow_graph->parsed_function().function().raw() == | 222 ASSERT(flow_graph->parsed_function().function().raw() == |
| 221 parsed_function.function().raw()); | 223 parsed_function.function().raw()); |
| 222 if (!is_optimizing) { | 224 if (!is_optimizing) { |
| 223 const intptr_t len = thread()->deopt_id(); | 225 const intptr_t len = thread()->deopt_id(); |
| 224 deopt_id_to_ic_data_ = new(zone()) ZoneGrowableArray<const ICData*>(len); | 226 deopt_id_to_ic_data_ = new(zone()) ZoneGrowableArray<const ICData*>(len); |
| 225 deopt_id_to_ic_data_->SetLength(len); | 227 deopt_id_to_ic_data_->SetLength(len); |
| 226 for (intptr_t i = 0; i < len; i++) { | 228 for (intptr_t i = 0; i < len; i++) { |
| 227 (*deopt_id_to_ic_data_)[i] = NULL; | 229 (*deopt_id_to_ic_data_)[i] = NULL; |
| 228 } | 230 } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 assembler->Comment(" Loop %" Pd "", loop_id); | 472 assembler->Comment(" Loop %" Pd "", loop_id); |
| 471 } | 473 } |
| 472 } | 474 } |
| 473 } | 475 } |
| 474 } | 476 } |
| 475 } | 477 } |
| 476 | 478 |
| 477 | 479 |
| 478 // We collect intervals while generating code. | 480 // We collect intervals while generating code. |
| 479 struct IntervalStruct { | 481 struct IntervalStruct { |
| 480 // 'start' and 'end' are pc-offsets. | 482 // 'start' and 'end' are pc-offsets. |
|
srdjan
2016/02/25 22:05:32
Adjust comment, there is no 'end; field any longer
Cutch
2016/02/25 22:36:39
Done.
| |
| 481 intptr_t start; | 483 intptr_t start; |
| 484 TokenPosition pos; | |
| 482 intptr_t inlining_id; | 485 intptr_t inlining_id; |
| 483 IntervalStruct(intptr_t s, intptr_t id) : start(s), inlining_id(id) {} | 486 IntervalStruct(intptr_t s, TokenPosition tp, intptr_t id) |
| 487 : start(s), pos(tp), inlining_id(id) {} | |
| 484 void Dump() { | 488 void Dump() { |
| 485 THR_Print("start: 0x%" Px " iid: %" Pd " ", start, inlining_id); | 489 THR_Print("start: 0x%" Px " iid: %" Pd " pos: %s", |
| 490 start, inlining_id, pos.ToCString()); | |
| 486 } | 491 } |
| 487 }; | 492 }; |
| 488 | 493 |
| 489 | 494 |
| 490 void FlowGraphCompiler::VisitBlocks() { | 495 void FlowGraphCompiler::VisitBlocks() { |
| 491 CompactBlocks(); | 496 CompactBlocks(); |
| 492 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL; | 497 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL; |
| 493 if (Assembler::EmittingComments()) { | 498 if (Assembler::EmittingComments()) { |
| 494 // 'loop_headers' were cleared, recompute. | 499 // 'loop_headers' were cleared, recompute. |
| 495 loop_headers = flow_graph().ComputeLoops(); | 500 loop_headers = flow_graph().ComputeLoops(); |
| 496 ASSERT(loop_headers != NULL); | 501 ASSERT(loop_headers != NULL); |
| 497 } | 502 } |
| 498 | 503 |
| 499 // For collecting intervals of inlined code. | 504 // For collecting intervals of inlined code. |
| 500 GrowableArray<IntervalStruct> intervals; | 505 GrowableArray<IntervalStruct> intervals; |
| 501 intptr_t prev_offset = 0; | 506 intptr_t prev_offset = 0; |
| 502 intptr_t prev_inlining_id = 0; | 507 intptr_t prev_inlining_id = 0; |
| 508 TokenPosition prev_inlining_pos = parsed_function_.function().token_pos(); | |
| 503 intptr_t max_inlining_id = 0; | 509 intptr_t max_inlining_id = 0; |
| 504 for (intptr_t i = 0; i < block_order().length(); ++i) { | 510 for (intptr_t i = 0; i < block_order().length(); ++i) { |
| 505 // Compile the block entry. | 511 // Compile the block entry. |
| 506 BlockEntryInstr* entry = block_order()[i]; | 512 BlockEntryInstr* entry = block_order()[i]; |
| 507 assembler()->Comment("B%" Pd "", entry->block_id()); | 513 assembler()->Comment("B%" Pd "", entry->block_id()); |
| 508 set_current_block(entry); | 514 set_current_block(entry); |
| 509 | 515 |
| 510 if (WasCompacted(entry)) { | 516 if (WasCompacted(entry)) { |
| 511 continue; | 517 continue; |
| 512 } | 518 } |
| 513 | 519 |
| 514 #if defined(DEBUG) | 520 #if defined(DEBUG) |
| 515 if (!is_optimizing()) { | 521 if (!is_optimizing()) { |
| 516 FrameStateClear(); | 522 FrameStateClear(); |
| 517 } | 523 } |
| 518 #endif | 524 #endif |
| 519 | 525 |
| 520 LoopInfoComment(assembler(), *entry, *loop_headers); | 526 LoopInfoComment(assembler(), *entry, *loop_headers); |
| 521 | 527 |
| 522 entry->set_offset(assembler()->CodeSize()); | 528 entry->set_offset(assembler()->CodeSize()); |
| 523 entry->EmitNativeCode(this); | 529 entry->EmitNativeCode(this); |
| 524 // Compile all successors until an exit, branch, or a block entry. | 530 // Compile all successors until an exit, branch, or a block entry. |
| 525 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 531 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 526 Instruction* instr = it.Current(); | 532 Instruction* instr = it.Current(); |
| 527 // Compose intervals. | 533 // Compose intervals. |
| 528 if (instr->has_inlining_id() && is_optimizing()) { | 534 if (instr->has_inlining_id() && is_optimizing()) { |
| 529 if (prev_inlining_id != instr->inlining_id()) { | 535 if (prev_inlining_id != instr->inlining_id()) { |
| 530 intervals.Add(IntervalStruct(prev_offset, prev_inlining_id)); | 536 intervals.Add( |
| 537 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id)); | |
| 531 prev_offset = assembler()->CodeSize(); | 538 prev_offset = assembler()->CodeSize(); |
| 532 prev_inlining_id = instr->inlining_id(); | 539 prev_inlining_id = instr->inlining_id(); |
| 540 prev_inlining_pos = inline_id_to_token_pos_[prev_inlining_id]; | |
| 533 if (prev_inlining_id > max_inlining_id) { | 541 if (prev_inlining_id > max_inlining_id) { |
| 534 max_inlining_id = prev_inlining_id; | 542 max_inlining_id = prev_inlining_id; |
| 535 } | 543 } |
| 536 } | 544 } |
| 537 } | 545 } |
| 538 if (FLAG_code_comments || | 546 if (FLAG_code_comments || |
| 539 FLAG_disassemble || FLAG_disassemble_optimized) { | 547 FLAG_disassemble || FLAG_disassemble_optimized) { |
| 540 if (FLAG_source_lines) { | 548 if (FLAG_source_lines) { |
| 541 EmitSourceLine(instr); | 549 EmitSourceLine(instr); |
| 542 } | 550 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 560 #endif | 568 #endif |
| 561 } | 569 } |
| 562 | 570 |
| 563 #if defined(DEBUG) | 571 #if defined(DEBUG) |
| 564 ASSERT(is_optimizing() || FrameStateIsSafeToCall()); | 572 ASSERT(is_optimizing() || FrameStateIsSafeToCall()); |
| 565 #endif | 573 #endif |
| 566 } | 574 } |
| 567 | 575 |
| 568 if (is_optimizing()) { | 576 if (is_optimizing()) { |
| 569 LogBlock lb; | 577 LogBlock lb; |
| 570 intervals.Add(IntervalStruct(prev_offset, prev_inlining_id)); | 578 intervals.Add( |
| 579 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id)); | |
| 571 inlined_code_intervals_ = | 580 inlined_code_intervals_ = |
| 572 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld); | 581 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld); |
| 573 Smi& start_h = Smi::Handle(); | 582 Smi& start_h = Smi::Handle(); |
| 574 Smi& caller_inline_id = Smi::Handle(); | 583 Smi& caller_inline_id = Smi::Handle(); |
| 575 Smi& inline_id = Smi::Handle(); | 584 Smi& inline_id = Smi::Handle(); |
| 576 for (intptr_t i = 0; i < intervals.length(); i++) { | 585 for (intptr_t i = 0; i < intervals.length(); i++) { |
| 577 if (FLAG_trace_inlining_intervals && is_optimizing()) { | 586 if (FLAG_trace_inlining_intervals && is_optimizing()) { |
| 578 const Function& function = | 587 const Function& function = |
| 579 *inline_id_to_function_.At(intervals[i].inlining_id); | 588 *inline_id_to_function_.At(intervals[i].inlining_id); |
| 580 intervals[i].Dump(); | 589 intervals[i].Dump(); |
| (...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1745 } | 1754 } |
| 1746 const Array& res = Array::Handle( | 1755 const Array& res = Array::Handle( |
| 1747 Array::New(inline_id_to_function_.length(), Heap::kOld)); | 1756 Array::New(inline_id_to_function_.length(), Heap::kOld)); |
| 1748 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) { | 1757 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) { |
| 1749 res.SetAt(i, *inline_id_to_function_[i]); | 1758 res.SetAt(i, *inline_id_to_function_[i]); |
| 1750 } | 1759 } |
| 1751 return res.raw(); | 1760 return res.raw(); |
| 1752 } | 1761 } |
| 1753 | 1762 |
| 1754 | 1763 |
| 1764 RawArray* FlowGraphCompiler::InliningIdToTokenPos() const { | |
| 1765 if (inline_id_to_token_pos_.length() == 0) { | |
| 1766 return Object::empty_array().raw(); | |
| 1767 } | |
| 1768 const Array& res = Array::Handle( | |
|
srdjan
2016/02/25 22:05:32
zone()
Cutch
2016/02/25 22:36:40
Done.
| |
| 1769 Array::New(inline_id_to_token_pos_.length(), Heap::kOld)); | |
| 1770 Smi& smi = Smi::Handle(); | |
|
srdjan
2016/02/25 22:05:32
zone()
Cutch
2016/02/25 22:36:40
Done.
| |
| 1771 for (intptr_t i = 0; i < inline_id_to_token_pos_.length(); i++) { | |
| 1772 smi = Smi::New(inline_id_to_token_pos_[i].value()); | |
| 1773 res.SetAt(i, smi); | |
| 1774 } | |
| 1775 return res.raw(); | |
| 1776 } | |
| 1777 | |
| 1778 | |
| 1755 RawArray* FlowGraphCompiler::CallerInliningIdMap() const { | 1779 RawArray* FlowGraphCompiler::CallerInliningIdMap() const { |
| 1756 if (caller_inline_id_.length() == 0) { | 1780 if (caller_inline_id_.length() == 0) { |
| 1757 return Object::empty_array().raw(); | 1781 return Object::empty_array().raw(); |
| 1758 } | 1782 } |
| 1759 const Array& res = Array::Handle( | 1783 const Array& res = Array::Handle( |
| 1760 Array::New(caller_inline_id_.length(), Heap::kOld)); | 1784 Array::New(caller_inline_id_.length(), Heap::kOld)); |
| 1761 Smi& smi = Smi::Handle(); | 1785 Smi& smi = Smi::Handle(); |
| 1762 for (intptr_t i = 0; i < caller_inline_id_.length(); i++) { | 1786 for (intptr_t i = 0; i < caller_inline_id_.length(); i++) { |
| 1763 smi = Smi::New(caller_inline_id_[i]); | 1787 smi = Smi::New(caller_inline_id_[i]); |
| 1764 res.SetAt(i, smi); | 1788 res.SetAt(i, smi); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1870 | 1894 |
| 1871 | 1895 |
| 1872 void FlowGraphCompiler::FrameStateClear() { | 1896 void FlowGraphCompiler::FrameStateClear() { |
| 1873 ASSERT(!is_optimizing()); | 1897 ASSERT(!is_optimizing()); |
| 1874 frame_state_.TruncateTo(0); | 1898 frame_state_.TruncateTo(0); |
| 1875 } | 1899 } |
| 1876 #endif | 1900 #endif |
| 1877 | 1901 |
| 1878 | 1902 |
| 1879 } // namespace dart | 1903 } // namespace dart |
| OLD | NEW |