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

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

Issue 1739963002: Remember token position where a function was inlined (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_inliner.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) 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
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
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
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' is the pc-offsets where the inlined code started.
483 // 'pos' is the token position where the inlined call occured.
481 intptr_t start; 484 intptr_t start;
485 TokenPosition pos;
482 intptr_t inlining_id; 486 intptr_t inlining_id;
483 IntervalStruct(intptr_t s, intptr_t id) : start(s), inlining_id(id) {} 487 IntervalStruct(intptr_t s, TokenPosition tp, intptr_t id)
488 : start(s), pos(tp), inlining_id(id) {}
484 void Dump() { 489 void Dump() {
485 THR_Print("start: 0x%" Px " iid: %" Pd " ", start, inlining_id); 490 THR_Print("start: 0x%" Px " iid: %" Pd " pos: %s",
491 start, inlining_id, pos.ToCString());
486 } 492 }
487 }; 493 };
488 494
489 495
490 void FlowGraphCompiler::VisitBlocks() { 496 void FlowGraphCompiler::VisitBlocks() {
491 CompactBlocks(); 497 CompactBlocks();
492 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL; 498 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL;
493 if (Assembler::EmittingComments()) { 499 if (Assembler::EmittingComments()) {
494 // 'loop_headers' were cleared, recompute. 500 // 'loop_headers' were cleared, recompute.
495 loop_headers = flow_graph().ComputeLoops(); 501 loop_headers = flow_graph().ComputeLoops();
496 ASSERT(loop_headers != NULL); 502 ASSERT(loop_headers != NULL);
497 } 503 }
498 504
499 // For collecting intervals of inlined code. 505 // For collecting intervals of inlined code.
500 GrowableArray<IntervalStruct> intervals; 506 GrowableArray<IntervalStruct> intervals;
501 intptr_t prev_offset = 0; 507 intptr_t prev_offset = 0;
502 intptr_t prev_inlining_id = 0; 508 intptr_t prev_inlining_id = 0;
509 TokenPosition prev_inlining_pos = parsed_function_.function().token_pos();
503 intptr_t max_inlining_id = 0; 510 intptr_t max_inlining_id = 0;
504 for (intptr_t i = 0; i < block_order().length(); ++i) { 511 for (intptr_t i = 0; i < block_order().length(); ++i) {
505 // Compile the block entry. 512 // Compile the block entry.
506 BlockEntryInstr* entry = block_order()[i]; 513 BlockEntryInstr* entry = block_order()[i];
507 assembler()->Comment("B%" Pd "", entry->block_id()); 514 assembler()->Comment("B%" Pd "", entry->block_id());
508 set_current_block(entry); 515 set_current_block(entry);
509 516
510 if (WasCompacted(entry)) { 517 if (WasCompacted(entry)) {
511 continue; 518 continue;
512 } 519 }
513 520
514 #if defined(DEBUG) 521 #if defined(DEBUG)
515 if (!is_optimizing()) { 522 if (!is_optimizing()) {
516 FrameStateClear(); 523 FrameStateClear();
517 } 524 }
518 #endif 525 #endif
519 526
520 LoopInfoComment(assembler(), *entry, *loop_headers); 527 LoopInfoComment(assembler(), *entry, *loop_headers);
521 528
522 entry->set_offset(assembler()->CodeSize()); 529 entry->set_offset(assembler()->CodeSize());
523 entry->EmitNativeCode(this); 530 entry->EmitNativeCode(this);
524 // Compile all successors until an exit, branch, or a block entry. 531 // Compile all successors until an exit, branch, or a block entry.
525 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 532 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
526 Instruction* instr = it.Current(); 533 Instruction* instr = it.Current();
527 // Compose intervals. 534 // Compose intervals.
528 if (instr->has_inlining_id() && is_optimizing()) { 535 if (instr->has_inlining_id() && is_optimizing()) {
529 if (prev_inlining_id != instr->inlining_id()) { 536 if (prev_inlining_id != instr->inlining_id()) {
530 intervals.Add(IntervalStruct(prev_offset, prev_inlining_id)); 537 intervals.Add(
538 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id));
531 prev_offset = assembler()->CodeSize(); 539 prev_offset = assembler()->CodeSize();
532 prev_inlining_id = instr->inlining_id(); 540 prev_inlining_id = instr->inlining_id();
541 prev_inlining_pos = inline_id_to_token_pos_[prev_inlining_id];
533 if (prev_inlining_id > max_inlining_id) { 542 if (prev_inlining_id > max_inlining_id) {
534 max_inlining_id = prev_inlining_id; 543 max_inlining_id = prev_inlining_id;
535 } 544 }
536 } 545 }
537 } 546 }
538 if (FLAG_code_comments || 547 if (FLAG_code_comments ||
539 FLAG_disassemble || FLAG_disassemble_optimized) { 548 FLAG_disassemble || FLAG_disassemble_optimized) {
540 if (FLAG_source_lines) { 549 if (FLAG_source_lines) {
541 EmitSourceLine(instr); 550 EmitSourceLine(instr);
542 } 551 }
(...skipping 17 matching lines...) Expand all
560 #endif 569 #endif
561 } 570 }
562 571
563 #if defined(DEBUG) 572 #if defined(DEBUG)
564 ASSERT(is_optimizing() || FrameStateIsSafeToCall()); 573 ASSERT(is_optimizing() || FrameStateIsSafeToCall());
565 #endif 574 #endif
566 } 575 }
567 576
568 if (is_optimizing()) { 577 if (is_optimizing()) {
569 LogBlock lb; 578 LogBlock lb;
570 intervals.Add(IntervalStruct(prev_offset, prev_inlining_id)); 579 intervals.Add(
580 IntervalStruct(prev_offset, prev_inlining_pos, prev_inlining_id));
571 inlined_code_intervals_ = 581 inlined_code_intervals_ =
572 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld); 582 Array::New(intervals.length() * Code::kInlIntNumEntries, Heap::kOld);
573 Smi& start_h = Smi::Handle(); 583 Smi& start_h = Smi::Handle();
574 Smi& caller_inline_id = Smi::Handle(); 584 Smi& caller_inline_id = Smi::Handle();
575 Smi& inline_id = Smi::Handle(); 585 Smi& inline_id = Smi::Handle();
576 for (intptr_t i = 0; i < intervals.length(); i++) { 586 for (intptr_t i = 0; i < intervals.length(); i++) {
577 if (FLAG_trace_inlining_intervals && is_optimizing()) { 587 if (FLAG_trace_inlining_intervals && is_optimizing()) {
578 const Function& function = 588 const Function& function =
579 *inline_id_to_function_.At(intervals[i].inlining_id); 589 *inline_id_to_function_.At(intervals[i].inlining_id);
580 intervals[i].Dump(); 590 intervals[i].Dump();
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 } 1755 }
1746 const Array& res = Array::Handle( 1756 const Array& res = Array::Handle(
1747 Array::New(inline_id_to_function_.length(), Heap::kOld)); 1757 Array::New(inline_id_to_function_.length(), Heap::kOld));
1748 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) { 1758 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) {
1749 res.SetAt(i, *inline_id_to_function_[i]); 1759 res.SetAt(i, *inline_id_to_function_[i]);
1750 } 1760 }
1751 return res.raw(); 1761 return res.raw();
1752 } 1762 }
1753 1763
1754 1764
1765 RawArray* FlowGraphCompiler::InliningIdToTokenPos() const {
1766 if (inline_id_to_token_pos_.length() == 0) {
1767 return Object::empty_array().raw();
1768 }
1769 const Array& res = Array::Handle(zone(),
1770 Array::New(inline_id_to_token_pos_.length(), Heap::kOld));
1771 Smi& smi = Smi::Handle(zone());
1772 for (intptr_t i = 0; i < inline_id_to_token_pos_.length(); i++) {
1773 smi = Smi::New(inline_id_to_token_pos_[i].value());
1774 res.SetAt(i, smi);
1775 }
1776 return res.raw();
1777 }
1778
1779
1755 RawArray* FlowGraphCompiler::CallerInliningIdMap() const { 1780 RawArray* FlowGraphCompiler::CallerInliningIdMap() const {
1756 if (caller_inline_id_.length() == 0) { 1781 if (caller_inline_id_.length() == 0) {
1757 return Object::empty_array().raw(); 1782 return Object::empty_array().raw();
1758 } 1783 }
1759 const Array& res = Array::Handle( 1784 const Array& res = Array::Handle(
1760 Array::New(caller_inline_id_.length(), Heap::kOld)); 1785 Array::New(caller_inline_id_.length(), Heap::kOld));
1761 Smi& smi = Smi::Handle(); 1786 Smi& smi = Smi::Handle();
1762 for (intptr_t i = 0; i < caller_inline_id_.length(); i++) { 1787 for (intptr_t i = 0; i < caller_inline_id_.length(); i++) {
1763 smi = Smi::New(caller_inline_id_[i]); 1788 smi = Smi::New(caller_inline_id_[i]);
1764 res.SetAt(i, smi); 1789 res.SetAt(i, smi);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 1895
1871 1896
1872 void FlowGraphCompiler::FrameStateClear() { 1897 void FlowGraphCompiler::FrameStateClear() {
1873 ASSERT(!is_optimizing()); 1898 ASSERT(!is_optimizing());
1874 frame_state_.TruncateTo(0); 1899 frame_state_.TruncateTo(0);
1875 } 1900 }
1876 #endif 1901 #endif
1877 1902
1878 1903
1879 } // namespace dart 1904 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_inliner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698