1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/crankshaft/hydrogen-osr.h" 6 7 #include "src/crankshaft/hydrogen.h" 8 #include "src/objects-inl.h" 9 10 namespace v8 { 11 namespace internal { 12 13 // True iff. we are compiling for OSR and the statement is the entry. 14 bool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) { 15 return statement->OsrEntryId() == builder_->current_info()->osr_ast_id(); 16 } 17 18 19 HBasicBlock* HOsrBuilder::BuildOsrLoopEntry(IterationStatement* statement) { 20 DCHECK(HasOsrEntryAt(statement)); 21 22 Zone* zone = builder_->zone(); 23 HGraph* graph = builder_->graph(); 24 25 // only one OSR point per compile is allowed. 26 DCHECK(graph->osr() == NULL); 27 28 // remember this builder as the one OSR builder in the graph. 29 graph->set_osr(this); 30 31 HBasicBlock* non_osr_entry = graph->CreateBasicBlock(); 32 osr_entry_ = graph->CreateBasicBlock(); 33 HValue* true_value = graph->GetConstantTrue(); 34 HBranch* test = builder_->New<HBranch>(true_value, ToBooleanHint::kNone, 35 non_osr_entry, osr_entry_); 36 builder_->FinishCurrentBlock(test); 37 38 HBasicBlock* loop_predecessor = graph->CreateBasicBlock(); 39 builder_->Goto(non_osr_entry, loop_predecessor); 40 41 builder_->set_current_block(osr_entry_); 42 osr_entry_->set_osr_entry(); 43 BailoutId osr_entry_id = statement->OsrEntryId(); 44 45 HEnvironment *environment = builder_->environment(); 46 int first_expression_index = environment->first_expression_index(); 47 int length = environment->length(); 48 osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone); 49 50 for (int i = 0; i < first_expression_index; ++i) { 51 HUnknownOSRValue* osr_value 52 = builder_->Add<HUnknownOSRValue>(environment, i); 53 environment->Bind(i, osr_value); 54 osr_values_->Add(osr_value, zone); 55 } 56 57 if (first_expression_index != length) { 58 environment->Drop(length - first_expression_index); 59 for (int i = first_expression_index; i < length; ++i) { 60 HUnknownOSRValue* osr_value 61 = builder_->Add<HUnknownOSRValue>(environment, i); 62 environment->Push(osr_value); 63 osr_values_->Add(osr_value, zone); 64 } 65 } 66 67 unoptimized_frame_slots_ = 68 environment->local_count() + environment->push_count(); 69 70 // Keep a copy of the old environment, since the OSR values need it 71 // to figure out where exactly they are located in the unoptimized frame. 72 environment = environment->Copy(); 73 builder_->current_block()->UpdateEnvironment(environment); 74 75 builder_->Add<HSimulate>(osr_entry_id); 76 builder_->Add<HOsrEntry>(osr_entry_id); 77 HContext* context = builder_->Add<HContext>(); 78 environment->BindContext(context); 79 builder_->Goto(loop_predecessor); 80 loop_predecessor->SetJoinId(statement->EntryId()); 81 builder_->set_current_block(loop_predecessor); 82 83 // Create the final loop entry 84 osr_loop_entry_ = builder_->BuildLoopEntry(); 85 return osr_loop_entry_; 86 } 87 88 89 void HOsrBuilder::FinishGraph() { 90 // do nothing for now. 91 } 92 93 94 void HOsrBuilder::FinishOsrValues() { 95 const ZoneList<HPhi*>* phis = osr_loop_entry_->phis(); 96 for (int j = 0; j < phis->length(); j++) { 97 HPhi* phi = phis->at(j); 98 if (phi->HasMergedIndex()) { 99 osr_values_->at(phi->merged_index())->set_incoming_value(phi); 100 } 101 } 102 } 103 104 } // namespace internal 105 } // namespace v8 106