Skip to content

Commit 595038d

Browse files
sjindel-googlecommit-bot@chromium.org
authored andcommitted
Re-land "[vm] Aggressive write-barrier elimination."
DoubleToIntegerInstr was incorrectly marked with CanCallDart() = false. Original CL is in patchset 3. Fixes #40593 This reverts commit e7403c1. Change-Id: Ibb33fcf6480c820a10c968a2e22339afc5286035 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135310 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Samir Jindel <[email protected]>
1 parent a9485e8 commit 595038d

18 files changed

+492
-30
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
@@ -611,7 +611,9 @@ void FlowGraphCompiler::VisitBlocks() {
611611
EmitInstructionPrologue(instr);
612612
ASSERT(pending_deoptimization_env_ == NULL);
613613
pending_deoptimization_env_ = instr->env();
614+
DEBUG_ONLY(current_instruction_ = instr);
614615
instr->EmitNativeCode(this);
616+
DEBUG_ONLY(current_instruction_ = nullptr);
615617
pending_deoptimization_env_ = NULL;
616618
if (IsPeephole(instr)) {
617619
ASSERT(top_of_stack_ == nullptr);
@@ -698,7 +700,9 @@ void FlowGraphCompiler::GenerateDeferredCode() {
698700
slow_path->instruction()->tag());
699701
SpecialStatsBegin(stats_tag);
700702
BeginCodeSourceRange();
703+
DEBUG_ONLY(current_instruction_ = slow_path->instruction());
701704
slow_path->GenerateCode(this);
705+
DEBUG_ONLY(current_instruction_ = nullptr);
702706
EndCodeSourceRange(slow_path->instruction()->token_pos());
703707
SpecialStatsEnd(stats_tag);
704708
}

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+
#ifdef 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:
@@ -1209,6 +1218,10 @@ class FlowGraphCompiler : public ValueObject {
12091218
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
12101219
Array& edge_counters_array_;
12111220

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

runtime/vm/compiler/backend/flow_graph_compiler_arm.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
997997
RawPcDescriptors::Kind kind,
998998
LocationSummary* locs,
999999
Code::EntryKind entry_kind) {
1000+
ASSERT(CanCallDart());
10001001
__ BranchLinkPatchable(stub, entry_kind);
10011002
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
10021003
}
@@ -1007,6 +1008,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
10071008
LocationSummary* locs,
10081009
const Function& target,
10091010
Code::EntryKind entry_kind) {
1011+
ASSERT(CanCallDart());
10101012
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
10111013
__ GenerateUnRelocatedPcRelativeCall();
10121014
AddPcRelativeCallTarget(target, entry_kind);
@@ -1086,6 +1088,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10861088
TokenPosition token_pos,
10871089
LocationSummary* locs,
10881090
Code::EntryKind entry_kind) {
1091+
ASSERT(CanCallDart());
10891092
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10901093
entry_kind == Code::EntryKind::kUnchecked);
10911094
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1111,6 +1114,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
11111114
LocationSummary* locs,
11121115
intptr_t try_index,
11131116
intptr_t slow_path_argument_count) {
1117+
ASSERT(CanCallDart());
11141118
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
11151119
const ArgumentsDescriptor args_desc(arguments_descriptor);
11161120
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1158,6 +1162,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11581162
LocationSummary* locs,
11591163
Code::EntryKind entry_kind,
11601164
bool receiver_can_be_smi) {
1165+
ASSERT(CanCallDart());
11611166
ASSERT(entry_kind == Code::EntryKind::kNormal ||
11621167
entry_kind == Code::EntryKind::kUnchecked);
11631168
ASSERT(ic_data.NumArgsTested() == 1);

runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
968968
RawPcDescriptors::Kind kind,
969969
LocationSummary* locs,
970970
Code::EntryKind entry_kind) {
971+
ASSERT(CanCallDart());
971972
__ BranchLinkPatchable(stub, entry_kind);
972973
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
973974
}
@@ -978,6 +979,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
978979
LocationSummary* locs,
979980
const Function& target,
980981
Code::EntryKind entry_kind) {
982+
ASSERT(CanCallDart());
981983
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
982984
__ GenerateUnRelocatedPcRelativeCall();
983985
AddPcRelativeCallTarget(target, entry_kind);
@@ -1047,6 +1049,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10471049
TokenPosition token_pos,
10481050
LocationSummary* locs,
10491051
Code::EntryKind entry_kind) {
1052+
ASSERT(CanCallDart());
10501053
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10511054
entry_kind == Code::EntryKind::kUnchecked);
10521055
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1078,6 +1081,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
10781081
LocationSummary* locs,
10791082
intptr_t try_index,
10801083
intptr_t slow_path_argument_count) {
1084+
ASSERT(CanCallDart());
10811085
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
10821086
const ArgumentsDescriptor args_desc(arguments_descriptor);
10831087
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1122,6 +1126,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11221126
LocationSummary* locs,
11231127
Code::EntryKind entry_kind,
11241128
bool receiver_can_be_smi) {
1129+
ASSERT(CanCallDart());
11251130
ASSERT(ic_data.NumArgsTested() == 1);
11261131
const Code& initial_stub = StubCode::UnlinkedCall();
11271132
const char* switchable_call_mode = "smiable";

runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
863863
RawPcDescriptors::Kind kind,
864864
LocationSummary* locs,
865865
Code::EntryKind entry_kind) {
866+
ASSERT(CanCallDart());
866867
__ Call(stub, /*moveable_target=*/false, entry_kind);
867868
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
868869
}
@@ -873,6 +874,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
873874
LocationSummary* locs,
874875
const Function& target,
875876
Code::EntryKind entry_kind) {
877+
ASSERT(CanCallDart());
876878
const auto& stub = StubCode::CallStaticFunction();
877879
__ Call(stub, /*movable_target=*/true, entry_kind);
878880
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
@@ -944,6 +946,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
944946
TokenPosition token_pos,
945947
LocationSummary* locs,
946948
Code::EntryKind entry_kind) {
949+
ASSERT(CanCallDart());
947950
ASSERT(entry_kind == Code::EntryKind::kNormal ||
948951
entry_kind == Code::EntryKind::kUnchecked);
949952
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
@@ -969,6 +972,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
969972
LocationSummary* locs,
970973
intptr_t try_index,
971974
intptr_t slow_path_argument_count) {
975+
ASSERT(CanCallDart());
972976
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
973977
const ArgumentsDescriptor args_desc(arguments_descriptor);
974978
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(

runtime/vm/compiler/backend/flow_graph_compiler_x64.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,7 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
982982
RawPcDescriptors::Kind kind,
983983
LocationSummary* locs,
984984
Code::EntryKind entry_kind) {
985+
ASSERT(CanCallDart());
985986
__ CallPatchable(stub, entry_kind);
986987
EmitCallsiteMetadata(token_pos, deopt_id, kind, locs);
987988
}
@@ -992,6 +993,7 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
992993
LocationSummary* locs,
993994
const Function& target,
994995
Code::EntryKind entry_kind) {
996+
ASSERT(CanCallDart());
995997
ASSERT(is_optimizing());
996998
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
997999
__ GenerateUnRelocatedPcRelativeCall();
@@ -1075,6 +1077,7 @@ void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
10751077
TokenPosition token_pos,
10761078
LocationSummary* locs,
10771079
Code::EntryKind entry_kind) {
1080+
ASSERT(CanCallDart());
10781081
ASSERT(entry_kind == Code::EntryKind::kNormal ||
10791082
entry_kind == Code::EntryKind::kUnchecked);
10801083
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
@@ -1100,6 +1103,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
11001103
LocationSummary* locs,
11011104
intptr_t try_index,
11021105
intptr_t slow_path_argument_count) {
1106+
ASSERT(CanCallDart());
11031107
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
11041108
const ArgumentsDescriptor args_desc(arguments_descriptor);
11051109
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
@@ -1141,6 +1145,7 @@ void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
11411145
LocationSummary* locs,
11421146
Code::EntryKind entry_kind,
11431147
bool receiver_can_be_smi) {
1148+
ASSERT(CanCallDart());
11441149
ASSERT(entry_kind == Code::EntryKind::kNormal ||
11451150
entry_kind == Code::EntryKind::kUnchecked);
11461151
ASSERT(ic_data.NumArgsTested() == 1);

runtime/vm/compiler/backend/il.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,15 @@ class Instruction : public ZoneAllocated {
10311031
// See StoreInstanceFieldInstr::HasUnknownSideEffects() for rationale.
10321032
virtual bool HasUnknownSideEffects() const = 0;
10331033

1034+
// Whether this instruction can call Dart code without going through
1035+
// the runtime.
1036+
//
1037+
// Must be true for any instruction which can call Dart code without
1038+
// first creating an exit frame to transition into the runtime.
1039+
//
1040+
// See also WriteBarrierElimination and Thread::RememberLiveTemporaries().
1041+
virtual bool CanCallDart() const { return false; }
1042+
10341043
virtual bool CanTriggerGC() const;
10351044

10361045
// Get the block entry for this instruction.
@@ -3143,6 +3152,8 @@ class BranchInstr : public Instruction {
31433152
return comparison()->HasUnknownSideEffects();
31443153
}
31453154

3155+
virtual bool CanCallDart() const { return comparison()->CanCallDart(); }
3156+
31463157
ComparisonInstr* comparison() const { return comparison_; }
31473158
void SetComparison(ComparisonInstr* comp);
31483159

@@ -3709,6 +3720,7 @@ class ClosureCallInstr : public TemplateDartCall<1> {
37093720
virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
37103721

37113722
virtual bool HasUnknownSideEffects() const { return true; }
3723+
virtual bool CanCallDart() const { return true; }
37123724

37133725
Code::EntryKind entry_kind() const { return entry_kind_; }
37143726

@@ -3784,6 +3796,7 @@ class InstanceCallBaseInstr : public TemplateDartCall<0> {
37843796
}
37853797

37863798
virtual bool HasUnknownSideEffects() const { return true; }
3799+
virtual bool CanCallDart() const { return true; }
37873800

37883801
void SetResultType(Zone* zone, CompileType new_type) {
37893802
result_type_ = new (zone) CompileType(new_type);
@@ -4335,6 +4348,7 @@ class IfThenElseInstr : public Definition {
43354348
virtual bool HasUnknownSideEffects() const {
43364349
return comparison()->HasUnknownSideEffects();
43374350
}
4351+
virtual bool CanCallDart() const { return comparison()->CanCallDart(); }
43384352

43394353
virtual bool AttributesEqual(Instruction* other) const {
43404354
IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
@@ -4463,6 +4477,7 @@ class StaticCallInstr : public TemplateDartCall<0> {
44634477
}
44644478

44654479
virtual bool HasUnknownSideEffects() const { return true; }
4480+
virtual bool CanCallDart() const { return true; }
44664481

44674482
// Initialize result type of this call instruction if target is a recognized
44684483
// method or has pragma annotation.
@@ -4721,6 +4736,9 @@ class NativeCallInstr : public TemplateDartCall<0> {
47214736

47224737
virtual bool HasUnknownSideEffects() const { return true; }
47234738

4739+
// Always creates an exit frame before more Dart code can be called.
4740+
virtual bool CanCallDart() const { return false; }
4741+
47244742
void SetupNative();
47254743

47264744
PRINT_OPERANDS_TO_SUPPORT
@@ -4780,6 +4798,9 @@ class FfiCallInstr : public Definition {
47804798

47814799
virtual bool HasUnknownSideEffects() const { return true; }
47824800

4801+
// Always creates an exit frame before more Dart code can be called.
4802+
virtual bool CanCallDart() const { return false; }
4803+
47834804
virtual Representation RequiredInputRepresentation(intptr_t idx) const;
47844805
virtual Representation representation() const;
47854806

@@ -5329,6 +5350,7 @@ class StringInterpolateInstr : public TemplateDefinition<1, Throws> {
53295350
virtual CompileType ComputeType() const;
53305351
// Issues a static call to Dart code which calls toString on objects.
53315352
virtual bool HasUnknownSideEffects() const { return true; }
5353+
virtual bool CanCallDart() const { return true; }
53325354
virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
53335355

53345356
const Function& CallFunction() const;
@@ -7006,6 +7028,7 @@ class CheckedSmiOpInstr : public TemplateDefinition<2, Throws> {
70067028
virtual bool RecomputeType();
70077029

70087030
virtual bool HasUnknownSideEffects() const { return true; }
7031+
virtual bool CanCallDart() const { return true; }
70097032

70107033
virtual Definition* Canonicalize(FlowGraph* flow_graph);
70117034

@@ -7050,6 +7073,7 @@ class CheckedSmiComparisonInstr : public TemplateComparison<2, Throws> {
70507073
bool is_negated() const { return is_negated_; }
70517074

70527075
virtual bool HasUnknownSideEffects() const { return true; }
7076+
virtual bool CanCallDart() const { return true; }
70537077

70547078
PRINT_OPERANDS_TO_SUPPORT
70557079

@@ -7685,6 +7709,8 @@ class DoubleToIntegerInstr : public TemplateDefinition<1, Throws> {
76857709

76867710
virtual bool HasUnknownSideEffects() const { return false; }
76877711

7712+
virtual bool CanCallDart() const { return true; }
7713+
76887714
private:
76897715
InstanceCallInstr* instance_call_;
76907716

runtime/vm/compiler/compiler_pass.cc

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "vm/compiler/backend/redundancy_elimination.h"
2020
#include "vm/compiler/backend/type_propagator.h"
2121
#include "vm/compiler/call_specializer.h"
22+
#include "vm/compiler/write_barrier_elimination.h"
2223
#if defined(DART_PRECOMPILER)
2324
#include "vm/compiler/aot/aot_call_specializer.h"
2425
#include "vm/compiler/aot/precompiler.h"
@@ -529,36 +530,6 @@ COMPILER_PASS(ReorderBlocks, {
529530
}
530531
});
531532

532-
static void WriteBarrierElimination(FlowGraph* flow_graph) {
533-
for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
534-
!block_it.Done(); block_it.Advance()) {
535-
BlockEntryInstr* block = block_it.Current();
536-
Definition* last_allocated = nullptr;
537-
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
538-
Instruction* current = it.Current();
539-
if (!current->CanTriggerGC()) {
540-
if (StoreInstanceFieldInstr* instr = current->AsStoreInstanceField()) {
541-
if (instr->instance()->definition() == last_allocated) {
542-
instr->set_emit_store_barrier(kNoStoreBarrier);
543-
}
544-
continue;
545-
}
546-
}
547-
548-
if (AllocationInstr* alloc = current->AsAllocation()) {
549-
if (alloc->WillAllocateNewOrRemembered()) {
550-
last_allocated = alloc;
551-
continue;
552-
}
553-
}
554-
555-
if (current->CanTriggerGC()) {
556-
last_allocated = nullptr;
557-
}
558-
}
559-
}
560-
}
561-
562533
COMPILER_PASS(WriteBarrierElimination,
563534
{ WriteBarrierElimination(flow_graph); });
564535

runtime/vm/compiler/compiler_sources.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ compiler_sources = [
165165
"stub_code_compiler_arm64.cc",
166166
"stub_code_compiler_ia32.cc",
167167
"stub_code_compiler_x64.cc",
168+
"write_barrier_elimination.cc",
169+
"write_barrier_elimination.h",
168170
]
169171

170172
compiler_sources_tests = [

0 commit comments

Comments
 (0)