Skip to content

Commit daf99dd

Browse files
committed
Assert sharing state of array contents when creating shared storage.
1 parent de3d97d commit daf99dd

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/main/java/org/truffleruby/core/array/library/SharedArrayStorage.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
import org.truffleruby.core.array.ArrayGuards;
1818
import org.truffleruby.core.array.library.ArrayStoreLibrary.ArrayAllocator;
1919
import org.truffleruby.language.RubyBaseNode;
20+
import org.truffleruby.language.RubyDynamicObject;
2021
import org.truffleruby.language.objects.ObjectGraph;
2122
import org.truffleruby.language.objects.ObjectGraphNode;
23+
import org.truffleruby.language.objects.shared.SharedObjects;
2224
import org.truffleruby.language.objects.shared.WriteBarrierNode;
2325

2426
import com.oracle.truffle.api.TruffleSafepoint;
@@ -43,6 +45,28 @@ public SharedArrayStorage(Object storage) {
4345
this.storage = storage;
4446
}
4547

48+
/* Method for checking that all elements in this array are correctly shared. This can only be called after the whole
49+
* stack of adjacent objects have been shared, which may not be true at the point the storage is converted to shared
50+
* storage. */
51+
@TruffleBoundary
52+
public boolean allElementsShared() {
53+
if (storage == null || storage instanceof ZeroLengthArrayStore) {
54+
return true;
55+
}
56+
ArrayStoreLibrary stores = ArrayStoreLibrary.getFactory()
57+
.getUncached(storage);
58+
var elements = stores.getIterable(storage, 0, stores.capacity(storage));
59+
for (var e : elements) {
60+
if (e == null || !(e instanceof RubyDynamicObject) || SharedObjects.isShared(e)) {
61+
continue;
62+
} else {
63+
System.err.printf("Unshared element %s.\n", e);
64+
return false;
65+
}
66+
}
67+
return true;
68+
}
69+
4670
@ExportMessage
4771
protected static boolean accepts(SharedArrayStorage store,
4872
@CachedLibrary(limit = "1") ArrayStoreLibrary stores) {

src/main/java/org/truffleruby/language/objects/shared/SharedObjects.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.truffleruby.RubyLanguage;
1818
import org.truffleruby.core.array.RubyArray;
1919
import org.truffleruby.core.array.library.ArrayStoreLibrary;
20+
import org.truffleruby.core.array.library.SharedArrayStorage;
2021
import org.truffleruby.core.module.RubyModule;
2122
import org.truffleruby.core.proc.RubyProc;
2223
import org.truffleruby.core.thread.RubyThread;
@@ -135,9 +136,16 @@ public static boolean assertPropagateSharing(RubyDynamicObject source, Object va
135136
public static void writeBarrier(RubyLanguage language, Object value) {
136137
if (language.options.SHARED_OBJECTS_ENABLED && value instanceof RubyDynamicObject && !isShared(value)) {
137138
shareObject((RubyDynamicObject) value);
139+
assert !(value instanceof RubyArray) || validateArray((RubyArray) value);
138140
}
139141
}
140142

143+
private static boolean validateArray(RubyArray value) {
144+
Object storage = value.getStore();
145+
assert storage instanceof SharedArrayStorage;
146+
return ((SharedArrayStorage) storage).allElementsShared();
147+
}
148+
141149
public static void propagate(RubyLanguage language, RubyDynamicObject source, Object value) {
142150
if (isShared(source)) {
143151
writeBarrier(language, value);

0 commit comments

Comments
 (0)