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

Unified Diff: runtime/vm/intermediate_language.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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 35b3f259666a8c1197f0cfe5141f9368738100b3..5ff497830adb0e475ad04d14628ce30406fdd00e 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -238,12 +238,14 @@ const Object& Value::BoundConstant() const {
GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function,
- TargetEntryInstr* normal_entry)
+ TargetEntryInstr* normal_entry,
+ intptr_t osr_id)
: BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex),
parsed_function_(parsed_function),
normal_entry_(normal_entry),
catch_entries_(),
initial_definitions_(),
+ osr_id_(osr_id),
spill_slot_count_(0),
fixed_slot_count_(0) {
}
@@ -780,6 +782,53 @@ void BlockEntryInstr::DiscoverBlocks(
}
+bool BlockEntryInstr::PruneUnreachable(FlowGraphBuilder* builder,
+ GraphEntryInstr* graph_entry,
+ intptr_t osr_id,
+ BitVector* block_marks) {
+ // Search for the instruction with the OSR id. Use a depth first search
+ // because basic blocks have not been discovered yet. Prune unreachable
+ // blocks by replacing the normal entry with a jump to the block
+ // containing the OSR entry point.
+
+ // Do not visit blocks more than once.
+ if (block_marks->Contains(block_id())) return false;
+ block_marks->Add(block_id());
+
+ // Search this block for the OSR id.
+ Instruction* instr = this;
+ for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
+ instr = it.Current();
+ if (instr->GetDeoptId() == osr_id) {
+ // Sanity check that we found a stack check instruction.
+ ASSERT(instr->IsCheckStackOverflow());
+ // Loop stack check checks are always in join blocks so that they can
+ // be the target of a goto.
+ ASSERT(IsJoinEntry());
+ // The instruction should be the first instruction in the block so
+ // we can simply jump to the beginning of the block.
+ ASSERT(instr->previous() == this);
+
+ GotoInstr* goto_join = new GotoInstr(AsJoinEntry());
+ goto_join->deopt_id_ = deopt_id_;
+ graph_entry->normal_entry()->LinkTo(goto_join);
+ return true;
+ }
+ }
+
+ // Recursively search the successors.
+ for (intptr_t i = instr->SuccessorCount() - 1; i >= 0; --i) {
+ if (instr->SuccessorAt(i)->PruneUnreachable(builder,
+ graph_entry,
+ osr_id,
+ block_marks)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const {
// TODO(fschneider): Make this faster by e.g. storing dominators for each
// block while computing the dominator tree.

Powered by Google App Engine
This is Rietveld 408576698