Skip to content

Commit

Permalink
Moving the GC related parts of RefTest to ManagedResourceTest
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Nov 28, 2024
1 parent 2e91135 commit 786f156
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package org.enso.interpreter.runtime;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import org.enso.common.MethodNames;
import org.enso.test.utils.ContextUtils;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class ManagedResourceTest {
private static Context ctx;
private static EnsoContext ensoCtx;
private static Value newRef;
private static Value createRef;
private static Value getRef;
private static Value finalizeRef;

@BeforeClass
public static void initCtx() throws Exception {
ctx = ContextUtils.createDefaultContext();
ensoCtx = ContextUtils.leakContext(ctx);
var code =
"""
import Standard.Base.Runtime.Managed_Resource.Managed_Resource
new_ref obj =
Managed_Resource.register obj (_->0)
create_ref obj system_resource =
Managed_Resource.register obj (_->0) system_resource
get_ref ref = ref.with it->
it
finalize_ref ref = ref.finalize
""";
var src = Source.newBuilder("enso", code, "gc.enso").build();
var gcEnso = ctx.eval(src);
newRef = gcEnso.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "new_ref");
createRef = gcEnso.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create_ref");
getRef = gcEnso.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "get_ref");
finalizeRef = gcEnso.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "finalize_ref");
}

@AfterClass
public static void closeCtx() throws Exception {
ctx.close();
ctx = null;
}

@Test
public void regularReference() throws Exception {
var obj = new Object();
var ref = newRef.execute(obj);

assertFalse("Value returned", ref.isNull());
assertEquals(
"Standard.Base.Runtime.Managed_Resource.Managed_Resource",
ref.getMetaObject().getMetaQualifiedName());

var weakRef = new WeakReference<>(obj);
obj = null;

assertEquals("We get the object", weakRef.get(), getRef.execute(ref).asHostObject());

assertGC("Weak wasn't released", false, weakRef);
assertFalse("Value was not GCed", getRef.execute(ref).isNull());
assertEquals("We get the object", weakRef.get(), getRef.execute(ref).asHostObject());

ensoCtx.getResourceManager().scheduleFinalization();
assertEquals(
"scheduleFinalization has no effect on regular reference",
weakRef.get(),
getRef.execute(ref).asHostObject());
}

@Test
public void explicitlyReclaimableReference() throws Exception {
var obj = new Object();
var ref = createRef.execute(obj, true);

assertFalse("Value returned", ref.isNull());
assertEquals(
"Standard.Base.Runtime.Managed_Resource.Managed_Resource",
ref.getMetaObject().getMetaQualifiedName());
assertEquals("We get the object", obj, getRef.execute(ref).asHostObject());

ensoCtx.getResourceManager().scheduleFinalization();

assertTrue("Value was GCed", getRef.execute(ref).isNull());
}

private static void assertGC(String msg, boolean expectGC, Reference<?> ref) {
for (var i = 1; i < Integer.MAX_VALUE / 2; i *= 2) {
if (ref.get() == null) {
break;
}
System.gc();
}
var obj = ref.get();
if (expectGC) {
assertNull(msg + " ref still alive", obj);
} else {
assertNotNull(msg + " ref has been cleaned", obj);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
Expand Down Expand Up @@ -77,36 +76,6 @@ public void regularReference() throws Exception {
getRef.execute(ref).asHostObject());
}

@Test
public void garbageCollectableReference() throws Exception {
var obj = new Object();
var ref = createRef.execute(obj, true);

assertFalse("Value returned", ref.isNull());
assertEquals("Standard.Base.Runtime.Ref.Ref", ref.getMetaObject().getMetaQualifiedName());
assertEquals("We get the object", obj, getRef.execute(ref).asHostObject());

var weakRef = new WeakReference<>(obj);
obj = null;
assertGC("Weak reference can be GCed", true, weakRef);

assertTrue("Value was GCed", getRef.execute(ref).isNull());
}

@Test
public void explicitlyReclaimableReference() throws Exception {
var obj = new Object();
var ref = createRef.execute(obj, true);

assertFalse("Value returned", ref.isNull());
assertEquals("Standard.Base.Runtime.Ref.Ref", ref.getMetaObject().getMetaQualifiedName());
assertEquals("We get the object", obj, getRef.execute(ref).asHostObject());

// ensoCtx.getReferencesManager().releaseAll();

assertTrue("Value was GCed", getRef.execute(ref).isNull());
}

private static void assertGC(String msg, boolean expectGC, Reference<?> ref) {
for (var i = 1; i < Integer.MAX_VALUE / 2; i *= 2) {
if (ref.get() == null) {
Expand Down

0 comments on commit 786f156

Please sign in to comment.