Error reporting when the generated code size exceeds JVM limits (65,535 bytes per method). Closed #4573. review by extempore.
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@24985 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
cbb21fd949
commit
8e38b90267
BIN
lib/fjbg.jar
BIN
lib/fjbg.jar
Binary file not shown.
|
|
@ -82,7 +82,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
|
|||
else new ClassBytecodeWriter with JavapBytecodeWriter { }
|
||||
}
|
||||
val codeGenerator = new BytecodeGenerator(bytecodeWriter)
|
||||
classes.values foreach (codeGenerator genClass _)
|
||||
classes.values foreach { c =>
|
||||
try codeGenerator.genClass(c)
|
||||
catch {
|
||||
case e: JCode.CodeSizeTooBigException =>
|
||||
log("Skipped class %s because it has methods that are too long.".format(c.toString))
|
||||
}
|
||||
}
|
||||
bytecodeWriter.close()
|
||||
classes.clear()
|
||||
}
|
||||
|
|
@ -785,6 +791,14 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
|
|||
addExceptionsAttribute(jmethod, excs)
|
||||
addAnnotations(jmethod, others)
|
||||
addParamAnnotations(jmethod, m.params.map(_.sym.annotations))
|
||||
|
||||
// check for code size
|
||||
try jmethod.freeze()
|
||||
catch {
|
||||
case e: JCode.CodeSizeTooBigException =>
|
||||
clasz.cunit.error(m.symbol.pos, "Code size exceeds JVM limits: %d".format(e.codeSize))
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
private def addRemoteException(jmethod: JMethod, meth: Symbol) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import ch.epfl.lamp.util.ByteArray;
|
|||
|
||||
public class JCode {
|
||||
protected boolean frozen = false;
|
||||
|
||||
public static int MAX_CODE_SIZE = 65535;
|
||||
|
||||
protected final FJBGContext context;
|
||||
protected final JMethod owner;
|
||||
|
|
@ -57,8 +59,8 @@ public class JCode {
|
|||
this.owner = owner;
|
||||
owner.setCode(this);
|
||||
int size = stream.readInt();
|
||||
if (size >= 65536) // section 4.10
|
||||
throw new Error("code size must be less than 65536: " + size);
|
||||
if (size > MAX_CODE_SIZE) // section 4.10
|
||||
throw new Error("code size must be less than " + MAX_CODE_SIZE + ": " + size);
|
||||
this.codeArray = new ByteArray(stream, size);
|
||||
}
|
||||
|
||||
|
|
@ -97,8 +99,19 @@ public class JCode {
|
|||
// Freezing
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class CodeSizeTooBigException extends OffsetTooBigException {
|
||||
public int codeSize;
|
||||
|
||||
public CodeSizeTooBigException(int size) {
|
||||
codeSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
public void freeze() throws OffsetTooBigException {
|
||||
assert !frozen;
|
||||
|
||||
if (getSize() > MAX_CODE_SIZE) throw new CodeSizeTooBigException(getSize());
|
||||
|
||||
patchAllOffset();
|
||||
codeArray.freeze();
|
||||
frozen = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue