Index: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart |
=================================================================== |
--- sdk/lib/_internal/compiler/implementation/ssa/optimize.dart (revision 15496) |
+++ sdk/lib/_internal/compiler/implementation/ssa/optimize.dart (working copy) |
@@ -39,8 +39,8 @@ |
new SsaConstantFolder(constantSystem, backend, work, types), |
new SsaTypeConversionInserter(compiler), |
new SsaTypePropagator(compiler, types), |
+ new SsaConstantFolder(constantSystem, backend, work, types), |
ahe
2012/11/30 08:11:42
Add a comment explaining why you call the constant
|
new SsaCheckInserter(backend, work, types, context.boundsChecked), |
- new SsaConstantFolder(constantSystem, backend, work, types), |
new SsaRedundantPhiEliminator(), |
new SsaDeadPhiEliminator(), |
new SsaConstantFolder(constantSystem, backend, work, types), |
@@ -207,6 +207,7 @@ |
} |
HInstruction handleInterceptorCall(HInvokeDynamic node) { |
+ if (node is !HInvokeDynamicMethod) return; |
ahe
2012/11/30 08:11:42
I don't understand this line.
|
HInstruction input = node.inputs[1]; |
if (input.isString(types) |
&& node.selector.name == const SourceString('toString')) { |
@@ -215,9 +216,7 @@ |
// Check if this call does not need to be intercepted. |
HType type = types[input]; |
var interceptor = node.inputs[0]; |
- if (node is HInvokeDynamicMethod |
- && interceptor is !HThis |
- && !type.canBePrimitive()) { |
+ if (interceptor is !HThis && !type.canBePrimitive()) { |
// If the type can be null, and the intercepted method can be in |
// the object class, keep the interceptor. |
if (type.canBeNull() |
@@ -228,6 +227,39 @@ |
return new HInvokeDynamicMethod( |
node.selector, node.inputs.getRange(1, node.inputs.length - 1)); |
} |
+ |
+ Selector selector = node.selector; |
+ SourceString selectorName = selector.name; |
+ Element target; |
+ if (input.isExtendableArray(types)) { |
+ if (selectorName == backend.jsArrayRemoveLast.name |
+ && selector.argumentCount == 0) { |
ahe
2012/11/30 08:11:42
Why isn't this selector.applies(backend.jsArrayRem
|
+ target = backend.jsArrayRemoveLast; |
+ } else if (selectorName == backend.jsArrayAdd.name |
+ && selector.argumentCount == 1 |
+ && selector.namedArgumentCount == 0 |
+ && !compiler.enableTypeAssertions) { |
+ target = backend.jsArrayAdd; |
+ } |
+ } else if (input.isString(types)) { |
+ if (selectorName == backend.jsStringSplit.name |
+ && selector.argumentCount == 1 |
+ && selector.namedArgumentCount == 0 |
+ && node.inputs[2].isString(types)) { |
+ target = backend.jsStringSplit; |
+ } else if (selectorName == backend.jsStringConcat.name |
+ && selector.argumentCount == 1 |
+ && selector.namedArgumentCount == 0 |
+ && node.inputs[2].isString(types)) { |
+ target = backend.jsStringConcat; |
+ } |
+ } |
+ if (target != null) { |
+ HInvokeDynamicMethod result = new HInvokeDynamicMethod( |
+ node.selector, node.inputs.getRange(1, node.inputs.length - 1)); |
+ result.element = target; |
+ return result; |
+ } |
return node; |
} |
@@ -717,20 +749,16 @@ |
class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
final HTypeMap types; |
- final ConstantSystem constantSystem; |
final Set<HInstruction> boundsChecked; |
final WorkItem work; |
+ final JavaScriptBackend backend; |
final String name = "SsaCheckInserter"; |
HGraph graph; |
- Element lengthInterceptor; |
- SsaCheckInserter(JavaScriptBackend backend, |
+ SsaCheckInserter(this.backend, |
this.work, |
this.types, |
- this.boundsChecked) |
- : constantSystem = backend.constantSystem { |
- lengthInterceptor = backend.jsArrayLength; |
- } |
+ this.boundsChecked); |
void visitGraph(HGraph graph) { |
this.graph = graph; |
@@ -750,8 +778,8 @@ |
HInstruction receiver, |
HInstruction index) { |
bool isAssignable = !receiver.isFixedArray(types); |
- HFieldGet length = |
- new HFieldGet(lengthInterceptor, receiver, isAssignable: isAssignable); |
+ HFieldGet length = new HFieldGet( |
+ backend.jsArrayLength, receiver, isAssignable: isAssignable); |
length.guaranteedType = HType.INTEGER; |
types[length] = HType.INTEGER; |
node.block.addBefore(node, length); |
@@ -795,6 +823,14 @@ |
node.changeUse(node.index, index); |
assert(node.isBuiltin(types)); |
} |
+ |
+ void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
+ Element element = node.element; |
+ if (element != backend.jsArrayRemoveLast) return; |
+ if (boundsChecked.contains(node)) return; |
+ insertBoundsCheck( |
+ node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); |
+ } |
} |
class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |