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

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 2882973002: [coverage] Block coverage with support for IfStatements (Closed)
Patch Set: Whitespace Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index b754897e759335c90ea8c4a94555f3d22d3e6a9f..beafa6a370dd30b1c363c70578df0a593537f0fb 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -737,6 +737,36 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
bool has_constant_pool_entry_;
};
+// Used to generate IncBlockCounter bytecodes and the {source range, slot}
+// mapping for block coverage.
+class BytecodeGenerator::BlockCoverageBuilder final : public ZoneObject {
+ public:
+ explicit BlockCoverageBuilder(Zone* zone, BytecodeArrayBuilder* builder)
+ : slots_(0, zone), builder_(builder) {}
+
+ static const int kNoCoverageArraySlot = -1;
+
+ int AllocateBlockCoverageSlot(SourceRange range) {
+ if (range.IsEmpty()) return kNoCoverageArraySlot;
+ const int slot = static_cast<int>(slots_.size());
+ slots_.emplace_back(range);
+ return slot;
+ }
+
+ void IncBlockCounter(int coverage_array_slot) {
+ if (coverage_array_slot == kNoCoverageArraySlot) return;
+ builder_->IncBlockCounter(coverage_array_slot);
+ }
+
+ const ZoneVector<SourceRange>& slots() const { return slots_; }
+
+ private:
+ // Contains source range information for allocated block coverage counter
+ // slots. Slot i covers range slots_[i].
+ ZoneVector<SourceRange> slots_;
+ BytecodeArrayBuilder* builder_;
+};
+
class BytecodeGenerator::CurrentScope final {
public:
CurrentScope(BytecodeGenerator* generator, Scope* scope)
@@ -767,6 +797,7 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
closure_scope_(info->scope()),
current_scope_(info->scope()),
globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
+ block_coverage_builder_(nullptr),
global_declarations_(0, info->zone()),
function_literals_(0, info->zone()),
native_function_literals_(0, info->zone()),
@@ -779,10 +810,21 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
generator_state_(),
loop_depth_(0) {
DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
+ if (info->is_block_coverage_enabled()) {
+ DCHECK(FLAG_block_coverage);
+ block_coverage_builder_ =
+ new (zone()) BlockCoverageBuilder(zone(), builder());
+ }
}
Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
AllocateDeferredConstants(isolate);
+
marja 2017/06/02 07:01:23 Since you're touching this, can you add a DCHECK h
jgruber 2017/06/02 07:18:31 Done.
+ if (info()->is_block_coverage_enabled()) {
+ info()->set_coverage_info(
+ isolate->factory()->NewCoverageInfo(block_coverage_builder_->slots()));
+ }
+
if (HasStackOverflow()) return Handle<BytecodeArray>();
return builder()->ToBytecodeArray(isolate);
}
@@ -1184,12 +1226,18 @@ void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
builder()->SetStatementPosition(stmt);
+
+ int then_slot = AllocateBlockCoverageSlot(stmt->then_range());
+ int else_slot = AllocateBlockCoverageSlot(stmt->else_range());
+
if (stmt->condition()->ToBooleanIsTrue()) {
// Generate then block unconditionally as always true.
+ IncBlockCounter(then_slot);
Visit(stmt->then_statement());
} else if (stmt->condition()->ToBooleanIsFalse()) {
// Generate else block unconditionally if it exists.
if (stmt->HasElseStatement()) {
+ IncBlockCounter(else_slot);
Visit(stmt->else_statement());
}
} else {
@@ -1202,11 +1250,13 @@ void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
TestFallthrough::kThen);
then_labels.Bind(builder());
+ IncBlockCounter(then_slot);
Visit(stmt->then_statement());
if (stmt->HasElseStatement()) {
builder()->Jump(&end_label);
else_labels.Bind(builder());
+ IncBlockCounter(else_slot);
Visit(stmt->else_statement());
} else {
else_labels.Bind(builder());
@@ -3899,6 +3949,18 @@ int BytecodeGenerator::feedback_index(FeedbackSlot slot) const {
return FeedbackVector::GetIndex(slot);
}
+int BytecodeGenerator::AllocateBlockCoverageSlot(SourceRange range) {
+ return (block_coverage_builder_ == nullptr)
+ ? BlockCoverageBuilder::kNoCoverageArraySlot
+ : block_coverage_builder_->AllocateBlockCoverageSlot(range);
+}
+
+void BytecodeGenerator::IncBlockCounter(int coverage_array_slot) {
+ if (block_coverage_builder_ != nullptr) {
+ block_coverage_builder_->IncBlockCounter(coverage_array_slot);
+ }
+}
+
Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
: Runtime::kStoreToSuper_Sloppy;
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | src/isolate.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698