mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:09:49 +00:00
[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:
parent
faa1c9ff98
commit
a205935d9a
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue