Skip to content

Better error messages in case of TooLarge* exceptions in GenBCode #14943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 19, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions compiler/src/dotty/tools/backend/jvm/GenBCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import scala.tools.asm.tree._
import tpd._
import StdNames._
import dotty.tools.io._
import scala.tools.asm.MethodTooLargeException
import scala.tools.asm.ClassTooLargeException

class GenBCode extends Phase {

Expand Down Expand Up @@ -512,7 +514,7 @@ class GenBCodePipeline(val int: DottyBackendInterface, val primitives: DottyPrim
* (c) tear down (closing the classfile-writer and clearing maps)
*
*/
def run(t: Tree): Unit = {
def run(t: Tree)(using Context): Unit = {
this.tree = t

// val bcodeStart = Statistics.startTimer(BackendStats.bcodeTimer)
Expand Down Expand Up @@ -558,18 +560,29 @@ class GenBCodePipeline(val int: DottyBackendInterface, val primitives: DottyPrim
* (c) dequeue one at a time from queue-2, convert it to byte-array, place in queue-3
* (d) serialize to disk by draining queue-3.
*/
private def buildAndSendToDisk(needsOutFolder: Boolean) = {

feedPipeline1()
// val genStart = Statistics.startTimer(BackendStats.bcodeGenStat)
(new Worker1(needsOutFolder)).run()
// Statistics.stopTimer(BackendStats.bcodeGenStat, genStart)

(new Worker2).run()

// val writeStart = Statistics.startTimer(BackendStats.bcodeWriteTimer)
drainQ3()
// Statistics.stopTimer(BackendStats.bcodeWriteTimer, writeStart)
private def buildAndSendToDisk(needsOutFolder: Boolean)(using Context) = {
try
feedPipeline1()
// val genStart = Statistics.startTimer(BackendStats.bcodeGenStat)
(new Worker1(needsOutFolder)).run()
// Statistics.stopTimer(BackendStats.bcodeGenStat, genStart)

(new Worker2).run()

// val writeStart = Statistics.startTimer(BackendStats.bcodeWriteTimer)
drainQ3()
// Statistics.stopTimer(BackendStats.bcodeWriteTimer, writeStart)
catch
case e: MethodTooLargeException =>
val method =
s"${e.getClassName.replaceAll("/", ".")}.${e.getMethodName}"
val msg =
s"Generated bytecode for method '$method' is too large. Size: ${e.getCodeSize} bytes. Limit is 64KB"
report.error(msg)
case e: ClassTooLargeException =>
val msg =
s"Class '${e.getClassName.replaceAll("/", ".")}' is too large. Constant pool size: ${e.getConstantPoolCount}. Limit is 64KB"
report.error(msg)

}

Expand Down