| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 void PrepareForOsrEntry(); | 75 void PrepareForOsrEntry(); |
| 76 | 76 |
| 77 void PrepareForLoopExit(Node* loop); | 77 void PrepareForLoopExit(Node* loop); |
| 78 | 78 |
| 79 private: | 79 private: |
| 80 explicit Environment(const Environment* copy); | 80 explicit Environment(const Environment* copy); |
| 81 void PrepareForLoop(); | 81 void PrepareForLoop(); |
| 82 | 82 |
| 83 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); | 83 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); |
| 84 void UpdateStateValues(Node** state_values, Node** values, int count); | 84 void UpdateStateValues(Node** state_values, Node** values, int count); |
| 85 void UpdateStateValuesWithCache(Node** state_values, Node** values, | 85 void UpdateStateValuesWithCache(Node** state_values, Node** values, int count, |
| 86 int count); | 86 const BitVector* liveness); |
| 87 | 87 |
| 88 int RegisterToValuesIndex(interpreter::Register the_register) const; | 88 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| 89 | 89 |
| 90 Zone* zone() const { return builder_->local_zone(); } | 90 Zone* zone() const { return builder_->local_zone(); } |
| 91 Graph* graph() const { return builder_->graph(); } | 91 Graph* graph() const { return builder_->graph(); } |
| 92 CommonOperatorBuilder* common() const { return builder_->common(); } | 92 CommonOperatorBuilder* common() const { return builder_->common(); } |
| 93 BytecodeGraphBuilder* builder() const { return builder_; } | 93 BytecodeGraphBuilder* builder() const { return builder_; } |
| 94 const NodeVector* values() const { return &values_; } | 94 const NodeVector* values() const { return &values_; } |
| 95 NodeVector* values() { return &values_; } | 95 NodeVector* values() { return &values_; } |
| 96 int register_base() const { return register_base_; } | 96 int register_base() const { return register_base_; } |
| 97 int accumulator_base() const { return accumulator_base_; } | 97 int accumulator_base() const { return accumulator_base_; } |
| 98 | 98 |
| 99 BytecodeGraphBuilder* builder_; | 99 BytecodeGraphBuilder* builder_; |
| 100 int register_count_; | 100 int register_count_; |
| 101 int parameter_count_; | 101 int parameter_count_; |
| 102 Node* context_; | 102 Node* context_; |
| 103 Node* control_dependency_; | 103 Node* control_dependency_; |
| 104 Node* effect_dependency_; | 104 Node* effect_dependency_; |
| 105 NodeVector values_; | 105 NodeVector values_; |
| 106 Node* parameters_state_values_; | 106 Node* parameters_state_values_; |
| 107 Node* registers_state_values_; | 107 Node* registers_state_values_; |
| 108 Node* accumulator_state_values_; | 108 Node* accumulator_state_values_; |
| 109 int register_base_; | 109 int register_base_; |
| 110 int accumulator_base_; | 110 int accumulator_base_; |
| 111 | |
| 112 // A working area for writing maybe-dead values to when updating the state | |
| 113 // values for registers. | |
| 114 NodeVector state_value_working_area_; | |
| 115 }; | 111 }; |
| 116 | 112 |
| 117 | 113 |
| 118 // Issues: | 114 // Issues: |
| 119 // - Scopes - intimately tied to AST. Need to eval what is needed. | 115 // - Scopes - intimately tied to AST. Need to eval what is needed. |
| 120 // - Need to resolve closure parameter treatment. | 116 // - Need to resolve closure parameter treatment. |
| 121 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, | 117 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
| 122 int register_count, | 118 int register_count, |
| 123 int parameter_count, | 119 int parameter_count, |
| 124 Node* control_dependency, | 120 Node* control_dependency, |
| 125 Node* context) | 121 Node* context) |
| 126 : builder_(builder), | 122 : builder_(builder), |
| 127 register_count_(register_count), | 123 register_count_(register_count), |
| 128 parameter_count_(parameter_count), | 124 parameter_count_(parameter_count), |
| 129 context_(context), | 125 context_(context), |
| 130 control_dependency_(control_dependency), | 126 control_dependency_(control_dependency), |
| 131 effect_dependency_(control_dependency), | 127 effect_dependency_(control_dependency), |
| 132 values_(builder->local_zone()), | 128 values_(builder->local_zone()), |
| 133 parameters_state_values_(nullptr), | 129 parameters_state_values_(nullptr), |
| 134 registers_state_values_(nullptr), | 130 registers_state_values_(nullptr), |
| 135 accumulator_state_values_(nullptr), | 131 accumulator_state_values_(nullptr) { |
| 136 state_value_working_area_(builder->local_zone()) { | |
| 137 // The layout of values_ is: | 132 // The layout of values_ is: |
| 138 // | 133 // |
| 139 // [receiver] [parameters] [registers] [accumulator] | 134 // [receiver] [parameters] [registers] [accumulator] |
| 140 // | 135 // |
| 141 // parameter[0] is the receiver (this), parameters 1..N are the | 136 // parameter[0] is the receiver (this), parameters 1..N are the |
| 142 // parameters supplied to the method (arg0..argN-1). The accumulator | 137 // parameters supplied to the method (arg0..argN-1). The accumulator |
| 143 // is stored separately. | 138 // is stored separately. |
| 144 | 139 |
| 145 // Parameters including the receiver | 140 // Parameters including the receiver |
| 146 for (int i = 0; i < parameter_count; i++) { | 141 for (int i = 0; i < parameter_count; i++) { |
| 147 const char* debug_name = (i == 0) ? "%this" : nullptr; | 142 const char* debug_name = (i == 0) ? "%this" : nullptr; |
| 148 const Operator* op = common()->Parameter(i, debug_name); | 143 const Operator* op = common()->Parameter(i, debug_name); |
| 149 Node* parameter = builder->graph()->NewNode(op, graph()->start()); | 144 Node* parameter = builder->graph()->NewNode(op, graph()->start()); |
| 150 values()->push_back(parameter); | 145 values()->push_back(parameter); |
| 151 } | 146 } |
| 152 | 147 |
| 153 // Registers | 148 // Registers |
| 154 register_base_ = static_cast<int>(values()->size()); | 149 register_base_ = static_cast<int>(values()->size()); |
| 155 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 150 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
| 156 values()->insert(values()->end(), register_count, undefined_constant); | 151 values()->insert(values()->end(), register_count, undefined_constant); |
| 157 | 152 |
| 158 // Accumulator | 153 // Accumulator |
| 159 accumulator_base_ = static_cast<int>(values()->size()); | 154 accumulator_base_ = static_cast<int>(values()->size()); |
| 160 values()->push_back(undefined_constant); | 155 values()->push_back(undefined_constant); |
| 161 | |
| 162 state_value_working_area_.resize(register_count_); | |
| 163 } | 156 } |
| 164 | 157 |
| 165 BytecodeGraphBuilder::Environment::Environment( | 158 BytecodeGraphBuilder::Environment::Environment( |
| 166 const BytecodeGraphBuilder::Environment* other) | 159 const BytecodeGraphBuilder::Environment* other) |
| 167 : builder_(other->builder_), | 160 : builder_(other->builder_), |
| 168 register_count_(other->register_count_), | 161 register_count_(other->register_count_), |
| 169 parameter_count_(other->parameter_count_), | 162 parameter_count_(other->parameter_count_), |
| 170 context_(other->context_), | 163 context_(other->context_), |
| 171 control_dependency_(other->control_dependency_), | 164 control_dependency_(other->control_dependency_), |
| 172 effect_dependency_(other->effect_dependency_), | 165 effect_dependency_(other->effect_dependency_), |
| 173 values_(other->zone()), | 166 values_(other->zone()), |
| 174 parameters_state_values_(nullptr), | 167 parameters_state_values_(nullptr), |
| 175 registers_state_values_(nullptr), | 168 registers_state_values_(nullptr), |
| 176 accumulator_state_values_(nullptr), | 169 accumulator_state_values_(nullptr), |
| 177 register_base_(other->register_base_), | 170 register_base_(other->register_base_), |
| 178 accumulator_base_(other->accumulator_base_), | 171 accumulator_base_(other->accumulator_base_) { |
| 179 // Environments can share their working area. | |
| 180 state_value_working_area_(other->state_value_working_area_) { | |
| 181 values_ = other->values_; | 172 values_ = other->values_; |
| 182 } | 173 } |
| 183 | 174 |
| 184 | 175 |
| 185 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( | 176 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( |
| 186 interpreter::Register the_register) const { | 177 interpreter::Register the_register) const { |
| 187 if (the_register.is_parameter()) { | 178 if (the_register.is_parameter()) { |
| 188 return the_register.ToParameterIndex(parameter_count()); | 179 return the_register.ToParameterIndex(parameter_count()); |
| 189 } else { | 180 } else { |
| 190 return the_register.index() + register_base(); | 181 return the_register.index() + register_base(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 Node* rename = | 382 Node* rename = |
| 392 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); | 383 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); |
| 393 values_[i] = rename; | 384 values_[i] = rename; |
| 394 } | 385 } |
| 395 } | 386 } |
| 396 | 387 |
| 397 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 388 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
| 398 Node** values, | 389 Node** values, |
| 399 int count) { | 390 int count) { |
| 400 if (StateValuesRequireUpdate(state_values, values, count)) { | 391 if (StateValuesRequireUpdate(state_values, values, count)) { |
| 401 const Operator* op = common()->StateValues(count); | 392 const Operator* op = common()->StateValues(count, SparseInputMask::Dense()); |
| 402 (*state_values) = graph()->NewNode(op, count, values); | 393 (*state_values) = graph()->NewNode(op, count, values); |
| 403 } | 394 } |
| 404 } | 395 } |
| 405 | 396 |
| 406 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache( | 397 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache( |
| 407 Node** state_values, Node** values, int count) { | 398 Node** state_values, Node** values, int count, const BitVector* liveness) { |
| 408 *state_values = builder_->state_values_cache_.GetNodeForValues( | 399 *state_values = builder_->state_values_cache_.GetNodeForValues( |
| 409 values, static_cast<size_t>(count)); | 400 values, static_cast<size_t>(count), liveness); |
| 410 } | 401 } |
| 411 | 402 |
| 412 Node* BytecodeGraphBuilder::Environment::Checkpoint( | 403 Node* BytecodeGraphBuilder::Environment::Checkpoint( |
| 413 BailoutId bailout_id, OutputFrameStateCombine combine, | 404 BailoutId bailout_id, OutputFrameStateCombine combine, |
| 414 bool owner_has_exception, const BytecodeLivenessState* liveness) { | 405 bool owner_has_exception, const BytecodeLivenessState* liveness) { |
| 415 UpdateStateValues(¶meters_state_values_, &values()->at(0), | 406 UpdateStateValues(¶meters_state_values_, &values()->at(0), |
| 416 parameter_count()); | 407 parameter_count()); |
| 417 | 408 |
| 418 if (liveness) { | 409 // TODO(leszeks): We should pass a view of the liveness bitvector here, with |
| 419 Node* optimized_out = builder()->jsgraph()->OptimizedOutConstant(); | 410 // offset and count, rather than passing the entire bitvector and assuming |
| 411 // that register liveness starts at offset 0. |
| 412 UpdateStateValuesWithCache(®isters_state_values_, |
| 413 &values()->at(register_base()), register_count(), |
| 414 liveness ? &liveness->bit_vector() : nullptr); |
| 420 | 415 |
| 421 for (int i = 0; i < register_count(); ++i) { | 416 Node* accumulator_value = liveness == nullptr || liveness->AccumulatorIsLive() |
| 422 state_value_working_area_[i] = liveness->RegisterIsLive(i) | 417 ? values()->at(accumulator_base()) |
| 423 ? values()->at(register_base() + i) | 418 : builder()->jsgraph()->OptimizedOutConstant(); |
| 424 : optimized_out; | 419 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1); |
| 425 } | |
| 426 | |
| 427 Node* accumulator_value = liveness->AccumulatorIsLive() | |
| 428 ? values()->at(accumulator_base()) | |
| 429 : optimized_out; | |
| 430 | |
| 431 UpdateStateValuesWithCache(®isters_state_values_, | |
| 432 state_value_working_area_.data(), | |
| 433 register_count()); | |
| 434 | |
| 435 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1); | |
| 436 } else { | |
| 437 UpdateStateValuesWithCache(®isters_state_values_, | |
| 438 &values()->at(register_base()), | |
| 439 register_count()); | |
| 440 UpdateStateValues(&accumulator_state_values_, | |
| 441 &values()->at(accumulator_base()), 1); | |
| 442 } | |
| 443 | 420 |
| 444 const Operator* op = common()->FrameState( | 421 const Operator* op = common()->FrameState( |
| 445 bailout_id, combine, builder()->frame_state_function_info()); | 422 bailout_id, combine, builder()->frame_state_function_info()); |
| 446 Node* result = graph()->NewNode( | 423 Node* result = graph()->NewNode( |
| 447 op, parameters_state_values_, registers_state_values_, | 424 op, parameters_state_values_, registers_state_values_, |
| 448 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), | 425 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), |
| 449 builder()->graph()->start()); | 426 builder()->graph()->start()); |
| 450 | 427 |
| 451 return result; | 428 return result; |
| 452 } | 429 } |
| (...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2213 it->source_position().ScriptOffset(), start_position_.InliningId())); |
| 2237 it->Advance(); | 2214 it->Advance(); |
| 2238 } else { | 2215 } else { |
| 2239 DCHECK_GT(it->code_offset(), offset); | 2216 DCHECK_GT(it->code_offset(), offset); |
| 2240 } | 2217 } |
| 2241 } | 2218 } |
| 2242 | 2219 |
| 2243 } // namespace compiler | 2220 } // namespace compiler |
| 2244 } // namespace internal | 2221 } // namespace internal |
| 2245 } // namespace v8 | 2222 } // namespace v8 |
| OLD | NEW |