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

Side by Side 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 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_allocator.h" 10 #include "vm/flow_graph_allocator.h"
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 231
232 const Object& Value::BoundConstant() const { 232 const Object& Value::BoundConstant() const {
233 ASSERT(BindsToConstant()); 233 ASSERT(BindsToConstant());
234 ConstantInstr* constant = definition()->AsConstant(); 234 ConstantInstr* constant = definition()->AsConstant();
235 ASSERT(constant != NULL); 235 ASSERT(constant != NULL);
236 return constant->value(); 236 return constant->value();
237 } 237 }
238 238
239 239
240 GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function, 240 GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function,
241 TargetEntryInstr* normal_entry) 241 TargetEntryInstr* normal_entry,
242 intptr_t osr_id)
242 : BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex), 243 : BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex),
243 parsed_function_(parsed_function), 244 parsed_function_(parsed_function),
244 normal_entry_(normal_entry), 245 normal_entry_(normal_entry),
245 catch_entries_(), 246 catch_entries_(),
246 initial_definitions_(), 247 initial_definitions_(),
248 osr_id_(osr_id),
247 spill_slot_count_(0), 249 spill_slot_count_(0),
248 fixed_slot_count_(0) { 250 fixed_slot_count_(0) {
249 } 251 }
250 252
251 253
252 ConstantInstr* GraphEntryInstr::constant_null() { 254 ConstantInstr* GraphEntryInstr::constant_null() {
253 ASSERT(initial_definitions_.length() > 0); 255 ASSERT(initial_definitions_.length() > 0);
254 for (intptr_t i = 0; i < initial_definitions_.length(); ++i) { 256 for (intptr_t i = 0; i < initial_definitions_.length(); ++i) {
255 ConstantInstr* defn = initial_definitions_[i]->AsConstant(); 257 ConstantInstr* defn = initial_definitions_[i]->AsConstant();
256 if (defn != NULL && defn->value().IsNull()) return defn; 258 if (defn != NULL && defn->value().IsNull()) return defn;
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 variable_count, 775 variable_count,
774 fixed_parameter_count); 776 fixed_parameter_count);
775 } 777 }
776 778
777 // 6. Assign postorder number and add the block entry to the list. 779 // 6. Assign postorder number and add the block entry to the list.
778 set_postorder_number(postorder->length()); 780 set_postorder_number(postorder->length());
779 postorder->Add(this); 781 postorder->Add(this);
780 } 782 }
781 783
782 784
785 bool BlockEntryInstr::PruneUnreachable(FlowGraphBuilder* builder,
786 GraphEntryInstr* graph_entry,
787 intptr_t osr_id,
788 BitVector* block_marks) {
789 // Search for the instruction with the OSR id. Use a depth first search
790 // because basic blocks have not been discovered yet. Prune unreachable
791 // blocks by replacing the normal entry with a jump to the block
792 // containing the OSR entry point.
793
794 // Do not visit blocks more than once.
795 if (block_marks->Contains(block_id())) return false;
796 block_marks->Add(block_id());
797
798 // Search this block for the OSR id.
799 Instruction* instr = this;
800 for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
801 instr = it.Current();
802 if (instr->GetDeoptId() == osr_id) {
803 // Sanity check that we found a stack check instruction.
804 ASSERT(instr->IsCheckStackOverflow());
805 // Loop stack check checks are always in join blocks so that they can
806 // be the target of a goto.
807 ASSERT(IsJoinEntry());
808 // The instruction should be the first instruction in the block so
809 // we can simply jump to the beginning of the block.
810 ASSERT(instr->previous() == this);
811
812 GotoInstr* goto_join = new GotoInstr(AsJoinEntry());
813 goto_join->deopt_id_ = deopt_id_;
814 graph_entry->normal_entry()->LinkTo(goto_join);
815 return true;
816 }
817 }
818
819 // Recursively search the successors.
820 for (intptr_t i = instr->SuccessorCount() - 1; i >= 0; --i) {
821 if (instr->SuccessorAt(i)->PruneUnreachable(builder,
822 graph_entry,
823 osr_id,
824 block_marks)) {
825 return true;
826 }
827 }
828 return false;
829 }
830
831
783 bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const { 832 bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const {
784 // TODO(fschneider): Make this faster by e.g. storing dominators for each 833 // TODO(fschneider): Make this faster by e.g. storing dominators for each
785 // block while computing the dominator tree. 834 // block while computing the dominator tree.
786 ASSERT(other != NULL); 835 ASSERT(other != NULL);
787 BlockEntryInstr* current = other; 836 BlockEntryInstr* current = other;
788 while (current != NULL && current != this) { 837 while (current != NULL && current != this) {
789 current = current->dominator(); 838 current = current->dominator();
790 } 839 }
791 return current == this; 840 return current == this;
792 } 841 }
(...skipping 1700 matching lines...) Expand 10 before | Expand all | Expand 10 after
2493 default: 2542 default:
2494 UNREACHABLE(); 2543 UNREACHABLE();
2495 } 2544 }
2496 return kPowRuntimeEntry; 2545 return kPowRuntimeEntry;
2497 } 2546 }
2498 2547
2499 2548
2500 #undef __ 2549 #undef __
2501 2550
2502 } // namespace dart 2551 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698