Skip to content

Commit 32782cd

Browse files
magarciaEPFLadriaanm
authored andcommitted
SI-6188 backport (ICodeReader wrongly ignored exception handlers)
A backport of scala@61cc8ff The original fix (above) includes a test case that relies on scala.util.Success which as of this writing isn't there in 2.9.x. The test case requires a previously compiled classfile (where bytecode for an @inline method with exception handlers can be found). Ticket SI-6188 contains a self-contained example (not dependent on scala.util.Success) with _1 and _2 .scala files . Alternatively that test case could be used instead. The backported fix (this commit) is safe in the sense that it prevents methods read by ICodeReader containing exception handlers from being inlined, even if marked @inline. Alternatively, the same effect can be achieved by annotating a method as @noinline.
1 parent 98b16a6 commit 32782cd

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

src/compiler/scala/tools/nsc/backend/icode/Members.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ trait Members { self: ICodes =>
154154
var returnType: TypeKind = _
155155

156156
var recursive: Boolean = false
157+
var bytecodeHasEHs = false // set by ICodeReader only, used by Inliner to prevent inlining (SI-6188)
157158

158159
/** local variables and method parameters */
159160
var locals: List[Local] = Nil

src/compiler/scala/tools/nsc/backend/opt/Inliners.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ abstract class Inliners extends SubComponent {
311311
def isRecursive = m.recursive
312312
def hasCode = m.code != null
313313
def hasSourceFile = m.sourceFile != null
314-
def hasHandlers = handlers.nonEmpty
314+
def hasHandlers = handlers.nonEmpty || m.bytecodeHasEHs
315315

316316
// the number of inlined calls in 'm', used by 'shouldInline'
317317
var inlinedCalls = 0
@@ -495,7 +495,7 @@ abstract class Inliners extends SubComponent {
495495
}
496496

497497
def isStampedForInlining(stack: TypeStack) =
498-
!sameSymbols && inc.hasCode && shouldInline && isSafeToInline(stack)
498+
!sameSymbols && inc.hasCode && !inc.m.bytecodeHasEHs && shouldInline && isSafeToInline(stack)
499499

500500
def logFailure(stack: TypeStack) = log(
501501
"""|inline failed for %s:

src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ abstract class ICodeReader extends ClassfileParser {
618618
while (pc < codeLength) parseInstruction
619619

620620
val exceptionEntries = in.nextChar.toInt
621+
code.containsEHs = (exceptionEntries != 0)
621622
var i = 0
622623
while (i < exceptionEntries) {
623624
// skip start end PC
@@ -669,6 +670,7 @@ abstract class ICodeReader extends ClassfileParser {
669670

670671
var containsDUPX = false
671672
var containsNEW = false
673+
var containsEHs = false
672674

673675
def emit(i: Instruction) {
674676
instrs += ((pc, i))
@@ -686,6 +688,7 @@ abstract class ICodeReader extends ClassfileParser {
686688

687689
val code = new Code(method)
688690
method.setCode(code)
691+
method.bytecodeHasEHs = containsEHs
689692
var bb = code.startBlock
690693

691694
def makeBasicBlocks: mutable.Map[Int, BasicBlock] =

0 commit comments

Comments
 (0)