mirror of
https://github.com/netbirdio/gomobile-tvos-fork.git
synced 2026-05-22 18:43:29 -07:00
mobile/bind: fix RefMap invariant
RefMap tracks its number of live Ref instances in the 'live' member. However, when a reference was removed and later added, 'live' wasn't updated accordingly. Fix and add a test. Change-Id: I806e17ea0319d76db4d07b5f8d9107b146ee80db Reviewed-on: https://go-review.googlesource.com/19975 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
+5
-4
@@ -154,7 +154,7 @@ public class Seq {
|
||||
|
||||
public Seq.Object obj; // for Java obj: pointers to the Java obj.
|
||||
|
||||
private Ref(int refnum, Seq.Object o) {
|
||||
Ref(int refnum, Seq.Object o) {
|
||||
this.refnum = refnum;
|
||||
this.refcnt = 0;
|
||||
this.obj = o;
|
||||
@@ -281,7 +281,7 @@ public class Seq {
|
||||
// RefMap is a mapping of integers to Ref objects.
|
||||
//
|
||||
// The integers can be sparse. In Go this would be a map[int]*Ref.
|
||||
private static final class RefMap {
|
||||
static final class RefMap {
|
||||
private int next = 0;
|
||||
private int live = 0;
|
||||
private int[] keys = new int[16];
|
||||
@@ -315,6 +315,7 @@ public class Seq {
|
||||
if (i >= 0) {
|
||||
if (objs[i] == null) {
|
||||
objs[i] = obj;
|
||||
live++;
|
||||
}
|
||||
if (objs[i] != obj) {
|
||||
throw new RuntimeException("replacing an existing ref (with key "+key+")");
|
||||
@@ -337,7 +338,7 @@ public class Seq {
|
||||
next++;
|
||||
}
|
||||
|
||||
private void grow() {
|
||||
private void grow() {
|
||||
// Compact and (if necessary) grow backing store.
|
||||
int[] newKeys;
|
||||
Ref[] newObjs;
|
||||
@@ -370,7 +371,7 @@ public class Seq {
|
||||
if (live != next) {
|
||||
throw new RuntimeException("bad state: live="+live+", next="+next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int roundPow2(int x) {
|
||||
int p = 1;
|
||||
|
||||
@@ -33,6 +33,22 @@ public class SeqTest extends InstrumentationTestCase {
|
||||
assertEquals("const Log2E", 1/0.693147180559945309417232121458176568075500134360255254120680009, Testpkg.Log2E, 0.0001);
|
||||
}
|
||||
|
||||
public void testRefMap() {
|
||||
// Ensure that the RefMap.live count is kept in sync
|
||||
// even a particular reference number is removed and
|
||||
// added again
|
||||
Seq.RefMap m = new Seq.RefMap();
|
||||
Seq.Ref r = new Seq.Ref(1, null);
|
||||
m.put(r.refnum, r);
|
||||
m.remove(r.refnum);
|
||||
m.put(r.refnum, r);
|
||||
// Force the RefMap to grow, to activate the sanity
|
||||
// checking of the live count in RefMap.grow.
|
||||
for (int i = 2; i < 24; i++) {
|
||||
m.put(i, new Seq.Ref(i, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void testVar() {
|
||||
assertEquals("var StringVar", "a string var", Testpkg.getStringVar());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user