summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-08-06 11:01:17 +0200
committerMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-08-06 11:01:17 +0200
commit61cc8ff61c81a1276a921ad5288ee3bebea1c96e (patch)
tree516aabb9f5ce523ef26b0e3ac8099dd818bb314d /src
parenta05a68a9894f78fc8d7423c722e516a7ee49d559 (diff)
downloadscala-61cc8ff61c81a1276a921ad5288ee3bebea1c96e.tar.gz
scala-61cc8ff61c81a1276a921ad5288ee3bebea1c96e.tar.bz2
scala-61cc8ff61c81a1276a921ad5288ee3bebea1c96e.zip
SI-6188 ICodeReader notes exception handlers, Inliner takes them into account
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala13
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala3
3 files changed, 16 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index 00f4a9d262..44c4a3a6db 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -170,6 +170,7 @@ trait Members {
var sourceFile: SourceFile = NoSourceFile
var returnType: TypeKind = _
var recursive: Boolean = false
+ var bytecodeHasEHs = false // set by ICodeReader only, used by Inliner to prevent inlining (SI-6188)
/** local variables and method parameters */
var locals: List[Local] = Nil
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index cce18d436f..dd7676a371 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -405,6 +405,12 @@ abstract class Inliners extends SubComponent {
val inc = new IMethodInfo(callee)
val pair = new CallerCalleeInfo(caller, inc, fresh, inlinedMethodCount)
+ if(inc.hasHandlers && (stackLength == -1)) {
+ // no inlining is done, yet don't warn about it, stackLength == -1 indicates we're trying to inlineWithoutTFA.
+ // Shortly, a TFA will be computed and an error message reported if indeed inlining not possible.
+ return false
+ }
+
(pair isStampedForInlining stackLength) match {
case inlInfo if inlInfo.isSafe =>
@@ -605,7 +611,7 @@ abstract class Inliners extends SubComponent {
def isSmall = (length <= SMALL_METHOD_SIZE) && blocks(0).length < 10
def isLarge = length > MAX_INLINE_SIZE
def isRecursive = m.recursive
- def hasHandlers = handlers.nonEmpty
+ def hasHandlers = handlers.nonEmpty || m.bytecodeHasEHs
def isSynchronized = sym.hasFlag(Flags.SYNCHRONIZED)
def hasNonFinalizerHandler = handlers exists {
@@ -941,6 +947,7 @@ abstract class Inliners extends SubComponent {
if(inc.isRecursive) { rs ::= "is recursive" }
if(isInlineForbidden) { rs ::= "is annotated @noinline" }
if(inc.isSynchronized) { rs ::= "is synchronized method" }
+ if(inc.m.bytecodeHasEHs) { rs ::= "bytecode contains exception handlers / finally clause" } // SI-6188
if(rs.isEmpty) null else rs.mkString("", ", and ", "")
}
@@ -974,6 +981,10 @@ abstract class Inliners extends SubComponent {
return DontInlineHere("too low score (heuristics)")
}
+ if(inc.hasHandlers && (stackLength != 0)) {
+ // TODO pending return DontInlineHere("callee contains exception handlers / finally clause, and is invoked with non-empty operand stack") // SI-6157
+ }
+
if(isKnownToInlineSafely) { return InlineableAtThisCaller }
if(stackLength > inc.minimumStack && inc.hasNonFinalizerHandler) {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index bb9f9bde98..3a3be4dc78 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -594,6 +594,7 @@ abstract class ICodeReader extends ClassfileParser {
while (pc < codeLength) parseInstruction
val exceptionEntries = in.nextChar.toInt
+ code.containsEHs = (exceptionEntries != 0)
var i = 0
while (i < exceptionEntries) {
// skip start end PC
@@ -647,6 +648,7 @@ abstract class ICodeReader extends ClassfileParser {
var containsDUPX = false
var containsNEW = false
+ var containsEHs = false
def emit(i: Instruction) {
instrs += ((pc, i))
@@ -664,6 +666,7 @@ abstract class ICodeReader extends ClassfileParser {
val code = new Code(method)
method.setCode(code)
+ method.bytecodeHasEHs = containsEHs
var bb = code.startBlock
def makeBasicBlocks: mutable.Map[Int, BasicBlock] =