Commit f8a5c85d authored by jgruber's avatar jgruber Committed by Commit Bot

[coverage] Unify slot handling in BreakableControlFlowBuilders

Move block coverage slot creation into BreakableControlFlowBuilder for
Switch/Loop/Block constructs.

Bug: v8:6000
Change-Id: I4fa7fdb2ffbb56fd1016c22741458c103b42219c
Reviewed-on: https://chromium-review.googlesource.com/571808
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46808}
parent 512ea515
...@@ -1037,7 +1037,6 @@ void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) { ...@@ -1037,7 +1037,6 @@ void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
VisitDeclarations(stmt->scope()->declarations()); VisitDeclarations(stmt->scope()->declarations());
} }
VisitStatements(stmt->statements()); VisitStatements(stmt->statements());
block_builder.EndBlock();
} }
void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
...@@ -1285,7 +1284,8 @@ void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -1285,7 +1284,8 @@ void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// We need this scope because we visit for register values. We have to // We need this scope because we visit for register values. We have to
// maintain a execution result scope where registers can be allocated. // maintain a execution result scope where registers can be allocated.
ZoneList<CaseClause*>* clauses = stmt->cases(); ZoneList<CaseClause*>* clauses = stmt->cases();
SwitchBuilder switch_builder(builder(), clauses->length()); SwitchBuilder switch_builder(builder(), block_coverage_builder_, stmt,
clauses->length());
ControlScopeForBreakable scope(this, stmt, &switch_builder); ControlScopeForBreakable scope(this, stmt, &switch_builder);
int default_index = -1; int default_index = -1;
...@@ -1324,13 +1324,9 @@ void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -1324,13 +1324,9 @@ void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Iterate over all cases and create the case bodies. // Iterate over all cases and create the case bodies.
for (int i = 0; i < clauses->length(); i++) { for (int i = 0; i < clauses->length(); i++) {
CaseClause* clause = clauses->at(i); CaseClause* clause = clauses->at(i);
switch_builder.SetCaseTarget(i); switch_builder.SetCaseTarget(i, clause);
BuildIncrementBlockCoverageCounterIfEnabled(clause, SourceRangeKind::kBody);
VisitStatements(clause->statements()); VisitStatements(clause->statements());
} }
switch_builder.BindBreakTarget();
BuildIncrementBlockCoverageCounterIfEnabled(stmt,
SourceRangeKind::kContinuation);
} }
void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
......
...@@ -11,7 +11,12 @@ namespace interpreter { ...@@ -11,7 +11,12 @@ namespace interpreter {
BreakableControlFlowBuilder::~BreakableControlFlowBuilder() { BreakableControlFlowBuilder::~BreakableControlFlowBuilder() {
BindBreakTarget();
DCHECK(break_labels_.empty() || break_labels_.is_bound()); DCHECK(break_labels_.empty() || break_labels_.is_bound());
if (block_coverage_builder_ != nullptr && needs_continuation_counter()) {
block_coverage_builder_->IncrementBlockCounter(
node_, SourceRangeKind::kContinuation);
}
} }
void BreakableControlFlowBuilder::BindBreakTarget() { void BreakableControlFlowBuilder::BindBreakTarget() {
...@@ -40,29 +45,12 @@ void BreakableControlFlowBuilder::EmitJumpIfNull(BytecodeLabels* sites) { ...@@ -40,29 +45,12 @@ void BreakableControlFlowBuilder::EmitJumpIfNull(BytecodeLabels* sites) {
builder()->JumpIfNull(sites->New()); builder()->JumpIfNull(sites->New());
} }
void BlockBuilder::EndBlock() {
if (statement_->labels() != nullptr) {
builder()->Bind(&block_end_);
BindBreakTarget();
}
if (block_coverage_builder_ != nullptr && needs_continuation_counter_) {
block_coverage_builder_->IncrementBlockCounter(
statement_, SourceRangeKind::kContinuation);
}
}
LoopBuilder::~LoopBuilder() { LoopBuilder::~LoopBuilder() {
DCHECK(continue_labels_.empty() || continue_labels_.is_bound()); DCHECK(continue_labels_.empty() || continue_labels_.is_bound());
BindBreakTarget();
// Restore the parent jump table. // Restore the parent jump table.
if (generator_jump_table_location_ != nullptr) { if (generator_jump_table_location_ != nullptr) {
*generator_jump_table_location_ = parent_generator_jump_table_; *generator_jump_table_location_ = parent_generator_jump_table_;
} }
// Generate block coverage counter for the continuation.
if (block_coverage_builder_ != nullptr) {
block_coverage_builder_->IncrementBlockCounter(
block_coverage_continuation_slot_);
}
} }
void LoopBuilder::LoopHeader() { void LoopBuilder::LoopHeader() {
...@@ -120,10 +108,13 @@ SwitchBuilder::~SwitchBuilder() { ...@@ -120,10 +108,13 @@ SwitchBuilder::~SwitchBuilder() {
#endif #endif
} }
void SwitchBuilder::SetCaseTarget(int index, CaseClause* clause) {
void SwitchBuilder::SetCaseTarget(int index) {
BytecodeLabel& site = case_sites_.at(index); BytecodeLabel& site = case_sites_.at(index);
builder()->Bind(&site); builder()->Bind(&site);
if (block_coverage_builder_) {
block_coverage_builder_->IncrementBlockCounter(clause,
SourceRangeKind::kBody);
}
} }
......
...@@ -34,14 +34,15 @@ class V8_EXPORT_PRIVATE ControlFlowBuilder BASE_EMBEDDED { ...@@ -34,14 +34,15 @@ class V8_EXPORT_PRIVATE ControlFlowBuilder BASE_EMBEDDED {
class V8_EXPORT_PRIVATE BreakableControlFlowBuilder class V8_EXPORT_PRIVATE BreakableControlFlowBuilder
: public ControlFlowBuilder { : public ControlFlowBuilder {
public: public:
explicit BreakableControlFlowBuilder(BytecodeArrayBuilder* builder) BreakableControlFlowBuilder(BytecodeArrayBuilder* builder,
: ControlFlowBuilder(builder), break_labels_(builder->zone()) {} BlockCoverageBuilder* block_coverage_builder,
AstNode* node)
: ControlFlowBuilder(builder),
break_labels_(builder->zone()),
node_(node),
block_coverage_builder_(block_coverage_builder) {}
virtual ~BreakableControlFlowBuilder(); virtual ~BreakableControlFlowBuilder();
// This method should be called by the control flow owner before
// destruction to update sites that emit jumps for break.
void BindBreakTarget();
// This method is called when visiting break statements in the AST. // This method is called when visiting break statements in the AST.
// Inserts a jump to an unbound label that is patched when the corresponding // Inserts a jump to an unbound label that is patched when the corresponding
// BindBreakTarget is called. // BindBreakTarget is called.
...@@ -58,6 +59,9 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder ...@@ -58,6 +59,9 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder
BytecodeLabels* break_labels() { return &break_labels_; } BytecodeLabels* break_labels() { return &break_labels_; }
void set_needs_continuation_counter() { needs_continuation_counter_ = true; } void set_needs_continuation_counter() { needs_continuation_counter_ = true; }
bool needs_continuation_counter() const {
return needs_continuation_counter_;
}
protected: protected:
void EmitJump(BytecodeLabels* labels); void EmitJump(BytecodeLabels* labels);
...@@ -68,12 +72,17 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder ...@@ -68,12 +72,17 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder
void EmitJumpIfUndefined(BytecodeLabels* labels); void EmitJumpIfUndefined(BytecodeLabels* labels);
void EmitJumpIfNull(BytecodeLabels* labels); void EmitJumpIfNull(BytecodeLabels* labels);
// Called from the destructor to update sites that emit jumps for break.
void BindBreakTarget();
// Unbound labels that identify jumps for break statements in the code. // Unbound labels that identify jumps for break statements in the code.
BytecodeLabels break_labels_; BytecodeLabels break_labels_;
// A continuation counter (for block coverage) is needed e.g. when // A continuation counter (for block coverage) is needed e.g. when
// encountering a break statement. // encountering a break statement.
AstNode* node_;
bool needs_continuation_counter_ = false; bool needs_continuation_counter_ = false;
BlockCoverageBuilder* block_coverage_builder_;
}; };
...@@ -84,16 +93,8 @@ class V8_EXPORT_PRIVATE BlockBuilder final ...@@ -84,16 +93,8 @@ class V8_EXPORT_PRIVATE BlockBuilder final
BlockBuilder(BytecodeArrayBuilder* builder, BlockBuilder(BytecodeArrayBuilder* builder,
BlockCoverageBuilder* block_coverage_builder, BlockCoverageBuilder* block_coverage_builder,
BreakableStatement* statement) BreakableStatement* statement)
: BreakableControlFlowBuilder(builder), : BreakableControlFlowBuilder(builder, block_coverage_builder,
block_coverage_builder_(block_coverage_builder), statement) {}
statement_(statement) {}
void EndBlock();
private:
BytecodeLabel block_end_;
BlockCoverageBuilder* block_coverage_builder_;
BreakableStatement* statement_;
}; };
...@@ -103,18 +104,15 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder { ...@@ -103,18 +104,15 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
public: public:
LoopBuilder(BytecodeArrayBuilder* builder, LoopBuilder(BytecodeArrayBuilder* builder,
BlockCoverageBuilder* block_coverage_builder, AstNode* node) BlockCoverageBuilder* block_coverage_builder, AstNode* node)
: BreakableControlFlowBuilder(builder), : BreakableControlFlowBuilder(builder, block_coverage_builder, node),
continue_labels_(builder->zone()), continue_labels_(builder->zone()),
generator_jump_table_location_(nullptr), generator_jump_table_location_(nullptr),
parent_generator_jump_table_(nullptr), parent_generator_jump_table_(nullptr) {
block_coverage_builder_(block_coverage_builder) {
if (block_coverage_builder_ != nullptr) { if (block_coverage_builder_ != nullptr) {
set_needs_continuation_counter();
block_coverage_body_slot_ = block_coverage_body_slot_ =
block_coverage_builder_->AllocateBlockCoverageSlot( block_coverage_builder_->AllocateBlockCoverageSlot(
node, SourceRangeKind::kBody); node, SourceRangeKind::kBody);
block_coverage_continuation_slot_ =
block_coverage_builder_->AllocateBlockCoverageSlot(
node, SourceRangeKind::kContinuation);
} }
} }
~LoopBuilder(); ~LoopBuilder();
...@@ -148,8 +146,6 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder { ...@@ -148,8 +146,6 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
BytecodeJumpTable* parent_generator_jump_table_; BytecodeJumpTable* parent_generator_jump_table_;
int block_coverage_body_slot_; int block_coverage_body_slot_;
int block_coverage_continuation_slot_;
BlockCoverageBuilder* block_coverage_builder_;
}; };
...@@ -157,8 +153,10 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder { ...@@ -157,8 +153,10 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
class V8_EXPORT_PRIVATE SwitchBuilder final class V8_EXPORT_PRIVATE SwitchBuilder final
: public BreakableControlFlowBuilder { : public BreakableControlFlowBuilder {
public: public:
explicit SwitchBuilder(BytecodeArrayBuilder* builder, int number_of_cases) SwitchBuilder(BytecodeArrayBuilder* builder,
: BreakableControlFlowBuilder(builder), BlockCoverageBuilder* block_coverage_builder,
SwitchStatement* statement, int number_of_cases)
: BreakableControlFlowBuilder(builder, block_coverage_builder, statement),
case_sites_(builder->zone()) { case_sites_(builder->zone()) {
case_sites_.resize(number_of_cases); case_sites_.resize(number_of_cases);
} }
...@@ -166,7 +164,7 @@ class V8_EXPORT_PRIVATE SwitchBuilder final ...@@ -166,7 +164,7 @@ class V8_EXPORT_PRIVATE SwitchBuilder final
// This method should be called by the SwitchBuilder owner when the case // This method should be called by the SwitchBuilder owner when the case
// statement with |index| is emitted to update the case jump site. // statement with |index| is emitted to update the case jump site.
void SetCaseTarget(int index); void SetCaseTarget(int index, CaseClause* clause);
// This method is called when visiting case comparison operation for |index|. // This method is called when visiting case comparison operation for |index|.
// Inserts a JumpIfTrue with ToBooleanMode |mode| to a unbound label that is // Inserts a JumpIfTrue with ToBooleanMode |mode| to a unbound label that is
...@@ -189,8 +187,8 @@ class V8_EXPORT_PRIVATE SwitchBuilder final ...@@ -189,8 +187,8 @@ class V8_EXPORT_PRIVATE SwitchBuilder final
// A class to help with co-ordinating control flow in try-catch statements. // A class to help with co-ordinating control flow in try-catch statements.
class V8_EXPORT_PRIVATE TryCatchBuilder final : public ControlFlowBuilder { class V8_EXPORT_PRIVATE TryCatchBuilder final : public ControlFlowBuilder {
public: public:
explicit TryCatchBuilder(BytecodeArrayBuilder* builder, TryCatchBuilder(BytecodeArrayBuilder* builder,
HandlerTable::CatchPrediction catch_prediction) HandlerTable::CatchPrediction catch_prediction)
: ControlFlowBuilder(builder), : ControlFlowBuilder(builder),
handler_id_(builder->NewHandlerEntry()), handler_id_(builder->NewHandlerEntry()),
catch_prediction_(catch_prediction) {} catch_prediction_(catch_prediction) {}
...@@ -210,8 +208,8 @@ class V8_EXPORT_PRIVATE TryCatchBuilder final : public ControlFlowBuilder { ...@@ -210,8 +208,8 @@ class V8_EXPORT_PRIVATE TryCatchBuilder final : public ControlFlowBuilder {
// A class to help with co-ordinating control flow in try-finally statements. // A class to help with co-ordinating control flow in try-finally statements.
class V8_EXPORT_PRIVATE TryFinallyBuilder final : public ControlFlowBuilder { class V8_EXPORT_PRIVATE TryFinallyBuilder final : public ControlFlowBuilder {
public: public:
explicit TryFinallyBuilder(BytecodeArrayBuilder* builder, TryFinallyBuilder(BytecodeArrayBuilder* builder,
HandlerTable::CatchPrediction catch_prediction) HandlerTable::CatchPrediction catch_prediction)
: ControlFlowBuilder(builder), : ControlFlowBuilder(builder),
handler_id_(builder->NewHandlerEntry()), handler_id_(builder->NewHandlerEntry()),
catch_prediction_(catch_prediction), catch_prediction_(catch_prediction),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment