Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/bailout.dart

Issue 16944004: Change how we deal with manual inlining of argument error and NSM when propagating types. This chan… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/bailout.dart (revision 24017)
+++ sdk/lib/_internal/compiler/implementation/ssa/bailout.dart (working copy)
@@ -214,44 +214,6 @@
return calledInLoop;
}
- // Returns whether an invocation of [selector] on [receiver] will throw a
- // [ArgumentError] if the argument is not of the right type.
- bool willThrowArgumentError(Selector selector,
- HInstruction receiver,
- HType speculativeType) {
- if (receiver != null
- && (receiver.isInteger() || receiver.isString(compiler))) {
- return selector.isOperator()
- && selector.name != const SourceString('==')
- && (speculativeType.isNumber() && !speculativeType.isInteger());
- }
- return false;
- }
-
- // Returns whether an invocation of [selector] will throw a
- // [NoSuchMethodError] if the receiver is not of the type
- // [speculativeType].
- bool willThrowNoSuchMethodErrorIfNot(Selector selector,
- HType speculativeType) {
- return compiler.world.hasSingleMatch(selector)
- // In some cases, we want the receiver to be an integer,
- // but that does not mean we will get a NoSuchMethodError
- // if it's not: the receiver could be a double.
- && !speculativeType.isInteger()
- // We speculate on the [operator==] instruction, but we know it
- // will never throw a [NoSuchMethodError].
- && selector.name != const SourceString('==');
- }
-
- bool shouldInsertTypeGuard(HInstruction instruction, HType speculativeType) {
- if (!speculativeType.isUseful()) return false;
- // If the types agree we don't need to check.
- if (speculativeType == instruction.instructionType) return false;
- // If a bailout check is more expensive than doing the actual operation
- // don't do it either.
- return typeGuardWouldBeValuable(instruction, speculativeType);
- }
-
HInstruction computeFirstDominatingUserWithSelector(
HInstruction instruction) {
// TODO(ngeoffray): We currently only look at the instruction's
@@ -283,49 +245,43 @@
bool tryTypeConversion(HInstruction instruction, HType speculativeType) {
HInstruction firstUser =
computeFirstDominatingUserWithSelector(instruction);
- if (firstUser == null) return false;
+ if (firstUser is !HInvokeDynamic) return false;
// If we have found a user with a selector, we find out if it
- // will throw [NoSuchMethodError] or [ArgumentError].
+ // will throw [NoSuchMethodError] or [ArgumentError]. If it does,
+ // then we change just add a [HTypeConversion] instruction and
+ // avoid a bailout.
Selector selector = firstUser.selector;
- Selector receiverSelectorOnThrow = null;
+ if (!selector.isOperator()) return false;
HInstruction receiver = firstUser.getDartReceiver(compiler);
- bool willThrow = false;
- if (receiver == instruction) {
- if (willThrowNoSuchMethodErrorIfNot(selector, speculativeType)) {
- receiverSelectorOnThrow = selector;
- willThrow = true;
- }
- // We need to call the actual method in checked mode to get
- // the right type error.
- } else if (!compiler.enableTypeAssertions
- && willThrowArgumentError(selector, receiver, speculativeType)) {
- willThrow = true;
- }
- if (!willThrow) return false;
-
- HTypeConversion check = new HTypeConversion(
- null,
- receiverSelectorOnThrow == null
- ? HTypeConversion.ARGUMENT_TYPE_CHECK
- : HTypeConversion.RECEIVER_TYPE_CHECK,
- speculativeType,
- instruction,
- receiverSelectorOnThrow);
- hasInsertedChecks = true;
- firstUser.block.addBefore(firstUser, check);
- instruction.replaceAllUsersDominatedBy(firstUser, check);
- return true;
+ if (instruction == receiver) {
+ // If the instruction on which we're speculating the
+ // type is the receiver of the call, check if it will throw
+ // [NoSuchMethodError] if [instruction] is not of the speculated
+ // type.
+ return checkReceiver(firstUser);
+ } else if (!selector.isUnaryOperator()
+ && instruction == firstUser.inputs[2]) {
+ // If the instruction is a parameter of the call, we check if
+ // the method will throw an [ArgumentError] if [instruction] is
+ // not of the speculated type.
+ return checkArgument(firstUser);
+ }
+ return false;
}
bool updateType(HInstruction instruction) {
bool hasChanged = super.updateType(instruction);
HType speculativeType = savedTypes[instruction];
- if (speculativeType == null) return hasChanged;
+ if (speculativeType == null
+ || !speculativeType.isUseful()
+ || speculativeType == instruction.instructionType) {
+ return hasChanged;
+ }
- if (shouldInsertTypeGuard(instruction, speculativeType)
- && !tryTypeConversion(instruction, speculativeType)) {
+ if (!tryTypeConversion(instruction, speculativeType)
+ && typeGuardWouldBeValuable(instruction, speculativeType)) {
HInstruction insertionPoint;
if (instruction is HPhi) {
insertionPoint = instruction.block.first;
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698