summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-12-16 15:24:37 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-12-16 15:24:37 +0000
commite2edb26440c01dcef033732b6ac065b2a0928033 (patch)
tree49273bcfbc5c22dcb86e2b15b64af6ae816f3be2 /src
parent9ada1110c5311f5a383a8ba48be59aae9337cead (diff)
downloadscala-e2edb26440c01dcef033732b6ac065b2a0928033.tar.gz
scala-e2edb26440c01dcef033732b6ac065b2a0928033.tar.bz2
scala-e2edb26440c01dcef033732b6ac065b2a0928033.zip
Removed the 'codeGenerator' field, which was a ...
Removed the 'codeGenerator' field, which was a source of leaks. Refactored javaName/javaType and the like. Now javaName does only name mangling, and it is overriden by the BytecodeGenerator to keep track of inner classes. JVMUtils now can be instantited by third party tools like Eclipse and use javaName without polluting the code generator's state. review by extempore.
Diffstat (limited to 'src')
-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 => ()