mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:19:48 +00:00
Don't lower to HIndexAssign when the value should be checked
'--checked' and '--strong' accidentally lowered []= to HIndexAssign, in effect removing the check on the parametric covariant argument. This makes --checked slower for some array-update-intensive benchmarks. Change-Id: I8c36e1db15ac6a98e1ec9ca01b2ebdd3effafc1b Reviewed-on: https://dart-review.googlesource.com/51802 Commit-Queue: Stephen Adams <sra@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
3b057dea98
commit
2f9f8088b5
|
@ -1122,6 +1122,12 @@ class CommonElements {
|
|||
_env.lookupLibrary(Uris.dart__native_typed_data, required: true),
|
||||
'NativeTypedArrayOfInt');
|
||||
|
||||
ClassEntity _typedArrayOfDoubleClass;
|
||||
ClassEntity get typedArrayOfDoubleClass =>
|
||||
_typedArrayOfDoubleClass ??= _findClass(
|
||||
_env.lookupLibrary(Uris.dart__native_typed_data, required: true),
|
||||
'NativeTypedArrayOfDouble');
|
||||
|
||||
// From dart:_js_embedded_names
|
||||
|
||||
/// Holds the class for the [JsGetName] enum.
|
||||
|
|
|
@ -122,16 +122,52 @@ class IndexAssignSpecializer extends InvokeDynamicSpecializer {
|
|||
CompilerOptions options,
|
||||
CommonElements commonElements,
|
||||
ClosedWorld closedWorld) {
|
||||
if (instruction.inputs[1].isMutableIndexable(closedWorld)) {
|
||||
if (!instruction.inputs[2].isInteger(closedWorld) &&
|
||||
options.enableTypeAssertions) {
|
||||
// We want the right checked mode error.
|
||||
HInstruction receiver = instruction.inputs[1];
|
||||
HInstruction index = instruction.inputs[2];
|
||||
if (!receiver.isMutableIndexable(closedWorld)) return null;
|
||||
if (!index.isInteger(closedWorld) && options.enableTypeAssertions) {
|
||||
// We want the right checked mode error.
|
||||
return null;
|
||||
}
|
||||
|
||||
HInstruction value = instruction.inputs[3];
|
||||
if (options.parameterCheckPolicy.isEmitted) {
|
||||
if (!_valueParameterCheckAlwaysSucceeds(
|
||||
instruction, receiver, value, commonElements, closedWorld)) {
|
||||
return null;
|
||||
}
|
||||
return new HIndexAssign(instruction.inputs[1], instruction.inputs[2],
|
||||
instruction.inputs[3], instruction.selector);
|
||||
}
|
||||
return null;
|
||||
return new HIndexAssign(receiver, index, value, instruction.selector);
|
||||
}
|
||||
|
||||
/// Returns [true] if [value] meets the requirements for being stored into
|
||||
/// indexable [receiver].
|
||||
bool _valueParameterCheckAlwaysSucceeds(
|
||||
HInvokeDynamic instruction,
|
||||
HInstruction receiver,
|
||||
HInstruction value,
|
||||
CommonElements commonElements,
|
||||
ClosedWorld closedWorld) {
|
||||
// Handle typed arrays by recognizing the exact implementation of `[]=` and
|
||||
// checking if [value] has the appropriate type.
|
||||
if (instruction.element != null) {
|
||||
ClassEntity cls = instruction.element.enclosingClass;
|
||||
if (cls == commonElements.typedArrayOfIntClass) {
|
||||
return value.isInteger(closedWorld);
|
||||
} else if (cls == commonElements.typedArrayOfDoubleClass) {
|
||||
return value.isNumber(closedWorld);
|
||||
}
|
||||
}
|
||||
|
||||
// The type check will pass if it passed before. We know it passed before if
|
||||
// the value was loaded from the same indexable.
|
||||
if (value is HIndex) {
|
||||
if (value.receiver.nonCheck() == receiver.nonCheck()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue