Skip to content

Commit

Permalink
new bytecode emitter, GenBCode, for now under a flag
Browse files Browse the repository at this point in the history
GenBCode is a drop-in replacement for GenASM with several advantages:

  - faster: ICode isn't necessary anymore.
    Instead, the ASTs delivered by CleanUp (an expression language)
    are translated directly into a stack-language (ASM Tree nodes)

  - future-proofing for Java 8 (MethodHandles, invokedynamic).

  - documentation included, shared mutable state kept to a minimum,
    all contributing to making GenBCode more maintainable
    than its counterpart (its counterpart being GenICode + GenASM).

A few tests are modified in this commit, for reasons given below.

(1) files/neg/case-collision

    Just like GenASM, GenBCode also detects output classfiles
    differing only in case. However the error message differs
    from that of GenASM (collisions may be show in different order).
    Thus the original test now has a flags file containing -neo:GenASM
    and a new test (files/neg/case-collision2) has been added
    for GenBCode. The .check files in each case show expected output.

(2) files/pos/t5031_3

    Currently the test above doesn't work with GenBCode
    (try with -neo:GenBCode in the flags file)
    The root cause lies in the fix to
    https://issues.scala-lang.org/browse/SI-5031
    which weakened an assertion in GenASM
    (GenBCode keeps the original assertion).
    Actually that ticket mentions the fix is a "workaround"

(3) files/run/t7008-scala-defined

    This test also passes only under GenASM and not GenBCode,
    thus the flags file. GenASM turns a bling eye to:

      An AbstractTypeSymbol (SI-7122) has reached the bytecode emitter,
      for which no JVM-level internal name can be found:
      ScalaClassWithCheckedExceptions_1.E1

    The error message above (shown by GenBCode) highlights
    there's no ScalaClassWithCheckedExceptions_1.E1 class,
    thus shouldn't show up in the emitted bytecode
    (GenASM emits bytecode that mentions the inexistent class).
  • Loading branch information
magarciaEPFL committed Jun 1, 2013
1 parent c4d1217 commit 22ee2df
Show file tree
Hide file tree
Showing 23 changed files with 6,751 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/asm/scala/tools/asm/tree/MethodNode.java
Expand Up @@ -458,7 +458,7 @@ public void visitEnd() {
*/
protected LabelNode getLabelNode(final Label l) {
if (!(l.info instanceof LabelNode)) {
l.info = new LabelNode();
l.info = new LabelNode(l);
}
return (LabelNode) l.info;
}
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/scala/tools/nsc/Global.scala
Expand Up @@ -26,6 +26,7 @@ import transform.patmat.PatternMatching
import transform._
import backend.icode.{ ICodes, GenICode, ICodeCheckers }
import backend.{ ScalaPrimitives, Platform, JavaPlatform }
import backend.jvm.GenBCode
import backend.jvm.GenASM
import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
Expand Down Expand Up @@ -617,6 +618,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val runsRightAfter = None
} with GenASM

// phaseName = "bcode"
object genBCode extends {
val global: Global.this.type = Global.this
val runsAfter = List("dce")
val runsRightAfter = None
} with GenBCode

// phaseName = "terminal"
object terminal extends {
val global: Global.this.type = Global.this
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
Expand Up @@ -38,9 +38,13 @@ trait JavaPlatform extends Platform {
// replaces the tighter abstract definition here. If we had DOT typing rules, the two
// types would be conjoined and everything would work out. Yet another reason to push for DOT.

private def classEmitPhase =
if (settings.isBCodeActive) genBCode
else genASM

def platformPhases = List(
flatten, // get rid of inner classes
genASM // generate .class files
classEmitPhase // generate .class files
)

lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
Expand Up @@ -52,6 +52,7 @@ abstract class GenICode extends SubComponent {
}

override def apply(unit: CompilationUnit): Unit = {
if (settings.isBCodeActive) { return }

This comment has been minimized.

Copy link
@gkossakowski

gkossakowski Jun 25, 2013

I find it confusing that we still have icode phase but it does nothing in case GenBCode is enabled. Why phase assembly doesn't depend on isBCodeActive value so it assembles the right phases?

This comment has been minimized.

Copy link
@magarciaEPFL

magarciaEPFL Jun 27, 2013

Author Owner

It's a long story, details in scala#2620 (comment)

this.unit = unit
unit.icode.clear()
informProgress("Generating icode for " + unit)
Expand Down

0 comments on commit 22ee2df

Please sign in to comment.