OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 void PrepareForOsrEntry(); | 73 void PrepareForOsrEntry(); |
74 | 74 |
75 void PrepareForLoopExit(Node* loop); | 75 void PrepareForLoopExit(Node* loop); |
76 | 76 |
77 private: | 77 private: |
78 explicit Environment(const Environment* copy); | 78 explicit Environment(const Environment* copy); |
79 void PrepareForLoop(); | 79 void PrepareForLoop(); |
80 | 80 |
81 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); | 81 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); |
82 void UpdateStateValues(Node** state_values, Node** values, int count); | 82 void UpdateStateValues(Node** state_values, Node** values, int count); |
83 void UpdateStateValuesWithCache(Node** state_values, Node** values, | 83 void UpdateStateValuesWithCache(Node** state_values, Node** values, int count, |
84 int count); | 84 const BitVector* liveness); |
85 | 85 |
86 int RegisterToValuesIndex(interpreter::Register the_register) const; | 86 int RegisterToValuesIndex(interpreter::Register the_register) const; |
87 | 87 |
88 Zone* zone() const { return builder_->local_zone(); } | 88 Zone* zone() const { return builder_->local_zone(); } |
89 Graph* graph() const { return builder_->graph(); } | 89 Graph* graph() const { return builder_->graph(); } |
90 CommonOperatorBuilder* common() const { return builder_->common(); } | 90 CommonOperatorBuilder* common() const { return builder_->common(); } |
91 BytecodeGraphBuilder* builder() const { return builder_; } | 91 BytecodeGraphBuilder* builder() const { return builder_; } |
92 const NodeVector* values() const { return &values_; } | 92 const NodeVector* values() const { return &values_; } |
93 NodeVector* values() { return &values_; } | 93 NodeVector* values() { return &values_; } |
94 int register_base() const { return register_base_; } | 94 int register_base() const { return register_base_; } |
95 int accumulator_base() const { return accumulator_base_; } | 95 int accumulator_base() const { return accumulator_base_; } |
96 | 96 |
97 BytecodeGraphBuilder* builder_; | 97 BytecodeGraphBuilder* builder_; |
98 int register_count_; | 98 int register_count_; |
99 int parameter_count_; | 99 int parameter_count_; |
100 Node* context_; | 100 Node* context_; |
101 Node* control_dependency_; | 101 Node* control_dependency_; |
102 Node* effect_dependency_; | 102 Node* effect_dependency_; |
103 NodeVector values_; | 103 NodeVector values_; |
104 Node* parameters_state_values_; | 104 Node* parameters_state_values_; |
105 Node* registers_state_values_; | 105 Node* registers_state_values_; |
106 Node* accumulator_state_values_; | 106 Node* accumulator_state_values_; |
107 int register_base_; | 107 int register_base_; |
108 int accumulator_base_; | 108 int accumulator_base_; |
109 | |
110 // A working area for writing maybe-dead values to when updating the state | |
111 // values for registers. | |
112 NodeVector state_value_working_area_; | |
113 }; | 109 }; |
114 | 110 |
115 | 111 |
116 // Issues: | 112 // Issues: |
117 // - Scopes - intimately tied to AST. Need to eval what is needed. | 113 // - Scopes - intimately tied to AST. Need to eval what is needed. |
118 // - Need to resolve closure parameter treatment. | 114 // - Need to resolve closure parameter treatment. |
119 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, | 115 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
120 int register_count, | 116 int register_count, |
121 int parameter_count, | 117 int parameter_count, |
122 Node* control_dependency, | 118 Node* control_dependency, |
123 Node* context) | 119 Node* context) |
124 : builder_(builder), | 120 : builder_(builder), |
125 register_count_(register_count), | 121 register_count_(register_count), |
126 parameter_count_(parameter_count), | 122 parameter_count_(parameter_count), |
127 context_(context), | 123 context_(context), |
128 control_dependency_(control_dependency), | 124 control_dependency_(control_dependency), |
129 effect_dependency_(control_dependency), | 125 effect_dependency_(control_dependency), |
130 values_(builder->local_zone()), | 126 values_(builder->local_zone()), |
131 parameters_state_values_(nullptr), | 127 parameters_state_values_(nullptr), |
132 registers_state_values_(nullptr), | 128 registers_state_values_(nullptr), |
133 accumulator_state_values_(nullptr), | 129 accumulator_state_values_(nullptr) { |
134 state_value_working_area_(builder->local_zone()) { | |
135 // The layout of values_ is: | 130 // The layout of values_ is: |
136 // | 131 // |
137 // [receiver] [parameters] [registers] [accumulator] | 132 // [receiver] [parameters] [registers] [accumulator] |
138 // | 133 // |
139 // parameter[0] is the receiver (this), parameters 1..N are the | 134 // parameter[0] is the receiver (this), parameters 1..N are the |
140 // parameters supplied to the method (arg0..argN-1). The accumulator | 135 // parameters supplied to the method (arg0..argN-1). The accumulator |
141 // is stored separately. | 136 // is stored separately. |
142 | 137 |
143 // Parameters including the receiver | 138 // Parameters including the receiver |
144 for (int i = 0; i < parameter_count; i++) { | 139 for (int i = 0; i < parameter_count; i++) { |
145 const char* debug_name = (i == 0) ? "%this" : nullptr; | 140 const char* debug_name = (i == 0) ? "%this" : nullptr; |
146 const Operator* op = common()->Parameter(i, debug_name); | 141 const Operator* op = common()->Parameter(i, debug_name); |
147 Node* parameter = builder->graph()->NewNode(op, graph()->start()); | 142 Node* parameter = builder->graph()->NewNode(op, graph()->start()); |
148 values()->push_back(parameter); | 143 values()->push_back(parameter); |
149 } | 144 } |
150 | 145 |
151 // Registers | 146 // Registers |
152 register_base_ = static_cast<int>(values()->size()); | 147 register_base_ = static_cast<int>(values()->size()); |
153 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 148 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
154 values()->insert(values()->end(), register_count, undefined_constant); | 149 values()->insert(values()->end(), register_count, undefined_constant); |
155 | 150 |
156 // Accumulator | 151 // Accumulator |
157 accumulator_base_ = static_cast<int>(values()->size()); | 152 accumulator_base_ = static_cast<int>(values()->size()); |
158 values()->push_back(undefined_constant); | 153 values()->push_back(undefined_constant); |
159 | |
160 state_value_working_area_.resize(register_count_); | |
161 } | 154 } |
162 | 155 |
163 BytecodeGraphBuilder::Environment::Environment( | 156 BytecodeGraphBuilder::Environment::Environment( |
164 const BytecodeGraphBuilder::Environment* other) | 157 const BytecodeGraphBuilder::Environment* other) |
165 : builder_(other->builder_), | 158 : builder_(other->builder_), |
166 register_count_(other->register_count_), | 159 register_count_(other->register_count_), |
167 parameter_count_(other->parameter_count_), | 160 parameter_count_(other->parameter_count_), |
168 context_(other->context_), | 161 context_(other->context_), |
169 control_dependency_(other->control_dependency_), | 162 control_dependency_(other->control_dependency_), |
170 effect_dependency_(other->effect_dependency_), | 163 effect_dependency_(other->effect_dependency_), |
171 values_(other->zone()), | 164 values_(other->zone()), |
172 parameters_state_values_(nullptr), | 165 parameters_state_values_(nullptr), |
173 registers_state_values_(nullptr), | 166 registers_state_values_(nullptr), |
174 accumulator_state_values_(nullptr), | 167 accumulator_state_values_(nullptr), |
175 register_base_(other->register_base_), | 168 register_base_(other->register_base_), |
176 accumulator_base_(other->accumulator_base_), | 169 accumulator_base_(other->accumulator_base_) { |
177 // Environments can share their working area. | |
178 state_value_working_area_(other->state_value_working_area_) { | |
179 values_ = other->values_; | 170 values_ = other->values_; |
180 } | 171 } |
181 | 172 |
182 | 173 |
183 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( | 174 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( |
184 interpreter::Register the_register) const { | 175 interpreter::Register the_register) const { |
185 if (the_register.is_parameter()) { | 176 if (the_register.is_parameter()) { |
186 return the_register.ToParameterIndex(parameter_count()); | 177 return the_register.ToParameterIndex(parameter_count()); |
187 } else { | 178 } else { |
188 return the_register.index() + register_base(); | 179 return the_register.index() + register_base(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 Node* rename = | 380 Node* rename = |
390 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); | 381 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); |
391 values_[i] = rename; | 382 values_[i] = rename; |
392 } | 383 } |
393 } | 384 } |
394 | 385 |
395 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 386 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
396 Node** values, | 387 Node** values, |
397 int count) { | 388 int count) { |
398 if (StateValuesRequireUpdate(state_values, values, count)) { | 389 if (StateValuesRequireUpdate(state_values, values, count)) { |
399 const Operator* op = common()->StateValues(count); | 390 const Operator* op = common()->StateValues(count, 0u); |
400 (*state_values) = graph()->NewNode(op, count, values); | 391 (*state_values) = graph()->NewNode(op, count, values); |
401 } | 392 } |
402 } | 393 } |
403 | 394 |
404 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache( | 395 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache( |
405 Node** state_values, Node** values, int count) { | 396 Node** state_values, Node** values, int count, const BitVector* liveness) { |
406 *state_values = builder_->state_values_cache_.GetNodeForValues( | 397 *state_values = builder_->state_values_cache_.GetNodeForValues( |
407 values, static_cast<size_t>(count)); | 398 values, static_cast<size_t>(count), liveness); |
408 } | 399 } |
409 | 400 |
410 Node* BytecodeGraphBuilder::Environment::Checkpoint( | 401 Node* BytecodeGraphBuilder::Environment::Checkpoint( |
411 BailoutId bailout_id, OutputFrameStateCombine combine, | 402 BailoutId bailout_id, OutputFrameStateCombine combine, |
412 bool owner_has_exception, const BitVector* liveness) { | 403 bool owner_has_exception, const BitVector* liveness) { |
413 UpdateStateValues(¶meters_state_values_, &values()->at(0), | 404 UpdateStateValues(¶meters_state_values_, &values()->at(0), |
414 parameter_count()); | 405 parameter_count()); |
415 | 406 |
416 if (liveness) { | 407 UpdateStateValuesWithCache(®isters_state_values_, |
417 Node* optimized_out = builder()->jsgraph()->OptimizedOutConstant(); | 408 &values()->at(register_base()), register_count(), |
| 409 liveness); |
418 | 410 |
419 for (int i = 0; i < register_count(); ++i) { | 411 Node* accumulator_value = |
420 state_value_working_area_[i] = liveness->Contains(i) | 412 liveness == nullptr || liveness->Contains(register_count()) |
421 ? values()->at(register_base() + i) | 413 ? values()->at(accumulator_base()) |
422 : optimized_out; | 414 : builder()->jsgraph()->OptimizedOutConstant(); |
423 } | 415 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1); |
424 | |
425 Node* accumulator_value = liveness->Contains(register_count()) | |
426 ? values()->at(accumulator_base()) | |
427 : optimized_out; | |
428 | |
429 UpdateStateValuesWithCache(®isters_state_values_, | |
430 state_value_working_area_.data(), | |
431 register_count()); | |
432 | |
433 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1); | |
434 } else { | |
435 UpdateStateValuesWithCache(®isters_state_values_, | |
436 &values()->at(register_base()), | |
437 register_count()); | |
438 UpdateStateValues(&accumulator_state_values_, | |
439 &values()->at(accumulator_base()), 1); | |
440 } | |
441 | 416 |
442 const Operator* op = common()->FrameState( | 417 const Operator* op = common()->FrameState( |
443 bailout_id, combine, builder()->frame_state_function_info()); | 418 bailout_id, combine, builder()->frame_state_function_info()); |
444 Node* result = graph()->NewNode( | 419 Node* result = graph()->NewNode( |
445 op, parameters_state_values_, registers_state_values_, | 420 op, parameters_state_values_, registers_state_values_, |
446 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), | 421 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), |
447 builder()->graph()->start()); | 422 builder()->graph()->start()); |
448 | 423 |
449 return result; | 424 return result; |
450 } | 425 } |
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2202 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2177 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2203 it->Advance(); | 2178 it->Advance(); |
2204 } else { | 2179 } else { |
2205 DCHECK_GT(it->code_offset(), offset); | 2180 DCHECK_GT(it->code_offset(), offset); |
2206 } | 2181 } |
2207 } | 2182 } |
2208 | 2183 |
2209 } // namespace compiler | 2184 } // namespace compiler |
2210 } // namespace internal | 2185 } // namespace internal |
2211 } // namespace v8 | 2186 } // namespace v8 |
OLD | NEW |