Skip to content

Commit ff90570

Browse files
committed
Refactor to a POJO for value wrappers.
PullRequest: truffleruby/514
2 parents a4624b6 + 9161480 commit ff90570

File tree

8 files changed

+129
-135
lines changed

8 files changed

+129
-135
lines changed

src/main/java/org/truffleruby/Layouts.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
import com.oracle.truffle.api.object.HiddenKey;
1313

14-
import org.truffleruby.cext.ValueWrapperLayout;
15-
import org.truffleruby.cext.ValueWrapperLayoutImpl;
1614
import org.truffleruby.core.HandleLayout;
1715
import org.truffleruby.core.HandleLayoutImpl;
1816
import org.truffleruby.core.array.ArrayLayout;
@@ -150,6 +148,5 @@ public abstract class Layouts {
150148
public static final TracePointLayout TRACE_POINT = TracePointLayoutImpl.INSTANCE;
151149
public static final DigestLayout DIGEST = DigestLayoutImpl.INSTANCE;
152150
public static final SystemCallErrorLayout SYSTEM_CALL_ERROR = SystemCallErrorLayoutImpl.INSTANCE;
153-
public static final ValueWrapperLayout VALUE_WRAPPER = ValueWrapperLayoutImpl.INSTANCE;
154151

155152
}

src/main/java/org/truffleruby/cext/UnwrapNode.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
/*
2+
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 1.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
110
package org.truffleruby.cext;
211

312
import static org.truffleruby.cext.ValueWrapperManager.TAG_MASK;
413
import static org.truffleruby.cext.ValueWrapperManager.LONG_TAG;
514
import static org.truffleruby.cext.ValueWrapperManager.OBJECT_TAG;
615
import static org.truffleruby.cext.ValueWrapperManager.FALSE_HANDLE;
716

8-
import org.truffleruby.Layouts;
9-
1017
import org.truffleruby.cext.UnwrapNodeGen.UnwrapNativeNodeGen;
1118
import org.truffleruby.language.NotProvided;
1219
import org.truffleruby.language.RubyBaseNode;
@@ -76,9 +83,9 @@ public static UnwrapNativeNode create() {
7683

7784
public abstract Object execute(Object value);
7885

79-
@Specialization(guards = "isWrapper(value)")
80-
public Object unwrapValue(DynamicObject value) {
81-
return Layouts.VALUE_WRAPPER.getObject(value);
86+
@Specialization
87+
public Object unwrapValue(ValueWrapper value) {
88+
return value.getObject();
8289
}
8390

8491
@Specialization(guards = "!isWrapper(value)")
@@ -104,6 +111,6 @@ public Object unwrapTypeCastObject(TruffleObject value,
104111
}
105112

106113
public static boolean isWrapper(TruffleObject value) {
107-
return ValueWrapperObjectType.isInstance(value);
114+
return value instanceof ValueWrapper;
108115
}
109116
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 1.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.cext;
11+
12+
import com.oracle.truffle.api.interop.ForeignAccess;
13+
import com.oracle.truffle.api.interop.TruffleObject;
14+
15+
/**
16+
* This object represents a VALUE in C which wraps the raw Ruby object. This allows foreign access
17+
* methods to be set up which convert these value wrappers to native pointers without affecting the
18+
* semantics of the wrapped objects.
19+
*/
20+
public class ValueWrapper implements TruffleObject {
21+
22+
private final Object object;
23+
private long handle;
24+
25+
public ValueWrapper(Object object, long handle) {
26+
this.object = object;
27+
this.handle = handle;
28+
}
29+
30+
public ForeignAccess getForeignAccess() {
31+
return ValueWrapperMessageResolutionForeign.ACCESS;
32+
}
33+
34+
public Object getObject() {
35+
return object;
36+
}
37+
38+
public long getHandle() {
39+
return handle;
40+
}
41+
42+
public void setHandle(long handle) {
43+
this.handle = handle;
44+
}
45+
46+
@Override
47+
public boolean equals(Object other) {
48+
if (!(other instanceof ValueWrapper)) {
49+
return false;
50+
}
51+
ValueWrapper otherWrapper = (ValueWrapper) other;
52+
if (handle != ValueWrapperManager.UNSET_HANDLE && otherWrapper.handle != ValueWrapperManager.UNSET_HANDLE) {
53+
return handle == otherWrapper.handle;
54+
}
55+
return (this.object.equals(otherWrapper.object));
56+
}
57+
58+
@Override
59+
public int hashCode() {
60+
return this.object.hashCode();
61+
}
62+
}

src/main/java/org/truffleruby/cext/ValueWrapperLayout.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/main/java/org/truffleruby/cext/ValueWrapperManager.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@
1111

1212
import java.lang.ref.WeakReference;
1313

14-
import org.truffleruby.Layouts;
1514
import org.truffleruby.RubyContext;
1615
import org.truffleruby.collections.LongHashMap;
1716
import org.truffleruby.extra.ffi.Pointer;
1817
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
19-
import com.oracle.truffle.api.object.DynamicObject;
2018

2119
public class ValueWrapperManager {
2220

@@ -39,7 +37,7 @@ public class ValueWrapperManager {
3937

4038
public static final long TAG_MASK = 0b111;
4139

42-
private final LongHashMap<WeakReference<DynamicObject>> handleMap = new LongHashMap<>(1024);
40+
private final LongHashMap<WeakReference<ValueWrapper>> handleMap = new LongHashMap<>(1024);
4341

4442
private final RubyContext context;
4543

@@ -52,30 +50,30 @@ public ValueWrapperManager(RubyContext context) {
5250
* that any given fixnum will translate to a given VALUE.
5351
*/
5452
@TruffleBoundary
55-
public synchronized DynamicObject longWrapper(long value) {
56-
return Layouts.VALUE_WRAPPER.createValueWrapper(value, UNSET_HANDLE);
53+
public synchronized ValueWrapper longWrapper(long value) {
54+
return new ValueWrapper(value, UNSET_HANDLE);
5755
}
5856

59-
public DynamicObject doubleWrapper(double value) {
60-
return Layouts.VALUE_WRAPPER.createValueWrapper(value, UNSET_HANDLE);
57+
public ValueWrapper doubleWrapper(double value) {
58+
return new ValueWrapper(value, UNSET_HANDLE);
6159
}
6260

6361
@TruffleBoundary
64-
public synchronized void addToHandleMap(long handle, DynamicObject wrapper) {
62+
public synchronized void addToHandleMap(long handle, ValueWrapper wrapper) {
6563
handleMap.put(handle, new WeakReference<>(wrapper));
6664
}
6765

6866
@TruffleBoundary
6967
public synchronized Object getFromHandleMap(long handle) {
70-
WeakReference<DynamicObject> ref = handleMap.get(handle);
71-
DynamicObject object;
68+
WeakReference<ValueWrapper> ref = handleMap.get(handle);
69+
ValueWrapper wrapper;
7270
if (ref == null) {
7371
return null;
7472
}
75-
if ((object = ref.get()) == null) {
73+
if ((wrapper = ref.get()) == null) {
7674
return null;
7775
}
78-
return Layouts.VALUE_WRAPPER.getObject(object);
76+
return wrapper.getObject();
7977
}
8078

8179
@TruffleBoundary
@@ -84,22 +82,22 @@ public synchronized void removeFromHandleMap(long handle) {
8482
}
8583

8684
@TruffleBoundary
87-
public synchronized long createNativeHandle(DynamicObject wrapper) {
85+
public synchronized long createNativeHandle(ValueWrapper wrapper) {
8886
Pointer handlePointer = Pointer.malloc(1);
8987
long handleAddress = handlePointer.getAddress();
9088
if ((handleAddress & TAG_MASK) != 0) {
9189
throw new RuntimeException("unaligned malloc for native handle");
9290
}
93-
Layouts.VALUE_WRAPPER.setHandle(wrapper, handleAddress);
91+
wrapper.setHandle(handleAddress);
9492
addToHandleMap(handleAddress, wrapper);
9593
context.getMarkingService().keepObject(wrapper);
9694
addFinalizer(wrapper, handlePointer);
9795
return handleAddress;
9896
}
9997

100-
public void addFinalizer(DynamicObject wrapper, Pointer handle) {
98+
public void addFinalizer(ValueWrapper wrapper, Pointer handle) {
10199
context.getFinalizationService().addFinalizer(
102-
wrapper, null, ValueWrapperObjectType.class,
100+
wrapper, null, ValueWrapper.class,
103101
createFinalizer(handle), null);
104102
}
105103

src/main/java/org/truffleruby/cext/ValueWrapperMessageResolution.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,41 @@
99
*/
1010
package org.truffleruby.cext;
1111

12-
import org.truffleruby.Layouts;
1312
import org.truffleruby.RubyContext;
1413
import org.truffleruby.RubyLanguage;
1514

1615
import com.oracle.truffle.api.CompilerDirectives;
1716
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
1817
import com.oracle.truffle.api.frame.VirtualFrame;
18+
import com.oracle.truffle.api.interop.CanResolve;
1919
import com.oracle.truffle.api.interop.MessageResolution;
2020
import com.oracle.truffle.api.interop.Resolve;
21+
import com.oracle.truffle.api.interop.TruffleObject;
2122
import com.oracle.truffle.api.nodes.Node;
22-
import com.oracle.truffle.api.object.DynamicObject;
2323
import com.oracle.truffle.api.profiles.BranchProfile;
2424

25-
@MessageResolution(receiverType = ValueWrapperObjectType.class)
25+
@MessageResolution(receiverType = ValueWrapper.class)
2626
public class ValueWrapperMessageResolution {
2727

28+
@CanResolve
29+
public abstract static class IsInstance extends Node {
30+
31+
protected boolean test(TruffleObject receiver) {
32+
return receiver instanceof ValueWrapper;
33+
}
34+
}
35+
2836
@Resolve(message = "IS_POINTER")
2937
public static abstract class ForeignIsPointerNode extends Node {
3038

31-
protected boolean access(VirtualFrame frame, DynamicObject wrapper) {
39+
protected boolean access(VirtualFrame frame, ValueWrapper wrapper) {
3240
return true;
3341
}
3442
}
3543

3644
@Resolve(message = "TO_NATIVE")
3745
public static abstract class ForeignToNativeNode extends Node {
38-
protected Object access(VirtualFrame frame, DynamicObject receiver) {
46+
protected Object access(VirtualFrame frame, ValueWrapper receiver) {
3947
return receiver;
4048
}
4149
}
@@ -46,8 +54,8 @@ public static abstract class ForeignAsPointerNode extends Node {
4654
@CompilationFinal private RubyContext context;
4755
private final BranchProfile createHandleProfile = BranchProfile.create();
4856

49-
protected long access(VirtualFrame frame, DynamicObject wrapper) {
50-
long handle = Layouts.VALUE_WRAPPER.getHandle(wrapper);
57+
protected long access(VirtualFrame frame, ValueWrapper wrapper) {
58+
long handle = wrapper.getHandle();
5159
if (handle == ValueWrapperManager.UNSET_HANDLE) {
5260
createHandleProfile.enter();
5361
handle = getContext().getValueWrapperManager().createNativeHandle(wrapper);

src/main/java/org/truffleruby/cext/ValueWrapperObjectType.java

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)