diff options
Diffstat (limited to 'src')
9 files changed, 68 insertions, 40 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index be74fe4e78..e60ea9a341 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -633,10 +633,10 @@ abstract class GenICode extends SubComponent { ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx) ctx1.bb.emit(CREATE_ARRAY(elem), tree.pos) - case REFERENCE(cls) => + case rt @ REFERENCE(cls) => assert(ctor.owner == cls, "Symbol " + ctor.owner.fullNameString + " is different than " + tpt) - ctx1.bb.emit(NEW(generatedType), tree.pos) + ctx1.bb.emit(NEW(rt), tree.pos) ctx1.bb.emit(DUP(generatedType)) ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx) @@ -1101,6 +1101,8 @@ abstract class GenICode extends SubComponent { case DOUBLE => Literal(0.0d) case REFERENCE(cls) => Literal(null: Any) case ARRAY(elem) => Literal(null: Any) + case BOXED(_) => Literal(null: Any) + case ConcatClass => abort("no zero of ConcatClass") } def getZeroOf(k: TypeKind): Instruction = k match { @@ -1115,6 +1117,8 @@ abstract class GenICode extends SubComponent { case DOUBLE => CONSTANT(Constant(0.0d)) case REFERENCE(cls) => CONSTANT(Constant(null: Any)) case ARRAY(elem) => CONSTANT(Constant(null: Any)) + case BOXED(_) => CONSTANT(Constant(null: Any)) + case ConcatClass => abort("no zero of ConcatClass") } diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 0f8d1091a1..654da7762e 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -216,6 +216,20 @@ trait Members requires ICodes { symbol.hasFlag(Flags.STATIC) || symbol.hasFlag(Flags.STATICMEMBER) || symbol.owner.isImplClass; override def toString() = symbol.fullNameString; + + import opcodes._ + def checkLocals: Unit = if (code ne null) { + Console.println("[checking locals of " + this + "]") + for (val bb <- code.blocks; val i <- bb.toList) i match { + case LOAD_LOCAL(l) => + if (!this.locals.contains(l)) + Console.println("Local " + l + " is not declared in " + this) + case STORE_LOCAL(l) => + if (!this.locals.contains(l)) + Console.println("Local " + l + " is not declared in " + this) + case _ => () + } + } } /** Represent local variables and parameters */ @@ -228,7 +242,7 @@ trait Members requires ICodes { /** Ending PC for this local's visbility range. */ var end: Int = _ - /** PC-based ranges for this local variable's visibility range */ + /** PC-based ranges for this local variable's visibility */ var ranges: List[Pair[Int, Int]] = Nil override def equals(other: Any): Boolean = ( diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index e50bc65cc4..6002c3ea6d 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -322,7 +322,7 @@ trait Opcodes requires ICodes { * Stack: ...:arg1:arg2:...:argn * ->: ...:ref */ - case class NEW(kind: TypeKind) extends Instruction { + case class NEW(kind: REFERENCE) extends Instruction { /** Returns a string representation of this instruction */ override def toString(): String = "NEW "+ kind; diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 7d6bb09ba3..4da3c1db2b 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -350,6 +350,9 @@ abstract class CopyPropagation { case MONITOR_EXIT() => out.stack = out.stack.drop(1) + case SCOPE_ENTER(_) | SCOPE_EXIT(_) => + () + case _ => dump abort("Unknown instruction: " + i) diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala index abb79ef3e5..4be33c4ef1 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala @@ -79,7 +79,7 @@ abstract class Liveness { backwardAnalysis(blockTransfer) if (settings.debug.value) { linearizer.linearize(method).foreach(b => if (b != method.code.startBlock) - assert(in(b) != lattice.bottom, + assert(lattice.bottom != in(b), "Block " + b + " in " + this.method + " has input equal to bottom -- not visited?")); } } diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala index fcb369615e..9d27858b0a 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala @@ -316,6 +316,9 @@ abstract class TypeFlowAnalysis { case MONITOR_EXIT() => stack.pop + case SCOPE_ENTER(_) | SCOPE_EXIT(_) => + () + case _ => dump abort("Unknown instruction: " + i) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 0a4de0e814..36a2307212 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -817,7 +817,7 @@ abstract class GenJVM extends SubComponent { jcode.emitDUP() jcode.emitIFNONNULL(nonNull) jcode.emitPOP() - boxKind match { + (boxKind: @unsealed) match { case BYTE => jcode.emitPUSH(0: Byte) case SHORT => jcode.emitPUSH(0: Short) case CHAR => jcode.emitPUSH(0: Char) @@ -909,7 +909,7 @@ abstract class GenJVM extends SubComponent { } case _ => - kind match { + (kind: @unsealed) match { case LONG => jcode.emitLCMP() case FLOAT => jcode.emitFCMPG() case DOUBLE => jcode.emitDCMPG() @@ -945,7 +945,7 @@ abstract class GenJVM extends SubComponent { } case _ => - kind match { + (kind: @unsealed) match { case LONG => jcode.emitLCONST_0(); jcode.emitLCMP() case FLOAT => jcode.emitFCONST_0(); jcode.emitFCMPL() case DOUBLE => jcode.emitDCONST_0(); jcode.emitDCMPL() @@ -1050,7 +1050,7 @@ abstract class GenJVM extends SubComponent { op match { case ADD => jcode.emitADD(javaType(kind)) case SUB => - kind match { + (kind: @unsealed) match { case BOOL | BYTE | CHAR | SHORT | INT => jcode.emitISUB() case LONG => jcode.emitLSUB() @@ -1059,7 +1059,7 @@ abstract class GenJVM extends SubComponent { } case MUL => - kind match { + (kind: @unsealed) match { case BOOL | BYTE | CHAR | SHORT | INT => jcode.emitIMUL() case LONG => jcode.emitLMUL() @@ -1068,7 +1068,7 @@ abstract class GenJVM extends SubComponent { } case DIV => - kind match { + (kind: @unsealed) match { case BOOL | BYTE | CHAR | SHORT | INT => jcode.emitIDIV() case LONG => jcode.emitLDIV() @@ -1077,7 +1077,7 @@ abstract class GenJVM extends SubComponent { } case REM => - kind match { + (kind: @unsealed) match { case BOOL | BYTE | CHAR | SHORT | INT => jcode.emitIREM() case LONG => jcode.emitLREM() @@ -1375,7 +1375,7 @@ abstract class GenJVM extends SubComponent { sym.isNonBottomSubClass(definitions.ClassfileAnnotationClass)) - def javaType(t: TypeKind): JType = t match { + def javaType(t: TypeKind): JType = (t: @unsealed) match { case UNIT => JType.VOID case BOOL => JType.BOOLEAN case BYTE => JType.BYTE diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index d4df49d05f..354bf647a8 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -154,7 +154,7 @@ abstract class ClosureElimination extends SubComponent { } /* Partial mapping from values to instructions that load them. */ - def valueToInstruction(v: Value): Instruction = v match { + def valueToInstruction(v: Value): Instruction = (v: @unsealed) match { case Deref(LocalVar(v)) => LOAD_LOCAL(v) diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 3afbbb56f0..ea3442222e 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -69,9 +69,6 @@ abstract class Inliners extends SubComponent { /* Map 'original' blocks to the ones inlined in the caller. */ val inlinedBlock: Map[BasicBlock, BasicBlock] = new HashMap; - /* Map callee's parameters to inlined local variables. */ - val argsToLocal: Map[Local, Local] = new HashMap; - val instrBefore = block.toList.takeWhile( i => i ne instr); val instrAfter = block.toList.drop(instrBefore.length + 1); @@ -91,6 +88,8 @@ abstract class Inliners extends SubComponent { def newBlock = { val b = caller.code.newBlock; activeHandlers.foreach (.addBlock(b)); + if (retVal ne null) b.varsInScope += retVal + b.varsInScope += inlinedThis b } @@ -101,24 +100,15 @@ abstract class Inliners extends SubComponent { handler } + var inlinedLocals: Map[Local, Local] = new HashMap + /** alfa-rename `l' in caller's context. */ def dupLocal(l: Local): Local = { val sym = caller.symbol.newVariable(l.sym.pos, freshName(l.sym.name.toString())); - sym.setInfo(l.sym.tpe); - new Local(sym, l.kind, false) - } - - /** Adds parameters from another method as locals */ - def addParamsAsLocals(m: IMethod, ls: List[Local]): Unit = { - m.locals = m.locals ::: (ls map { a => - if (a.arg) { - //val l = new Local(a.sym, a.kind, false); - val l = dupLocal(a); - argsToLocal += a -> l; - l - } else - a - }); +// sym.setInfo(l.sym.tpe); + val dupped = new Local(sym, l.kind, false) + inlinedLocals(l) = dupped + dupped } def addLocals(m: IMethod, ls: List[Local]) = @@ -148,23 +138,37 @@ abstract class Inliners extends SubComponent { case RETURN(kind) => JUMP(afterBlock); - case LOAD_LOCAL(l) if (argsToLocal.isDefinedAt(l)) => - Console.println("Replacing load_local"); - LOAD_LOCAL(argsToLocal(l)) + case LOAD_LOCAL(l) if inlinedLocals.isDefinedAt(l) => + LOAD_LOCAL(inlinedLocals(l)) + + case STORE_LOCAL(l) if inlinedLocals.isDefinedAt(l) => + STORE_LOCAL(inlinedLocals(l)) + + case LOAD_LOCAL(l) => + assert(caller.locals contains l, + "Could not find local '" + l + "' in locals, nor in inlinedLocals: " + inlinedLocals) + i + case STORE_LOCAL(l) => + assert(caller.locals contains l, + "Could not find local '" + l + "' in locals, nor in inlinedLocals: " + inlinedLocals) + i + + case SCOPE_ENTER(l) if inlinedLocals.isDefinedAt(l) => + SCOPE_ENTER(inlinedLocals(l)) - case STORE_LOCAL(l) if (argsToLocal.isDefinedAt(l)) => - Console.println("Replacing store_local"); - STORE_LOCAL(argsToLocal(l)) + case SCOPE_EXIT(l) if inlinedLocals.isDefinedAt(l) => + SCOPE_EXIT(inlinedLocals(l)) case _ => i } - addLocals(caller, callee.locals); + addLocals(caller, callee.locals map dupLocal); addLocal(caller, inlinedThis); if (retVal ne null) addLocal(caller, retVal); callee.code.blocks.foreach { b => inlinedBlock += b -> newBlock; + inlinedBlock(b).varsInScope ++= (b.varsInScope map inlinedLocals) } // analyse callee @@ -177,7 +181,7 @@ abstract class Inliners extends SubComponent { // store the arguments into special locals callee.params.reverse.foreach { param => - block.emit(STORE_LOCAL(param), targetPos); + block.emit(STORE_LOCAL(inlinedLocals(param)), targetPos); } block.emit(STORE_LOCAL(inlinedThis), targetPos); |