Skip to content
Snippets Groups Projects
Commit b00e2147 authored by Florian Angerer's avatar Florian Angerer
Browse files

Simulating R's precious list using a map with object count.

parent b0bf1d09
Branches
No related tags found
No related merge requests found
...@@ -32,9 +32,10 @@ import java.nio.charset.StandardCharsets; ...@@ -32,9 +32,10 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function; import java.util.function.Function;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
...@@ -1598,8 +1599,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { ...@@ -1598,8 +1599,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
@TruffleBoundary @TruffleBoundary
public void R_PreserveObject(Object obj) { public void R_PreserveObject(Object obj) {
guaranteeInstanceOf(obj, RObject.class); guaranteeInstanceOf(obj, RObject.class);
HashSet<RObject> list = getContext().preserveList; IdentityHashMap<RObject, AtomicInteger> preserveList = getContext().preserveList;
list.add((RObject) obj); AtomicInteger prevCnt = preserveList.putIfAbsent((RObject) obj, new AtomicInteger(1));
if (prevCnt != null) {
prevCnt.incrementAndGet();
}
} }
@Override @Override
...@@ -1607,9 +1611,17 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { ...@@ -1607,9 +1611,17 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
public void R_ReleaseObject(Object obj) { public void R_ReleaseObject(Object obj) {
guaranteeInstanceOf(obj, RObject.class); guaranteeInstanceOf(obj, RObject.class);
RFFIContext context = getContext(); RFFIContext context = getContext();
HashSet<RObject> list = context.preserveList; IdentityHashMap<RObject, AtomicInteger> preserveList = context.preserveList;
if (list.remove(obj)) { AtomicInteger atomicInteger = preserveList.get(obj);
context.registerReferenceUsedInNative(obj); if (atomicInteger != null) {
int decrementAndGet = atomicInteger.decrementAndGet();
if (decrementAndGet == 0) {
// remove from "list"
preserveList.remove(obj);
context.registerReferenceUsedInNative(obj);
}
} else {
// TODO report ?
} }
} }
......
...@@ -23,7 +23,10 @@ ...@@ -23,7 +23,10 @@
package com.oracle.truffle.r.runtime.ffi; package com.oracle.truffle.r.runtime.ffi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.TruffleObject;
...@@ -74,7 +77,7 @@ public abstract class RFFIContext extends RFFI { ...@@ -74,7 +77,7 @@ public abstract class RFFIContext extends RFFI {
* FastR equivalent of GNUR's special dedicated global list that is GC root and so any vectors * FastR equivalent of GNUR's special dedicated global list that is GC root and so any vectors
* added to it will be guaranteed to be preserved. * added to it will be guaranteed to be preserved.
*/ */
public final HashSet<RObject> preserveList = new HashSet<>(); public final IdentityHashMap<RObject, AtomicInteger> preserveList = new IdentityHashMap<>();
public abstract TruffleObject lookupNativeFunction(NativeFunction function); public abstract TruffleObject lookupNativeFunction(NativeFunction function);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment