为什么大型数组构造函数调用会破坏Scala编译器?

时间:2015-07-22 19:03:15

标签: arrays scala compiler-errors

我正在为一份工作做一些图像处理,并用Im4Java编写脚本。为了编写一些单元格,我决定只将一个局部图像存储为代码中的字节数组。我抓住了一个简单的测试图像

Example Image Pulled from Wikipedia

然后将其转换为字节数组,如下所示:

import java.nio.file.{Paths, Files}
import java.nio.charset.StandardCharsets
val stuff =scala.io.Source.fromFile(fileName)(scala.io.Codec.ISO8859).map(_.toByte).toArray
Files.write(Paths.get("tmp.txt"), stuff.mkString(",").getBytes(StandardCharsets.UTF_8))

然后将这些字节放入Array[Byte] apply构造函数中:

class testCase() {
    val smallFile = Array[Byte](-1,-40,-1, …) // 9816 arguments to the constructor passed here
}

当我尝试编译它时(参见this gist中的完整scala文件)我很惊讶地看到它破坏了编译器的性能!我得到以下stacktrace(我已经截断了一点):

[error] uncaught exception during compilation: java.lang.StackOverflowError
java.lang.StackOverflowError
at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1241)
at scala.reflect.internal.Symbols$Symbol.baseTypeSeqLength$1(Symbols.scala:1628)
at scala.reflect.internal.Symbols$Symbol.isLess(Symbols.scala:1631)
at scala.reflect.internal.Types$Type.baseTypeIndex(Types.scala:992)
at scala.reflect.internal.Types$CompoundType.baseType(Types.scala:1655)
at scala.reflect.internal.Types$ClassTypeRef$class.baseType(Types.scala:2186)
at scala.reflect.internal.Types$TypeRef$$anon$6.baseType(Types.scala:2544)
at scala.reflect.internal.Types$class.firstTry$1(Types.scala:6064)
at scala.reflect.internal.Types$class.isSubType2(Types.scala:6228)
at scala.reflect.internal.Types$class.isSubType(Types.scala:5837)
at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:13)
at scala.reflect.internal.Types$class.fourthTry$1(Types.scala:6223)
at scala.reflect.internal.Types$class.thirdTryRef$1(Types.scala:6123)
at scala.reflect.internal.Types$class.thirdTry$1(Types.scala:6145)
at scala.reflect.internal.Types$class.secondTry$1(Types.scala:6109)
at scala.reflect.internal.Types$class.firstTry$1(Types.scala:6070)
at scala.reflect.internal.Types$class.isSubType2(Types.scala:6228)
at scala.reflect.internal.Types$class.isSubType(Types.scala:5837)
at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:13)
at scala.reflect.internal.Types$Type.$less$colon$less(Types.scala:872)
at scala.tools.nsc.typechecker.Typers$Typer.adapt(Typers.scala:1091)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5660)
at scala.tools.nsc.typechecker.Typers$Typer.typedArg(Typers.scala:3042)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3069)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071)
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071)
(etc as this is where the stackoverflow happens)

我正在使用Scala 2.10.5编译器和java jdk1.7.0_79

我可能只是使用较小的图像或其他东西来解决我的问题,但我想知道为什么编译器会这样做以及是否可以修复它?

1 个答案:

答案 0 :(得分:6)

好吧,我试图重现你的问题,更新的scalac(2.11.7)有更好的错误信息(希望它能解决问题):

» scalac Arrays.scala
Arrays.scala:1: error: Could not write class testCase because it exceeds JVM code size limits. Method <init>'s code too large!
class testCase()  {
      ^
one error found

所以看起来,就像@Marius noted in comments一样,你按照每种方法点击64K字节码&#34; JVM强加的限制。