KT-5248 Don't wrap variable if it is captured only in inlined closures

Remove non-escaping Ref's on bytecode postprocessing pass.
This commit is contained in:
Dmitry Petrov
2017-01-31 15:43:17 +03:00
parent 3fc106572e
commit 3c09a26e16
38 changed files with 1115 additions and 26 deletions

View File

@@ -0,0 +1,16 @@
// WITH_RUNTIME
fun test() {
var x = 0
run {
run {
run {
++x
}
}
}
}
// 0 NEW
// 0 GETFIELD
// 0 PUTFIELD

View File

@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun test() {
var x = 0
run { ++x }
}
// 0 NEW
// 0 GETFIELD
// 0 PUTFIELD

View File

@@ -0,0 +1,15 @@
// WITH_RUNTIME
fun test() {
var x = 0
run {
val obj = object {
fun foo() { ++x }
}
obj.foo()
}
}
// 1 NEW kotlin/jvm/internal/Ref\$IntRef
// 2 GETFIELD kotlin/jvm/internal/Ref\$IntRef\.element
// 2 PUTFIELD kotlin/jvm/internal/Ref\$IntRef\.element

View File

@@ -0,0 +1,12 @@
// WITH_RUNTIME
fun runNoInline(f: () -> Unit) = f()
fun test() {
var x = 0
runNoInline { ++x }
}
// 1 NEW kotlin/jvm/internal/Ref\$IntRef
// 2 GETFIELD kotlin/jvm/internal/Ref\$IntRef\.element
// 2 PUTFIELD kotlin/jvm/internal/Ref\$IntRef\.element

View File

@@ -0,0 +1,20 @@
// WITH_RUNTIME
fun runNoInline(f: () -> Unit) = f()
fun test() {
var x = 0
run {
run {
runNoInline {
run {
++x
}
}
}
}
}
// 1 NEW kotlin/jvm/internal/Ref\$IntRef
// 2 GETFIELD kotlin/jvm/internal/Ref\$IntRef\.element
// 2 PUTFIELD kotlin/jvm/internal/Ref\$IntRef\.element

View File

@@ -0,0 +1,25 @@
// WITH_RUNTIME
fun box(): String {
var xl = 0L // Long, size 2
var xi = 0 // Int, size 1
var xd = 0.0 // Double, size 2
run {
xl++
xd += 1.0
xi++
}
run {
run {
xl++
xd += 1.0
xi++
}
}
return "OK"
}
// 0 NEW

View File

@@ -0,0 +1,32 @@
// WITH_RUNTIME
fun box(): String {
run {
run {
var x1 = 0
run { ++x1 }
if (x1 == 0) return "fail"
}
run {
var x2 = 0
run { x2++ }
if (x2 == 0) return "fail"
}
}
return "OK"
}
// Shared variable slots (x1, x2):
// 5 ILOAD 0
// 4 ISTORE 0
// Temporary variable slots for 'x2++':
// 1 ILOAD 1
// 1 ISTORE 1
// 0 NEW
// 0 GETFIELD
// 0 PUTFIELD

View File

@@ -0,0 +1,14 @@
// WITH_RUNTIME
fun add(x: Int, y: Int) = x + y
fun test() {
var x = 0
run {
x += add(1, try { 1 } catch (e: Throwable) { 42 })
}
}
// 0 NEW
// 0 GETFIELD
// 0 PUTFIELD