| OLD | NEW |
| (Empty) |
| 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 DCHECK(HasOsrEntryAt(statement)); | |
| 19 | |
| 20 Zone* zone = builder_->zone(); | |
| 21 HGraph* graph = builder_->graph(); | |
| 22 | |
| 23 // only one OSR point per compile is allowed. | |
| 24 DCHECK(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 internal | |
| 103 } // namespace v8 | |
| OLD | NEW |