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

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

Issue 1641723002: [interpreter] Translate exception handlers into graph. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 4 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
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/compiler/bytecode-branch-analysis.h" 7 #include "src/compiler/bytecode-branch-analysis.h"
8 #include "src/compiler/linkage.h" 8 #include "src/compiler/linkage.h"
9 #include "src/compiler/operator-properties.h" 9 #include "src/compiler/operator-properties.h"
10 #include "src/interpreter/bytecodes.h" 10 #include "src/interpreter/bytecodes.h"
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 int output_poke_end = output_poke_start + output_poke_count; 368 int output_poke_end = output_poke_start + output_poke_count;
369 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(), 369 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
370 output_poke_start, output_poke_end) && 370 output_poke_start, output_poke_end) &&
371 StateValuesAreUpToDate(&registers_state_values_, register_base(), 371 StateValuesAreUpToDate(&registers_state_values_, register_base(),
372 register_count(), output_poke_start, 372 register_count(), output_poke_start,
373 output_poke_end) && 373 output_poke_end) &&
374 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(), 374 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
375 1, output_poke_start, output_poke_end); 375 1, output_poke_start, output_poke_end);
376 } 376 }
377 377
378
379 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 378 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
380 CompilationInfo* compilation_info, 379 CompilationInfo* compilation_info,
381 JSGraph* jsgraph) 380 JSGraph* jsgraph)
382 : local_zone_(local_zone), 381 : local_zone_(local_zone),
383 info_(compilation_info), 382 info_(compilation_info),
384 jsgraph_(jsgraph), 383 jsgraph_(jsgraph),
385 bytecode_array_(handle(info()->shared_info()->bytecode_array())), 384 bytecode_array_(handle(info()->shared_info()->bytecode_array())),
385 exception_handler_table_(
386 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
386 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 387 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
387 FrameStateType::kInterpretedFunction, 388 FrameStateType::kInterpretedFunction,
388 bytecode_array()->parameter_count(), 389 bytecode_array()->parameter_count(),
389 bytecode_array()->register_count(), info()->shared_info(), 390 bytecode_array()->register_count(), info()->shared_info(),
390 CALL_MAINTAINS_NATIVE_CONTEXT)), 391 CALL_MAINTAINS_NATIVE_CONTEXT)),
391 merge_environments_(local_zone), 392 merge_environments_(local_zone),
392 loop_header_environments_(local_zone), 393 loop_header_environments_(local_zone),
394 exception_handlers_(local_zone),
395 current_exception_handler_(0),
393 input_buffer_size_(0), 396 input_buffer_size_(0),
394 input_buffer_(nullptr), 397 input_buffer_(nullptr),
395 exit_controls_(local_zone) {} 398 exit_controls_(local_zone) {}
396 399
397
398 Node* BytecodeGraphBuilder::GetNewTarget() { 400 Node* BytecodeGraphBuilder::GetNewTarget() {
399 if (!new_target_.is_set()) { 401 if (!new_target_.is_set()) {
400 int params = bytecode_array()->parameter_count(); 402 int params = bytecode_array()->parameter_count();
401 int index = Linkage::GetJSCallNewTargetParamIndex(params); 403 int index = Linkage::GetJSCallNewTargetParamIndex(params);
402 const Operator* op = common()->Parameter(index, "%new.target"); 404 const Operator* op = common()->Parameter(index, "%new.target");
403 Node* node = NewNode(op, graph()->start()); 405 Node* node = NewNode(op, graph()->start());
404 new_target_.set(node); 406 new_target_.set(node);
405 } 407 }
406 return new_target_.get(); 408 return new_target_.get();
407 } 409 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 522
521 void BytecodeGraphBuilder::VisitBytecodes() { 523 void BytecodeGraphBuilder::VisitBytecodes() {
522 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone()); 524 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
523 analysis.Analyze(); 525 analysis.Analyze();
524 set_branch_analysis(&analysis); 526 set_branch_analysis(&analysis);
525 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 527 interpreter::BytecodeArrayIterator iterator(bytecode_array());
526 set_bytecode_iterator(&iterator); 528 set_bytecode_iterator(&iterator);
527 while (!iterator.done()) { 529 while (!iterator.done()) {
528 int current_offset = iterator.current_offset(); 530 int current_offset = iterator.current_offset();
529 if (analysis.is_reachable(current_offset)) { 531 if (analysis.is_reachable(current_offset)) {
532 EnterAndExitExceptionHandlers(current_offset);
530 MergeEnvironmentsOfForwardBranches(current_offset); 533 MergeEnvironmentsOfForwardBranches(current_offset);
531 BuildLoopHeaderForBackwardBranches(current_offset); 534 BuildLoopHeaderForBackwardBranches(current_offset);
532 535
533 switch (iterator.current_bytecode()) { 536 switch (iterator.current_bytecode()) {
534 #define BYTECODE_CASE(name, ...) \ 537 #define BYTECODE_CASE(name, ...) \
535 case interpreter::Bytecode::k##name: \ 538 case interpreter::Bytecode::k##name: \
536 Visit##name(iterator); \ 539 Visit##name(iterator); \
537 break; 540 break;
538 BYTECODE_LIST(BYTECODE_CASE) 541 BYTECODE_LIST(BYTECODE_CASE)
539 #undef BYTECODE_CODE 542 #undef BYTECODE_CODE
540 } 543 }
541 } 544 }
542 iterator.Advance(); 545 iterator.Advance();
543 } 546 }
544 set_branch_analysis(nullptr); 547 set_branch_analysis(nullptr);
545 set_bytecode_iterator(nullptr); 548 set_bytecode_iterator(nullptr);
549 DCHECK(exception_handlers_.empty());
546 } 550 }
547 551
548 552
549 void BytecodeGraphBuilder::VisitLdaZero( 553 void BytecodeGraphBuilder::VisitLdaZero(
550 const interpreter::BytecodeArrayIterator& iterator) { 554 const interpreter::BytecodeArrayIterator& iterator) {
551 Node* node = jsgraph()->ZeroConstant(); 555 Node* node = jsgraph()->ZeroConstant();
552 environment()->BindAccumulator(node); 556 environment()->BindAccumulator(node);
553 } 557 }
554 558
555 559
(...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 1946
1943 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { 1947 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1944 if (size > input_buffer_size_) { 1948 if (size > input_buffer_size_) {
1945 size = size + kInputBufferSizeIncrement + input_buffer_size_; 1949 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1946 input_buffer_ = local_zone()->NewArray<Node*>(size); 1950 input_buffer_ = local_zone()->NewArray<Node*>(size);
1947 input_buffer_size_ = size; 1951 input_buffer_size_ = size;
1948 } 1952 }
1949 return input_buffer_; 1953 return input_buffer_;
1950 } 1954 }
1951 1955
1956 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1957 Handle<HandlerTable> table = exception_handler_table();
1958 int num_entries = table->NumberOfRangeEntries();
1959
1960 // Potentially exit exception handlers.
1961 while (!exception_handlers_.empty()) {
1962 int current_end = exception_handlers_.top().end_offset_;
1963 if (current_offset < current_end) break; // Still covered by range.
1964 exception_handlers_.pop();
1965 }
1966
1967 // Potentially enter exception handlers.
1968 while (current_exception_handler_ < num_entries) {
1969 int next_start = table->GetRangeStart(current_exception_handler_);
1970 if (current_offset < next_start) break; // Not yet covered by range.
1971 int next_end = table->GetRangeEnd(current_exception_handler_);
1972 int next_handler = table->GetRangeHandler(current_exception_handler_);
1973 exception_handlers_.push({next_start, next_end, next_handler});
1974 current_exception_handler_++;
1975 }
1976 }
1952 1977
1953 void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) { 1978 void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) {
1954 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 1979 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1955 DCHECK_EQ(IrOpcode::kDead, 1980 DCHECK_EQ(IrOpcode::kDead,
1956 NodeProperties::GetFrameStateInput(node, 0)->opcode()); 1981 NodeProperties::GetFrameStateInput(node, 0)->opcode());
1957 NodeProperties::ReplaceFrameStateInput( 1982 NodeProperties::ReplaceFrameStateInput(
1958 node, 0, environment()->Checkpoint(BailoutId(0), 1983 node, 0, environment()->Checkpoint(BailoutId(0),
1959 OutputFrameStateCombine::Ignore())); 1984 OutputFrameStateCombine::Ignore()));
1960 } 1985 }
1961 1986
1962 1987
1963 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, 1988 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1964 Node** value_inputs, bool incomplete) { 1989 Node** value_inputs, bool incomplete) {
1965 DCHECK_EQ(op->ValueInputCount(), value_input_count); 1990 DCHECK_EQ(op->ValueInputCount(), value_input_count);
1966 1991
1967 bool has_context = OperatorProperties::HasContextInput(op); 1992 bool has_context = OperatorProperties::HasContextInput(op);
1968 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); 1993 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1969 bool has_control = op->ControlInputCount() == 1; 1994 bool has_control = op->ControlInputCount() == 1;
1970 bool has_effect = op->EffectInputCount() == 1; 1995 bool has_effect = op->EffectInputCount() == 1;
1971 1996
1972 DCHECK_LT(op->ControlInputCount(), 2); 1997 DCHECK_LT(op->ControlInputCount(), 2);
1973 DCHECK_LT(op->EffectInputCount(), 2); 1998 DCHECK_LT(op->EffectInputCount(), 2);
1974 1999
1975 Node* result = nullptr; 2000 Node* result = nullptr;
1976 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) { 2001 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1977 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); 2002 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1978 } else { 2003 } else {
2004 bool inside_handler = !exception_handlers_.empty();
1979 int input_count_with_deps = value_input_count; 2005 int input_count_with_deps = value_input_count;
1980 if (has_context) ++input_count_with_deps; 2006 if (has_context) ++input_count_with_deps;
1981 input_count_with_deps += frame_state_count; 2007 input_count_with_deps += frame_state_count;
1982 if (has_control) ++input_count_with_deps; 2008 if (has_control) ++input_count_with_deps;
1983 if (has_effect) ++input_count_with_deps; 2009 if (has_effect) ++input_count_with_deps;
1984 Node** buffer = EnsureInputBufferSize(input_count_with_deps); 2010 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1985 memcpy(buffer, value_inputs, kPointerSize * value_input_count); 2011 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1986 Node** current_input = buffer + value_input_count; 2012 Node** current_input = buffer + value_input_count;
1987 if (has_context) { 2013 if (has_context) {
1988 *current_input++ = environment()->Context(); 2014 *current_input++ = environment()->Context();
(...skipping 13 matching lines...) Expand all
2002 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); 2028 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
2003 if (!environment()->IsMarkedAsUnreachable()) { 2029 if (!environment()->IsMarkedAsUnreachable()) {
2004 // Update the current control dependency for control-producing nodes. 2030 // Update the current control dependency for control-producing nodes.
2005 if (NodeProperties::IsControl(result)) { 2031 if (NodeProperties::IsControl(result)) {
2006 environment()->UpdateControlDependency(result); 2032 environment()->UpdateControlDependency(result);
2007 } 2033 }
2008 // Update the current effect dependency for effect-producing nodes. 2034 // Update the current effect dependency for effect-producing nodes.
2009 if (result->op()->EffectOutputCount() > 0) { 2035 if (result->op()->EffectOutputCount() > 0) {
2010 environment()->UpdateEffectDependency(result); 2036 environment()->UpdateEffectDependency(result);
2011 } 2037 }
2038 // Add implicit exception continuation for throwing nodes.
2039 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
2040 int throw_offset = bytecode_iterator()->current_offset();
2041 int handler_offset = exception_handlers_.top().handler_offset_;
2042 // TODO(mstarzinger): Thread through correct prediction!
2043 IfExceptionHint hint = IfExceptionHint::kLocallyCaught;
2044 // TODO(mstarzinger): For now we mutate the branch analysis result and
2045 // add the artificial control flow from throw-site to handler-entry.
2046 // This can be simplified by pushing environment forward along the
2047 // direction of the data-flow.
2048 branch_analysis_->AddExceptionalBranch(throw_offset, handler_offset);
2049 Environment* success_env = environment()->CopyForConditional();
2050 const Operator* op = common()->IfException(hint);
2051 Node* effect = environment()->GetEffectDependency();
2052 Node* on_exception = graph()->NewNode(op, effect, result);
2053 environment()->UpdateControlDependency(on_exception);
2054 environment()->UpdateEffectDependency(on_exception);
2055 environment()->BindAccumulator(on_exception);
2056 BuildJump(throw_offset, handler_offset);
2057 set_environment(success_env);
2058 }
2012 // Add implicit success continuation for throwing nodes. 2059 // Add implicit success continuation for throwing nodes.
2013 if (!result->op()->HasProperty(Operator::kNoThrow)) { 2060 if (!result->op()->HasProperty(Operator::kNoThrow)) {
2014 const Operator* if_success = common()->IfSuccess(); 2061 const Operator* if_success = common()->IfSuccess();
2015 Node* on_success = graph()->NewNode(if_success, result); 2062 Node* on_success = graph()->NewNode(if_success, result);
2016 environment_->UpdateControlDependency(on_success); 2063 environment()->UpdateControlDependency(on_success);
2017 } 2064 }
2018 } 2065 }
2019 } 2066 }
2020 2067
2021 return result; 2068 return result;
2022 } 2069 }
2023 2070
2024 2071
2025 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) { 2072 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
2026 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); 2073 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 2147
2101 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 2148 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
2102 if (environment()->IsMarkedAsUnreachable()) return; 2149 if (environment()->IsMarkedAsUnreachable()) return;
2103 environment()->MarkAsUnreachable(); 2150 environment()->MarkAsUnreachable();
2104 exit_controls_.push_back(exit); 2151 exit_controls_.push_back(exit);
2105 } 2152 }
2106 2153
2107 } // namespace compiler 2154 } // namespace compiler
2108 } // namespace internal 2155 } // namespace internal
2109 } // namespace v8 2156 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698