From b00e2147a1cd1b9feb8e32a4b9cc239eaf53622c Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Mon, 9 Oct 2017 10:30:48 +0200 Subject: [PATCH] Simulating R's precious list using a map with object count. --- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 24 ++++++++++++++----- .../truffle/r/runtime/ffi/RFFIContext.java | 5 +++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index afe1fbe86e..061fc37d80 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -32,9 +32,10 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -1598,8 +1599,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { @TruffleBoundary public void R_PreserveObject(Object obj) { guaranteeInstanceOf(obj, RObject.class); - HashSet<RObject> list = getContext().preserveList; - list.add((RObject) obj); + IdentityHashMap<RObject, AtomicInteger> preserveList = getContext().preserveList; + AtomicInteger prevCnt = preserveList.putIfAbsent((RObject) obj, new AtomicInteger(1)); + if (prevCnt != null) { + prevCnt.incrementAndGet(); + } } @Override @@ -1607,9 +1611,17 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { public void R_ReleaseObject(Object obj) { guaranteeInstanceOf(obj, RObject.class); RFFIContext context = getContext(); - HashSet<RObject> list = context.preserveList; - if (list.remove(obj)) { - context.registerReferenceUsedInNative(obj); + IdentityHashMap<RObject, AtomicInteger> preserveList = context.preserveList; + AtomicInteger atomicInteger = preserveList.get(obj); + if (atomicInteger != null) { + int decrementAndGet = atomicInteger.decrementAndGet(); + if (decrementAndGet == 0) { + // remove from "list" + preserveList.remove(obj); + context.registerReferenceUsedInNative(obj); + } + } else { + // TODO report ? } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java index d7c4b530de..407d1eae6f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java @@ -23,7 +23,10 @@ package com.oracle.truffle.r.runtime.ffi; import java.util.ArrayList; +import java.util.HashMap; 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.interop.TruffleObject; @@ -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 * 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); -- GitLab