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 <hyangah@gmail.com>
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) 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 @@
 	}
 
 	// 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 @@
 }
 
 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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -46,7 +46,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -78,7 +78,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -107,7 +107,7 @@
     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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -61,7 +61,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -194,7 +194,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -267,7 +267,7 @@
         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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -90,7 +90,7 @@
         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 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -166,7 +166,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -178,7 +178,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -190,7 +190,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -202,7 +202,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -214,7 +214,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -226,7 +226,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -239,7 +239,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -251,7 +251,7 @@
         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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -93,7 +93,7 @@
         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 @@
     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 @@
         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 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -99,7 +99,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -111,7 +111,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -123,7 +123,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }
         
@@ -134,7 +134,7 @@
         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 @@
         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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -75,7 +75,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -118,7 +118,7 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -186,7 +186,7 @@
         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 @@
     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 @@
         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 @@
     private final int refnum;
     
     @Override public final int incRefnum() {
-          Seq.incGoRef(refnum);
+          Seq.incGoRef(refnum, this);
           return refnum;
     }
     
@@ -78,7 +78,7 @@
         private final int refnum;
         
         @Override public final int incRefnum() {
-              Seq.incGoRef(refnum);
+              Seq.incGoRef(refnum, this);
               return refnum;
         }