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

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

Issue 790213004: Add inlining ranges/intervals to code objects so that we can map a pc to the inlined stack. The map… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 | Annotate | Revision Log
« 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 if (it.CurrentLocation().IsInvalid()) { 73 if (it.CurrentLocation().IsInvalid()) {
74 MaterializeObjectInstr* mat = 74 MaterializeObjectInstr* mat =
75 it.CurrentValue()->definition()->AsMaterializeObject(); 75 it.CurrentValue()->definition()->AsMaterializeObject();
76 ASSERT(mat != NULL); 76 ASSERT(mat != NULL);
77 builder->AddMaterialization(mat); 77 builder->AddMaterialization(mat);
78 } 78 }
79 } 79 }
80 } 80 }
81 81
82 82
83 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, 83 FlowGraphCompiler::FlowGraphCompiler(
84 FlowGraph* flow_graph, 84 Assembler* assembler,
85 bool is_optimizing) 85 FlowGraph* flow_graph,
86 : isolate_(Isolate::Current()), 86 bool is_optimizing,
87 assembler_(assembler), 87 const GrowableArray<const Function*>& inline_id_to_function)
88 parsed_function_(*flow_graph->parsed_function()), 88 : isolate_(Isolate::Current()),
89 flow_graph_(*flow_graph), 89 assembler_(assembler),
90 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)), 90 parsed_function_(*flow_graph->parsed_function()),
91 current_block_(NULL), 91 flow_graph_(*flow_graph),
92 exception_handlers_list_(NULL), 92 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)),
93 pc_descriptors_list_(NULL), 93 current_block_(NULL),
94 stackmap_table_builder_( 94 exception_handlers_list_(NULL),
95 is_optimizing ? new StackmapTableBuilder() : NULL), 95 pc_descriptors_list_(NULL),
96 block_info_(block_order_.length()), 96 stackmap_table_builder_(
97 deopt_infos_(), 97 is_optimizing ? new StackmapTableBuilder() : NULL),
98 static_calls_target_table_(GrowableObjectArray::ZoneHandle( 98 block_info_(block_order_.length()),
99 GrowableObjectArray::New())), 99 deopt_infos_(),
100 is_optimizing_(is_optimizing), 100 static_calls_target_table_(GrowableObjectArray::ZoneHandle(
101 may_reoptimize_(false), 101 GrowableObjectArray::New())),
102 intrinsic_mode_(false), 102 is_optimizing_(is_optimizing),
103 double_class_(Class::ZoneHandle( 103 may_reoptimize_(false),
104 isolate_->object_store()->double_class())), 104 intrinsic_mode_(false),
105 mint_class_(Class::ZoneHandle( 105 double_class_(Class::ZoneHandle(
106 isolate_->object_store()->mint_class())), 106 isolate_->object_store()->double_class())),
107 float32x4_class_(Class::ZoneHandle( 107 mint_class_(Class::ZoneHandle(
108 isolate_->object_store()->float32x4_class())), 108 isolate_->object_store()->mint_class())),
109 float64x2_class_(Class::ZoneHandle( 109 float32x4_class_(Class::ZoneHandle(
110 isolate_->object_store()->float64x2_class())), 110 isolate_->object_store()->float32x4_class())),
111 int32x4_class_(Class::ZoneHandle( 111 float64x2_class_(Class::ZoneHandle(
112 isolate_->object_store()->int32x4_class())), 112 isolate_->object_store()->float64x2_class())),
113 list_class_(Class::ZoneHandle( 113 int32x4_class_(Class::ZoneHandle(
114 Library::Handle(Library::CoreLibrary()). 114 isolate_->object_store()->int32x4_class())),
115 LookupClass(Symbols::List()))), 115 list_class_(Class::ZoneHandle(
116 parallel_move_resolver_(this), 116 Library::Handle(Library::CoreLibrary()).
117 pending_deoptimization_env_(NULL), 117 LookupClass(Symbols::List()))),
118 entry_patch_pc_offset_(Code::kInvalidPc), 118 parallel_move_resolver_(this),
119 patch_code_pc_offset_(Code::kInvalidPc), 119 pending_deoptimization_env_(NULL),
120 lazy_deopt_pc_offset_(Code::kInvalidPc) { 120 entry_patch_pc_offset_(Code::kInvalidPc),
121 patch_code_pc_offset_(Code::kInvalidPc),
122 lazy_deopt_pc_offset_(Code::kInvalidPc),
123 deopt_id_to_ic_data_(NULL),
124 inlined_code_intervals_(NULL),
125 inline_id_to_function_(inline_id_to_function) {
121 if (!is_optimizing) { 126 if (!is_optimizing) {
122 const intptr_t len = isolate()->deopt_id(); 127 const intptr_t len = isolate()->deopt_id();
123 deopt_id_to_ic_data_ = new(isolate()) ZoneGrowableArray<const ICData*>(len); 128 deopt_id_to_ic_data_ = new(isolate()) ZoneGrowableArray<const ICData*>(len);
124 deopt_id_to_ic_data_->SetLength(len); 129 deopt_id_to_ic_data_->SetLength(len);
125 for (intptr_t i = 0; i < len; i++) { 130 for (intptr_t i = 0; i < len; i++) {
126 (*deopt_id_to_ic_data_)[i] = NULL; 131 (*deopt_id_to_ic_data_)[i] = NULL;
127 } 132 }
128 const Array& old_saved_icdata = Array::Handle(isolate(), 133 const Array& old_saved_icdata = Array::Handle(isolate(),
129 flow_graph->parsed_function()->function().ic_data_array()); 134 flow_graph->parsed_function()->function().ic_data_array());
130 const intptr_t saved_len = 135 const intptr_t saved_len =
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 loop_it.Advance()) { 334 loop_it.Advance()) {
330 if (loop_it.Current() == block.preorder_number()) { 335 if (loop_it.Current() == block.preorder_number()) {
331 assembler->Comment(" Loop %" Pd "", loop_id); 336 assembler->Comment(" Loop %" Pd "", loop_id);
332 } 337 }
333 } 338 }
334 } 339 }
335 } 340 }
336 } 341 }
337 342
338 343
344 // We collect intervals while generating code.
345 struct IntervalStruct {
346 // 'start' and 'end' are pc-offsets.
347 intptr_t start;
348 intptr_t end;
349 intptr_t inlining_id;
350 IntervalStruct(intptr_t s, intptr_t e, intptr_t id)
351 : start(s), end(e), inlining_id(id) {}
352 };
353
354
339 void FlowGraphCompiler::VisitBlocks() { 355 void FlowGraphCompiler::VisitBlocks() {
340 CompactBlocks(); 356 CompactBlocks();
341 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL; 357 const ZoneGrowableArray<BlockEntryInstr*>* loop_headers = NULL;
342 if (Assembler::EmittingComments()) { 358 if (Assembler::EmittingComments()) {
343 // 'loop_headers' were cleared, recompute. 359 // 'loop_headers' were cleared, recompute.
344 loop_headers = flow_graph().ComputeLoops(); 360 loop_headers = flow_graph().ComputeLoops();
345 ASSERT(loop_headers != NULL); 361 ASSERT(loop_headers != NULL);
346 } 362 }
347 363
364 // For collecting intervals of inlined code.
365 GrowableArray<IntervalStruct> intervals;
366 intptr_t prev_offset = 0;
367 intptr_t prev_inlining_id = 0;
368 intptr_t max_inlining_id = 0;
348 for (intptr_t i = 0; i < block_order().length(); ++i) { 369 for (intptr_t i = 0; i < block_order().length(); ++i) {
349 // Compile the block entry. 370 // Compile the block entry.
350 BlockEntryInstr* entry = block_order()[i]; 371 BlockEntryInstr* entry = block_order()[i];
351 assembler()->Comment("B%" Pd "", entry->block_id()); 372 assembler()->Comment("B%" Pd "", entry->block_id());
352 set_current_block(entry); 373 set_current_block(entry);
353 374
354 if (WasCompacted(entry)) { 375 if (WasCompacted(entry)) {
355 continue; 376 continue;
356 } 377 }
357 378
358 LoopInfoComment(assembler(), *entry, *loop_headers); 379 LoopInfoComment(assembler(), *entry, *loop_headers);
359 380
360 entry->set_offset(assembler()->CodeSize()); 381 entry->set_offset(assembler()->CodeSize());
361 entry->EmitNativeCode(this); 382 entry->EmitNativeCode(this);
362 // Compile all successors until an exit, branch, or a block entry. 383 // Compile all successors until an exit, branch, or a block entry.
363 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 384 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
364 Instruction* instr = it.Current(); 385 Instruction* instr = it.Current();
386 // Compose intervals.
387 if (instr->has_inlining_id() && is_optimizing()) {
388 if (prev_inlining_id != instr->inlining_id()) {
389 intervals.Add(IntervalStruct(prev_offset,
390 assembler()->CodeSize(),
391 prev_inlining_id));
392 prev_offset = assembler()->CodeSize();
393 prev_inlining_id = instr->inlining_id();
394 if (prev_inlining_id > max_inlining_id) {
395 max_inlining_id = prev_inlining_id;
396 }
397 }
398 }
365 if (FLAG_code_comments || 399 if (FLAG_code_comments ||
366 FLAG_disassemble || 400 FLAG_disassemble ||
367 FLAG_disassemble_optimized) { 401 FLAG_disassemble_optimized) {
368 if (FLAG_source_lines) { 402 if (FLAG_source_lines) {
369 EmitSourceLine(instr); 403 EmitSourceLine(instr);
370 } 404 }
371 EmitComment(instr); 405 EmitComment(instr);
372 } 406 }
373 if (instr->IsParallelMove()) { 407 if (instr->IsParallelMove()) {
374 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); 408 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove());
375 } else { 409 } else {
376 EmitInstructionPrologue(instr); 410 EmitInstructionPrologue(instr);
377 ASSERT(pending_deoptimization_env_ == NULL); 411 ASSERT(pending_deoptimization_env_ == NULL);
378 pending_deoptimization_env_ = instr->env(); 412 pending_deoptimization_env_ = instr->env();
379 instr->EmitNativeCode(this); 413 instr->EmitNativeCode(this);
380 pending_deoptimization_env_ = NULL; 414 pending_deoptimization_env_ = NULL;
381 EmitInstructionEpilogue(instr); 415 EmitInstructionEpilogue(instr);
382 } 416 }
383 } 417 }
384 } 418 }
419
420 intervals.Add(IntervalStruct(prev_offset, assembler()->CodeSize(),
421 prev_inlining_id));
422 // Note that ranges [start..end] must be monotonically increasing in
423 // 'intervals' array.
424 inlined_code_intervals_ = &Array::ZoneHandle(Array::New(
425 (max_inlining_id + 1) * Code::kInlIntNumEntries, Heap::kOld));
426
427 Smi& start_h = Smi::Handle();
428 Smi& end_h = Smi::Handle();
429 for (intptr_t i = 0; i < intervals.length(); i++) {
430 const intptr_t id = intervals[i].inlining_id;
431 end_h = Smi::New(intervals[i].end);
432 if (inlined_code_intervals_->At
433 (id * Code::kInlIntNumEntries + Code::kInlIntFunction) ==
434 Object::null()) {
435 start_h = Smi::New(intervals[i].start);
436 inlined_code_intervals_->SetAt(
437 id * Code::kInlIntNumEntries + Code::kInlIntStart, start_h);
438 inlined_code_intervals_->SetAt(
439 id * Code::kInlIntNumEntries + Code::kInlIntEnd, end_h);
440 const Function* function =
441 inline_id_to_function_.At(intervals[i].inlining_id);
442 inlined_code_intervals_->SetAt(
443 id * Code::kInlIntNumEntries + Code::kInlIntFunction, *function);
444 } else {
445 // Check for monotonic increase.
446 #if defined(DEBUG)
447 Smi& temp = Smi::Handle();
448 temp ^= inlined_code_intervals_->At(
449 id * Code::kInlIntNumEntries + Code::kInlIntStart);
450 start_h = Smi::New(intervals[i].start);
451 ASSERT(temp.Value() <= start_h.Value());
452 temp ^= inlined_code_intervals_->At(
453 id * Code::kInlIntNumEntries + Code::kInlIntEnd);
454 ASSERT(temp.Value() <= end_h.Value());
455 #endif
Cutch 2014/12/19 18:15:01 Also add an ASSERT that functions match.
srdjan 2014/12/19 19:58:44 Done.
456 inlined_code_intervals_->SetAt(
457 id * Code::kInlIntNumEntries + Code::kInlIntEnd, end_h);
458 }
459 }
385 set_current_block(NULL); 460 set_current_block(NULL);
386 } 461 }
387 462
388 463
389 void FlowGraphCompiler::Bailout(const char* reason) { 464 void FlowGraphCompiler::Bailout(const char* reason) {
390 const Function& function = parsed_function_.function(); 465 const Function& function = parsed_function_.function();
391 Report::MessageF(Report::kBailout, 466 Report::MessageF(Report::kBailout,
392 Script::Handle(function.script()), 467 Script::Handle(function.script()),
393 function.token_pos(), 468 function.token_pos(),
394 "FlowGraphCompiler Bailout: %s %s", 469 "FlowGraphCompiler Bailout: %s %s",
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 case kUnboxedMint: 1555 case kUnboxedMint:
1481 return mint_class(); 1556 return mint_class();
1482 default: 1557 default:
1483 UNREACHABLE(); 1558 UNREACHABLE();
1484 return Class::ZoneHandle(); 1559 return Class::ZoneHandle();
1485 } 1560 }
1486 } 1561 }
1487 1562
1488 1563
1489 } // namespace dart 1564 } // 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