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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2882973002: [coverage] Block coverage with support for IfStatements (Closed)
Patch Set: Whitespace Created 3 years, 6 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 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins/builtins-constructor.h" 9 #include "src/builtins/builtins-constructor.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 const AstRawString* name; 730 const AstRawString* name;
731 FeedbackSlot slot; 731 FeedbackSlot slot;
732 FeedbackSlot literal_slot; 732 FeedbackSlot literal_slot;
733 FunctionLiteral* func; 733 FunctionLiteral* func;
734 }; 734 };
735 ZoneVector<Declaration> declarations_; 735 ZoneVector<Declaration> declarations_;
736 size_t constant_pool_entry_; 736 size_t constant_pool_entry_;
737 bool has_constant_pool_entry_; 737 bool has_constant_pool_entry_;
738 }; 738 };
739 739
740 // Used to generate IncBlockCounter bytecodes and the {source range, slot}
741 // mapping for block coverage.
742 class BytecodeGenerator::BlockCoverageBuilder final : public ZoneObject {
743 public:
744 explicit BlockCoverageBuilder(Zone* zone, BytecodeArrayBuilder* builder)
745 : slots_(0, zone), builder_(builder) {}
746
747 static const int kNoCoverageArraySlot = -1;
748
749 int AllocateBlockCoverageSlot(SourceRange range) {
750 if (range.IsEmpty()) return kNoCoverageArraySlot;
751 const int slot = static_cast<int>(slots_.size());
752 slots_.emplace_back(range);
753 return slot;
754 }
755
756 void IncBlockCounter(int coverage_array_slot) {
757 if (coverage_array_slot == kNoCoverageArraySlot) return;
758 builder_->IncBlockCounter(coverage_array_slot);
759 }
760
761 const ZoneVector<SourceRange>& slots() const { return slots_; }
762
763 private:
764 // Contains source range information for allocated block coverage counter
765 // slots. Slot i covers range slots_[i].
766 ZoneVector<SourceRange> slots_;
767 BytecodeArrayBuilder* builder_;
768 };
769
740 class BytecodeGenerator::CurrentScope final { 770 class BytecodeGenerator::CurrentScope final {
741 public: 771 public:
742 CurrentScope(BytecodeGenerator* generator, Scope* scope) 772 CurrentScope(BytecodeGenerator* generator, Scope* scope)
743 : generator_(generator), outer_scope_(generator->current_scope()) { 773 : generator_(generator), outer_scope_(generator->current_scope()) {
744 if (scope != nullptr) { 774 if (scope != nullptr) {
745 generator_->set_current_scope(scope); 775 generator_->set_current_scope(scope);
746 } 776 }
747 } 777 }
748 ~CurrentScope() { 778 ~CurrentScope() {
749 if (outer_scope_ != generator_->current_scope()) { 779 if (outer_scope_ != generator_->current_scope()) {
(...skipping 10 matching lines...) Expand all
760 : zone_(info->zone()), 790 : zone_(info->zone()),
761 builder_(new (zone()) BytecodeArrayBuilder( 791 builder_(new (zone()) BytecodeArrayBuilder(
762 info->isolate(), info->zone(), info->num_parameters_including_this(), 792 info->isolate(), info->zone(), info->num_parameters_including_this(),
763 info->scope()->num_stack_slots(), info->literal(), 793 info->scope()->num_stack_slots(), info->literal(),
764 info->SourcePositionRecordingMode())), 794 info->SourcePositionRecordingMode())),
765 info_(info), 795 info_(info),
766 ast_string_constants_(info->isolate()->ast_string_constants()), 796 ast_string_constants_(info->isolate()->ast_string_constants()),
767 closure_scope_(info->scope()), 797 closure_scope_(info->scope()),
768 current_scope_(info->scope()), 798 current_scope_(info->scope()),
769 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), 799 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
800 block_coverage_builder_(nullptr),
770 global_declarations_(0, info->zone()), 801 global_declarations_(0, info->zone()),
771 function_literals_(0, info->zone()), 802 function_literals_(0, info->zone()),
772 native_function_literals_(0, info->zone()), 803 native_function_literals_(0, info->zone()),
773 object_literals_(0, info->zone()), 804 object_literals_(0, info->zone()),
774 array_literals_(0, info->zone()), 805 array_literals_(0, info->zone()),
775 execution_control_(nullptr), 806 execution_control_(nullptr),
776 execution_context_(nullptr), 807 execution_context_(nullptr),
777 execution_result_(nullptr), 808 execution_result_(nullptr),
778 generator_jump_table_(nullptr), 809 generator_jump_table_(nullptr),
779 generator_state_(), 810 generator_state_(),
780 loop_depth_(0) { 811 loop_depth_(0) {
781 DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope()); 812 DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
813 if (info->is_block_coverage_enabled()) {
814 DCHECK(FLAG_block_coverage);
815 block_coverage_builder_ =
816 new (zone()) BlockCoverageBuilder(zone(), builder());
817 }
782 } 818 }
783 819
784 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { 820 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
785 AllocateDeferredConstants(isolate); 821 AllocateDeferredConstants(isolate);
822
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.
823 if (info()->is_block_coverage_enabled()) {
824 info()->set_coverage_info(
825 isolate->factory()->NewCoverageInfo(block_coverage_builder_->slots()));
826 }
827
786 if (HasStackOverflow()) return Handle<BytecodeArray>(); 828 if (HasStackOverflow()) return Handle<BytecodeArray>();
787 return builder()->ToBytecodeArray(isolate); 829 return builder()->ToBytecodeArray(isolate);
788 } 830 }
789 831
790 void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) { 832 void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) {
791 // Build global declaration pair arrays. 833 // Build global declaration pair arrays.
792 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { 834 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
793 Handle<FixedArray> declarations = 835 Handle<FixedArray> declarations =
794 globals_builder->AllocateDeclarations(info()); 836 globals_builder->AllocateDeclarations(info());
795 if (declarations.is_null()) return SetStackOverflow(); 837 if (declarations.is_null()) return SetStackOverflow();
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 1219 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
1178 builder()->SetStatementPosition(stmt); 1220 builder()->SetStatementPosition(stmt);
1179 VisitForEffect(stmt->expression()); 1221 VisitForEffect(stmt->expression());
1180 } 1222 }
1181 1223
1182 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 1224 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
1183 } 1225 }
1184 1226
1185 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 1227 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
1186 builder()->SetStatementPosition(stmt); 1228 builder()->SetStatementPosition(stmt);
1229
1230 int then_slot = AllocateBlockCoverageSlot(stmt->then_range());
1231 int else_slot = AllocateBlockCoverageSlot(stmt->else_range());
1232
1187 if (stmt->condition()->ToBooleanIsTrue()) { 1233 if (stmt->condition()->ToBooleanIsTrue()) {
1188 // Generate then block unconditionally as always true. 1234 // Generate then block unconditionally as always true.
1235 IncBlockCounter(then_slot);
1189 Visit(stmt->then_statement()); 1236 Visit(stmt->then_statement());
1190 } else if (stmt->condition()->ToBooleanIsFalse()) { 1237 } else if (stmt->condition()->ToBooleanIsFalse()) {
1191 // Generate else block unconditionally if it exists. 1238 // Generate else block unconditionally if it exists.
1192 if (stmt->HasElseStatement()) { 1239 if (stmt->HasElseStatement()) {
1240 IncBlockCounter(else_slot);
1193 Visit(stmt->else_statement()); 1241 Visit(stmt->else_statement());
1194 } 1242 }
1195 } else { 1243 } else {
1196 // TODO(oth): If then statement is BreakStatement or 1244 // TODO(oth): If then statement is BreakStatement or
1197 // ContinueStatement we can reduce number of generated 1245 // ContinueStatement we can reduce number of generated
1198 // jump/jump_ifs here. See BasicLoops test. 1246 // jump/jump_ifs here. See BasicLoops test.
1199 BytecodeLabel end_label; 1247 BytecodeLabel end_label;
1200 BytecodeLabels then_labels(zone()), else_labels(zone()); 1248 BytecodeLabels then_labels(zone()), else_labels(zone());
1201 VisitForTest(stmt->condition(), &then_labels, &else_labels, 1249 VisitForTest(stmt->condition(), &then_labels, &else_labels,
1202 TestFallthrough::kThen); 1250 TestFallthrough::kThen);
1203 1251
1204 then_labels.Bind(builder()); 1252 then_labels.Bind(builder());
1253 IncBlockCounter(then_slot);
1205 Visit(stmt->then_statement()); 1254 Visit(stmt->then_statement());
1206 1255
1207 if (stmt->HasElseStatement()) { 1256 if (stmt->HasElseStatement()) {
1208 builder()->Jump(&end_label); 1257 builder()->Jump(&end_label);
1209 else_labels.Bind(builder()); 1258 else_labels.Bind(builder());
1259 IncBlockCounter(else_slot);
1210 Visit(stmt->else_statement()); 1260 Visit(stmt->else_statement());
1211 } else { 1261 } else {
1212 else_labels.Bind(builder()); 1262 else_labels.Bind(builder());
1213 } 1263 }
1214 builder()->Bind(&end_label); 1264 builder()->Bind(&end_label);
1215 } 1265 }
1216 } 1266 }
1217 1267
1218 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 1268 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
1219 SloppyBlockFunctionStatement* stmt) { 1269 SloppyBlockFunctionStatement* stmt) {
(...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after
3892 } 3942 }
3893 3943
3894 LanguageMode BytecodeGenerator::language_mode() const { 3944 LanguageMode BytecodeGenerator::language_mode() const {
3895 return current_scope()->language_mode(); 3945 return current_scope()->language_mode();
3896 } 3946 }
3897 3947
3898 int BytecodeGenerator::feedback_index(FeedbackSlot slot) const { 3948 int BytecodeGenerator::feedback_index(FeedbackSlot slot) const {
3899 return FeedbackVector::GetIndex(slot); 3949 return FeedbackVector::GetIndex(slot);
3900 } 3950 }
3901 3951
3952 int BytecodeGenerator::AllocateBlockCoverageSlot(SourceRange range) {
3953 return (block_coverage_builder_ == nullptr)
3954 ? BlockCoverageBuilder::kNoCoverageArraySlot
3955 : block_coverage_builder_->AllocateBlockCoverageSlot(range);
3956 }
3957
3958 void BytecodeGenerator::IncBlockCounter(int coverage_array_slot) {
3959 if (block_coverage_builder_ != nullptr) {
3960 block_coverage_builder_->IncBlockCounter(coverage_array_slot);
3961 }
3962 }
3963
3902 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() { 3964 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
3903 return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 3965 return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
3904 : Runtime::kStoreToSuper_Sloppy; 3966 : Runtime::kStoreToSuper_Sloppy;
3905 } 3967 }
3906 3968
3907 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { 3969 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3908 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 3970 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3909 : Runtime::kStoreKeyedToSuper_Sloppy; 3971 : Runtime::kStoreKeyedToSuper_Sloppy;
3910 } 3972 }
3911 3973
3912 } // namespace interpreter 3974 } // namespace interpreter
3913 } // namespace internal 3975 } // namespace internal
3914 } // namespace v8 3976 } // namespace v8
OLDNEW
« 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