Skip to content

Commit c7d7552

Browse files
sjindel-googlecommit-bot@chromium.org
authored andcommitted
[vm] Re-land aggressive write-barrier elimination.
It incorrectly assumed that all stores in Dart code write to Instances. There is actually one exception, Contexts, which do not inherit from Instance. I've added asserts to ensure this kind of bug cannot resurface. The original change is in patchset 4. Change-Id: Ic2d8d05e70a4de738eb9fb5980487b4f27111b8c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136221 Commit-Queue: Samir Jindel <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Reviewed-by: Ryan Macnak <[email protected]>
1 parent 0dca599 commit c7d7552

23 files changed

+615
-85
lines changed

runtime/vm/bit_vector.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class BitVector : public ZoneAllocated {
7070
data_[i / kBitsPerWord] &= ~(static_cast<uword>(1) << (i % kBitsPerWord));
7171
}
7272

73+
void Set(intptr_t i, bool value) { value ? Add(i) : Remove(i); }
74+
7375
bool Equals(const BitVector& other) const;
7476

7577
// Add all elements that are in the bitvector from.
@@ -92,6 +94,14 @@ class BitVector : public ZoneAllocated {
9294
return (block & (static_cast<uword>(1) << (i % kBitsPerWord))) != 0;
9395
}
9496

97+
bool SubsetOf(const BitVector& other) {
98+
ASSERT(length_ == other.length_);
99+
for (intptr_t i = 0; i < data_length_; ++i) {
100+
if ((data_[i] & other.data_[i]) != data_[i]) return false;
101+
}
102+
return true;
103+
}
104+
95105
void Clear() {
96106
for (intptr_t i = 0; i < data_length_; i++) {
97107
data_[i] = 0;

runtime/vm/compiler/backend/flow_graph_compiler.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,9 @@ void FlowGraphCompiler::VisitBlocks() {
612612
EmitInstructionPrologue(instr);
613613
ASSERT(pending_deoptimization_env_ == NULL);
614614
pending_deoptimization_env_ = instr->env();
615+
DEBUG_ONLY(current_instruction_ = instr);
615616
instr->EmitNativeCode(this);
617+
DEBUG_ONLY(current_instruction_ = nullptr);
616618
pending_deoptimization_env_ = NULL;
617619
if (IsPeephole(instr)) {
618620
ASSERT(top_of_stack_ == nullptr);
@@ -703,7 +705,9 @@ void FlowGraphCompiler::GenerateDeferredCode() {
703705
slow_path->instruction()->tag());
704706
SpecialStatsBegin(stats_tag);
705707
BeginCodeSourceRange();
708+
DEBUG_ONLY(current_instruction_ = slow_path->instruction());
706709
slow_path->GenerateCode(this);
710+
DEBUG_ONLY(current_instruction_ = nullptr);
707711
EndCodeSourceRange(slow_path->instruction()->token_pos());
708712
SpecialStatsEnd(stats_tag);
709713
}

runtime/vm/compiler/backend/flow_graph_compiler.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,15 @@ class FlowGraphCompiler : public ValueObject {
11171117
// is amenable to a peephole optimization.
11181118
bool IsPeephole(Instruction* instr) const;
11191119

1120+
#if defined(DEBUG)
1121+
bool CanCallDart() const {
1122+
return current_instruction_ == nullptr ||
1123+
current_instruction_->CanCallDart();
1124+
}
1125+
#else
1126+
bool CanCallDart() const { return true; }
1127+
#endif
1128+
11201129
// This struct contains either function or code, the other one being NULL.
11211130
class StaticCallsStruct : public ZoneAllocated {
11221131
public:
@@ -1210,6 +1219,10 @@ class FlowGraphCompiler : public ValueObject {
12101219
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
12111220
Array& edge_counters_array_;
12121221

1222+
// Instruction currently running EmitNativeCode(). Useful for asserts.
1223+
// Does not include Phis and BlockEntrys.
1224+
DEBUG_ONLY(Instruction* current_instruction_ = nullptr);
1225+
12131226
DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler);
12141227
};
12151228

runtime/vm/compiler/backend/flow_graph_compiler_arm.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
10001000
RawPcDescriptors::Kind kind,
10011001
LocationSummary* locs,
10021002
Code::EntryKind entry_kind) {
1003+
ASSERT(CanCallDart());
10031004
__ BranchLinkPatchable(stub, entry_kind);
10041005
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
10051006
}
@@ -1010,6 +1011,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
10101011
LocationSummary* locs,
10111012
const Function& target,
10121013
Code::EntryKind entry_kind) {
1014+
ASSERT(CanCallDart());
10131015
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
10141016
__ GenerateUnRelocatedPcRelativeCall();
10151017
AddPcRelativeCallTarget(target, entry_kind);
@@ -1066,6 +1068,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(const Code& stub,
10661068
TokenPosition token_pos,
10671069
LocationSummary* locs,
10681070
Code::EntryKind entry_kind) {
1071+
ASSERT(CanCallDart());
10691072
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
10701073
// Each ICData propagated from unoptimized to optimized code contains the
10711074
// function that corresponds to the Dart function of that IC call. Due
@@ -1089,6 +1092,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10891092
TokenPosition token_pos,
10901093
LocationSummary* locs,
10911094
Code::EntryKind entry_kind) {
1095+
ASSERT(CanCallDart());
10921096
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10931097
entry_kind == Code::EntryKind::kUnchecked);
10941098
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1114,6 +1118,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
11141118
LocationSummary* locs,
11151119
intptr_t try_index,
11161120
intptr_t slow_path_argument_count) {
1121+
ASSERT(CanCallDart());
11171122
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
11181123
const ArgumentsDescriptor args_desc(arguments_descriptor);
11191124
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1161,6 +1166,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11611166
LocationSummary* locs,
11621167
Code::EntryKind entry_kind,
11631168
bool receiver_can_be_smi) {
1169+
ASSERT(CanCallDart());
11641170
ASSERT(entry_kind == Code::EntryKind::kNormal ||
11651171
entry_kind == Code::EntryKind::kUnchecked);
11661172
ASSERT(ic_data.NumArgsTested() == 1);
@@ -1205,6 +1211,7 @@ void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
12051211
LocationSummary* locs,
12061212
const ICData& ic_data,
12071213
Code::EntryKind entry_kind) {
1214+
ASSERT(CanCallDart());
12081215
const Code& stub =
12091216
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
12101217
__ LoadObject(R9, ic_data);
@@ -1221,6 +1228,7 @@ void FlowGraphCompiler::EmitOptimizedStaticCall(
12211228
TokenPosition token_pos,
12221229
LocationSummary* locs,
12231230
Code::EntryKind entry_kind) {
1231+
ASSERT(CanCallDart());
12241232
ASSERT(!function.IsClosureFunction());
12251233
if (function.HasOptionalParameters() || function.IsGeneric()) {
12261234
__ LoadObject(R4, arguments_descriptor);
@@ -1240,6 +1248,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
12401248
Register cid_reg,
12411249
int32_t selector_offset,
12421250
const Array& arguments_descriptor) {
1251+
ASSERT(CanCallDart());
12431252
ASSERT(cid_reg != ARGS_DESC_REG);
12441253
if (!arguments_descriptor.IsNull()) {
12451254
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);

runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
971971
RawPcDescriptors::Kind kind,
972972
LocationSummary* locs,
973973
Code::EntryKind entry_kind) {
974+
ASSERT(CanCallDart());
974975
__ BranchLinkPatchable(stub, entry_kind);
975976
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
976977
}
@@ -981,6 +982,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
981982
LocationSummary* locs,
982983
const Function& target,
983984
Code::EntryKind entry_kind) {
985+
ASSERT(CanCallDart());
984986
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
985987
__ GenerateUnRelocatedPcRelativeCall();
986988
AddPcRelativeCallTarget(target, entry_kind);
@@ -1028,6 +1030,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(const Code& stub,
10281030
TokenPosition token_pos,
10291031
LocationSummary* locs,
10301032
Code::EntryKind entry_kind) {
1033+
ASSERT(CanCallDart());
10311034
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
10321035
// Each ICData propagated from unoptimized to optimized code contains the
10331036
// function that corresponds to the Dart function of that IC call. Due
@@ -1050,6 +1053,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10501053
TokenPosition token_pos,
10511054
LocationSummary* locs,
10521055
Code::EntryKind entry_kind) {
1056+
ASSERT(CanCallDart());
10531057
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10541058
entry_kind == Code::EntryKind::kUnchecked);
10551059
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1081,6 +1085,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
10811085
LocationSummary* locs,
10821086
intptr_t try_index,
10831087
intptr_t slow_path_argument_count) {
1088+
ASSERT(CanCallDart());
10841089
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
10851090
const ArgumentsDescriptor args_desc(arguments_descriptor);
10861091
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1125,6 +1130,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11251130
LocationSummary* locs,
11261131
Code::EntryKind entry_kind,
11271132
bool receiver_can_be_smi) {
1133+
ASSERT(CanCallDart());
11281134
ASSERT(ic_data.NumArgsTested() == 1);
11291135
const Code& initial_stub = StubCode::UnlinkedCall();
11301136
const char* switchable_call_mode = "smiable";
@@ -1175,6 +1181,7 @@ void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
11751181
LocationSummary* locs,
11761182
const ICData& ic_data,
11771183
Code::EntryKind entry_kind) {
1184+
ASSERT(CanCallDart());
11781185
const Code& stub =
11791186
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
11801187
__ LoadObject(R5, ic_data);
@@ -1191,6 +1198,7 @@ void FlowGraphCompiler::EmitOptimizedStaticCall(
11911198
TokenPosition token_pos,
11921199
LocationSummary* locs,
11931200
Code::EntryKind entry_kind) {
1201+
ASSERT(CanCallDart());
11941202
ASSERT(!function.IsClosureFunction());
11951203
if (function.HasOptionalParameters() || function.IsGeneric()) {
11961204
__ LoadObject(R4, arguments_descriptor);
@@ -1210,6 +1218,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
12101218
Register cid_reg,
12111219
int32_t selector_offset,
12121220
const Array& arguments_descriptor) {
1221+
ASSERT(CanCallDart());
12131222
ASSERT(cid_reg != ARGS_DESC_REG);
12141223
if (!arguments_descriptor.IsNull()) {
12151224
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);

runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
866866
RawPcDescriptors::Kind kind,
867867
LocationSummary* locs,
868868
Code::EntryKind entry_kind) {
869+
ASSERT(CanCallDart());
869870
__ Call(stub, /*moveable_target=*/false, entry_kind);
870871
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
871872
}
@@ -876,6 +877,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
876877
LocationSummary* locs,
877878
const Function& target,
878879
Code::EntryKind entry_kind) {
880+
ASSERT(CanCallDart());
879881
const auto& stub = StubCode::CallStaticFunction();
880882
__ Call(stub, /*movable_target=*/true, entry_kind);
881883
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
@@ -897,6 +899,7 @@ void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
897899
LocationSummary* locs,
898900
const ICData& ic_data,
899901
Code::EntryKind entry_kind) {
902+
ASSERT(CanCallDart());
900903
const Code& stub =
901904
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
902905
__ LoadObject(ECX, ic_data);
@@ -924,6 +927,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(const Code& stub,
924927
TokenPosition token_pos,
925928
LocationSummary* locs,
926929
Code::EntryKind entry_kind) {
930+
ASSERT(CanCallDart());
927931
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
928932
// Each ICData propagated from unoptimized to optimized code contains the
929933
// function that corresponds to the Dart function of that IC call. Due
@@ -947,6 +951,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
947951
TokenPosition token_pos,
948952
LocationSummary* locs,
949953
Code::EntryKind entry_kind) {
954+
ASSERT(CanCallDart());
950955
ASSERT(entry_kind == Code::EntryKind::kNormal ||
951956
entry_kind == Code::EntryKind::kUnchecked);
952957
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
@@ -972,6 +977,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
972977
LocationSummary* locs,
973978
intptr_t try_index,
974979
intptr_t slow_path_argument_count) {
980+
ASSERT(CanCallDart());
975981
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
976982
const ArgumentsDescriptor args_desc(arguments_descriptor);
977983
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1019,6 +1025,7 @@ void FlowGraphCompiler::EmitOptimizedStaticCall(
10191025
TokenPosition token_pos,
10201026
LocationSummary* locs,
10211027
Code::EntryKind entry_kind) {
1028+
ASSERT(CanCallDart());
10221029
if (function.HasOptionalParameters() || function.IsGeneric()) {
10231030
__ LoadObject(EDX, arguments_descriptor);
10241031
} else {

runtime/vm/compiler/backend/flow_graph_compiler_x64.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
985985
RawPcDescriptors::Kind kind,
986986
LocationSummary* locs,
987987
Code::EntryKind entry_kind) {
988+
ASSERT(CanCallDart());
988989
__ CallPatchable(stub, entry_kind);
989990
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
990991
}
@@ -995,6 +996,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
995996
LocationSummary* locs,
996997
const Function& target,
997998
Code::EntryKind entry_kind) {
999+
ASSERT(CanCallDart());
9981000
ASSERT(is_optimizing());
9991001
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
10001002
__ GenerateUnRelocatedPcRelativeCall();
@@ -1027,6 +1029,7 @@ void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
10271029
LocationSummary* locs,
10281030
const ICData& ic_data,
10291031
Code::EntryKind entry_kind) {
1032+
ASSERT(CanCallDart());
10301033
const Code& stub =
10311034
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
10321035
__ LoadObject(RBX, ic_data);
@@ -1055,6 +1058,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(const Code& stub,
10551058
TokenPosition token_pos,
10561059
LocationSummary* locs,
10571060
Code::EntryKind entry_kind) {
1061+
ASSERT(CanCallDart());
10581062
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
10591063
// Each ICData propagated from unoptimized to optimized code contains the
10601064
// function that corresponds to the Dart function of that IC call. Due
@@ -1078,6 +1082,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10781082
TokenPosition token_pos,
10791083
LocationSummary* locs,
10801084
Code::EntryKind entry_kind) {
1085+
ASSERT(CanCallDart());
10811086
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10821087
entry_kind == Code::EntryKind::kUnchecked);
10831088
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1103,6 +1108,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
11031108
LocationSummary* locs,
11041109
intptr_t try_index,
11051110
intptr_t slow_path_argument_count) {
1111+
ASSERT(CanCallDart());
11061112
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
11071113
const ArgumentsDescriptor args_desc(arguments_descriptor);
11081114
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1144,6 +1150,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11441150
LocationSummary* locs,
11451151
Code::EntryKind entry_kind,
11461152
bool receiver_can_be_smi) {
1153+
ASSERT(CanCallDart());
11471154
ASSERT(entry_kind == Code::EntryKind::kNormal ||
11481155
entry_kind == Code::EntryKind::kUnchecked);
11491156
ASSERT(ic_data.NumArgsTested() == 1);
@@ -1186,6 +1193,7 @@ void FlowGraphCompiler::EmitOptimizedStaticCall(
11861193
TokenPosition token_pos,
11871194
LocationSummary* locs,
11881195
Code::EntryKind entry_kind) {
1196+
ASSERT(CanCallDart());
11891197
ASSERT(!function.IsClosureFunction());
11901198
if (function.HasOptionalParameters() || function.IsGeneric()) {
11911199
__ LoadObject(R10, arguments_descriptor);
@@ -1205,6 +1213,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
12051213
Register cid_reg,
12061214
int32_t selector_offset,
12071215
const Array& arguments_descriptor) {
1216+
ASSERT(CanCallDart());
12081217
const Register table_reg = RAX;
12091218
ASSERT(cid_reg != table_reg);
12101219
ASSERT(cid_reg != ARGS_DESC_REG);

0 commit comments

Comments
 (0)