[vm/compiler] Treat allocations generically in redundancy eliminator.

Instead of explicitly listing certain subclasses in some places, instead
allow any AllocationInstr subclass and just reject certain subclasses if
necessary.

Code size different in Flutter gallery (release-sizeopt):
* ARM7: Total -0.12%, instructions -0.14%, readonly -0.11%
* ARM8: Total -0.12%, instructions -0.15%, readonly -0.09%

TEST=Current test suite.

Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm64c-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-linux-debug-ia32-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-x64-try,vm-kernel-linux-debug-x64c-try
Change-Id: I4ce42d7185d4b3a83356e5131a5835fa858c4882
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/201832
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
Tess Strickland 2021-06-02 18:10:38 +00:00 committed by commit-bot@chromium.org
parent faa1c9ff98
commit a205935d9a
3 changed files with 29 additions and 22 deletions

View file

@ -456,12 +456,9 @@ class Place : public ValueObject {
static Place* Wrap(Zone* zone, const Place& place, intptr_t id);
static bool IsAllocation(Definition* defn) {
return (defn != NULL) &&
(defn->IsAllocateObject() || defn->IsAllocateClosure() ||
defn->IsCreateArray() || defn->IsAllocateTypedData() ||
defn->IsAllocateUninitializedContext() ||
(defn->IsStaticCall() &&
defn->AsStaticCall()->IsRecognizedFactory()));
return (defn != NULL) && (defn->IsAllocation() ||
(defn->IsStaticCall() &&
defn->AsStaticCall()->IsRecognizedFactory()));
}
private:
@ -1586,7 +1583,7 @@ void LICM::Optimize() {
}
void DelayAllocations::Optimize(FlowGraph* graph) {
// Go through all AllocateObject instructions and move them down to their
// Go through all Allocation instructions and move them down to their
// dominant use when doing so is sound.
DirectChainedHashMap<IdentitySetKeyValueTrait<Instruction*>> moved;
for (BlockIterator block_it = graph->reverse_postorder_iterator();
@ -1596,10 +1593,8 @@ void DelayAllocations::Optimize(FlowGraph* graph) {
for (ForwardInstructionIterator instr_it(block); !instr_it.Done();
instr_it.Advance()) {
Definition* def = instr_it.Current()->AsDefinition();
if (def != nullptr &&
(def->IsAllocateObject() || def->IsAllocateClosure() ||
def->IsCreateArray()) &&
def->env() == nullptr && !moved.HasKey(def)) {
if (def != nullptr && def->IsAllocation() && def->env() == nullptr &&
!moved.HasKey(def)) {
Instruction* use = DominantUse(def);
if (use != nullptr && !use->IsPhi() && IsOneTimeUse(use, def)) {
instr_it.RemoveCurrentFromGraph();
@ -3084,9 +3079,8 @@ static bool IsValidLengthForAllocationSinking(
// Returns true if the given instruction is an allocation that
// can be sunk by the Allocation Sinking pass.
static bool IsSupportedAllocation(Instruction* instr) {
return instr->IsAllocateObject() || instr->IsAllocateUninitializedContext() ||
instr->IsAllocateClosure() ||
(instr->IsArrayAllocation() &&
return instr->IsAllocation() &&
(!instr->IsArrayAllocation() ||
IsValidLengthForAllocationSinking(instr->AsArrayAllocation()));
}
@ -3639,6 +3633,9 @@ void AllocationSinking::CreateMaterializationAt(
} else if (auto instr = alloc->AsAllocateClosure()) {
cls = &Class::ZoneHandle(
flow_graph_->isolate_group()->object_store()->closure_class());
} else if (auto instr = alloc->AsAllocateContext()) {
cls = &Class::ZoneHandle(Object::context_class());
num_elements = instr->num_context_variables();
} else if (auto instr = alloc->AsAllocateUninitializedContext()) {
cls = &Class::ZoneHandle(Object::context_class());
num_elements = instr->num_context_variables();

View file

@ -19,26 +19,31 @@ const interestingLengths = <int>[
main() {
for (int interestingLength in interestingLengths) {
bool exceptionCheck(e) {
// Allow RangeError as the range check may happen before the allocation.
return e is RangeError || e is OutOfMemoryError;
}
print(interestingLength);
Expect.throws(() {
var bytearray = new Uint8List(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new Uint8ClampedList(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new Int8List(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new ByteData(interestingLength);
print(bytearray.getUint8(0));
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
}
}

View file

@ -21,26 +21,31 @@ const interestingLengths = <int>[
main() {
for (int interestingLength in interestingLengths) {
bool exceptionCheck(e) {
// Allow RangeError as the range check may happen before the allocation.
return e is RangeError || e is OutOfMemoryError;
}
print(interestingLength);
Expect.throws(() {
var bytearray = new Uint8List(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new Uint8ClampedList(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new Int8List(interestingLength);
print(bytearray.first);
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
Expect.throws(() {
var bytearray = new ByteData(interestingLength);
print(bytearray.getUint8(0));
}, (e) => e is OutOfMemoryError);
}, exceptionCheck);
}
}