Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.oracle.truffle.api.test.SubprocessTestUtils;
import org.graalvm.collections.Pair;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;
import org.graalvm.polyglot.Instrument;
Expand Down Expand Up @@ -1010,27 +1012,43 @@ private static void checkResolvedSourceSection(SourceSection sourceSection, int
}

@Test
public void testDebuggedSourcesCanBeReleasedAbsolute() {
testDebuggedSourcesCanBeReleased(() -> {
return Source.newBuilder(InstrumentationTestLanguage.ID, "STATEMENT", "file").cached(false).buildLiteral();
public void testDebuggedSourcesCanBeReleasedAbsolute() throws IOException, InterruptedException {
runInSubprocess(() -> {
testDebuggedSourcesCanBeReleased(() -> {
return Source.newBuilder(InstrumentationTestLanguage.ID, "STATEMENT", "file").cached(false).buildLiteral();
});
});
}

@Test
public void testDebuggedSourcesCanBeReleasedRelative() throws IOException {
String sourceContent = "\n relative source\nVarA";
String relativePath = "relative/test.file";
Path testSourcePath = Files.createTempDirectory("testPath").toRealPath();
Files.createDirectory(testSourcePath.resolve("relative"));
Path filePath = testSourcePath.resolve(relativePath);
Files.write(filePath, sourceContent.getBytes());
testDebuggedSourcesCanBeReleased(() -> {
TestDebugNoContentLanguage language = new TestDebugNoContentLanguage(relativePath, true, true);
ProxyLanguage.setDelegate(language);
return Source.newBuilder(ProxyLanguage.ID, sourceContent, "file").cached(false).buildLiteral();
public void testDebuggedSourcesCanBeReleasedRelative() throws IOException, InterruptedException {
runInSubprocess(() -> {
String sourceContent = "\n relative source\nVarA";
String relativePath = "relative/test.file";
try {
Path testSourcePath = Files.createTempDirectory("testPath").toRealPath();
Files.createDirectory(testSourcePath.resolve("relative"));
Path filePath = testSourcePath.resolve(relativePath);
Files.write(filePath, sourceContent.getBytes());
} catch (IOException ioe) {
throw new AssertionError(ioe);
}
testDebuggedSourcesCanBeReleased(() -> {
TestDebugNoContentLanguage language = new TestDebugNoContentLanguage(relativePath, true, true);
ProxyLanguage.setDelegate(language);
return Source.newBuilder(ProxyLanguage.ID, sourceContent, "file").cached(false).buildLiteral();
});
});
}

private static void runInSubprocess(Runnable runnable) throws IOException, InterruptedException {
if (ImageInfo.inImageCode()) {
runnable.run();
} else {
SubprocessTestUtils.newBuilder(DebuggerSessionTest.class, runnable).run();
}
}

private void testDebuggedSourcesCanBeReleased(Supplier<Source> sourceFactory) {
try (DebuggerSession session = tester.startSession()) {
GCUtils.assertObjectsCollectible(iteration -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@

import static org.junit.Assert.assertNotNull;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.Semaphore;

import com.oracle.truffle.api.test.SubprocessTestUtils;
import org.graalvm.nativeimage.ImageInfo;
import org.junit.Test;

import com.oracle.truffle.api.CompilerDirectives;
Expand Down Expand Up @@ -73,13 +76,23 @@
public class WeakCachedTest extends AbstractPolyglotTest {

@Test
public void testWeakSimpleNode() {
WeakSimpleNode node = WeakSimpleNodeGen.create();
Object o = new String("");
WeakReference<Object> ref = new WeakReference<>(o);
node.execute(o);
o = null;
GCUtils.assertGc("Reference is not collected", ref);
public void testWeakSimpleNode() throws IOException, InterruptedException {
runInSubprocess(() -> {
WeakSimpleNode node = WeakSimpleNodeGen.create();
Object o = new String("");
WeakReference<Object> ref = new WeakReference<>(o);
node.execute(o);
o = null;
GCUtils.assertGc("Reference is not collected", ref);
});
}

private static void runInSubprocess(Runnable runnable) throws IOException, InterruptedException {
if (ImageInfo.inImageCode()) {
runnable.run();
} else {
SubprocessTestUtils.newBuilder(WeakCachedTest.class, runnable).run();
}
}

@GenerateUncached
Expand All @@ -96,26 +109,28 @@ Object s0(String arg,
}

@Test
public void testWeakInlineCache() {
WeakInlineCacheNode node = WeakInlineCacheNodeGen.create();
Object o0 = new String("");
Object o1 = new String("");
Object o2 = new String("");
WeakReference<Object> ref0 = new WeakReference<>(o0);
WeakReference<Object> ref1 = new WeakReference<>(o1);
WeakReference<Object> ref2 = new WeakReference<>(o2);
node.execute(o0);
node.execute(o1);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref0);

node.execute(o1);
node.execute(o2);
o1 = null;
o2 = null;
GCUtils.assertGc("Reference is not collected", List.of(ref1, ref2));

assertFails(() -> node.execute(new String("")), UnsupportedSpecializationException.class);
public void testWeakInlineCache() throws IOException, InterruptedException {
runInSubprocess(() -> {
WeakInlineCacheNode node = WeakInlineCacheNodeGen.create();
Object o0 = new String("");
Object o1 = new String("");
Object o2 = new String("");
WeakReference<Object> ref0 = new WeakReference<>(o0);
WeakReference<Object> ref1 = new WeakReference<>(o1);
WeakReference<Object> ref2 = new WeakReference<>(o2);
node.execute(o0);
node.execute(o1);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref0);

node.execute(o1);
node.execute(o2);
o1 = null;
o2 = null;
GCUtils.assertGc("Reference is not collected", List.of(ref1, ref2));

assertFails(() -> node.execute(new String("")), UnsupportedSpecializationException.class);
});
}

@GenerateUncached
Expand All @@ -133,26 +148,28 @@ Object s0(String arg,
}

@Test
public void testWeakCachedLibrary() {
WeakCachedLibraryNode node = adoptNode(WeakCachedLibraryNodeGen.create()).get();
Object o0 = new String("");
Object o1 = new String("");
Object o2 = new String("");
WeakReference<Object> ref0 = new WeakReference<>(o0);
WeakReference<Object> ref1 = new WeakReference<>(o1);
WeakReference<Object> ref2 = new WeakReference<>(o2);
node.execute(o0);
node.execute(o1);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref0);

node.execute(o1);
node.execute(o2);
o1 = null;
o2 = null;
GCUtils.assertGc("Reference is not collected", List.of(ref1, ref2));

assertFails(() -> node.execute(new String("")), UnsupportedSpecializationException.class);
public void testWeakCachedLibrary() throws InterruptedException, IOException {
runInSubprocess(() -> {
WeakCachedLibraryNode node = adoptNode(WeakCachedLibraryNodeGen.create()).get();
Object o0 = new String("");
Object o1 = new String("");
Object o2 = new String("");
WeakReference<Object> ref0 = new WeakReference<>(o0);
WeakReference<Object> ref1 = new WeakReference<>(o1);
WeakReference<Object> ref2 = new WeakReference<>(o2);
node.execute(o0);
node.execute(o1);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref0);

node.execute(o1);
node.execute(o2);
o1 = null;
o2 = null;
GCUtils.assertGc("Reference is not collected", List.of(ref1, ref2));

assertFails(() -> node.execute(new String("")), UnsupportedSpecializationException.class);
});
}

@GenerateUncached
Expand Down Expand Up @@ -181,14 +198,16 @@ Object s0replace(String arg) {
}

@Test
public void testWeakSharedNode() {
WeakSharedCacheNode node = WeakSharedCacheNodeGen.create();
Object o0 = new String("");
WeakReference<Object> ref1 = new WeakReference<>(o0);
node.execute(o0, false);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref1);
node.execute("", false);
public void testWeakSharedNode() throws IOException, InterruptedException {
runInSubprocess(() -> {
WeakSharedCacheNode node = WeakSharedCacheNodeGen.create();
Object o0 = new String("");
WeakReference<Object> ref1 = new WeakReference<>(o0);
node.execute(o0, false);
o0 = null;
GCUtils.assertGc("Reference is not collected", ref1);
node.execute("", false);
});
}

@GenerateUncached
Expand Down Expand Up @@ -217,28 +236,33 @@ Object s1(String arg, boolean expectNull,
* reference cannot get collected.
*/
@Test
public void testConsistentGuardAndSpecialization() throws InterruptedException {
ConsistentGuardAndSpecializationNode node = ConsistentGuardAndSpecializationNodeGen.create();
Object o0 = new String("");
WeakReference<Object> ref1 = new WeakReference<>(o0);
node.execute(o0);
Thread t = new Thread(new Runnable() {
public void run() {
node.locksEnabled = true;
node.execute(new String(""));
public void testConsistentGuardAndSpecialization() throws IOException, InterruptedException {
runInSubprocess(() -> {
ConsistentGuardAndSpecializationNode node = ConsistentGuardAndSpecializationNodeGen.create();
Object o0 = new String("");
WeakReference<Object> ref1 = new WeakReference<>(o0);
node.execute(o0);
Thread t = new Thread(new Runnable() {
public void run() {
node.locksEnabled = true;
node.execute(new String(""));
}
});
t.start();
try {
node.waitForGuard.acquire();
o0 = null;
try {
GCUtils.assertNotGc("Reference is not collected", ref1);
} finally {
node.waitForSpecialization.release();
t.join();
}
} catch (InterruptedException ie) {
throw new AssertionError(ie);
}
GCUtils.assertGc("Reference is not collected", ref1);
});
t.start();
node.waitForGuard.acquire();
o0 = null;
try {
GCUtils.assertNotGc("Reference is not collected", ref1);
} finally {
node.waitForSpecialization.release();
t.join();
}
GCUtils.assertGc("Reference is not collected", ref1);

}

@Test
Expand Down
Loading