Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| index 064a52e1e9d17b601b616bc2e70046c6282e69eb..e1c7f458b225ed89a855cbc686e04c52d5b9ed11 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| @@ -19,6 +19,7 @@ class InterceptedElement extends ElementX { |
| DartType computeType(Compiler compiler) => ssaType.computeType(compiler); |
| } |
| + |
|
kasperl
2013/01/29 15:02:34
wat
karlklose
2013/01/30 12:01:19
Exactly. Removed.
|
| class SsaBuilderTask extends CompilerTask { |
| final CodeEmitterTask emitter; |
| // Loop tracking information. |
| @@ -2549,6 +2550,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| HInstruction runtimeType = getTypeArgument(variable); |
| add(runtimeType); |
| inputs.add(runtimeType); |
| + return '#'; |
|
kasperl
2013/01/29 15:02:34
wat? This isn't a List<HInstruction>.
karlklose
2013/01/30 12:01:19
This return belongs to the closure given to getTyp
|
| }); |
| HInstruction representation = createForeignArray(template, inputs); |
| add(representation); |
| @@ -2602,34 +2604,25 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| if (type.element.isTypeVariable() || |
| RuntimeTypeInformation.hasTypeArguments(type)) { |
| HInstruction typeInfo = getRuntimeTypeInfo(expression); |
| - // TODO(karlklose): make isSubtype a HInstruction to enable |
| - // optimizations? |
| - Element helper = compiler.findHelper(const SourceString('isSubtype')); |
| - HInstruction isSubtype = new HStatic(helper); |
| - add(isSubtype); |
| - // Build a list of representations for the type arguments. |
| + Element helper = |
| + compiler.findHelper(const SourceString('checkArguments')); |
| + HInstruction helperCall = new HStatic(helper); |
| + add(helperCall); |
| List<HInstruction> representations = |
| buildTypeArgumentRepresentations(type); |
| - // For each type argument, build a call to isSubtype, with the type |
| - // argument as first and the representation of the tested type as |
| - // second argument. |
| - List<HInstruction> checks = <HInstruction>[]; |
| - int index = 0; |
| - representations.forEach((HInstruction representation) { |
| - HInstruction position = graph.addConstantInt(index, constantSystem); |
| - // Get the index'th type argument from the runtime type information. |
| - HInstruction typeArgument = |
| - createForeign('#[#]', 'Object', [typeInfo, position]); |
| - add(typeArgument); |
| - // Create the call to isSubtype. |
| - List<HInstruction> inputs = |
| - <HInstruction>[isSubtype, typeArgument, representation]; |
| - HInstruction call = new HInvokeStatic(inputs); |
| - add(call); |
| - checks.add(call); |
| - index++; |
| - }); |
| - instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); |
| + String substitution = backend.namer.substitutionName(type.element); |
| + HInstruction fieldGet = |
| + createForeign('#.$substitution', 'Object', [expression]); |
|
kasperl
2013/01/29 15:02:34
Should the namer know about $substitution?
karlklose
2013/01/30 12:01:19
It does, this is interpolating the name that we go
|
| + HInstruction representationList = new HLiteralList(representations); |
| + add(fieldGet); |
| + add(representationList); |
| + List<HInstruction> inputs = <HInstruction>[helperCall, |
| + fieldGet, |
| + typeInfo, |
| + representationList]; |
| + HInstruction check = new HInvokeStatic(inputs); |
| + add(check); |
| + instruction = new HIs(type, <HInstruction>[expression, check]); |
| } else { |
| instruction = new HIs(type, <HInstruction>[expression]); |
| } |
| @@ -3005,6 +2998,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| handleForeignCreateIsolate(node); |
| } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { |
| stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); |
| + } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { |
| + stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); |
| } else { |
| throw "Unknown foreign: ${selector}"; |
| } |
| @@ -3123,14 +3118,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| return graph.addConstantNull(constantSystem); |
| } |
| - // These variables are shared between invocations of the helper. |
| - HInstruction typeInfo; |
| + // The inputs are shared between invocations of the helper. |
| List<HInstruction> inputs = <HInstruction>[]; |
| /** |
| * Helper to create an instruction that gets the value of a type variable. |
| */ |
| - void addTypeVariableReference(TypeVariableType type) { |
| + String addTypeVariableReference(TypeVariableType type) { |
| Element member = work.element; |
| if (member.enclosingElement.isClosure()) { |
| ClosureClassElement closureClass = member.enclosingElement; |
| @@ -3138,27 +3132,23 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| member = member.getOutermostEnclosingMemberOrTopLevel(); |
| } |
| if (member.isFactoryConstructor()) { |
| - // The type variable is stored in a parameter of the factory. |
| + // The type variable is stored in a parameter of the method. |
| inputs.add(localsHandler.readLocal(type.element)); |
| - } else if (member.isInstanceMember() |
| - || member.isGenerativeConstructor()) { |
| + } else if (member.isInstanceMember() || |
| + member.isGenerativeConstructor()) { |
| // The type variable is stored in [this]. |
| - if (typeInfo == null) { |
| - pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), |
| - localsHandler.readThis()); |
| - typeInfo = pop(); |
| - } |
| int index = RuntimeTypeInformation.getTypeVariableIndex(type); |
| - HInstruction foreign = createForeign('#[$index]', 'String', |
| - <HInstruction>[typeInfo]); |
| - add(foreign); |
| - inputs.add(foreign); |
| + pushInvokeHelper2(backend.getGetRuntimeTypeArgument(), |
| + localsHandler.readThis(), |
| + graph.addConstantInt(index, constantSystem)); |
| + inputs.add(pop()); |
| } else { |
| // TODO(ngeoffray): Match the VM behavior and throw an |
| // exception at runtime. |
| compiler.cancel('Unimplemented unresolved type variable', |
| node: currentNode); |
| } |
| + return '#'; |
| } |
| String template = rti.getTypeRepresentation(argument, |
| @@ -3172,13 +3162,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| Node currentNode, |
| HInstruction newObject) { |
| if (!compiler.world.needsRti(type.element)) return; |
| - List<HInstruction> inputs = <HInstruction>[]; |
| if (!type.isRaw) { |
| + List<HInstruction> inputs = <HInstruction>[]; |
| type.typeArguments.forEach((DartType argument) { |
| inputs.add(analyzeTypeArgument(argument, currentNode)); |
| }); |
| + callSetRuntimeTypeInfo(type.element, inputs, newObject); |
| } |
| - callSetRuntimeTypeInfo(type.element, inputs, newObject); |
| } |
| void callSetRuntimeTypeInfo(ClassElement element, |