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 |