Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: Scala 2.9.2, Scala 2.10.0-RC2
    • Fix Version/s: Scala 2.11.0-M2
    • Component/s: Compiler Backend
    • Labels:
    • Environment:

      Ubuntu 12.10 i386

      Description

      scalac generates bytecode which is unreachable. This problem affects performance.
      I am enclosing two example:
      1 - Look at method Test.crazy. From bytecode 68 to 76.
      2 - Look at method KevoreeLazyJarResources.loadJar(jarFile:String). From 148 to 159.
      I realized this because I am extending a JVM. The code run with JavaHotSpot but any way, this is not correct. The really weird is that in former case a lot of nop are generated. however, in the latter case it looks like if some code is duplicated. Maybe a potential source of bug

      1. KevoreeLazyJarResources.scala
        13 kB
        Inti Gonzalez
      2. Main.scala
        0.7 kB
        Inti Gonzalez

        Issue Links

          Activity

          Hide
          James Iry added a comment -

          Some amount of code duplication is a consequence of bytecode format 51 (the Java 6 bytecode format). With that rev the jsr and ret instructions are no longer usable. The result is that finally blocks need to be duplicated. Here's an approachable introduction: http://cliffhacks.blogspot.com/2008/02/java-6-tryfinally-compilation-without.html . Still, it should be possible to avoid some of the duplication by recognizing cases where flow out of a finally block is identical.

          An alternative would be to lift finally blocks into methods, but that would mean boxing mutable variables and we'd need a heuristic to decide when one alternative was better than the other.

          I'm investigation why we spit out so many nops and what it would take to avoid them during non-optimized builds. It's definitely feasible to drop them in the optimizer, but it would be nicer to just not have them.

          Show
          James Iry added a comment - Some amount of code duplication is a consequence of bytecode format 51 (the Java 6 bytecode format). With that rev the jsr and ret instructions are no longer usable. The result is that finally blocks need to be duplicated. Here's an approachable introduction: http://cliffhacks.blogspot.com/2008/02/java-6-tryfinally-compilation-without.html . Still, it should be possible to avoid some of the duplication by recognizing cases where flow out of a finally block is identical. An alternative would be to lift finally blocks into methods, but that would mean boxing mutable variables and we'd need a heuristic to decide when one alternative was better than the other. I'm investigation why we spit out so many nops and what it would take to avoid them during non-optimized builds. It's definitely feasible to drop them in the optimizer, but it would be nicer to just not have them.
          Hide
          Miguel Garcia added a comment -

          Regarding unreachable code. The new backend solves that issue, and the fix can be ported to GenASM. Here's the gist:

              /**
               *  When writing classfiles with "optimization level zero" (ie -neo:GenBCode)
               *  the very least we want to do is remove dead code beforehand,
               *  so as to prevent an artifact of stack-frames computation from showing up,
               *  the artifact described at http://asm.ow2.org/doc/developer-guide.html#deadcode
               *  That artifact results from the requirement by the Java 6 split verifier
               *  that a stack map frame be available for each basic block, even unreachable ones.
               *
               *  Just removing dead code might leave stale LocalVariableTable entries
               *  thus `cleanseMethod()` also gets rid of those.
               * */
              final def removeDeadCode() {
                for(mnode <- cnode.toMethodList; if Util.hasBytecodeInstructions(mnode)) {
                  Util.computeMaxLocalsMaxStack(mnode)
                  cleanseMethod(cnode.name, mnode) // remove unreachable code
                }
              }
          

          Excerpt from https://github.com/magarciaEPFL/scala/blob/GenRefactored/src/compiler/scala/tools/nsc/backend/jvm/BCodeOptIntra.scala

          The ASM visitors used in cleanseMethod() can be found at https://github.com/magarciaEPFL/scala/tree/GenRefactored/src/asm/scala/tools/asm/optimiz

          Show
          Miguel Garcia added a comment - Regarding unreachable code. The new backend solves that issue, and the fix can be ported to GenASM. Here's the gist: /** * When writing classfiles with "optimization level zero" (ie -neo:GenBCode) * the very least we want to do is remove dead code beforehand, * so as to prevent an artifact of stack-frames computation from showing up, * the artifact described at http://asm.ow2.org/doc/developer-guide.html#deadcode * That artifact results from the requirement by the Java 6 split verifier * that a stack map frame be available for each basic block, even unreachable ones. * * Just removing dead code might leave stale LocalVariableTable entries * thus `cleanseMethod()` also gets rid of those. * */ final def removeDeadCode() { for(mnode <- cnode.toMethodList; if Util.hasBytecodeInstructions(mnode)) { Util.computeMaxLocalsMaxStack(mnode) cleanseMethod(cnode.name, mnode) // remove unreachable code } } Excerpt from https://github.com/magarciaEPFL/scala/blob/GenRefactored/src/compiler/scala/tools/nsc/backend/jvm/BCodeOptIntra.scala The ASM visitors used in cleanseMethod() can be found at https://github.com/magarciaEPFL/scala/tree/GenRefactored/src/asm/scala/tools/asm/optimiz
          Show
          James Iry added a comment - https://github.com/scala/scala/pull/2158
          Hide
          James Iry added a comment -

          I've created a separate ticket SI-7181 to deal with the finally block duplication

          Show
          James Iry added a comment - I've created a separate ticket SI-7181 to deal with the finally block duplication

            People

            • Assignee:
              James Iry
              Reporter:
              Inti Gonzalez
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Due:
                Created:
                Updated:
                Resolved:

                Development