summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm/scala/tools/asm/MethodWriter.java7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala9
-rw-r--r--test/files/run/large_code.check3
-rw-r--r--test/files/run/large_code.scala24
4 files changed, 37 insertions, 6 deletions
diff --git a/src/asm/scala/tools/asm/MethodWriter.java b/src/asm/scala/tools/asm/MethodWriter.java
index 321bacb6fc..887cb28c6f 100644
--- a/src/asm/scala/tools/asm/MethodWriter.java
+++ b/src/asm/scala/tools/asm/MethodWriter.java
@@ -1853,7 +1853,12 @@ class MethodWriter extends MethodVisitor {
int size = 8;
if (code.length > 0) {
if (code.length > 65536) {
- throw new RuntimeException("Method code too large!");
+ String nameString = "";
+ int i = 0;
+ // find item that corresponds to the index of our name
+ while (i < cw.items.length && (cw.items[i] == null || cw.items[i].index != name)) i++;
+ if (cw.items[i] != null) nameString = cw.items[i].strVal1 +"'s ";
+ throw new RuntimeException("Method "+ nameString +"code too large!");
}
cw.newUTF8("Code");
size += 18 + code.length + 8 * handlerCount;
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 97140aca2e..19cdcd2590 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -450,7 +450,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
}
// -----------------------------------------------------------------------------------------
- // utitilies useful when emitting plain, mirror, and beaninfo classes.
+ // utilities useful when emitting plain, mirror, and beaninfo classes.
// -----------------------------------------------------------------------------------------
def writeIfNotTooBig(label: String, jclassName: String, jclass: asm.ClassWriter, sym: Symbol) {
@@ -458,9 +458,9 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
val arr = jclass.toByteArray()
bytecodeWriter.writeClass(label, jclassName, arr, sym)
} catch {
- case e: java.lang.RuntimeException if(e.getMessage() == "Class file too large!") =>
- // TODO check where ASM throws the equivalent of CodeSizeTooBigException
- log("Skipped class "+jclassName+" because it exceeds JVM limits (it's too big or has methods that are too long).")
+ case e: java.lang.RuntimeException if e != null && (e.getMessage contains "too large!") =>
+ reporter.error(sym.pos,
+ s"Could not write class $jclassName because it exceeds JVM code size limits. ${e.getMessage}")
}
}
@@ -1402,7 +1402,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
addInnerClasses(clasz.symbol, jclass)
jclass.visitEnd()
writeIfNotTooBig("" + c.symbol.name, thisName, jclass, c.symbol)
-
}
/**
diff --git a/test/files/run/large_code.check b/test/files/run/large_code.check
new file mode 100644
index 0000000000..6ad50967bc
--- /dev/null
+++ b/test/files/run/large_code.check
@@ -0,0 +1,3 @@
+newSource1.scala:1: error: Could not write class BigEnoughToFail because it exceeds JVM code size limits. Method tooLong's code too large!
+class BigEnoughToFail {
+ ^
diff --git a/test/files/run/large_code.scala b/test/files/run/large_code.scala
new file mode 100644
index 0000000000..f9d7f8c95b
--- /dev/null
+++ b/test/files/run/large_code.scala
@@ -0,0 +1,24 @@
+import scala.tools.partest._
+import java.io.{Console => _, _}
+
+// a cold run of partest takes about 15s for this test on my laptop
+object Test extends DirectTest {
+ override def extraSettings: String = "-usejavacp -d " + testOutput.path
+
+ // test that we hit the code size limit and error out gracefully
+ // 5958 is the magic number (2^16/11 -- each `a(1,2,3,4,5,6)` is 11 bytes of bytecode)
+ override def code
+ = s"""
+ |class BigEnoughToFail {
+ | def a(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int): Unit = {}
+ | def tooLong: Unit = {
+ | ${(1 to 5958) map (_ => "a(1,2,3,4,5,6)") mkString(";")}
+ | }
+ |}""".stripMargin.trim
+
+ override def show(): Unit = {
+ Console.withErr(System.out) {
+ compile()
+ }
+ }
+}