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

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

Issue 16693006: Initial implementation of on-stack replacement (OSR). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Clean up for review. Created 7 years, 6 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 | Annotate | Revision Log
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/flow_graph_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/flow_graph.h" 10 #include "vm/flow_graph.h"
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 ConnectIncomingPhiMoves(block->AsJoinEntry()); 503 ConnectIncomingPhiMoves(block->AsJoinEntry());
504 } else if (block->IsCatchBlockEntry()) { 504 } else if (block->IsCatchBlockEntry()) {
505 // Process initial definitions. 505 // Process initial definitions.
506 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); 506 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
507 for (intptr_t i = 0; 507 for (intptr_t i = 0;
508 i < catch_entry->initial_definitions()->length(); 508 i < catch_entry->initial_definitions()->length();
509 i++) { 509 i++) {
510 Definition* defn = (*catch_entry->initial_definitions())[i]; 510 Definition* defn = (*catch_entry->initial_definitions())[i];
511 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); 511 LiveRange* range = GetLiveRange(defn->ssa_temp_index());
512 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. 512 range->DefineAt(catch_entry->start_pos()); // Defined at block entry.
513
514 // Save range->End() because it may change in ProcessInitialDefinition.
515 intptr_t range_end = range->End();
516 ProcessInitialDefinition(defn, range, catch_entry); 513 ProcessInitialDefinition(defn, range, catch_entry);
517 spill_slots_.Add(range_end);
518 quad_spill_slots_.Add(false);
519
520 if (defn->IsParameter() && range->spill_slot().stack_index() >= 0) {
521 MarkAsObjectAtSafepoints(range);
522 }
523 } 514 }
524 } 515 }
525 } 516 }
526 517
527 // Process incoming parameters and constants. Do this after all other 518 // Process incoming parameters and constants. Do this after all other
528 // instructions so that safepoints for all calls have already been found. 519 // instructions so that safepoints for all calls have already been found.
529 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); 520 GraphEntryInstr* graph_entry = flow_graph_.graph_entry();
530 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { 521 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
531 Definition* defn = (*graph_entry->initial_definitions())[i]; 522 Definition* defn = (*graph_entry->initial_definitions())[i];
532 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); 523 LiveRange* range = GetLiveRange(defn->ssa_temp_index());
533 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); 524 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
534 range->DefineAt(graph_entry->start_pos()); 525 range->DefineAt(graph_entry->start_pos());
535
536 // Save range->End() because it may change in ProcessInitialDefinition.
537 intptr_t range_end = range->End();
538 ProcessInitialDefinition(defn, range, graph_entry); 526 ProcessInitialDefinition(defn, range, graph_entry);
539 if (defn->IsParameter() && flow_graph_.num_copied_params() > 0) {
540 spill_slots_.Add(range_end);
541 quad_spill_slots_.Add(false);
542
543 MarkAsObjectAtSafepoints(range);
544 }
545 } 527 }
546 } 528 }
547 529
548 530
549 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn, 531 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
550 LiveRange* range, 532 LiveRange* range,
551 BlockEntryInstr* block) { 533 BlockEntryInstr* block) {
534 // Save the range end because it may change below.
535 intptr_t range_end = range->End();
552 if (defn->IsParameter()) { 536 if (defn->IsParameter()) {
553 ParameterInstr* param = defn->AsParameter(); 537 ParameterInstr* param = defn->AsParameter();
554 // Assert that copied and non-copied parameters are mutually exclusive. 538 // Assert that copied and non-copied parameters are mutually exclusive.
555 // This might change in the future and, if so, the index will be wrong. 539 // This might change in the future and, if so, the index will be wrong.
556 ASSERT((flow_graph_.num_copied_params() == 0) || 540 ASSERT((flow_graph_.num_copied_params() == 0) ||
557 (flow_graph_.num_non_copied_params() == 0)); 541 (flow_graph_.num_non_copied_params() == 0));
558 // Slot index for the leftmost copied parameter is 0. 542 // Slot index for the leftmost copied parameter is 0.
559 intptr_t slot_index = param->index(); 543 intptr_t slot_index = param->index();
560 // Slot index for the rightmost fixed parameter is -1. 544 // Slot index for the rightmost fixed parameter is -1.
561 slot_index -= flow_graph_.num_non_copied_params(); 545 slot_index -= flow_graph_.num_non_copied_params();
(...skipping 10 matching lines...) Expand all
572 range->finger()->Initialize(range); 556 range->finger()->Initialize(range);
573 UsePosition* use = 557 UsePosition* use =
574 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); 558 range->finger()->FirstRegisterBeneficialUse(block->start_pos());
575 if (use != NULL) { 559 if (use != NULL) {
576 LiveRange* tail = 560 LiveRange* tail =
577 SplitBetween(range, block->start_pos(), use->pos()); 561 SplitBetween(range, block->start_pos(), use->pos());
578 // Parameters and constants are tagged, so allocated to CPU registers. 562 // Parameters and constants are tagged, so allocated to CPU registers.
579 CompleteRange(tail, Location::kRegister); 563 CompleteRange(tail, Location::kRegister);
580 } 564 }
581 ConvertAllUses(range); 565 ConvertAllUses(range);
566 if (defn->IsParameter() && range->spill_slot().stack_index() >= 0) {
srdjan 2013/06/11 17:12:02 Add parentheses.
Kevin Millikin (Google) 2013/06/14 10:10:42 Done.
567 // Parameters above the frame pointer consume spill slots and are marked
568 // in stack maps.
569 spill_slots_.Add(range_end);
570 quad_spill_slots_.Add(false);
571 MarkAsObjectAtSafepoints(range);
572 } else if (defn->IsConstant() && block->IsCatchBlockEntry()) {
573 // Constants at catch block entries consume spill slots.
574 spill_slots_.Add(range_end);
575 quad_spill_slots_.Add(false);
576 }
582 } 577 }
583 578
584 579
585 static Location::Kind RegisterKindFromPolicy(Location loc) { 580 static Location::Kind RegisterKindFromPolicy(Location loc) {
586 if (loc.policy() == Location::kRequiresFpuRegister) { 581 if (loc.policy() == Location::kRequiresFpuRegister) {
587 return Location::kFpuRegister; 582 return Location::kFpuRegister;
588 } else { 583 } else {
589 return Location::kRegister; 584 return Location::kRegister;
590 } 585 }
591 } 586 }
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 if (idx == spill_slots_.length()) { 1605 if (idx == spill_slots_.length()) {
1611 // No free spill slot found. Allocate a new one. 1606 // No free spill slot found. Allocate a new one.
1612 spill_slots_.Add(0); 1607 spill_slots_.Add(0);
1613 quad_spill_slots_.Add(need_quad); 1608 quad_spill_slots_.Add(need_quad);
1614 if (need_quad) { // Allocate two double stack slots if we need quad slot. 1609 if (need_quad) { // Allocate two double stack slots if we need quad slot.
1615 spill_slots_.Add(0); 1610 spill_slots_.Add(0);
1616 quad_spill_slots_.Add(need_quad); 1611 quad_spill_slots_.Add(need_quad);
1617 } 1612 }
1618 } 1613 }
1619 1614
1620
1621 // Set spill slot expiration boundary to the live range's end. 1615 // Set spill slot expiration boundary to the live range's end.
1622 spill_slots_[idx] = end; 1616 spill_slots_[idx] = end;
1623 if (need_quad) { 1617 if (need_quad) {
1624 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]); 1618 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]);
1625 idx++; // Use the higher index it corresponds to the lower stack address. 1619 idx++; // Use the higher index it corresponds to the lower stack address.
1626 spill_slots_[idx] = end; 1620 spill_slots_[idx] = end;
1627 } else { 1621 } else {
1628 ASSERT(!quad_spill_slots_[idx]); 1622 ASSERT(!quad_spill_slots_[idx]);
1629 } 1623 }
1630 1624
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2585 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2592 function.ToFullyQualifiedCString()); 2586 function.ToFullyQualifiedCString());
2593 FlowGraphPrinter printer(flow_graph_, true); 2587 FlowGraphPrinter printer(flow_graph_, true);
2594 printer.PrintBlocks(); 2588 printer.PrintBlocks();
2595 OS::Print("----------------------------------------------\n"); 2589 OS::Print("----------------------------------------------\n");
2596 } 2590 }
2597 } 2591 }
2598 2592
2599 2593
2600 } // namespace dart 2594 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698