OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.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.h" | 10 #include "src/compiler.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 158 } |
159 | 159 |
160 // Either 'break' or 'continue' to the target statement. | 160 // Either 'break' or 'continue' to the target statement. |
161 void BreakTo(BreakableStatement* target); | 161 void BreakTo(BreakableStatement* target); |
162 void ContinueTo(BreakableStatement* target); | 162 void ContinueTo(BreakableStatement* target); |
163 | 163 |
164 // Either 'return' or 'throw' the given value. | 164 // Either 'return' or 'throw' the given value. |
165 void ReturnValue(Node* return_value); | 165 void ReturnValue(Node* return_value); |
166 void ThrowValue(Node* exception_value); | 166 void ThrowValue(Node* exception_value); |
167 | 167 |
168 class DeferredCommands; | |
169 | |
170 protected: | 168 protected: |
171 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; | 169 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; |
172 | 170 |
173 // Performs one of the above commands on this stack of control scopes. This | 171 // Performs one of the above commands on this stack of control scopes. This |
174 // walks through the stack giving each scope a chance to execute or defer the | 172 // walks through the stack giving each scope a chance to execute or defer the |
175 // given command by overriding the {Execute} method appropriately. Note that | 173 // given command by overriding the {Execute} method appropriately. Note that |
176 // this also drops extra operands from the environment for each skipped scope. | 174 // this also drops extra operands from the environment for each skipped scope. |
177 void PerformCommand(Command cmd, Statement* target, Node* value); | 175 void PerformCommand(Command cmd, Statement* target, Node* value); |
178 | 176 |
179 // Interface to execute a given command in this scope. Returning {true} here | 177 // Interface to execute a given command in this scope. Returning {true} here |
(...skipping 19 matching lines...) Expand all Loading... |
199 int context_length() const { return context_length_; } | 197 int context_length() const { return context_length_; } |
200 int stack_height() const { return stack_height_; } | 198 int stack_height() const { return stack_height_; } |
201 | 199 |
202 private: | 200 private: |
203 AstGraphBuilder* builder_; | 201 AstGraphBuilder* builder_; |
204 ControlScope* outer_; | 202 ControlScope* outer_; |
205 int context_length_; | 203 int context_length_; |
206 int stack_height_; | 204 int stack_height_; |
207 }; | 205 }; |
208 | 206 |
209 // Helper class for a try-finally control scope. It can record intercepted | |
210 // control-flow commands that cause entry into a finally-block, and re-apply | |
211 // them after again leaving that block. Special tokens are used to identify | |
212 // paths going through the finally-block to dispatch after leaving the block. | |
213 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { | |
214 public: | |
215 explicit DeferredCommands(AstGraphBuilder* owner) | |
216 : owner_(owner), | |
217 deferred_(owner->local_zone()), | |
218 return_token_(nullptr), | |
219 throw_token_(nullptr) {} | |
220 | |
221 // One recorded control-flow command. | |
222 struct Entry { | |
223 Command command; // The command type being applied on this path. | |
224 Statement* statement; // The target statement for the command or {nullptr}. | |
225 Node* token; // A token identifying this particular path. | |
226 }; | |
227 | |
228 // Records a control-flow command while entering the finally-block. This also | |
229 // generates a new dispatch token that identifies one particular path. | |
230 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) { | |
231 Node* token = nullptr; | |
232 switch (cmd) { | |
233 case CMD_BREAK: | |
234 case CMD_CONTINUE: | |
235 token = NewPathToken(dispenser_.GetBreakContinueToken()); | |
236 break; | |
237 case CMD_THROW: | |
238 if (throw_token_) return throw_token_; | |
239 token = NewPathToken(TokenDispenserForFinally::kThrowToken); | |
240 throw_token_ = token; | |
241 break; | |
242 case CMD_RETURN: | |
243 if (return_token_) return return_token_; | |
244 token = NewPathToken(TokenDispenserForFinally::kReturnToken); | |
245 return_token_ = token; | |
246 break; | |
247 } | |
248 DCHECK_NOT_NULL(token); | |
249 deferred_.push_back({cmd, stmt, token}); | |
250 return token; | |
251 } | |
252 | |
253 // Returns the dispatch token to be used to identify the implicit fall-through | |
254 // path at the end of a try-block into the corresponding finally-block. | |
255 Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); } | |
256 | |
257 // Applies all recorded control-flow commands after the finally-block again. | |
258 // This generates a dynamic dispatch on the token from the entry point. | |
259 void ApplyDeferredCommands(Node* token, Node* value) { | |
260 SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size())); | |
261 dispatch.BeginSwitch(); | |
262 for (size_t i = 0; i < deferred_.size(); ++i) { | |
263 Node* condition = NewPathDispatchCondition(token, deferred_[i].token); | |
264 dispatch.BeginLabel(static_cast<int>(i), condition); | |
265 dispatch.EndLabel(); | |
266 } | |
267 for (size_t i = 0; i < deferred_.size(); ++i) { | |
268 dispatch.BeginCase(static_cast<int>(i)); | |
269 owner_->execution_control()->PerformCommand( | |
270 deferred_[i].command, deferred_[i].statement, value); | |
271 dispatch.EndCase(); | |
272 } | |
273 dispatch.EndSwitch(); | |
274 } | |
275 | |
276 protected: | |
277 Node* NewPathToken(int token_id) { | |
278 return owner_->jsgraph()->Constant(token_id); | |
279 } | |
280 Node* NewPathTokenForImplicitFallThrough() { | |
281 return NewPathToken(TokenDispenserForFinally::kFallThroughToken); | |
282 } | |
283 Node* NewPathDispatchCondition(Node* t1, Node* t2) { | |
284 return owner_->NewNode( | |
285 owner_->javascript()->StrictEqual(CompareOperationHint::kAny), t1, t2); | |
286 } | |
287 | |
288 private: | |
289 TokenDispenserForFinally dispenser_; | |
290 AstGraphBuilder* owner_; | |
291 ZoneVector<Entry> deferred_; | |
292 Node* return_token_; | |
293 Node* throw_token_; | |
294 }; | |
295 | |
296 | 207 |
297 // Control scope implementation for a BreakableStatement. | 208 // Control scope implementation for a BreakableStatement. |
298 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { | 209 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { |
299 public: | 210 public: |
300 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, | 211 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, |
301 ControlBuilder* control) | 212 ControlBuilder* control) |
302 : ControlScope(owner), target_(target), control_(control) {} | 213 : ControlScope(owner), target_(target), control_(control) {} |
303 | 214 |
304 protected: | 215 protected: |
305 bool Execute(Command cmd, Statement* target, Node** value) override { | 216 bool Execute(Command cmd, Statement* target, Node** value) override { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 } | 259 } |
349 return false; | 260 return false; |
350 } | 261 } |
351 | 262 |
352 private: | 263 private: |
353 BreakableStatement* target_; | 264 BreakableStatement* target_; |
354 LoopBuilder* control_; | 265 LoopBuilder* control_; |
355 }; | 266 }; |
356 | 267 |
357 | 268 |
358 // Control scope implementation for a TryCatchStatement. | |
359 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | |
360 public: | |
361 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchStatement* stmt, | |
362 TryCatchBuilder* control) | |
363 : ControlScope(owner), control_(control) { | |
364 builder()->try_nesting_level_++; // Increment nesting. | |
365 } | |
366 ~ControlScopeForCatch() { | |
367 builder()->try_nesting_level_--; // Decrement nesting. | |
368 } | |
369 | |
370 protected: | |
371 bool Execute(Command cmd, Statement* target, Node** value) override { | |
372 switch (cmd) { | |
373 case CMD_THROW: | |
374 control_->Throw(*value); | |
375 return true; | |
376 case CMD_BREAK: | |
377 case CMD_CONTINUE: | |
378 case CMD_RETURN: | |
379 break; | |
380 } | |
381 return false; | |
382 } | |
383 | |
384 private: | |
385 TryCatchBuilder* control_; | |
386 }; | |
387 | |
388 | |
389 // Control scope implementation for a TryFinallyStatement. | |
390 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | |
391 public: | |
392 ControlScopeForFinally(AstGraphBuilder* owner, TryFinallyStatement* stmt, | |
393 DeferredCommands* commands, TryFinallyBuilder* control) | |
394 : ControlScope(owner), commands_(commands), control_(control) { | |
395 builder()->try_nesting_level_++; // Increment nesting. | |
396 } | |
397 ~ControlScopeForFinally() { | |
398 builder()->try_nesting_level_--; // Decrement nesting. | |
399 } | |
400 | |
401 protected: | |
402 bool Execute(Command cmd, Statement* target, Node** value) override { | |
403 Node* token = commands_->RecordCommand(cmd, target, *value); | |
404 control_->LeaveTry(token, *value); | |
405 return true; | |
406 } | |
407 | |
408 private: | |
409 DeferredCommands* commands_; | |
410 TryFinallyBuilder* control_; | |
411 }; | |
412 | |
413 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, | 269 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, |
414 JSGraph* jsgraph, float invocation_frequency, | 270 JSGraph* jsgraph, float invocation_frequency, |
415 LoopAssignmentAnalysis* loop) | 271 LoopAssignmentAnalysis* loop) |
416 : isolate_(info->isolate()), | 272 : isolate_(info->isolate()), |
417 local_zone_(local_zone), | 273 local_zone_(local_zone), |
418 info_(info), | 274 info_(info), |
419 jsgraph_(jsgraph), | 275 jsgraph_(jsgraph), |
420 invocation_frequency_(invocation_frequency), | 276 invocation_frequency_(invocation_frequency), |
421 environment_(nullptr), | 277 environment_(nullptr), |
422 ast_context_(nullptr), | 278 ast_context_(nullptr), |
423 globals_(0, local_zone), | 279 globals_(0, local_zone), |
424 execution_control_(nullptr), | 280 execution_control_(nullptr), |
425 execution_context_(nullptr), | 281 execution_context_(nullptr), |
426 try_nesting_level_(0), | |
427 input_buffer_size_(0), | 282 input_buffer_size_(0), |
428 input_buffer_(nullptr), | 283 input_buffer_(nullptr), |
429 exit_controls_(local_zone), | 284 exit_controls_(local_zone), |
430 loop_assignment_analysis_(loop), | 285 loop_assignment_analysis_(loop), |
431 state_values_cache_(jsgraph), | 286 state_values_cache_(jsgraph), |
432 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 287 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
433 false, local_zone), | 288 false, local_zone), |
434 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 289 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
435 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, | 290 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, |
436 info->scope()->num_stack_slots(), info->shared_info())) { | 291 info->scope()->num_stack_slots(), info->shared_info())) { |
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 Node* condition = environment()->Pop(); | 1306 Node* condition = environment()->Pop(); |
1452 for_loop.BreakWhen(condition); | 1307 for_loop.BreakWhen(condition); |
1453 VisitForEffect(stmt->assign_each()); | 1308 VisitForEffect(stmt->assign_each()); |
1454 VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); | 1309 VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); |
1455 for_loop.EndBody(); | 1310 for_loop.EndBody(); |
1456 for_loop.EndLoop(); | 1311 for_loop.EndLoop(); |
1457 } | 1312 } |
1458 | 1313 |
1459 | 1314 |
1460 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1315 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
1461 TryCatchBuilder try_control(this); | 1316 // Exception handling is supported only by going through Ignition first. |
1462 | 1317 UNREACHABLE(); |
1463 // Evaluate the try-block inside a control scope. This simulates a handler | |
1464 // that is intercepting 'throw' control commands. | |
1465 try_control.BeginTry(); | |
1466 { | |
1467 ControlScopeForCatch scope(this, stmt, &try_control); | |
1468 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | |
1469 environment()->Push(current_context()); | |
1470 Visit(stmt->try_block()); | |
1471 environment()->Pop(); | |
1472 } | |
1473 try_control.EndTry(); | |
1474 | |
1475 // If requested, clear message object as we enter the catch block. | |
1476 if (stmt->clear_pending_message()) { | |
1477 Node* the_hole = jsgraph()->TheHoleConstant(); | |
1478 NewNode(javascript()->StoreMessage(), the_hole); | |
1479 } | |
1480 | |
1481 // Create a catch scope that binds the exception. | |
1482 Node* exception = try_control.GetExceptionNode(); | |
1483 Handle<String> name = stmt->variable()->name(); | |
1484 Handle<ScopeInfo> scope_info = stmt->scope()->scope_info(); | |
1485 const Operator* op = javascript()->CreateCatchContext(name, scope_info); | |
1486 Node* context = NewNode(op, exception, GetFunctionClosureForContext()); | |
1487 | |
1488 // Evaluate the catch-block. | |
1489 VisitInScope(stmt->catch_block(), stmt->scope(), context); | |
1490 try_control.EndCatch(); | |
1491 } | 1318 } |
1492 | 1319 |
1493 | 1320 |
1494 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 1321 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
1495 TryFinallyBuilder try_control(this); | 1322 // Exception handling is supported only by going through Ignition first. |
1496 | 1323 UNREACHABLE(); |
1497 // We keep a record of all paths that enter the finally-block to be able to | |
1498 // dispatch to the correct continuation point after the statements in the | |
1499 // finally-block have been evaluated. | |
1500 // | |
1501 // The try-finally construct can enter the finally-block in three ways: | |
1502 // 1. By exiting the try-block normally, falling through at the end. | |
1503 // 2. By exiting the try-block with a function-local control flow transfer | |
1504 // (i.e. through break/continue/return statements). | |
1505 // 3. By exiting the try-block with a thrown exception. | |
1506 Node* fallthrough_result = jsgraph()->TheHoleConstant(); | |
1507 ControlScope::DeferredCommands* commands = | |
1508 new (local_zone()) ControlScope::DeferredCommands(this); | |
1509 | |
1510 // Evaluate the try-block inside a control scope. This simulates a handler | |
1511 // that is intercepting all control commands. | |
1512 try_control.BeginTry(); | |
1513 { | |
1514 ControlScopeForFinally scope(this, stmt, commands, &try_control); | |
1515 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | |
1516 environment()->Push(current_context()); | |
1517 Visit(stmt->try_block()); | |
1518 environment()->Pop(); | |
1519 } | |
1520 try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result); | |
1521 | |
1522 // The result value semantics depend on how the block was entered: | |
1523 // - ReturnStatement: It represents the return value being returned. | |
1524 // - ThrowStatement: It represents the exception being thrown. | |
1525 // - BreakStatement/ContinueStatement: Filled with the hole. | |
1526 // - Falling through into finally-block: Filled with the hole. | |
1527 Node* result = try_control.GetResultValueNode(); | |
1528 Node* token = try_control.GetDispatchTokenNode(); | |
1529 | |
1530 // The result value, dispatch token and message is expected on the operand | |
1531 // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock). | |
1532 Node* message = NewNode(javascript()->LoadMessage()); | |
1533 environment()->Push(token); | |
1534 environment()->Push(result); | |
1535 environment()->Push(message); | |
1536 | |
1537 // Clear message object as we enter the finally block. | |
1538 Node* the_hole = jsgraph()->TheHoleConstant(); | |
1539 NewNode(javascript()->StoreMessage(), the_hole); | |
1540 | |
1541 // Evaluate the finally-block. | |
1542 Visit(stmt->finally_block()); | |
1543 try_control.EndFinally(); | |
1544 | |
1545 // The result value, dispatch token and message is restored from the operand | |
1546 // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock). | |
1547 message = environment()->Pop(); | |
1548 result = environment()->Pop(); | |
1549 token = environment()->Pop(); | |
1550 NewNode(javascript()->StoreMessage(), message); | |
1551 | |
1552 // Dynamic dispatch after the finally-block. | |
1553 commands->ApplyDeferredCommands(token, result); | |
1554 } | 1324 } |
1555 | 1325 |
1556 | 1326 |
1557 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1327 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
1558 Node* node = | 1328 Node* node = |
1559 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); | 1329 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); |
1560 PrepareFrameState(node, stmt->DebugBreakId()); | 1330 PrepareFrameState(node, stmt->DebugBreakId()); |
1561 environment()->MarkAllLocalsLive(); | 1331 environment()->MarkAllLocalsLive(); |
1562 } | 1332 } |
1563 | 1333 |
(...skipping 2480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4044 bool has_control = op->ControlInputCount() == 1; | 3814 bool has_control = op->ControlInputCount() == 1; |
4045 bool has_effect = op->EffectInputCount() == 1; | 3815 bool has_effect = op->EffectInputCount() == 1; |
4046 | 3816 |
4047 DCHECK(op->ControlInputCount() < 2); | 3817 DCHECK(op->ControlInputCount() < 2); |
4048 DCHECK(op->EffectInputCount() < 2); | 3818 DCHECK(op->EffectInputCount() < 2); |
4049 | 3819 |
4050 Node* result = nullptr; | 3820 Node* result = nullptr; |
4051 if (!has_context && !has_frame_state && !has_control && !has_effect) { | 3821 if (!has_context && !has_frame_state && !has_control && !has_effect) { |
4052 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); | 3822 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); |
4053 } else { | 3823 } else { |
4054 bool inside_try_scope = try_nesting_level_ > 0; | |
4055 int input_count_with_deps = value_input_count; | 3824 int input_count_with_deps = value_input_count; |
4056 if (has_context) ++input_count_with_deps; | 3825 if (has_context) ++input_count_with_deps; |
4057 if (has_frame_state) ++input_count_with_deps; | 3826 if (has_frame_state) ++input_count_with_deps; |
4058 if (has_control) ++input_count_with_deps; | 3827 if (has_control) ++input_count_with_deps; |
4059 if (has_effect) ++input_count_with_deps; | 3828 if (has_effect) ++input_count_with_deps; |
4060 Node** buffer = EnsureInputBufferSize(input_count_with_deps); | 3829 Node** buffer = EnsureInputBufferSize(input_count_with_deps); |
4061 memcpy(buffer, value_inputs, kPointerSize * value_input_count); | 3830 memcpy(buffer, value_inputs, kPointerSize * value_input_count); |
4062 Node** current_input = buffer + value_input_count; | 3831 Node** current_input = buffer + value_input_count; |
4063 if (has_context) { | 3832 if (has_context) { |
4064 *current_input++ = current_context(); | 3833 *current_input++ = current_context(); |
(...skipping 13 matching lines...) Expand all Loading... |
4078 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); | 3847 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); |
4079 if (!environment()->IsMarkedAsUnreachable()) { | 3848 if (!environment()->IsMarkedAsUnreachable()) { |
4080 // Update the current control dependency for control-producing nodes. | 3849 // Update the current control dependency for control-producing nodes. |
4081 if (NodeProperties::IsControl(result)) { | 3850 if (NodeProperties::IsControl(result)) { |
4082 environment_->UpdateControlDependency(result); | 3851 environment_->UpdateControlDependency(result); |
4083 } | 3852 } |
4084 // Update the current effect dependency for effect-producing nodes. | 3853 // Update the current effect dependency for effect-producing nodes. |
4085 if (result->op()->EffectOutputCount() > 0) { | 3854 if (result->op()->EffectOutputCount() > 0) { |
4086 environment_->UpdateEffectDependency(result); | 3855 environment_->UpdateEffectDependency(result); |
4087 } | 3856 } |
4088 // Add implicit exception continuation for throwing nodes. | |
4089 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { | |
4090 // Copy the environment for the success continuation. | |
4091 Environment* success_env = environment()->CopyForConditional(); | |
4092 const Operator* op = common()->IfException(); | |
4093 Node* effect = environment()->GetEffectDependency(); | |
4094 Node* on_exception = graph()->NewNode(op, effect, result); | |
4095 environment_->UpdateControlDependency(on_exception); | |
4096 environment_->UpdateEffectDependency(on_exception); | |
4097 execution_control()->ThrowValue(on_exception); | |
4098 set_environment(success_env); | |
4099 } | |
4100 // Add implicit success continuation for throwing nodes. | 3857 // Add implicit success continuation for throwing nodes. |
4101 if (!result->op()->HasProperty(Operator::kNoThrow)) { | 3858 if (!result->op()->HasProperty(Operator::kNoThrow)) { |
4102 const Operator* op = common()->IfSuccess(); | 3859 const Operator* op = common()->IfSuccess(); |
4103 Node* on_success = graph()->NewNode(op, result); | 3860 Node* on_success = graph()->NewNode(op, result); |
4104 environment_->UpdateControlDependency(on_success); | 3861 environment_->UpdateControlDependency(on_success); |
4105 } | 3862 } |
4106 } | 3863 } |
4107 } | 3864 } |
4108 | 3865 |
4109 return result; | 3866 return result; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4344 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, | 4101 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, |
4345 SourcePositionTable* source_positions, int inlining_id) | 4102 SourcePositionTable* source_positions, int inlining_id) |
4346 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, | 4103 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, |
4347 loop_assignment), | 4104 loop_assignment), |
4348 source_positions_(source_positions), | 4105 source_positions_(source_positions), |
4349 start_position_(info->shared_info()->start_position(), inlining_id) {} | 4106 start_position_(info->shared_info()->start_position(), inlining_id) {} |
4350 | 4107 |
4351 } // namespace compiler | 4108 } // namespace compiler |
4352 } // namespace internal | 4109 } // namespace internal |
4353 } // namespace v8 | 4110 } // namespace v8 |
OLD | NEW |