summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala104
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala9
2 files changed, 63 insertions, 50 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index c158d951a7..6a3c7a000a 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -50,19 +50,22 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
def name = phaseName
override def erasedTypes = true
- object codeGenerator extends BytecodeGenerator
override def run {
+ // we reinstantiate the bytecode generator at each run, to allow the GC
+ // to collect everything
+ val codeGenerator = new BytecodeGenerator
if (settings.debug.value) inform("[running phase " + name + " on icode]")
if (settings.Xdce.value)
for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym))
icodes.classes -= sym
- classes.values foreach apply
+ classes.values foreach codeGenerator.genClass
+ classes.clear
}
- override def apply(cls: IClass) {
- codeGenerator.genClass(cls)
+ def apply(cls: IClass) {
+ error("no implementation")
}
}
@@ -633,15 +636,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
}
}
- def isTopLevelModule(sym: Symbol): Boolean =
- atPhase (currentRun.picklerPhase.next) {
- sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass
- }
-
- def isStaticModule(sym: Symbol): Boolean = {
- sym.isModuleClass && !sym.isImplClass && !sym.isLifted
- }
-
def genField(f: IField) {
if (settings.debug.value)
log("Adding field: " + f.symbol.fullName)
@@ -1731,41 +1725,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
////////////////////// Utilities ////////////////////////
- /**
- * Return the Java modifiers for the given symbol.
- * Java modifiers for classes:
- * - public, abstract, final, strictfp (not used)
- * for interfaces:
- * - the same as for classes, without 'final'
- * for fields:
- * - public, private (*)
- * - static, final
- * for methods:
- * - the same as for fields, plus:
- * - abstract, synchronized (not used), strictfp (not used), native (not used)
- *
- * (*) protected cannot be used, since inner classes 'see' protected members,
- * and they would fail verification after lifted.
- */
- def javaFlags(sym: Symbol): Int = {
- def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
- // constructors of module classes should be private
- // PP: why are they only being marked private at this stage and not earlier?
- val isConsideredPrivate =
- sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
-
- mkFlags(
- if (isConsideredPrivate) ACC_PRIVATE else ACC_PUBLIC,
- if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0,
- if (sym.isInterface) ACC_INTERFACE else 0,
- if (sym.isFinal && !sym.enclClass.isInterface && !sym.isClassConstructor) ACC_FINAL else 0,
- if (sym.isStaticMember) ACC_STATIC else 0,
- if (sym.isBridge) ACC_BRIDGE else 0,
- if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
- if (sym.isVarargsMethod) ACC_VARARGS else 0
- )
+ override def javaName(sym: Symbol): String = {
+ if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass)
+ innerClasses = innerClasses + sym
+ super.javaName(sym)
}
+
/** Calls to methods in 'sym' need invokeinterface? */
def needsInterfaceCall(sym: Symbol): Boolean = {
log("checking for interface call: " + sym.fullName)
@@ -1808,4 +1774,50 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
def assert(cond: Boolean) { assert(cond, "Assertion failed.") }
}
+
+ /**
+ * Return the Java modifiers for the given symbol.
+ * Java modifiers for classes:
+ * - public, abstract, final, strictfp (not used)
+ * for interfaces:
+ * - the same as for classes, without 'final'
+ * for fields:
+ * - public, private (*)
+ * - static, final
+ * for methods:
+ * - the same as for fields, plus:
+ * - abstract, synchronized (not used), strictfp (not used), native (not used)
+ *
+ * (*) protected cannot be used, since inner classes 'see' protected members,
+ * and they would fail verification after lifted.
+ */
+ def javaFlags(sym: Symbol): Int = {
+ def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
+ // constructors of module classes should be private
+ // PP: why are they only being marked private at this stage and not earlier?
+ val isConsideredPrivate =
+ sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
+
+ mkFlags(
+ if (isConsideredPrivate) ACC_PRIVATE else ACC_PUBLIC,
+ if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0,
+ if (sym.isInterface) ACC_INTERFACE else 0,
+ if (sym.isFinal && !sym.enclClass.isInterface && !sym.isClassConstructor) ACC_FINAL else 0,
+ if (sym.isStaticMember) ACC_STATIC else 0,
+ if (sym.isBridge) ACC_BRIDGE else 0,
+ if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
+ if (sym.isVarargsMethod) ACC_VARARGS else 0
+ )
+ }
+
+ def isTopLevelModule(sym: Symbol): Boolean =
+ atPhase (currentRun.picklerPhase.next) {
+ sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass
+ }
+
+ def isStaticModule(sym: Symbol): Boolean = {
+ sym.isModuleClass && !sym.isImplClass && !sym.isLifted
+ }
+
+
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
index cd0d253954..38c22b930c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
@@ -43,8 +43,11 @@ trait GenJVMUtil {
DOUBLE -> new JObjectType("java.lang.Double")
)
+ /** This trait may be used by tools who need access to
+ * utility methods like javaName and javaType. (for instance,
+ * the Eclipse plugin uses it).
+ */
trait BytecodeUtil {
- self: BytecodeGenerator =>
val conds = immutable.Map[TestOp, Int](
EQ -> JExtendedCode.COND_EQ,
@@ -84,9 +87,6 @@ trait GenJVMUtil {
else getPrimitiveCompanion(sym.companionModule) match {
case Some(sym) => javaName(sym)
case _ =>
- if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass)
- innerClasses = innerClasses + sym
-
val prefix =
if (sym.isClass || (sym.isModule && !sym.isMethod)) sym.fullName('/')
else sym.simpleName.toString.trim()
@@ -132,6 +132,7 @@ trait GenJVMUtil {
ts foreach ( t => { res(i) = javaType(t); i += 1 } );
res
}
+
protected def genConstant(jcode: JExtendedCode, const: Constant) {
const.tag match {
case UnitTag => ()