Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 928213003: Model exceptional edges from call nodes in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 private: 320 private:
321 BreakableStatement* target_; 321 BreakableStatement* target_;
322 LoopBuilder* control_; 322 LoopBuilder* control_;
323 }; 323 };
324 324
325 325
326 // Control scope implementation for a TryCatchStatement. 326 // Control scope implementation for a TryCatchStatement.
327 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { 327 class AstGraphBuilder::ControlScopeForCatch : public ControlScope {
328 public: 328 public:
329 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) 329 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control)
330 : ControlScope(owner, 0), control_(control) {} 330 : ControlScope(owner, 0), control_(control) {
331 builder()->try_nesting_level_++; // Increment nesting.
332 }
333 ~ControlScopeForCatch() {
334 builder()->try_nesting_level_--; // Decrement nesting.
335 }
331 336
332 protected: 337 protected:
333 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { 338 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
334 switch (cmd) { 339 switch (cmd) {
335 case CMD_THROW: 340 case CMD_THROW:
336 control_->Throw(value); 341 control_->Throw(value);
337 return true; 342 return true;
338 case CMD_BREAK: 343 case CMD_BREAK:
339 case CMD_CONTINUE: 344 case CMD_CONTINUE:
340 case CMD_RETURN: 345 case CMD_RETURN:
341 break; 346 break;
342 } 347 }
343 return false; 348 return false;
344 } 349 }
345 350
346 private: 351 private:
347 TryCatchBuilder* control_; 352 TryCatchBuilder* control_;
348 }; 353 };
349 354
350 355
351 // Control scope implementation for a TryFinallyStatement. 356 // Control scope implementation for a TryFinallyStatement.
352 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { 357 class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
353 public: 358 public:
354 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, 359 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands,
355 TryFinallyBuilder* control) 360 TryFinallyBuilder* control)
356 : ControlScope(owner, 0), commands_(commands), control_(control) {} 361 : ControlScope(owner, 0), commands_(commands), control_(control) {
362 builder()->try_nesting_level_++; // Increment nesting.
363 }
364 ~ControlScopeForFinally() {
365 builder()->try_nesting_level_--; // Decrement nesting.
366 }
357 367
358 protected: 368 protected:
359 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { 369 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
360 Node* token = commands_->RecordCommand(cmd, target, value); 370 Node* token = commands_->RecordCommand(cmd, target, value);
361 control_->LeaveTry(token); 371 control_->LeaveTry(token);
362 return true; 372 return true;
363 } 373 }
364 374
365 private: 375 private:
366 DeferredCommands* commands_; 376 DeferredCommands* commands_;
367 TryFinallyBuilder* control_; 377 TryFinallyBuilder* control_;
368 }; 378 };
369 379
370 380
371 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 381 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
372 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) 382 JSGraph* jsgraph, LoopAssignmentAnalysis* loop)
373 : local_zone_(local_zone), 383 : local_zone_(local_zone),
374 info_(info), 384 info_(info),
375 jsgraph_(jsgraph), 385 jsgraph_(jsgraph),
376 environment_(nullptr), 386 environment_(nullptr),
377 ast_context_(nullptr), 387 ast_context_(nullptr),
378 globals_(0, local_zone), 388 globals_(0, local_zone),
379 execution_control_(nullptr), 389 execution_control_(nullptr),
380 execution_context_(nullptr), 390 execution_context_(nullptr),
391 try_nesting_level_(0),
381 input_buffer_size_(0), 392 input_buffer_size_(0),
382 input_buffer_(nullptr), 393 input_buffer_(nullptr),
383 exit_control_(nullptr), 394 exit_control_(nullptr),
384 loop_assignment_analysis_(loop) { 395 loop_assignment_analysis_(loop) {
385 InitializeAstVisitor(info->isolate(), local_zone); 396 InitializeAstVisitor(info->isolate(), local_zone);
386 } 397 }
387 398
388 399
389 Node* AstGraphBuilder::GetFunctionClosure() { 400 Node* AstGraphBuilder::GetFunctionClosure() {
390 if (!function_closure_.is_set()) { 401 if (!function_closure_.is_set()) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 if (FLAG_trace) { 490 if (FLAG_trace) {
480 // TODO(mstarzinger): Only traces implicit return. 491 // TODO(mstarzinger): Only traces implicit return.
481 Node* return_value = jsgraph()->UndefinedConstant(); 492 Node* return_value = jsgraph()->UndefinedConstant();
482 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); 493 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
483 } 494 }
484 495
485 // Return 'undefined' in case we can fall off the end. 496 // Return 'undefined' in case we can fall off the end.
486 BuildReturn(jsgraph()->UndefinedConstant()); 497 BuildReturn(jsgraph()->UndefinedConstant());
487 498
488 // Finish the basic structure of the graph. 499 // Finish the basic structure of the graph.
489 environment()->UpdateControlDependency(exit_control()); 500 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control()));
490 graph()->SetEnd(NewNode(common()->End()));
491 501
492 return true; 502 return true;
493 } 503 }
494 504
495 505
496 // Left-hand side can only be a property, a global or a variable slot. 506 // Left-hand side can only be a property, a global or a variable slot.
497 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 507 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
498 508
499 509
500 // Determine the left-hand side kind of an assignment. 510 // Determine the left-hand side kind of an assignment.
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 bool has_control = op->ControlInputCount() == 1; 2957 bool has_control = op->ControlInputCount() == 1;
2948 bool has_effect = op->EffectInputCount() == 1; 2958 bool has_effect = op->EffectInputCount() == 1;
2949 2959
2950 DCHECK(op->ControlInputCount() < 2); 2960 DCHECK(op->ControlInputCount() < 2);
2951 DCHECK(op->EffectInputCount() < 2); 2961 DCHECK(op->EffectInputCount() < 2);
2952 2962
2953 Node* result = NULL; 2963 Node* result = NULL;
2954 if (!has_context && !has_framestate && !has_control && !has_effect) { 2964 if (!has_context && !has_framestate && !has_control && !has_effect) {
2955 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); 2965 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
2956 } else { 2966 } else {
2967 bool inside_try_scope = try_nesting_level_ > 0;
2957 int input_count_with_deps = value_input_count; 2968 int input_count_with_deps = value_input_count;
2958 if (has_context) ++input_count_with_deps; 2969 if (has_context) ++input_count_with_deps;
2959 if (has_framestate) ++input_count_with_deps; 2970 if (has_framestate) ++input_count_with_deps;
2960 if (has_control) ++input_count_with_deps; 2971 if (has_control) ++input_count_with_deps;
2961 if (has_effect) ++input_count_with_deps; 2972 if (has_effect) ++input_count_with_deps;
2962 Node** buffer = EnsureInputBufferSize(input_count_with_deps); 2973 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
2963 memcpy(buffer, value_inputs, kPointerSize * value_input_count); 2974 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
2964 Node** current_input = buffer + value_input_count; 2975 Node** current_input = buffer + value_input_count;
2965 if (has_context) { 2976 if (has_context) {
2966 *current_input++ = current_context(); 2977 *current_input++ = current_context();
2967 } 2978 }
2968 if (has_framestate) { 2979 if (has_framestate) {
2969 // The frame state will be inserted later. Here we misuse 2980 // The frame state will be inserted later. Here we misuse
2970 // the {DeadControl} node as a sentinel to be later overwritten 2981 // the {DeadControl} node as a sentinel to be later overwritten
2971 // with the real frame state. 2982 // with the real frame state.
2972 *current_input++ = jsgraph()->DeadControl(); 2983 *current_input++ = jsgraph()->DeadControl();
2973 } 2984 }
2974 if (has_effect) { 2985 if (has_effect) {
2975 *current_input++ = environment_->GetEffectDependency(); 2986 *current_input++ = environment_->GetEffectDependency();
2976 } 2987 }
2977 if (has_control) { 2988 if (has_control) {
2978 *current_input++ = environment_->GetControlDependency(); 2989 *current_input++ = environment_->GetControlDependency();
2979 } 2990 }
2980 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); 2991 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
2981 if (has_effect) { 2992 if (has_effect) {
2982 environment_->UpdateEffectDependency(result); 2993 environment_->UpdateEffectDependency(result);
2983 } 2994 }
2984 if (result->op()->ControlOutputCount() > 0 && 2995 if (!environment()->IsMarkedAsUnreachable()) {
2985 !environment()->IsMarkedAsUnreachable()) { 2996 // Update the current control dependency for control-producing nodes.
2986 environment_->UpdateControlDependency(result); 2997 if (NodeProperties::IsControl(result)) {
2998 environment_->UpdateControlDependency(result);
2999 }
3000 // Add implicit exception continuation for throwing nodes.
3001 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
3002 Node* on_exception = graph()->NewNode(common()->IfException(), result);
3003 environment_->UpdateControlDependency(on_exception);
3004 if (FLAG_turbo_exceptions) {
3005 execution_control()->ThrowValue(jsgraph()->UndefinedConstant());
3006 }
3007 }
3008 // Add implicit success continuation for throwing nodes.
3009 if (!result->op()->HasProperty(Operator::kNoThrow)) {
3010 Node* on_success = graph()->NewNode(common()->IfSuccess(), result);
3011 environment_->UpdateControlDependency(on_success);
3012 }
2987 } 3013 }
2988 } 3014 }
2989 3015
2990 return result; 3016 return result;
2991 } 3017 }
2992 3018
2993 3019
2994 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 3020 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
2995 if (environment()->IsMarkedAsUnreachable()) return; 3021 if (environment()->IsMarkedAsUnreachable()) return;
2996 if (exit_control() != NULL) { 3022 if (exit_control() != NULL) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
3150 // Phi does not exist yet, introduce one. 3176 // Phi does not exist yet, introduce one.
3151 value = NewPhi(inputs, value, control); 3177 value = NewPhi(inputs, value, control);
3152 value->ReplaceInput(inputs - 1, other); 3178 value->ReplaceInput(inputs - 1, other);
3153 } 3179 }
3154 return value; 3180 return value;
3155 } 3181 }
3156 3182
3157 } // namespace compiler 3183 } // namespace compiler
3158 } // namespace internal 3184 } // namespace internal
3159 } // namespace v8 3185 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698