No more weak JNI refs!
Summary: @public Completely removes the usage of weak JNI refs. This is great, because node allocation and deallocation no longer go through a VM-global lock to access the weak reference table. This is also great, because we can no longer overflow that ref table. Performance is comparable to weak refs. Reviewed By: marco-cova Differential Revision: D14423068 fbshipit-source-id: 62003d2d6fd971e91460a26fb3477046f26e2ba5
This commit is contained in:
committed by
Facebook Github Bot
parent
7890672ecc
commit
3331a9e480
@@ -36,8 +36,6 @@ public class YogaNodeJNI extends YogaNode {
|
|||||||
private static final int PADDING = 2;
|
private static final int PADDING = 2;
|
||||||
private static final int BORDER = 4;
|
private static final int BORDER = 4;
|
||||||
|
|
||||||
private final boolean mAvoidGlobalJNIRefs;
|
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
private float mWidth = YogaConstants.UNDEFINED;
|
private float mWidth = YogaConstants.UNDEFINED;
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@@ -78,17 +76,15 @@ public class YogaNodeJNI extends YogaNode {
|
|||||||
|
|
||||||
private native long jni_YGNodeNew();
|
private native long jni_YGNodeNew();
|
||||||
public YogaNodeJNI() {
|
public YogaNodeJNI() {
|
||||||
mAvoidGlobalJNIRefs = false;
|
|
||||||
mNativePointer = jni_YGNodeNew();
|
mNativePointer = jni_YGNodeNew();
|
||||||
if (mNativePointer == 0) {
|
if (mNativePointer == 0) {
|
||||||
throw new IllegalStateException("Failed to allocate native memory");
|
throw new IllegalStateException("Failed to allocate native memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long jni_YGNodeNewWithConfig(long configPointer, boolean avoidGlobalJNIRefs);
|
private native long jni_YGNodeNewWithConfig(long configPointer);
|
||||||
public YogaNodeJNI(YogaConfig config) {
|
public YogaNodeJNI(YogaConfig config) {
|
||||||
mAvoidGlobalJNIRefs = config.avoidGlobalJNIRefs;
|
mNativePointer = jni_YGNodeNewWithConfig(config.mNativePointer);
|
||||||
mNativePointer = jni_YGNodeNewWithConfig(config.mNativePointer, mAvoidGlobalJNIRefs);
|
|
||||||
if (mNativePointer == 0) {
|
if (mNativePointer == 0) {
|
||||||
throw new IllegalStateException("Failed to allocate native memory");
|
throw new IllegalStateException("Failed to allocate native memory");
|
||||||
}
|
}
|
||||||
@@ -231,21 +227,19 @@ public class YogaNodeJNI extends YogaNode {
|
|||||||
long[] nativePointers = null;
|
long[] nativePointers = null;
|
||||||
YogaNodeJNI[] nodes = null;
|
YogaNodeJNI[] nodes = null;
|
||||||
|
|
||||||
if (mAvoidGlobalJNIRefs) {
|
ArrayList<YogaNodeJNI> n = new ArrayList<>();
|
||||||
ArrayList<YogaNodeJNI> n = new ArrayList<>();
|
n.add(this);
|
||||||
n.add(this);
|
for (int i = 0; i < n.size(); ++i) {
|
||||||
for (int i = 0; i < n.size(); ++i) {
|
List<YogaNodeJNI> children = n.get(i).mChildren;
|
||||||
List<YogaNodeJNI> children = n.get(i).mChildren;
|
if (children != null) {
|
||||||
if (children != null) {
|
n.addAll(children);
|
||||||
n.addAll(children);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes = n.toArray(new YogaNodeJNI[n.size()]);
|
nodes = n.toArray(new YogaNodeJNI[n.size()]);
|
||||||
nativePointers = new long[nodes.length];
|
nativePointers = new long[nodes.length];
|
||||||
for (int i = 0; i < nodes.length; ++i) {
|
for (int i = 0; i < nodes.length; ++i) {
|
||||||
nativePointers[i] = nodes[i].mNativePointer;
|
nativePointers[i] = nodes[i].mNativePointer;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jni_YGNodeCalculateLayout(mNativePointer, width, height, nativePointers, nodes);
|
jni_YGNodeCalculateLayout(mNativePointer, width, height, nativePointers, nodes);
|
||||||
|
@@ -89,11 +89,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct YGNodeContext {
|
struct YGNodeContext {
|
||||||
weak_ref<jobject>* ygNodeJObjectRef{nullptr};
|
|
||||||
int edgeSetFlag = 0;
|
int edgeSetFlag = 0;
|
||||||
~YGNodeContext() {
|
|
||||||
delete ygNodeJObjectRef;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int MARGIN = 1;
|
const int MARGIN = 1;
|
||||||
@@ -107,13 +103,7 @@ static inline YGNodeContext* ygNodeRefToYGNodeContext(YGNodeRef node) {
|
|||||||
static inline local_ref<JYogaNode> YGNodeJobject(
|
static inline local_ref<JYogaNode> YGNodeJobject(
|
||||||
YGNodeRef node,
|
YGNodeRef node,
|
||||||
void* layoutContext) {
|
void* layoutContext) {
|
||||||
if (layoutContext == nullptr) {
|
return reinterpret_cast<PtrJNodeMap*>(layoutContext)->ref(node);
|
||||||
return (reinterpret_cast<weak_ref<JYogaNode>*>(
|
|
||||||
ygNodeRefToYGNodeContext(node)->ygNodeJObjectRef))
|
|
||||||
->lockLocal();
|
|
||||||
} else {
|
|
||||||
return reinterpret_cast<PtrJNodeMap*>(layoutContext)->ref(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGTransferLayoutDirection(
|
static void YGTransferLayoutDirection(
|
||||||
@@ -320,25 +310,20 @@ static int YGJNILogFunc(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
YGNodeContext* createYGNodeContext(alias_ref<jobject> thiz) {
|
YGNodeContext* createYGNodeContext() {
|
||||||
YGNodeContext* ygNodeContext = new YGNodeContext();
|
return new YGNodeContext();
|
||||||
ygNodeContext->ygNodeJObjectRef = new weak_ref<jobject>(make_weak(thiz));
|
|
||||||
return ygNodeContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
|
jlong jni_YGNodeNew(alias_ref<jobject>) {
|
||||||
const YGNodeRef node = YGNodeNew();
|
const YGNodeRef node = YGNodeNew();
|
||||||
node->setContext(createYGNodeContext(thiz));
|
node->setContext(createYGNodeContext());
|
||||||
node->setPrintFunc(YGPrint);
|
node->setPrintFunc(YGPrint);
|
||||||
return reinterpret_cast<jlong>(node);
|
return reinterpret_cast<jlong>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong jni_YGNodeNewWithConfig(
|
jlong jni_YGNodeNewWithConfig(alias_ref<jobject>, jlong configPointer) {
|
||||||
alias_ref<jobject> thiz,
|
|
||||||
jlong configPointer,
|
|
||||||
jboolean avoidGlobalJNIRefs) {
|
|
||||||
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
|
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
|
||||||
node->setContext(createYGNodeContext(avoidGlobalJNIRefs ? nullptr : thiz));
|
node->setContext(createYGNodeContext());
|
||||||
return reinterpret_cast<jlong>(node);
|
return reinterpret_cast<jlong>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +802,7 @@ static void YGNodeSetStyleInputs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void jni_YGNodeSetStyleInputs(
|
void jni_YGNodeSetStyleInputs(
|
||||||
alias_ref<jobject> thiz,
|
alias_ref<jobject>,
|
||||||
jlong nativePointer,
|
jlong nativePointer,
|
||||||
alias_ref<JArrayFloat> styleInputs,
|
alias_ref<JArrayFloat> styleInputs,
|
||||||
jint size) {
|
jint size) {
|
||||||
|
Reference in New Issue
Block a user