bind: replace Java finalizers with PhantomReferences
Android runs a finalizer watchdog that tracks the running time of finalizers and throws an exception if any runs too long. Our finalizers do very little work and as such are not affected by the timeout. However, there has been reports, for example: https://stackoverflow.com/questions/24021609/how-to-handle-java-util-concurrent-timeoutexception-android-os-binderproxy-fin that the watchdog does not take into account periods where the device goes to sleep in the middle of a finalizer run. So if a given app runs in the background, the Java GC starts a finalizer and the device goes to sleep before it returns, an exception will crash the app if the sleep period extends the watchdog timeout. The problem might be fixed on some newer version of Android, but the problem is reported for as late as Android 6. The suggested workaround is to use PhantomReferences and run a background thread that take dead references off a ReferenceQueue and perform cleanup. This CL builds on the previous CL and splits up the Ref class so Refs only reference counts Java objects, while a new class GoRef tracks Go references. The Go references are wrapped in PhantomReferences that in turn appear on a GoRefQueue to be cleaned up by a background (daemon) Thread. Change-Id: I04e3296b851999c612d3baf6a593cc044c2c5bdd Reviewed-on: https://go-review.googlesource.com/106876 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
5b452fe89a
commit
e7d878f9d0
@ -229,9 +229,8 @@ func (g *JavaGen) GenClass(idx int) error {
|
||||
}
|
||||
|
||||
func (g *JavaGen) genProxyImpl(name string) {
|
||||
g.Printf("private final Seq.Ref ref;\n\n")
|
||||
g.Printf("private final int refnum;\n\n")
|
||||
g.Printf("@Override public final int incRefnum() {\n")
|
||||
g.Printf(" int refnum = ref.refnum;\n")
|
||||
g.Printf(" Seq.incGoRef(refnum);\n")
|
||||
g.Printf(" return refnum;\n")
|
||||
g.Printf("}\n\n")
|
||||
@ -303,10 +302,10 @@ func (g *JavaGen) genStruct(s structInfo) {
|
||||
}
|
||||
if jinf == nil || jinf.genNoargCon {
|
||||
// constructor for Go instantiated instances.
|
||||
g.Printf("%s(int refnum) { this.ref = Seq.trackGoRef(refnum); }\n\n", n)
|
||||
g.Printf("%s(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }\n\n", n)
|
||||
if len(cons) == 0 {
|
||||
// Generate default no-arg constructor
|
||||
g.Printf("public %s() { this.ref = Seq.trackGoRef(__New()); }\n\n", n)
|
||||
g.Printf("public %s() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }\n\n", n)
|
||||
g.Printf("private static native int __New();\n\n")
|
||||
}
|
||||
}
|
||||
@ -420,7 +419,7 @@ func (g *JavaGen) genConstructor(f *types.Func, n string, jcls bool) {
|
||||
}
|
||||
g.Printf(");\n")
|
||||
}
|
||||
g.Printf("this.ref = Seq.trackGoRef(")
|
||||
g.Printf("this.refnum = ")
|
||||
g.Printf("__%s(", f.Name())
|
||||
for i := 0; i < params.Len(); i++ {
|
||||
if i > 0 {
|
||||
@ -428,7 +427,8 @@ func (g *JavaGen) genConstructor(f *types.Func, n string, jcls bool) {
|
||||
}
|
||||
g.Printf(g.paramName(params, i))
|
||||
}
|
||||
g.Printf("));\n")
|
||||
g.Printf(");\n")
|
||||
g.Printf("Seq.trackGoRef(refnum, this);\n")
|
||||
g.Outdent()
|
||||
g.Printf("}\n\n")
|
||||
g.Printf("private static native int __%s(", f.Name())
|
||||
@ -1601,7 +1601,7 @@ func (g *JavaGen) GenJava() error {
|
||||
g.Printf(" implements Seq.Proxy, %s {\n", g.javaTypeName(n))
|
||||
g.Indent()
|
||||
g.genProxyImpl("proxy" + n)
|
||||
g.Printf("proxy%s(int refnum) { this.ref = Seq.trackGoRef(refnum); }\n\n", n)
|
||||
g.Printf("proxy%s(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }\n\n", n)
|
||||
|
||||
if isErrorType(iface.obj.Type()) {
|
||||
g.Printf("@Override public String getMessage() { return error(); }\n\n")
|
||||
|
@ -4,8 +4,15 @@
|
||||
|
||||
package go;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import go.Universe;
|
||||
@ -21,6 +28,9 @@ public class Seq {
|
||||
// use single Ref for null Object
|
||||
public static final Ref nullRef = new Ref(NULL_REFNUM, null);
|
||||
|
||||
// The singleton GoRefQueue
|
||||
private static final GoRefQueue goRefQueue = new GoRefQueue();
|
||||
|
||||
static {
|
||||
// Look for the shim class auto-generated by gomobile bind.
|
||||
// Its only purpose is to call System.loadLibrary.
|
||||
@ -66,7 +76,8 @@ public class Seq {
|
||||
return o.incRefnum();
|
||||
}
|
||||
|
||||
// trackGoRef returns a Ref for a Go refnum.
|
||||
// trackGoRef tracks a Go reference and decrements its refcount
|
||||
// when the given GoObject wrapper is garbage collected.
|
||||
//
|
||||
// TODO(crawshaw): We could cut down allocations for frequently
|
||||
// sent Go objects by maintaining a map to weak references. This
|
||||
@ -75,11 +86,11 @@ public class Seq {
|
||||
// of any Java debugging session.
|
||||
//
|
||||
// When we have real code, examine the tradeoffs.
|
||||
public static Ref trackGoRef(int refnum) {
|
||||
public static void trackGoRef(int refnum, GoObject obj) {
|
||||
if (refnum > 0) {
|
||||
throw new RuntimeException("trackGoRef called with Java refnum " + refnum);
|
||||
}
|
||||
return new Ref(refnum, null);
|
||||
goRefQueue.track(refnum, obj);
|
||||
}
|
||||
|
||||
public static Ref getRef(int refnum) {
|
||||
@ -89,7 +100,7 @@ public class Seq {
|
||||
// Increment the Go reference count before sending over a refnum.
|
||||
public static native void incGoRef(int refnum);
|
||||
|
||||
// Informs the Go ref tracker that Java is done with this ref.
|
||||
// Informs the Go ref tracker that Java is done with this refnum.
|
||||
static native void destroyRef(int refnum);
|
||||
|
||||
// decRef is called from seq.FinalizeRef
|
||||
@ -113,23 +124,14 @@ public class Seq {
|
||||
// in Go.
|
||||
public interface Proxy extends GoObject {}
|
||||
|
||||
// A Ref is an object tagged with an integer for passing back and
|
||||
// forth across the language boundary.
|
||||
//
|
||||
// A Ref may represent either an instance of a Java object,
|
||||
// or an instance of a Go object. The explicit allocation of a Ref
|
||||
// is used to pin Go object instances when they are passed to Java.
|
||||
// The Go Seq library maintains a reference to the instance in a map
|
||||
// keyed by the Ref number. When the JVM calls finalize, we ask Go
|
||||
// to clear the entry in the map.
|
||||
// A Ref represents an instance of a Java object passed back and forth
|
||||
// across the language boundary.
|
||||
public static final class Ref {
|
||||
// refnum < 0: Go object tracked by Java
|
||||
// refnum > 0: Java object tracked by Go
|
||||
public final int refnum;
|
||||
|
||||
private int refcnt; // for Java obj: track how many times sent to Go.
|
||||
private int refcnt; // Track how many times sent to Go.
|
||||
|
||||
public final Object obj; // for Java obj: pointers to the Java obj.
|
||||
public final Object obj; // The referenced Java obj.
|
||||
|
||||
Ref(int refnum, Object o) {
|
||||
if (refnum < 0) {
|
||||
@ -140,15 +142,6 @@ public class Seq {
|
||||
this.obj = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (refnum < 0) {
|
||||
// Go object: signal Go to decrement the reference count.
|
||||
Seq.destroyRef(refnum);
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
void inc() {
|
||||
// Count how many times this ref's Java object is passed to Go.
|
||||
if (refcnt == Integer.MAX_VALUE) {
|
||||
@ -256,6 +249,53 @@ public class Seq {
|
||||
}
|
||||
}
|
||||
|
||||
// GoRefQueue is a queue of GoRefs that are no longer live. An internal thread
|
||||
// processes the queue and decrement the reference count on the Go side.
|
||||
static class GoRefQueue extends ReferenceQueue<GoObject> {
|
||||
// The set of tracked GoRefs. If we don't hold on to the GoRef instances, the Java GC
|
||||
// will not add them to the queue when their referents are reclaimed.
|
||||
private final Collection<GoRef> refs = Collections.synchronizedCollection(new HashSet<GoRef>());
|
||||
|
||||
void track(int refnum, GoObject obj) {
|
||||
refs.add(new GoRef(refnum, obj, this));
|
||||
}
|
||||
|
||||
GoRefQueue() {
|
||||
Thread daemon = new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
GoRef ref = (GoRef)remove();
|
||||
refs.remove(ref);
|
||||
destroyRef(ref.refnum);
|
||||
ref.clear();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
daemon.setDaemon(true);
|
||||
daemon.setName("GoRefQueue Finalizer Thread");
|
||||
daemon.start();
|
||||
}
|
||||
}
|
||||
|
||||
// A GoRef is a PhantomReference to a Java proxy for a Go object.
|
||||
// GoRefs are enqueued to the singleton GoRefQueue when no longer live,
|
||||
// so the corresponding reference count can be decremented.
|
||||
static class GoRef extends PhantomReference<GoObject> {
|
||||
final int refnum;
|
||||
|
||||
GoRef(int refnum, GoObject obj, GoRefQueue q) {
|
||||
super(obj, q);
|
||||
if (refnum > 0) {
|
||||
throw new RuntimeException("GoRef instantiated with a Java refnum " + refnum);
|
||||
}
|
||||
this.refnum = refnum;
|
||||
}
|
||||
}
|
||||
|
||||
// RefMap is a mapping of integers to Ref objects.
|
||||
//
|
||||
// The integers can be sparse. In Go this would be a map[int]*Ref.
|
||||
|
27
bind/testdata/classes.java.golden
vendored
27
bind/testdata/classes.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class Future implements Seq.GoObject, java.util.concurrent.Future {
|
||||
static { Java.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
Future(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
Future(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public Future() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public Future() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -44,17 +43,17 @@ import go.Seq;
|
||||
public final class InputStream extends java.io.InputStream implements Seq.GoObject {
|
||||
static { Java.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
public InputStream() {
|
||||
super();
|
||||
this.ref = Seq.trackGoRef(__NewInputStream());
|
||||
this.refnum = __NewInputStream();
|
||||
Seq.trackGoRef(refnum, this);
|
||||
}
|
||||
|
||||
private static native int __NewInputStream();
|
||||
@ -76,17 +75,16 @@ import go.Seq;
|
||||
public final class Object extends java.lang.Object implements Seq.GoObject {
|
||||
static { Java.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
Object(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
Object(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public Object() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public Object() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -106,17 +104,16 @@ import go.Seq;
|
||||
public final class Runnable implements Seq.GoObject, java.lang.Runnable {
|
||||
static { Java.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
Runnable(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
Runnable(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public Runnable() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public Runnable() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
|
27
bind/testdata/doc.java.golden
vendored
27
bind/testdata/doc.java.golden
vendored
@ -12,17 +12,16 @@ import go.Seq;
|
||||
public final class NoDoc implements Seq.Proxy {
|
||||
static { Doc.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
NoDoc(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
NoDoc(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public NoDoc() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public NoDoc() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -59,10 +58,9 @@ import go.Seq;
|
||||
public final class S implements Seq.Proxy {
|
||||
static { Doc.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
@ -71,12 +69,13 @@ public final class S implements Seq.Proxy {
|
||||
* NewS is a constructor.
|
||||
*/
|
||||
public S() {
|
||||
this.ref = Seq.trackGoRef(__NewS());
|
||||
this.refnum = __NewS();
|
||||
Seq.trackGoRef(refnum, this);
|
||||
}
|
||||
|
||||
private static native int __NewS();
|
||||
|
||||
S(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
/**
|
||||
* SF is a field.
|
||||
@ -192,17 +191,16 @@ import go.Seq;
|
||||
public final class S2 implements Seq.Proxy {
|
||||
static { Doc.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
S2(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S2(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public S2() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public S2() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -266,15 +264,14 @@ public abstract class Doc {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyI implements Seq.Proxy, I {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void im();
|
||||
}
|
||||
|
12
bind/testdata/ignore.java.golden
vendored
12
bind/testdata/ignore.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class S implements Seq.Proxy, I {
|
||||
static { Ignore.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
S(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public S() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public S() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -88,15 +87,14 @@ public abstract class Ignore {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyI implements Seq.Proxy, I {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
// skipped method I.Argument with unsupported parameter or return types
|
||||
|
||||
|
45
bind/testdata/interfaces.java.golden
vendored
45
bind/testdata/interfaces.java.golden
vendored
@ -151,120 +151,111 @@ public abstract class Interfaces {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyError implements Seq.Proxy, Error {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyError(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyError(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void err() throws Exception;
|
||||
}
|
||||
private static final class proxyI implements Seq.Proxy, I {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native int rand();
|
||||
}
|
||||
private static final class proxyI1 implements Seq.Proxy, I1 {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI1(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI1(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void j();
|
||||
}
|
||||
private static final class proxyI2 implements Seq.Proxy, I2 {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI2(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI2(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void g();
|
||||
}
|
||||
private static final class proxyI3 implements Seq.Proxy, I3 {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI3(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI3(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native I1 f();
|
||||
}
|
||||
private static final class proxyInterfaces implements Seq.Proxy, Interfaces_ {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyInterfaces(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyInterfaces(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void someMethod();
|
||||
}
|
||||
private static final class proxyLargerI implements Seq.Proxy, LargerI {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyLargerI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyLargerI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void anotherFunc();
|
||||
public native int rand();
|
||||
}
|
||||
private static final class proxySameI implements Seq.Proxy, SameI {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxySameI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxySameI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native int rand();
|
||||
}
|
||||
private static final class proxyWithParam implements Seq.Proxy, WithParam {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyWithParam(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyWithParam(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void hasParam(boolean p0);
|
||||
}
|
||||
|
12
bind/testdata/issue10788.java.golden
vendored
12
bind/testdata/issue10788.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class TestStruct implements Seq.Proxy {
|
||||
static { Issue10788.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
TestStruct(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
TestStruct(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public TestStruct() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public TestStruct() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -91,15 +90,14 @@ public abstract class Issue10788 {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyTestInterface implements Seq.Proxy, TestInterface {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyTestInterface(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyTestInterface(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void doSomeWork(TestStruct s);
|
||||
public native void multipleUnnamedParams(long p0, String p1, long p2);
|
||||
|
7
bind/testdata/issue12328.java.golden
vendored
7
bind/testdata/issue12328.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class T implements Seq.Proxy {
|
||||
static { Issue12328.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
T(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
T(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public T() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public T() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
|
5
bind/testdata/issue12403.java.golden
vendored
5
bind/testdata/issue12403.java.golden
vendored
@ -34,15 +34,14 @@ public abstract class Issue12403 {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyParsable implements Seq.Proxy, Parsable {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyParsable(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyParsable(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String fromJSON(String jstr);
|
||||
public native String toJSON() throws Exception;
|
||||
|
25
bind/testdata/java.java.golden
vendored
25
bind/testdata/java.java.golden
vendored
@ -84,66 +84,61 @@ public abstract class Java {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyF implements Seq.Proxy, F {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyF(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyF(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String toString();
|
||||
}
|
||||
private static final class proxyL implements Seq.Proxy, L {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyL(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyL(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String toString();
|
||||
}
|
||||
private static final class proxyO implements Seq.Proxy, O {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyO(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyO(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String toString();
|
||||
}
|
||||
private static final class proxyR implements Seq.Proxy, R {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyR(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyR(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
}
|
||||
private static final class proxyS implements Seq.Proxy, S {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyS(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyS(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String toString();
|
||||
}
|
||||
|
5
bind/testdata/keywords.java.golden
vendored
5
bind/testdata/keywords.java.golden
vendored
@ -87,15 +87,14 @@ public abstract class Keywords {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyKeywordCaller implements Seq.Proxy, KeywordCaller {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyKeywordCaller(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyKeywordCaller(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void abstract_();
|
||||
public native void assert_();
|
||||
|
26
bind/testdata/structs.java.golden
vendored
26
bind/testdata/structs.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class S implements Seq.Proxy {
|
||||
static { Structs.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
S(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public S() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public S() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -73,17 +72,16 @@ import go.Seq;
|
||||
public final class S2 implements Seq.Proxy, I {
|
||||
static { Structs.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
S2(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S2(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public S2() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public S2() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -117,17 +115,16 @@ import go.Seq;
|
||||
public final class Structs_ implements Seq.Proxy, I {
|
||||
static { Structs.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
Structs_(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
Structs_(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public Structs_() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public Structs_() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -186,15 +183,14 @@ public abstract class Structs {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyI implements Seq.Proxy, I {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native void m();
|
||||
}
|
||||
|
7
bind/testdata/underscores.java.golden
vendored
7
bind/testdata/underscores.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class Underscore_struct implements Seq.Proxy {
|
||||
static { Underscore_pkg.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
Underscore_struct(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
Underscore_struct(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public Underscore_struct() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public Underscore_struct() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
|
5
bind/testdata/universe.java.golden
vendored
5
bind/testdata/universe.java.golden
vendored
@ -33,15 +33,14 @@ public abstract class Universe {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyerror extends Exception implements Seq.Proxy, error {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyerror(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyerror(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
@Override public String getMessage() { return error(); }
|
||||
|
||||
|
12
bind/testdata/vars.java.golden
vendored
12
bind/testdata/vars.java.golden
vendored
@ -9,17 +9,16 @@ import go.Seq;
|
||||
public final class S implements Seq.Proxy, I {
|
||||
static { Vars.touch(); }
|
||||
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
S(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
S(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public S() { this.ref = Seq.trackGoRef(__New()); }
|
||||
public S() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
|
||||
|
||||
private static native int __New();
|
||||
|
||||
@ -76,15 +75,14 @@ public abstract class Vars {
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyI implements Seq.Proxy, I {
|
||||
private final Seq.Ref ref;
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyI(int refnum) { this.ref = Seq.trackGoRef(refnum); }
|
||||
proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user