From 60d29bfb46d1487e59f38e7f377e86159b492aa4 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 14 Apr 2018 12:55:03 +0200 Subject: [PATCH] bind: pin Go objects while incrementing their reference count When passing a refnum across the language barrier there is a small window where a proxy object itself can be garbage collected, its reference count go to 0 and the object be gone when the refnum is dereferenced on the other side. In Go the proxy object is pinned with runtime.KeepAlive. This CL implements the same mechanism in Java by passing the proxy object to native code, ensuring the Java GC can't reclaim it during the call. Change-Id: I23824439012eb00f90d729f59d4846999f24f01f Reviewed-on: https://go-review.googlesource.com/107095 Reviewed-by: Hyang-Ah Hana Kim --- bind/genjava.go | 2 +- bind/java/Seq.java | 5 ++++- bind/java/seq_android.c.support | 2 +- bind/testdata/classes.java.golden | 8 ++++---- bind/testdata/doc.java.golden | 8 ++++---- bind/testdata/ignore.java.golden | 4 ++-- bind/testdata/interfaces.java.golden | 18 +++++++++--------- bind/testdata/issue10788.java.golden | 4 ++-- bind/testdata/issue12328.java.golden | 2 +- bind/testdata/issue12403.java.golden | 2 +- bind/testdata/java.java.golden | 10 +++++----- bind/testdata/keywords.java.golden | 2 +- bind/testdata/structs.java.golden | 8 ++++---- bind/testdata/underscores.java.golden | 2 +- bind/testdata/universe.java.golden | 2 +- bind/testdata/vars.java.golden | 4 ++-- 16 files changed, 43 insertions(+), 40 deletions(-) diff --git a/bind/genjava.go b/bind/genjava.go index d6d7f26..633f9aa 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -231,7 +231,7 @@ func (g *JavaGen) GenClass(idx int) error { func (g *JavaGen) genProxyImpl(name string) { g.Printf("private final int refnum;\n\n") g.Printf("@Override public final int incRefnum() {\n") - g.Printf(" Seq.incGoRef(refnum);\n") + g.Printf(" Seq.incGoRef(refnum, this);\n") g.Printf(" return refnum;\n") g.Printf("}\n\n") } diff --git a/bind/java/Seq.java b/bind/java/Seq.java index 8d0a8b0..cb77dd0 100644 --- a/bind/java/Seq.java +++ b/bind/java/Seq.java @@ -98,7 +98,10 @@ public class Seq { } // Increment the Go reference count before sending over a refnum. - public static native void incGoRef(int refnum); + // The ref parameter is only used to make sure the referenced + // object is not garbage collected before Go increments the + // count. It's the equivalent of Go's runtime.KeepAlive. + public static native void incGoRef(int refnum, GoObject ref); // Informs the Go ref tracker that Java is done with this refnum. static native void destroyRef(int refnum); diff --git a/bind/java/seq_android.c.support b/bind/java/seq_android.c.support index c4fafc2..77ec5f4 100644 --- a/bind/java/seq_android.c.support +++ b/bind/java/seq_android.c.support @@ -350,7 +350,7 @@ Java_go_Seq_destroyRef(JNIEnv *env, jclass clazz, jint refnum) { } JNIEXPORT void JNICALL -Java_go_Seq_incGoRef(JNIEnv *env, jclass clazz, jint refnum) { +Java_go_Seq_incGoRef(JNIEnv *env, jclass clazz, jint refnum, jobject ref) { IncGoRef(refnum); } diff --git a/bind/testdata/classes.java.golden b/bind/testdata/classes.java.golden index 200a317..44c6ca9 100644 --- a/bind/testdata/classes.java.golden +++ b/bind/testdata/classes.java.golden @@ -12,7 +12,7 @@ public final class Future implements Seq.GoObject, java.util.concurrent.Future { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -46,7 +46,7 @@ public final class InputStream extends java.io.InputStream implements Seq.GoObje private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -78,7 +78,7 @@ public final class Object extends java.lang.Object implements Seq.GoObject { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -107,7 +107,7 @@ public final class Runnable implements Seq.GoObject, java.lang.Runnable { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/doc.java.golden b/bind/testdata/doc.java.golden index 2a94563..8a2ac77 100644 --- a/bind/testdata/doc.java.golden +++ b/bind/testdata/doc.java.golden @@ -15,7 +15,7 @@ public final class NoDoc implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -61,7 +61,7 @@ public final class S implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -194,7 +194,7 @@ public final class S2 implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -267,7 +267,7 @@ public abstract class Doc { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/ignore.java.golden b/bind/testdata/ignore.java.golden index 09acc5a..df327a0 100644 --- a/bind/testdata/ignore.java.golden +++ b/bind/testdata/ignore.java.golden @@ -12,7 +12,7 @@ public final class S implements Seq.Proxy, I { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -90,7 +90,7 @@ public abstract class Ignore { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/interfaces.java.golden b/bind/testdata/interfaces.java.golden index fece954..a25fb29 100644 --- a/bind/testdata/interfaces.java.golden +++ b/bind/testdata/interfaces.java.golden @@ -154,7 +154,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -166,7 +166,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -178,7 +178,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -190,7 +190,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -202,7 +202,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -214,7 +214,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -226,7 +226,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -239,7 +239,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -251,7 +251,7 @@ public abstract class Interfaces { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/issue10788.java.golden b/bind/testdata/issue10788.java.golden index 82ea13e..29191c5 100644 --- a/bind/testdata/issue10788.java.golden +++ b/bind/testdata/issue10788.java.golden @@ -12,7 +12,7 @@ public final class TestStruct implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -93,7 +93,7 @@ public abstract class Issue10788 { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/issue12328.java.golden b/bind/testdata/issue12328.java.golden index 27acc7e..7b24a59 100644 --- a/bind/testdata/issue12328.java.golden +++ b/bind/testdata/issue12328.java.golden @@ -12,7 +12,7 @@ public final class T implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/issue12403.java.golden b/bind/testdata/issue12403.java.golden index 231f6a3..31aef58 100644 --- a/bind/testdata/issue12403.java.golden +++ b/bind/testdata/issue12403.java.golden @@ -37,7 +37,7 @@ public abstract class Issue12403 { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/java.java.golden b/bind/testdata/java.java.golden index c47beba..e905d43 100644 --- a/bind/testdata/java.java.golden +++ b/bind/testdata/java.java.golden @@ -87,7 +87,7 @@ public abstract class Java { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -99,7 +99,7 @@ public abstract class Java { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -111,7 +111,7 @@ public abstract class Java { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -123,7 +123,7 @@ public abstract class Java { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -134,7 +134,7 @@ public abstract class Java { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/keywords.java.golden b/bind/testdata/keywords.java.golden index df30f41..e2c744a 100644 --- a/bind/testdata/keywords.java.golden +++ b/bind/testdata/keywords.java.golden @@ -90,7 +90,7 @@ public abstract class Keywords { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/structs.java.golden b/bind/testdata/structs.java.golden index fad0c5f..d8a8006 100644 --- a/bind/testdata/structs.java.golden +++ b/bind/testdata/structs.java.golden @@ -12,7 +12,7 @@ public final class S implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -75,7 +75,7 @@ public final class S2 implements Seq.Proxy, I { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -118,7 +118,7 @@ public final class Structs_ implements Seq.Proxy, I { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -186,7 +186,7 @@ public abstract class Structs { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/underscores.java.golden b/bind/testdata/underscores.java.golden index 4fa14cd..58c64d0 100644 --- a/bind/testdata/underscores.java.golden +++ b/bind/testdata/underscores.java.golden @@ -12,7 +12,7 @@ public final class Underscore_struct implements Seq.Proxy { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/universe.java.golden b/bind/testdata/universe.java.golden index f1578c4..e7d21c2 100644 --- a/bind/testdata/universe.java.golden +++ b/bind/testdata/universe.java.golden @@ -36,7 +36,7 @@ public abstract class Universe { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } diff --git a/bind/testdata/vars.java.golden b/bind/testdata/vars.java.golden index 7b22a1d..f92423f 100644 --- a/bind/testdata/vars.java.golden +++ b/bind/testdata/vars.java.golden @@ -12,7 +12,7 @@ public final class S implements Seq.Proxy, I { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; } @@ -78,7 +78,7 @@ public abstract class Vars { private final int refnum; @Override public final int incRefnum() { - Seq.incGoRef(refnum); + Seq.incGoRef(refnum, this); return refnum; }