Chromium Code Reviews| 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 17 matching lines...) Expand all Loading... | |
| 28 // Specifies whether environment binding methods should attach frame state | 28 // Specifies whether environment binding methods should attach frame state |
| 29 // inputs to nodes representing the value being bound. This is done because | 29 // inputs to nodes representing the value being bound. This is done because |
| 30 // the {OutputFrameStateCombine} is closely related to the binding method. | 30 // the {OutputFrameStateCombine} is closely related to the binding method. |
| 31 enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState }; | 31 enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState }; |
| 32 | 32 |
| 33 int parameter_count() const { return parameter_count_; } | 33 int parameter_count() const { return parameter_count_; } |
| 34 int register_count() const { return register_count_; } | 34 int register_count() const { return register_count_; } |
| 35 | 35 |
| 36 Node* LookupAccumulator() const; | 36 Node* LookupAccumulator() const; |
| 37 Node* LookupRegister(interpreter::Register the_register) const; | 37 Node* LookupRegister(interpreter::Register the_register) const; |
| 38 void MarkAllRegistersLive(); | |
| 39 | 38 |
| 40 void BindAccumulator(Node* node, | 39 void BindAccumulator(Node* node, |
| 41 FrameStateAttachmentMode mode = kDontAttachFrameState); | 40 FrameStateAttachmentMode mode = kDontAttachFrameState); |
| 42 void BindRegister(interpreter::Register the_register, Node* node, | 41 void BindRegister(interpreter::Register the_register, Node* node, |
| 43 FrameStateAttachmentMode mode = kDontAttachFrameState); | 42 FrameStateAttachmentMode mode = kDontAttachFrameState); |
| 44 void BindRegistersToProjections( | 43 void BindRegistersToProjections( |
| 45 interpreter::Register first_reg, Node* node, | 44 interpreter::Register first_reg, Node* node, |
| 46 FrameStateAttachmentMode mode = kDontAttachFrameState); | 45 FrameStateAttachmentMode mode = kDontAttachFrameState); |
| 47 void RecordAfterState(Node* node, | 46 void RecordAfterState(Node* node, |
| 48 FrameStateAttachmentMode mode = kDontAttachFrameState); | 47 FrameStateAttachmentMode mode = kDontAttachFrameState); |
| 49 | 48 |
| 50 // Effect dependency tracked by this environment. | 49 // Effect dependency tracked by this environment. |
| 51 Node* GetEffectDependency() { return effect_dependency_; } | 50 Node* GetEffectDependency() { return effect_dependency_; } |
| 52 void UpdateEffectDependency(Node* dependency) { | 51 void UpdateEffectDependency(Node* dependency) { |
| 53 effect_dependency_ = dependency; | 52 effect_dependency_ = dependency; |
| 54 } | 53 } |
| 55 | 54 |
| 56 // Preserve a checkpoint of the environment for the IR graph. Any | 55 // Preserve a checkpoint of the environment for the IR graph. Any |
| 57 // further mutation of the environment will not affect checkpoints. | 56 // further mutation of the environment will not affect checkpoints. |
| 58 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine, | 57 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine, |
| 59 bool owner_has_exception); | 58 bool owner_has_exception, const BitVector* liveness); |
| 60 | 59 |
| 61 // Control dependency tracked by this environment. | 60 // Control dependency tracked by this environment. |
| 62 Node* GetControlDependency() const { return control_dependency_; } | 61 Node* GetControlDependency() const { return control_dependency_; } |
| 63 void UpdateControlDependency(Node* dependency) { | 62 void UpdateControlDependency(Node* dependency) { |
| 64 control_dependency_ = dependency; | 63 control_dependency_ = dependency; |
| 65 } | 64 } |
| 66 | 65 |
| 67 Node* Context() const { return context_; } | 66 Node* Context() const { return context_; } |
| 68 void SetContext(Node* new_context) { context_ = new_context; } | 67 void SetContext(Node* new_context) { context_ = new_context; } |
| 69 | 68 |
| 70 Environment* CopyForConditional(); | 69 Environment* CopyForConditional(); |
| 71 Environment* CopyForLoop(); | 70 Environment* CopyForLoop(); |
| 72 Environment* CopyForOsrEntry(); | 71 Environment* CopyForOsrEntry(); |
| 73 void Merge(Environment* other); | 72 void Merge(Environment* other); |
| 74 void PrepareForOsrEntry(); | 73 void PrepareForOsrEntry(); |
| 75 | 74 |
| 76 void PrepareForLoopExit(Node* loop); | 75 void PrepareForLoopExit(Node* loop); |
| 77 | 76 |
| 78 private: | 77 private: |
| 79 Environment(const Environment* copy, LivenessAnalyzerBlock* liveness_block); | 78 explicit Environment(const Environment* copy); |
| 80 void PrepareForLoop(); | 79 void PrepareForLoop(); |
| 81 | 80 |
| 82 bool StateValuesRequireUpdate(Node** state_values, int offset, int count); | 81 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); |
| 83 void UpdateStateValues(Node** state_values, int offset, int count); | 82 void UpdateStateValues(Node** state_values, Node** values, int count); |
| 83 void UpdateStateValuesWithCache(Node** state_values, Node** values, | |
| 84 int count); | |
| 84 | 85 |
| 85 int RegisterToValuesIndex(interpreter::Register the_register) const; | 86 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| 86 | 87 |
| 87 bool IsLivenessBlockConsistent() const; | |
| 88 | |
| 89 Zone* zone() const { return builder_->local_zone(); } | 88 Zone* zone() const { return builder_->local_zone(); } |
| 90 Graph* graph() const { return builder_->graph(); } | 89 Graph* graph() const { return builder_->graph(); } |
| 91 CommonOperatorBuilder* common() const { return builder_->common(); } | 90 CommonOperatorBuilder* common() const { return builder_->common(); } |
| 92 BytecodeGraphBuilder* builder() const { return builder_; } | 91 BytecodeGraphBuilder* builder() const { return builder_; } |
| 93 LivenessAnalyzerBlock* liveness_block() const { return liveness_block_; } | |
| 94 const NodeVector* values() const { return &values_; } | 92 const NodeVector* values() const { return &values_; } |
| 95 NodeVector* values() { return &values_; } | 93 NodeVector* values() { return &values_; } |
| 96 int register_base() const { return register_base_; } | 94 int register_base() const { return register_base_; } |
| 97 int accumulator_base() const { return accumulator_base_; } | 95 int accumulator_base() const { return accumulator_base_; } |
| 98 | 96 |
| 99 BytecodeGraphBuilder* builder_; | 97 BytecodeGraphBuilder* builder_; |
| 100 int register_count_; | 98 int register_count_; |
| 101 int parameter_count_; | 99 int parameter_count_; |
| 102 LivenessAnalyzerBlock* liveness_block_; | |
| 103 Node* context_; | 100 Node* context_; |
| 104 Node* control_dependency_; | 101 Node* control_dependency_; |
| 105 Node* effect_dependency_; | 102 Node* effect_dependency_; |
| 106 NodeVector values_; | 103 NodeVector values_; |
| 107 Node* parameters_state_values_; | 104 Node* parameters_state_values_; |
| 108 Node* registers_state_values_; | 105 Node* registers_state_values_; |
| 109 Node* accumulator_state_values_; | 106 Node* accumulator_state_values_; |
| 110 int register_base_; | 107 int register_base_; |
| 111 int accumulator_base_; | 108 int accumulator_base_; |
| 109 | |
| 110 NodeVector tmp_values_; | |
|
Jarin
2016/11/24 12:47:17
Nit: Could we give this a more descriptive name (c
Leszek Swirski
2016/11/25 17:31:27
Done.
| |
| 112 }; | 111 }; |
| 113 | 112 |
| 114 | 113 |
| 115 // Issues: | 114 // Issues: |
| 116 // - Scopes - intimately tied to AST. Need to eval what is needed. | 115 // - Scopes - intimately tied to AST. Need to eval what is needed. |
| 117 // - Need to resolve closure parameter treatment. | 116 // - Need to resolve closure parameter treatment. |
| 118 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, | 117 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
| 119 int register_count, | 118 int register_count, |
| 120 int parameter_count, | 119 int parameter_count, |
| 121 Node* control_dependency, | 120 Node* control_dependency, |
| 122 Node* context) | 121 Node* context) |
| 123 : builder_(builder), | 122 : builder_(builder), |
| 124 register_count_(register_count), | 123 register_count_(register_count), |
| 125 parameter_count_(parameter_count), | 124 parameter_count_(parameter_count), |
| 126 liveness_block_(builder->is_liveness_analysis_enabled_ | |
| 127 ? builder_->liveness_analyzer()->NewBlock() | |
| 128 : nullptr), | |
| 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), |
| 132 tmp_values_(builder->local_zone()) { | |
| 136 // The layout of values_ is: | 133 // The layout of values_ is: |
| 137 // | 134 // |
| 138 // [receiver] [parameters] [registers] [accumulator] | 135 // [receiver] [parameters] [registers] [accumulator] |
| 139 // | 136 // |
| 140 // parameter[0] is the receiver (this), parameters 1..N are the | 137 // parameter[0] is the receiver (this), parameters 1..N are the |
| 141 // parameters supplied to the method (arg0..argN-1). The accumulator | 138 // parameters supplied to the method (arg0..argN-1). The accumulator |
| 142 // is stored separately. | 139 // is stored separately. |
| 143 | 140 |
| 144 // Parameters including the receiver | 141 // Parameters including the receiver |
| 145 for (int i = 0; i < parameter_count; i++) { | 142 for (int i = 0; i < parameter_count; i++) { |
| 146 const char* debug_name = (i == 0) ? "%this" : nullptr; | 143 const char* debug_name = (i == 0) ? "%this" : nullptr; |
| 147 const Operator* op = common()->Parameter(i, debug_name); | 144 const Operator* op = common()->Parameter(i, debug_name); |
| 148 Node* parameter = builder->graph()->NewNode(op, graph()->start()); | 145 Node* parameter = builder->graph()->NewNode(op, graph()->start()); |
| 149 values()->push_back(parameter); | 146 values()->push_back(parameter); |
| 150 } | 147 } |
| 151 | 148 |
| 152 // Registers | 149 // Registers |
| 153 register_base_ = static_cast<int>(values()->size()); | 150 register_base_ = static_cast<int>(values()->size()); |
| 154 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 151 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
| 155 values()->insert(values()->end(), register_count, undefined_constant); | 152 values()->insert(values()->end(), register_count, undefined_constant); |
| 156 | 153 |
| 157 // Accumulator | 154 // Accumulator |
| 158 accumulator_base_ = static_cast<int>(values()->size()); | 155 accumulator_base_ = static_cast<int>(values()->size()); |
| 159 values()->push_back(undefined_constant); | 156 values()->push_back(undefined_constant); |
| 157 | |
| 158 tmp_values_.resize(register_count_); | |
| 160 } | 159 } |
| 161 | 160 |
| 162 BytecodeGraphBuilder::Environment::Environment( | 161 BytecodeGraphBuilder::Environment::Environment( |
| 163 const BytecodeGraphBuilder::Environment* other, | 162 const BytecodeGraphBuilder::Environment* other) |
| 164 LivenessAnalyzerBlock* liveness_block) | |
| 165 : builder_(other->builder_), | 163 : builder_(other->builder_), |
| 166 register_count_(other->register_count_), | 164 register_count_(other->register_count_), |
| 167 parameter_count_(other->parameter_count_), | 165 parameter_count_(other->parameter_count_), |
| 168 liveness_block_(liveness_block), | |
| 169 context_(other->context_), | 166 context_(other->context_), |
| 170 control_dependency_(other->control_dependency_), | 167 control_dependency_(other->control_dependency_), |
| 171 effect_dependency_(other->effect_dependency_), | 168 effect_dependency_(other->effect_dependency_), |
| 172 values_(other->zone()), | 169 values_(other->zone()), |
| 173 parameters_state_values_(nullptr), | 170 parameters_state_values_(nullptr), |
| 174 registers_state_values_(nullptr), | 171 registers_state_values_(nullptr), |
| 175 accumulator_state_values_(nullptr), | 172 accumulator_state_values_(nullptr), |
| 176 register_base_(other->register_base_), | 173 register_base_(other->register_base_), |
| 177 accumulator_base_(other->accumulator_base_) { | 174 accumulator_base_(other->accumulator_base_), |
| 175 tmp_values_(other->zone()) { | |
| 178 values_ = other->values_; | 176 values_ = other->values_; |
| 177 tmp_values_.resize(register_count_); | |
| 179 } | 178 } |
| 180 | 179 |
| 181 | 180 |
| 182 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( | 181 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( |
| 183 interpreter::Register the_register) const { | 182 interpreter::Register the_register) const { |
| 184 if (the_register.is_parameter()) { | 183 if (the_register.is_parameter()) { |
| 185 return the_register.ToParameterIndex(parameter_count()); | 184 return the_register.ToParameterIndex(parameter_count()); |
| 186 } else { | 185 } else { |
| 187 return the_register.index() + register_base(); | 186 return the_register.index() + register_base(); |
| 188 } | 187 } |
| 189 } | 188 } |
| 190 | 189 |
| 191 bool BytecodeGraphBuilder::Environment::IsLivenessBlockConsistent() const { | |
| 192 return !builder_->IsLivenessAnalysisEnabled() == | |
| 193 (liveness_block() == nullptr); | |
| 194 } | |
| 195 | |
| 196 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { | 190 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { |
| 197 DCHECK(IsLivenessBlockConsistent()); | |
| 198 if (liveness_block() != nullptr) { | |
| 199 liveness_block()->LookupAccumulator(); | |
| 200 } | |
| 201 return values()->at(accumulator_base_); | 191 return values()->at(accumulator_base_); |
| 202 } | 192 } |
| 203 | 193 |
| 204 | 194 |
| 205 Node* BytecodeGraphBuilder::Environment::LookupRegister( | 195 Node* BytecodeGraphBuilder::Environment::LookupRegister( |
| 206 interpreter::Register the_register) const { | 196 interpreter::Register the_register) const { |
| 207 if (the_register.is_current_context()) { | 197 if (the_register.is_current_context()) { |
| 208 return Context(); | 198 return Context(); |
| 209 } else if (the_register.is_function_closure()) { | 199 } else if (the_register.is_function_closure()) { |
| 210 return builder()->GetFunctionClosure(); | 200 return builder()->GetFunctionClosure(); |
| 211 } else if (the_register.is_new_target()) { | 201 } else if (the_register.is_new_target()) { |
| 212 return builder()->GetNewTarget(); | 202 return builder()->GetNewTarget(); |
| 213 } else { | 203 } else { |
| 214 int values_index = RegisterToValuesIndex(the_register); | 204 int values_index = RegisterToValuesIndex(the_register); |
| 215 if (liveness_block() != nullptr && !the_register.is_parameter()) { | |
| 216 DCHECK(IsLivenessBlockConsistent()); | |
| 217 liveness_block()->Lookup(the_register.index()); | |
| 218 } | |
| 219 return values()->at(values_index); | 205 return values()->at(values_index); |
| 220 } | 206 } |
| 221 } | 207 } |
| 222 | 208 |
| 223 void BytecodeGraphBuilder::Environment::MarkAllRegistersLive() { | |
| 224 DCHECK(IsLivenessBlockConsistent()); | |
| 225 if (liveness_block() != nullptr) { | |
| 226 for (int i = 0; i < register_count(); ++i) { | |
| 227 liveness_block()->Lookup(i); | |
| 228 } | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 void BytecodeGraphBuilder::Environment::BindAccumulator( | 209 void BytecodeGraphBuilder::Environment::BindAccumulator( |
| 233 Node* node, FrameStateAttachmentMode mode) { | 210 Node* node, FrameStateAttachmentMode mode) { |
| 234 if (mode == FrameStateAttachmentMode::kAttachFrameState) { | 211 if (mode == FrameStateAttachmentMode::kAttachFrameState) { |
| 235 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0)); | 212 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0)); |
| 236 } | 213 } |
| 237 DCHECK(IsLivenessBlockConsistent()); | |
| 238 if (liveness_block() != nullptr) { | |
| 239 liveness_block()->BindAccumulator(); | |
| 240 } | |
| 241 values()->at(accumulator_base_) = node; | 214 values()->at(accumulator_base_) = node; |
| 242 } | 215 } |
| 243 | 216 |
| 244 void BytecodeGraphBuilder::Environment::BindRegister( | 217 void BytecodeGraphBuilder::Environment::BindRegister( |
| 245 interpreter::Register the_register, Node* node, | 218 interpreter::Register the_register, Node* node, |
| 246 FrameStateAttachmentMode mode) { | 219 FrameStateAttachmentMode mode) { |
| 247 int values_index = RegisterToValuesIndex(the_register); | 220 int values_index = RegisterToValuesIndex(the_register); |
| 248 if (mode == FrameStateAttachmentMode::kAttachFrameState) { | 221 if (mode == FrameStateAttachmentMode::kAttachFrameState) { |
| 249 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( | 222 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( |
| 250 accumulator_base_ - values_index)); | 223 accumulator_base_ - values_index)); |
| 251 } | 224 } |
| 252 values()->at(values_index) = node; | 225 values()->at(values_index) = node; |
| 253 if (liveness_block() != nullptr && !the_register.is_parameter()) { | |
| 254 DCHECK(IsLivenessBlockConsistent()); | |
| 255 liveness_block()->Bind(the_register.index()); | |
| 256 } | |
| 257 } | 226 } |
| 258 | 227 |
| 259 void BytecodeGraphBuilder::Environment::BindRegistersToProjections( | 228 void BytecodeGraphBuilder::Environment::BindRegistersToProjections( |
| 260 interpreter::Register first_reg, Node* node, | 229 interpreter::Register first_reg, Node* node, |
| 261 FrameStateAttachmentMode mode) { | 230 FrameStateAttachmentMode mode) { |
| 262 int values_index = RegisterToValuesIndex(first_reg); | 231 int values_index = RegisterToValuesIndex(first_reg); |
| 263 if (mode == FrameStateAttachmentMode::kAttachFrameState) { | 232 if (mode == FrameStateAttachmentMode::kAttachFrameState) { |
| 264 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( | 233 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( |
| 265 accumulator_base_ - values_index)); | 234 accumulator_base_ - values_index)); |
| 266 } | 235 } |
| 267 for (int i = 0; i < node->op()->ValueOutputCount(); i++) { | 236 for (int i = 0; i < node->op()->ValueOutputCount(); i++) { |
| 268 values()->at(values_index + i) = | 237 values()->at(values_index + i) = |
| 269 builder()->NewNode(common()->Projection(i), node); | 238 builder()->NewNode(common()->Projection(i), node); |
| 270 } | 239 } |
| 271 } | 240 } |
| 272 | 241 |
| 273 void BytecodeGraphBuilder::Environment::RecordAfterState( | 242 void BytecodeGraphBuilder::Environment::RecordAfterState( |
| 274 Node* node, FrameStateAttachmentMode mode) { | 243 Node* node, FrameStateAttachmentMode mode) { |
| 275 if (mode == FrameStateAttachmentMode::kAttachFrameState) { | 244 if (mode == FrameStateAttachmentMode::kAttachFrameState) { |
| 276 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); | 245 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); |
| 277 } | 246 } |
| 278 } | 247 } |
| 279 | 248 |
| 280 | 249 |
| 281 BytecodeGraphBuilder::Environment* | 250 BytecodeGraphBuilder::Environment* |
| 282 BytecodeGraphBuilder::Environment::CopyForLoop() { | 251 BytecodeGraphBuilder::Environment::CopyForLoop() { |
| 283 PrepareForLoop(); | 252 PrepareForLoop(); |
| 284 if (liveness_block() != nullptr) { | 253 return new (zone()) Environment(this); |
| 285 // Finish the current block before copying. | |
| 286 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); | |
| 287 } | |
| 288 return new (zone()) Environment(this, liveness_block()); | |
| 289 } | 254 } |
| 290 | 255 |
| 291 BytecodeGraphBuilder::Environment* | 256 BytecodeGraphBuilder::Environment* |
| 292 BytecodeGraphBuilder::Environment::CopyForOsrEntry() { | 257 BytecodeGraphBuilder::Environment::CopyForOsrEntry() { |
| 293 return new (zone()) | 258 return new (zone()) Environment(this); |
| 294 Environment(this, builder_->liveness_analyzer()->NewBlock()); | |
| 295 } | 259 } |
| 296 | 260 |
| 297 BytecodeGraphBuilder::Environment* | 261 BytecodeGraphBuilder::Environment* |
| 298 BytecodeGraphBuilder::Environment::CopyForConditional() { | 262 BytecodeGraphBuilder::Environment::CopyForConditional() { |
| 299 LivenessAnalyzerBlock* copy_liveness_block = nullptr; | 263 return new (zone()) Environment(this); |
| 300 if (liveness_block() != nullptr) { | |
| 301 copy_liveness_block = | |
| 302 builder_->liveness_analyzer()->NewBlock(liveness_block()); | |
| 303 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); | |
| 304 } | |
| 305 return new (zone()) Environment(this, copy_liveness_block); | |
| 306 } | 264 } |
| 307 | 265 |
| 308 | 266 |
| 309 void BytecodeGraphBuilder::Environment::Merge( | 267 void BytecodeGraphBuilder::Environment::Merge( |
| 310 BytecodeGraphBuilder::Environment* other) { | 268 BytecodeGraphBuilder::Environment* other) { |
| 311 if (builder_->is_liveness_analysis_enabled_) { | |
| 312 if (GetControlDependency()->opcode() != IrOpcode::kLoop) { | |
| 313 liveness_block_ = | |
| 314 builder()->liveness_analyzer()->NewBlock(liveness_block()); | |
| 315 } | |
| 316 liveness_block()->AddPredecessor(other->liveness_block()); | |
| 317 } | |
| 318 | |
| 319 // Create a merge of the control dependencies of both environments and update | 269 // Create a merge of the control dependencies of both environments and update |
| 320 // the current environment's control dependency accordingly. | 270 // the current environment's control dependency accordingly. |
| 321 Node* control = builder()->MergeControl(GetControlDependency(), | 271 Node* control = builder()->MergeControl(GetControlDependency(), |
| 322 other->GetControlDependency()); | 272 other->GetControlDependency()); |
| 323 UpdateControlDependency(control); | 273 UpdateControlDependency(control); |
| 324 | 274 |
| 325 // Create a merge of the effect dependencies of both environments and update | 275 // Create a merge of the effect dependencies of both environments and update |
| 326 // the current environment's effect dependency accordingly. | 276 // the current environment's effect dependency accordingly. |
| 327 Node* effect = builder()->MergeEffect(GetEffectDependency(), | 277 Node* effect = builder()->MergeEffect(GetEffectDependency(), |
| 328 other->GetEffectDependency(), control); | 278 other->GetEffectDependency(), control); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 int size = static_cast<int>(values()->size()); | 326 int size = static_cast<int>(values()->size()); |
| 377 for (int i = 0; i < size; i++) { | 327 for (int i = 0; i < size; i++) { |
| 378 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. | 328 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. |
| 379 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; | 329 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; |
| 380 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; | 330 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; |
| 381 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry); | 331 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry); |
| 382 } | 332 } |
| 383 | 333 |
| 384 BailoutId loop_id(builder_->bytecode_iterator().current_offset()); | 334 BailoutId loop_id(builder_->bytecode_iterator().current_offset()); |
| 385 Node* frame_state = | 335 Node* frame_state = |
| 386 Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false); | 336 Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false, nullptr); |
| 387 Node* checkpoint = | 337 Node* checkpoint = |
| 388 graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry); | 338 graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry); |
| 389 UpdateEffectDependency(checkpoint); | 339 UpdateEffectDependency(checkpoint); |
| 390 | 340 |
| 391 // Create the OSR guard nodes. | 341 // Create the OSR guard nodes. |
| 392 const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized); | 342 const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized); |
| 393 Node* effect = checkpoint; | 343 Node* effect = checkpoint; |
| 394 for (int i = 0; i < size; i++) { | 344 for (int i = 0; i < size; i++) { |
| 395 values()->at(i) = effect = | 345 values()->at(i) = effect = |
| 396 graph()->NewNode(guard_op, values()->at(i), effect, entry); | 346 graph()->NewNode(guard_op, values()->at(i), effect, entry); |
| 397 } | 347 } |
| 398 Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry); | 348 Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry); |
| 399 SetContext(context); | 349 SetContext(context); |
| 400 UpdateEffectDependency(effect); | 350 UpdateEffectDependency(effect); |
| 401 } | 351 } |
| 402 | 352 |
| 403 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( | 353 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
| 404 Node** state_values, int offset, int count) { | 354 Node** state_values, Node** values, int count) { |
| 405 if (*state_values == nullptr) { | 355 if (*state_values == nullptr) { |
| 406 return true; | 356 return true; |
| 407 } | 357 } |
| 408 DCHECK_EQ((*state_values)->InputCount(), count); | 358 DCHECK_EQ((*state_values)->InputCount(), count); |
| 409 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); | |
| 410 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | |
| 411 for (int i = 0; i < count; i++) { | 359 for (int i = 0; i < count; i++) { |
| 412 if ((*state_values)->InputAt(i) != env_values[i]) { | 360 if ((*state_values)->InputAt(i) != values[i]) { |
| 413 return true; | 361 return true; |
| 414 } | 362 } |
| 415 } | 363 } |
| 416 return false; | 364 return false; |
| 417 } | 365 } |
| 418 | 366 |
| 419 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) { | 367 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) { |
| 420 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); | 368 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); |
| 421 | 369 |
| 422 Node* control = GetControlDependency(); | 370 Node* control = GetControlDependency(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 436 | 384 |
| 437 // Rename the environmnent values. | 385 // Rename the environmnent values. |
| 438 for (size_t i = 0; i < values_.size(); i++) { | 386 for (size_t i = 0; i < values_.size(); i++) { |
| 439 Node* rename = | 387 Node* rename = |
| 440 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); | 388 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); |
| 441 values_[i] = rename; | 389 values_[i] = rename; |
| 442 } | 390 } |
| 443 } | 391 } |
| 444 | 392 |
| 445 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 393 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
| 446 int offset, | 394 Node** values, |
| 447 int count) { | 395 int count) { |
| 448 if (StateValuesRequireUpdate(state_values, offset, count)) { | 396 if (StateValuesRequireUpdate(state_values, values, count)) { |
| 449 const Operator* op = common()->StateValues(count); | 397 const Operator* op = common()->StateValues(count); |
| 450 (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); | 398 (*state_values) = graph()->NewNode(op, count, values); |
| 451 } | 399 } |
| 452 } | 400 } |
| 453 | 401 |
| 402 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache( | |
| 403 Node** state_values, Node** values, int count) { | |
| 404 *state_values = builder_->state_values_cache_.GetNodeForValues( | |
| 405 values, static_cast<size_t>(count)); | |
| 406 } | |
| 407 | |
| 454 Node* BytecodeGraphBuilder::Environment::Checkpoint( | 408 Node* BytecodeGraphBuilder::Environment::Checkpoint( |
| 455 BailoutId bailout_id, OutputFrameStateCombine combine, | 409 BailoutId bailout_id, OutputFrameStateCombine combine, |
| 456 bool owner_has_exception) { | 410 bool owner_has_exception, const BitVector* liveness) { |
| 457 UpdateStateValues(¶meters_state_values_, 0, parameter_count()); | 411 UpdateStateValues(¶meters_state_values_, &values()->at(0), |
| 458 UpdateStateValues(®isters_state_values_, register_base(), | 412 parameter_count()); |
| 459 register_count()); | 413 |
| 460 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); | 414 if (liveness) { |
| 415 Node* optimized_out = builder()->jsgraph()->OptimizedOutConstant(); | |
| 416 | |
| 417 for (int i = 0; i < register_count(); ++i) { | |
| 418 tmp_values_[i] = liveness->Contains(i) ? values()->at(register_base() + i) | |
| 419 : optimized_out; | |
| 420 } | |
| 421 | |
| 422 Node* accumulator_value = liveness->Contains(register_count()) | |
| 423 ? values()->at(accumulator_base()) | |
| 424 : optimized_out; | |
| 425 | |
| 426 UpdateStateValuesWithCache(®isters_state_values_, tmp_values_.data(), | |
| 427 register_count()); | |
| 428 | |
| 429 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1); | |
| 430 } else { | |
| 431 UpdateStateValuesWithCache(®isters_state_values_, | |
| 432 &values()->at(register_base()), | |
| 433 register_count()); | |
| 434 UpdateStateValues(&accumulator_state_values_, | |
| 435 &values()->at(accumulator_base()), 1); | |
| 436 } | |
| 437 | |
| 438 // PrintF("liveness: "); | |
| 439 // for (int i = 0; i < liveness->length(); ++i) { | |
| 440 // if (liveness && !liveness->Contains(i)) { | |
| 441 // PrintF("."); | |
| 442 // } else { | |
| 443 // PrintF("L"); | |
| 444 // } | |
| 445 // } | |
| 446 // PrintF("\n"); | |
| 447 | |
| 448 // PrintF("stv live: "); | |
| 449 // for (const auto& node : StateValuesAccess(registers_state_values_)) { | |
| 450 // if (node.node == builder()->jsgraph()->OptimizedOutConstant()) { | |
| 451 // PrintF("."); | |
| 452 // } else { | |
| 453 // PrintF("L"); | |
| 454 // } | |
| 455 // } | |
| 456 // for (const auto& node : StateValuesAccess(accumulator_state_values_)) { | |
| 457 // if (node.node == builder()->jsgraph()->OptimizedOutConstant()) { | |
| 458 // PrintF("."); | |
| 459 // } else { | |
| 460 // PrintF("L"); | |
| 461 // } | |
| 462 // } | |
| 463 // PrintF("\n"); | |
| 461 | 464 |
| 462 const Operator* op = common()->FrameState( | 465 const Operator* op = common()->FrameState( |
| 463 bailout_id, combine, builder()->frame_state_function_info()); | 466 bailout_id, combine, builder()->frame_state_function_info()); |
| 464 Node* result = graph()->NewNode( | 467 Node* result = graph()->NewNode( |
| 465 op, parameters_state_values_, registers_state_values_, | 468 op, parameters_state_values_, registers_state_values_, |
| 466 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), | 469 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), |
| 467 builder()->graph()->start()); | 470 builder()->graph()->start()); |
| 468 | 471 |
| 469 if (liveness_block() != nullptr) { | |
| 470 // If the owning node has an exception, register the checkpoint to the | |
| 471 // predecessor so that the checkpoint is used for both the normal and the | |
| 472 // exceptional paths. Yes, this is a terrible hack and we might want | |
| 473 // to use an explicit frame state for the exceptional path. | |
| 474 if (owner_has_exception) { | |
| 475 liveness_block()->GetPredecessor()->Checkpoint(result); | |
| 476 } else { | |
| 477 liveness_block()->Checkpoint(result); | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 return result; | 472 return result; |
| 482 } | 473 } |
| 483 | 474 |
| 484 BytecodeGraphBuilder::BytecodeGraphBuilder( | 475 BytecodeGraphBuilder::BytecodeGraphBuilder( |
| 485 Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, | 476 Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, |
| 486 float invocation_frequency, SourcePositionTable* source_positions, | 477 float invocation_frequency, SourcePositionTable* source_positions, |
| 487 int inlining_id) | 478 int inlining_id) |
| 488 : local_zone_(local_zone), | 479 : local_zone_(local_zone), |
| 489 jsgraph_(jsgraph), | 480 jsgraph_(jsgraph), |
| 490 invocation_frequency_(invocation_frequency), | 481 invocation_frequency_(invocation_frequency), |
| 491 bytecode_array_(handle(info->shared_info()->bytecode_array())), | 482 bytecode_array_(handle(info->shared_info()->bytecode_array())), |
| 492 exception_handler_table_( | 483 exception_handler_table_( |
| 493 handle(HandlerTable::cast(bytecode_array()->handler_table()))), | 484 handle(HandlerTable::cast(bytecode_array()->handler_table()))), |
| 494 feedback_vector_(handle(info->closure()->feedback_vector())), | 485 feedback_vector_(handle(info->closure()->feedback_vector())), |
| 495 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 486 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 496 FrameStateType::kInterpretedFunction, | 487 FrameStateType::kInterpretedFunction, |
| 497 bytecode_array()->parameter_count(), | 488 bytecode_array()->parameter_count(), |
| 498 bytecode_array()->register_count(), info->shared_info())), | 489 bytecode_array()->register_count(), info->shared_info())), |
| 499 osr_ast_id_(info->osr_ast_id()), | 490 osr_ast_id_(info->osr_ast_id()), |
| 500 merge_environments_(local_zone), | 491 merge_environments_(local_zone), |
| 501 exception_handlers_(local_zone), | 492 exception_handlers_(local_zone), |
| 502 current_exception_handler_(0), | 493 current_exception_handler_(0), |
| 503 input_buffer_size_(0), | 494 input_buffer_size_(0), |
| 504 input_buffer_(nullptr), | 495 input_buffer_(nullptr), |
| 505 exit_controls_(local_zone), | 496 exit_controls_(local_zone), |
| 506 is_liveness_analysis_enabled_(FLAG_analyze_environment_liveness && | 497 is_liveness_analysis_enabled_(FLAG_analyze_environment_liveness && |
| 507 info->is_deoptimization_enabled()), | 498 info->is_deoptimization_enabled()), |
| 508 state_values_cache_(jsgraph), | 499 state_values_cache_(jsgraph), |
| 509 liveness_analyzer_( | |
| 510 static_cast<size_t>(bytecode_array()->register_count()), true, | |
| 511 local_zone), | |
| 512 source_positions_(source_positions), | 500 source_positions_(source_positions), |
| 513 start_position_(info->shared_info()->start_position(), inlining_id) {} | 501 start_position_(info->shared_info()->start_position(), inlining_id) {} |
| 514 | 502 |
| 515 Node* BytecodeGraphBuilder::GetNewTarget() { | 503 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 516 if (!new_target_.is_set()) { | 504 if (!new_target_.is_set()) { |
| 517 int params = bytecode_array()->parameter_count(); | 505 int params = bytecode_array()->parameter_count(); |
| 518 int index = Linkage::GetJSCallNewTargetParamIndex(params); | 506 int index = Linkage::GetJSCallNewTargetParamIndex(params); |
| 519 const Operator* op = common()->Parameter(index, "%new.target"); | 507 const Operator* op = common()->Parameter(index, "%new.target"); |
| 520 Node* node = NewNode(op, graph()->start()); | 508 Node* node = NewNode(op, graph()->start()); |
| 521 new_target_.set(node); | 509 new_target_.set(node); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 | 567 |
| 580 VisitBytecodes(stack_check); | 568 VisitBytecodes(stack_check); |
| 581 | 569 |
| 582 // Finish the basic structure of the graph. | 570 // Finish the basic structure of the graph. |
| 583 DCHECK_NE(0u, exit_controls_.size()); | 571 DCHECK_NE(0u, exit_controls_.size()); |
| 584 int const input_count = static_cast<int>(exit_controls_.size()); | 572 int const input_count = static_cast<int>(exit_controls_.size()); |
| 585 Node** const inputs = &exit_controls_.front(); | 573 Node** const inputs = &exit_controls_.front(); |
| 586 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); | 574 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); |
| 587 graph()->SetEnd(end); | 575 graph()->SetEnd(end); |
| 588 | 576 |
| 589 ClearNonLiveSlotsInFrameStates(); | |
| 590 | |
| 591 return true; | 577 return true; |
| 592 } | 578 } |
| 593 | 579 |
| 594 void BytecodeGraphBuilder::PrepareEagerCheckpoint() { | 580 void BytecodeGraphBuilder::PrepareEagerCheckpoint() { |
| 595 if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) { | 581 if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) { |
| 596 // Create an explicit checkpoint node for before the operation. This only | 582 // Create an explicit checkpoint node for before the operation. This only |
| 597 // needs to happen if we aren't effect-dominated by a {Checkpoint} already. | 583 // needs to happen if we aren't effect-dominated by a {Checkpoint} already. |
| 598 Node* node = NewNode(common()->Checkpoint()); | 584 Node* node = NewNode(common()->Checkpoint()); |
| 599 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); | 585 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); |
| 600 DCHECK_EQ(IrOpcode::kDead, | 586 DCHECK_EQ(IrOpcode::kDead, |
| 601 NodeProperties::GetFrameStateInput(node)->opcode()); | 587 NodeProperties::GetFrameStateInput(node)->opcode()); |
| 602 BailoutId bailout_id(bytecode_iterator().current_offset()); | 588 BailoutId bailout_id(bytecode_iterator().current_offset()); |
| 589 | |
| 590 const BitVector* liveness_before = bytecode_analysis()->GetInLivenessFor( | |
| 591 bytecode_iterator().current_offset()); | |
| 592 | |
| 603 Node* frame_state_before = environment()->Checkpoint( | 593 Node* frame_state_before = environment()->Checkpoint( |
| 604 bailout_id, OutputFrameStateCombine::Ignore(), false); | 594 bailout_id, OutputFrameStateCombine::Ignore(), false, liveness_before); |
| 605 NodeProperties::ReplaceFrameStateInput(node, frame_state_before); | 595 NodeProperties::ReplaceFrameStateInput(node, frame_state_before); |
| 606 } | 596 } |
| 607 } | 597 } |
| 608 | 598 |
| 609 void BytecodeGraphBuilder::PrepareFrameState(Node* node, | 599 void BytecodeGraphBuilder::PrepareFrameState(Node* node, |
| 610 OutputFrameStateCombine combine) { | 600 OutputFrameStateCombine combine) { |
| 611 if (OperatorProperties::HasFrameStateInput(node->op())) { | 601 if (OperatorProperties::HasFrameStateInput(node->op())) { |
| 612 // Add the frame state for after the operation. The node in question has | 602 // Add the frame state for after the operation. The node in question has |
| 613 // already been created and had a {Dead} frame state input up until now. | 603 // already been created and had a {Dead} frame state input up until now. |
| 614 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); | 604 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); |
| 615 DCHECK_EQ(IrOpcode::kDead, | 605 DCHECK_EQ(IrOpcode::kDead, |
| 616 NodeProperties::GetFrameStateInput(node)->opcode()); | 606 NodeProperties::GetFrameStateInput(node)->opcode()); |
| 617 BailoutId bailout_id(bytecode_iterator().current_offset()); | 607 BailoutId bailout_id(bytecode_iterator().current_offset()); |
| 618 bool has_exception = NodeProperties::IsExceptionalCall(node); | 608 bool has_exception = NodeProperties::IsExceptionalCall(node); |
| 619 Node* frame_state_after = | 609 |
| 620 environment()->Checkpoint(bailout_id, combine, has_exception); | 610 const BitVector* liveness_after = bytecode_analysis()->GetOutLivenessFor( |
| 611 bytecode_iterator().current_offset()); | |
| 612 | |
| 613 Node* frame_state_after = environment()->Checkpoint( | |
| 614 bailout_id, combine, has_exception, liveness_after); | |
| 621 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); | 615 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); |
| 622 } | 616 } |
| 623 } | 617 } |
| 624 | 618 |
| 625 void BytecodeGraphBuilder::ClearNonLiveSlotsInFrameStates() { | |
| 626 if (!IsLivenessAnalysisEnabled()) { | |
| 627 return; | |
| 628 } | |
| 629 NonLiveFrameStateSlotReplacer replacer( | |
| 630 &state_values_cache_, jsgraph()->OptimizedOutConstant(), | |
| 631 liveness_analyzer()->local_count(), true, local_zone()); | |
| 632 liveness_analyzer()->Run(&replacer); | |
| 633 if (FLAG_trace_environment_liveness) { | |
| 634 OFStream os(stdout); | |
| 635 liveness_analyzer()->Print(os); | |
| 636 } | |
| 637 } | |
| 638 | |
| 639 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { | 619 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { |
| 640 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone()); | 620 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone()); |
| 641 bytecode_analysis.Analyze(); | 621 bytecode_analysis.Analyze(); |
| 642 set_bytecode_analysis(&bytecode_analysis); | 622 set_bytecode_analysis(&bytecode_analysis); |
| 643 | 623 |
| 644 interpreter::BytecodeArrayIterator iterator(bytecode_array()); | 624 interpreter::BytecodeArrayIterator iterator(bytecode_array()); |
| 645 set_bytecode_iterator(&iterator); | 625 set_bytecode_iterator(&iterator); |
| 646 SourcePositionTableIterator source_position_iterator( | 626 SourcePositionTableIterator source_position_iterator( |
| 647 bytecode_array()->source_position_table()); | 627 bytecode_array()->source_position_table()); |
| 648 | 628 |
| 629 if (FLAG_trace_environment_liveness) { | |
| 630 OFStream of(stdout); | |
| 631 | |
| 632 interpreter::BytecodeArrayIterator trace_iterator(bytecode_array()); | |
| 633 | |
| 634 for (; !trace_iterator.done(); trace_iterator.Advance()) { | |
| 635 const BitVector* in_liveness = | |
| 636 bytecode_analysis.GetInLivenessFor(trace_iterator.current_offset()); | |
| 637 for (int i = 0; i < in_liveness->length(); ++i) { | |
| 638 of << (in_liveness->Contains(i) ? "L" : "."); | |
| 639 } | |
| 640 of << " -> "; | |
| 641 | |
| 642 const BitVector* out_liveness = | |
| 643 bytecode_analysis.GetOutLivenessFor(trace_iterator.current_offset()); | |
| 644 for (int i = 0; i < out_liveness->length(); ++i) { | |
| 645 of << (out_liveness->Contains(i) ? "L" : "."); | |
| 646 } | |
| 647 of << " | " << trace_iterator.current_offset() << ": "; | |
| 648 trace_iterator.Output(of) << std::endl; | |
| 649 } | |
| 650 } | |
| 651 | |
| 649 BuildOSRNormalEntryPoint(); | 652 BuildOSRNormalEntryPoint(); |
| 653 OFStream of(stdout); | |
| 654 | |
| 650 for (; !iterator.done(); iterator.Advance()) { | 655 for (; !iterator.done(); iterator.Advance()) { |
| 651 int current_offset = iterator.current_offset(); | 656 int current_offset = iterator.current_offset(); |
| 652 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); | 657 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); |
| 653 EnterAndExitExceptionHandlers(current_offset); | 658 EnterAndExitExceptionHandlers(current_offset); |
| 654 SwitchToMergeEnvironment(current_offset); | 659 SwitchToMergeEnvironment(current_offset); |
| 655 if (environment() != nullptr) { | 660 if (environment() != nullptr) { |
| 656 BuildLoopHeaderEnvironment(current_offset); | 661 BuildLoopHeaderEnvironment(current_offset); |
| 657 BuildOSRLoopEntryPoint(current_offset); | 662 BuildOSRLoopEntryPoint(current_offset); |
| 658 | 663 |
| 659 // Skip the first stack check if stack_check is false | 664 // Skip the first stack check if stack_check is false |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1760 Node* control = | 1765 Node* control = |
| 1761 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator()); | 1766 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator()); |
| 1762 MergeControlToLeaveFunction(control); | 1767 MergeControlToLeaveFunction(control); |
| 1763 } | 1768 } |
| 1764 | 1769 |
| 1765 void BytecodeGraphBuilder::VisitDebugger() { | 1770 void BytecodeGraphBuilder::VisitDebugger() { |
| 1766 PrepareEagerCheckpoint(); | 1771 PrepareEagerCheckpoint(); |
| 1767 Node* call = | 1772 Node* call = |
| 1768 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); | 1773 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); |
| 1769 environment()->BindAccumulator(call, Environment::kAttachFrameState); | 1774 environment()->BindAccumulator(call, Environment::kAttachFrameState); |
| 1770 environment()->MarkAllRegistersLive(); | |
| 1771 } | 1775 } |
| 1772 | 1776 |
| 1773 // We cannot create a graph from the debugger copy of the bytecode array. | 1777 // We cannot create a graph from the debugger copy of the bytecode array. |
| 1774 #define DEBUG_BREAK(Name, ...) \ | 1778 #define DEBUG_BREAK(Name, ...) \ |
| 1775 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); } | 1779 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); } |
| 1776 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK); | 1780 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK); |
| 1777 #undef DEBUG_BREAK | 1781 #undef DEBUG_BREAK |
| 1778 | 1782 |
| 1779 void BytecodeGraphBuilder::BuildForInPrepare() { | 1783 void BytecodeGraphBuilder::BuildForInPrepare() { |
| 1780 PrepareEagerCheckpoint(); | 1784 PrepareEagerCheckpoint(); |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2226 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2230 it->source_position().ScriptOffset(), start_position_.InliningId())); |
| 2227 it->Advance(); | 2231 it->Advance(); |
| 2228 } else { | 2232 } else { |
| 2229 DCHECK_GT(it->code_offset(), offset); | 2233 DCHECK_GT(it->code_offset(), offset); |
| 2230 } | 2234 } |
| 2231 } | 2235 } |
| 2232 | 2236 |
| 2233 } // namespace compiler | 2237 } // namespace compiler |
| 2234 } // namespace internal | 2238 } // namespace internal |
| 2235 } // namespace v8 | 2239 } // namespace v8 |
| OLD | NEW |