| 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 |