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