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

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: Addressed comments by Benedikt Meurer. 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 2449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2950 bool has_control = op->ControlInputCount() == 1; 2960 bool has_control = op->ControlInputCount() == 1;
2951 bool has_effect = op->EffectInputCount() == 1; 2961 bool has_effect = op->EffectInputCount() == 1;
2952 2962
2953 DCHECK(op->ControlInputCount() < 2); 2963 DCHECK(op->ControlInputCount() < 2);
2954 DCHECK(op->EffectInputCount() < 2); 2964 DCHECK(op->EffectInputCount() < 2);
2955 2965
2956 Node* result = NULL; 2966 Node* result = NULL;
2957 if (!has_context && !has_framestate && !has_control && !has_effect) { 2967 if (!has_context && !has_framestate && !has_control && !has_effect) {
2958 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); 2968 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
2959 } else { 2969 } else {
2970 bool inside_try_scope = try_nesting_level_ > 0;
2960 int input_count_with_deps = value_input_count; 2971 int input_count_with_deps = value_input_count;
2961 if (has_context) ++input_count_with_deps; 2972 if (has_context) ++input_count_with_deps;
2962 if (has_framestate) ++input_count_with_deps; 2973 if (has_framestate) ++input_count_with_deps;
2963 if (has_control) ++input_count_with_deps; 2974 if (has_control) ++input_count_with_deps;
2964 if (has_effect) ++input_count_with_deps; 2975 if (has_effect) ++input_count_with_deps;
2965 Node** buffer = EnsureInputBufferSize(input_count_with_deps); 2976 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
2966 memcpy(buffer, value_inputs, kPointerSize * value_input_count); 2977 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
2967 Node** current_input = buffer + value_input_count; 2978 Node** current_input = buffer + value_input_count;
2968 if (has_context) { 2979 if (has_context) {
2969 *current_input++ = current_context(); 2980 *current_input++ = current_context();
2970 } 2981 }
2971 if (has_framestate) { 2982 if (has_framestate) {
2972 // The frame state will be inserted later. Here we misuse 2983 // The frame state will be inserted later. Here we misuse
2973 // the dead_control node as a sentinel to be later overwritten 2984 // the dead_control node as a sentinel to be later overwritten
2974 // with the real frame state. 2985 // with the real frame state.
2975 *current_input++ = dead_control(); 2986 *current_input++ = dead_control();
2976 } 2987 }
2977 if (has_effect) { 2988 if (has_effect) {
2978 *current_input++ = environment_->GetEffectDependency(); 2989 *current_input++ = environment_->GetEffectDependency();
2979 } 2990 }
2980 if (has_control) { 2991 if (has_control) {
2981 *current_input++ = environment_->GetControlDependency(); 2992 *current_input++ = environment_->GetControlDependency();
2982 } 2993 }
2983 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); 2994 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
2984 if (has_effect) { 2995 if (has_effect) {
2985 environment_->UpdateEffectDependency(result); 2996 environment_->UpdateEffectDependency(result);
2986 } 2997 }
2987 if (result->op()->ControlOutputCount() > 0 && 2998 if (!environment()->IsMarkedAsUnreachable()) {
2988 !environment()->IsMarkedAsUnreachable()) { 2999 // Update the current control dependency for control-producing nodes.
2989 environment_->UpdateControlDependency(result); 3000 if (NodeProperties::IsControl(result)) {
3001 environment_->UpdateControlDependency(result);
3002 }
3003 // Add implicit exception continuation for throwing nodes.
3004 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
3005 Node* on_exception = graph()->NewNode(common()->IfException(), result);
3006 environment_->UpdateControlDependency(on_exception);
3007 if (FLAG_turbo_exceptions) {
3008 execution_control()->ThrowValue(jsgraph()->UndefinedConstant());
3009 }
3010 }
3011 // Add implicit success continuation for throwing nodes.
3012 if (!result->op()->HasProperty(Operator::kNoThrow)) {
3013 Node* on_success = graph()->NewNode(common()->IfSuccess(), result);
3014 environment_->UpdateControlDependency(on_success);
3015 }
2990 } 3016 }
2991 } 3017 }
2992 3018
2993 return result; 3019 return result;
2994 } 3020 }
2995 3021
2996 3022
2997 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 3023 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
2998 if (environment()->IsMarkedAsUnreachable()) return; 3024 if (environment()->IsMarkedAsUnreachable()) return;
2999 if (exit_control() != NULL) { 3025 if (exit_control() != NULL) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3163 Node* dead_node = graph()->NewNode(common()->Dead()); 3189 Node* dead_node = graph()->NewNode(common()->Dead());
3164 dead_control_.set(dead_node); 3190 dead_control_.set(dead_node);
3165 return dead_node; 3191 return dead_node;
3166 } 3192 }
3167 return dead_control_.get(); 3193 return dead_control_.get();
3168 } 3194 }
3169 3195
3170 } // namespace compiler 3196 } // namespace compiler
3171 } // namespace internal 3197 } // namespace internal
3172 } // namespace v8 3198 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698