Skip to content

Commit 6468f8f

Browse files
committed
Fix marking of doubles and large Fixnums.
1 parent f954b3d commit 6468f8f

File tree

7 files changed

+74
-11
lines changed

7 files changed

+74
-11
lines changed

src/main/java/org/truffleruby/RubyContext.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ public class RubyContext {
108108
private final CodeLoader codeLoader = new CodeLoader(this);
109109
private final FeatureLoader featureLoader = new FeatureLoader(this);
110110
private final TraceManager traceManager;
111-
private final ReferenceProcessor referenceProcessor = new ReferenceProcessor(this);
112-
private final FinalizationService finalizationService = new FinalizationService(this, referenceProcessor);
113-
private final MarkingService markingService = new MarkingService(this, referenceProcessor);
111+
private final ReferenceProcessor referenceProcessor;
112+
private final FinalizationService finalizationService;
113+
private final MarkingService markingService;
114114
private final ObjectSpaceManager objectSpaceManager = new ObjectSpaceManager(this);
115115
private final SharedObjects sharedObjects = new SharedObjects(this);
116116
private final AtExitManager atExitManager = new AtExitManager(this);
@@ -174,6 +174,10 @@ public RubyContext(RubyLanguage language, TruffleLanguage.Env env) {
174174

175175
options = createOptions(env);
176176

177+
referenceProcessor = new ReferenceProcessor(this);
178+
finalizationService = new FinalizationService(this, referenceProcessor);
179+
markingService = new MarkingService(this, referenceProcessor);
180+
177181
// We need to construct this at runtime
178182
random = createRandomInstance();
179183

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,11 +1357,11 @@ public abstract static class AddToMarkList extends CoreMethodArrayArgumentsNode
13571357
public DynamicObject addToMarkList(VirtualFrame frmae, Object markedObject,
13581358
@Cached("create()") BranchProfile exceptionProfile,
13591359
@Cached("create()") BranchProfile noExceptionProfile,
1360-
@Cached("createUnwrapNode()") UnwrapNode unwrapNode) {
1361-
Object unwrappedValue = unwrapNode.execute(markedObject);
1362-
if (unwrappedValue != null) {
1360+
@Cached("create()") UnwrapNode.ToWrapperNode toWrapperNode) {
1361+
ValueWrapper wrappedValue = toWrapperNode.execute(markedObject);
1362+
if (wrappedValue != null) {
13631363
noExceptionProfile.enter();
1364-
getList().add(unwrappedValue);
1364+
getList().add(wrappedValue);
13651365
}
13661366
// We do nothing here if the handle cannot be resolved. If we are marking an object
13671367
// which is only reachable via weak refs then the handles of objects it is iteself

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static org.truffleruby.cext.ValueWrapperManager.OBJECT_TAG;
1515
import static org.truffleruby.cext.ValueWrapperManager.FALSE_HANDLE;
1616

17+
import org.truffleruby.cext.UnwrapNodeGen.ToWrapperNodeGen;
1718
import org.truffleruby.cext.UnwrapNodeGen.UnwrapNativeNodeGen;
1819
import org.truffleruby.language.NotProvided;
1920
import org.truffleruby.language.RubyBaseNode;
@@ -81,6 +82,53 @@ public static UnwrapNativeNode create() {
8182
}
8283
}
8384

85+
@ImportStatic(Message.class)
86+
public static abstract class ToWrapperNode extends RubyBaseNode {
87+
88+
public abstract ValueWrapper execute(Object value);
89+
90+
@Specialization
91+
public ValueWrapper wrappedValueWrapper(ValueWrapper value) {
92+
return value;
93+
}
94+
95+
@Specialization(guards = "!isWrapper(value)")
96+
public ValueWrapper unwrapTypeCastObject(TruffleObject value,
97+
@Cached("IS_POINTER.createNode()") Node isPointerNode,
98+
@Cached("AS_POINTER.createNode()") Node asPointerNode,
99+
@Cached("create()") UnwrapNativeNode unwrapNativeNode,
100+
@Cached("create()") WrapNode wrapNode,
101+
@Cached("create()") BranchProfile unsupportedProfile,
102+
@Cached("create()") BranchProfile nonPointerProfile) {
103+
if (ForeignAccess.sendIsPointer(isPointerNode, value)) {
104+
long handle = 0;
105+
try {
106+
handle = ForeignAccess.sendAsPointer(asPointerNode, value);
107+
} catch (UnsupportedMessageException e) {
108+
unsupportedProfile.enter();
109+
throw new RaiseException(getContext(), coreExceptions().argumentError(e.getMessage(), this, e));
110+
}
111+
Object obj = unwrapNativeNode.execute(handle);
112+
if (obj != null) {
113+
return wrapNode.execute(obj);
114+
} else {
115+
return null;
116+
}
117+
} else {
118+
nonPointerProfile.enter();
119+
throw new RaiseException(getContext(), coreExceptions().argumentError("Not a handle or a pointer", this));
120+
}
121+
}
122+
123+
public static boolean isWrapper(TruffleObject value) {
124+
return value instanceof ValueWrapper;
125+
}
126+
127+
public static ToWrapperNode create() {
128+
return ToWrapperNodeGen.create();
129+
}
130+
}
131+
84132
public abstract Object execute(Object value);
85133

86134
@Specialization

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
public abstract class WrapNode extends RubyBaseNode {
3737

38-
public abstract TruffleObject execute(Object value);
38+
public abstract ValueWrapper execute(Object value);
3939

4040
@Specialization
4141
public ValueWrapper wrapLong(long value,
@@ -94,7 +94,7 @@ public ValueWrapper wrapValue(DynamicObject value,
9494
}
9595

9696
@Specialization(guards = "!isRubyBasicObject(value)")
97-
public TruffleObject wrapNonRubyObject(TruffleObject value) {
97+
public ValueWrapper wrapNonRubyObject(TruffleObject value) {
9898
throw new RaiseException(getContext(), coreExceptions().argumentError("Attempt to wrap something that isn't an Ruby object", this));
9999
}
100100

@@ -106,4 +106,7 @@ public WriteObjectFieldNode createWriter() {
106106
return WriteObjectFieldNodeGen.create(Layouts.VALUE_WRAPPER_IDENTIFIER);
107107
}
108108

109+
public static WrapNode create() {
110+
return WrapNodeGen.create();
111+
}
109112
}

src/main/java/org/truffleruby/core/MarkingService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,18 @@ public ReferenceProcessingService<MarkerReference> service() {
7979
}
8080
}
8181

82-
private final int cacheSize = context.getOptions().CEXTS_MARKING_CACHE;
82+
private final int cacheSize;
8383

8484
private final ThreadLocal<Deque<ArrayList<Object>>> stackPreservation = ThreadLocal.withInitial(() -> new ArrayDeque<>());
8585

86-
private Object[] keptObjects = new Object[cacheSize];
86+
private Object[] keptObjects;
8787

8888
private int counter = 0;
8989

9090
public MarkingService(RubyContext context, ReferenceProcessor referenceProcessor) {
9191
super(context, referenceProcessor);
92+
cacheSize = context.getOptions().CEXTS_MARKING_CACHE;
93+
keptObjects = new Object[cacheSize];
9294
}
9395

9496
public void keepObject(Object object) {

src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public abstract static class EachObjectNode extends YieldingCoreMethodNode {
110110
public int eachObject(NotProvided ofClass, DynamicObject block) {
111111
int count = 0;
112112

113+
getContext().getMarkingService().runMarkersAndDropKeptList();
113114
for (DynamicObject object : ObjectGraph.stopAndGetAllObjects(this, getContext())) {
114115
if (!isHidden(object)) {
115116
yield(block, object);
@@ -126,6 +127,7 @@ public int eachObject(DynamicObject ofClass, DynamicObject block,
126127
@Cached("create()") IsANode isANode) {
127128
int count = 0;
128129

130+
getContext().getMarkingService().runMarkersAndDropKeptList();
129131
for (DynamicObject object : ObjectGraph.stopAndGetAllObjects(this, getContext())) {
130132
if (!isHidden(object) && isANode.executeIsA(object, ofClass)) {
131133
yield(block, object);

src/main/java/org/truffleruby/language/objects/ObjectGraph.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.oracle.truffle.api.object.Property;
2020
import org.truffleruby.Layouts;
2121
import org.truffleruby.RubyContext;
22+
import org.truffleruby.cext.ValueWrapper;
2223
import org.truffleruby.core.hash.Entry;
2324
import org.truffleruby.core.queue.SizedQueue;
2425
import org.truffleruby.core.queue.UnsizedQueue;
@@ -129,6 +130,9 @@ public static Set<DynamicObject> getAdjacentObjects(DynamicObject object) {
129130
}
130131
} else if (propertyValue instanceof Object[]) {
131132
for (Object element : (Object[]) propertyValue) {
133+
if (element instanceof ValueWrapper) {
134+
element = ((ValueWrapper) element).getObject();
135+
}
132136
if (element instanceof DynamicObject) {
133137
reachable.add((DynamicObject) element);
134138
}

0 commit comments

Comments
 (0)