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