Skip to content

Commit c0dad5b

Browse files
committed
Correctly sync native state of Boolean singleton wrappers.
1 parent 88012af commit c0dad5b

File tree

2 files changed

+148
-17
lines changed

2 files changed

+148
-17
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/CExtNodes.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,11 @@ public abstract static class MaterializeDelegateNode extends CExtBaseNode {
472472
PInt doBoolNativeWrapper(BoolNativeWrapper object) {
473473
PInt materializedInt = factory().createInt(object.getValue());
474474
object.setMaterializedObject(materializedInt);
475-
materializedInt.setNativeWrapper(object);
475+
if (materializedInt.getNativeWrapper() != null) {
476+
object.setNativePointer(materializedInt.getNativeWrapper().getNativePointer());
477+
} else {
478+
materializedInt.setNativeWrapper(object);
479+
}
476480
return materializedInt;
477481
}
478482

@@ -507,6 +511,12 @@ PFloat doDoubleNativeWrapper(DoubleNativeWrapper object) {
507511
return materializedInt;
508512
}
509513

514+
@Specialization(guards = "isMaterialized(object)")
515+
Object doMaterialized(PrimitiveNativeWrapper object,
516+
@SuppressWarnings("unused") @Cached("object.getClass()") Class<? extends PrimitiveNativeWrapper> cachedClass) {
517+
return CompilerDirectives.castExact(object, cachedClass).getDelegate();
518+
}
519+
510520
@Specialization(guards = {"!isPrimitiveNativeWrapper(object)", "object.getClass() == cachedClass"}, limit = "3")
511521
Object doNativeWrapper(PythonNativeWrapper object,
512522
@SuppressWarnings("unused") @Cached("object.getClass()") Class<? extends PythonNativeWrapper> cachedClass) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonObjectNativeWrapperMR.java

Lines changed: 137 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.MaterializeDelegateNode;
5454
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToJavaNode;
5555
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
56+
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.BoolNativeWrapper;
5657
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.DynamicObjectNativeWrapper;
5758
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PySequenceArrayWrapper;
5859
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PyUnicodeData;
@@ -61,6 +62,7 @@
6162
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonNativeWrapper;
6263
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonObjectNativeWrapper;
6364
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.PAsPointerNodeGen;
65+
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.PIsPointerNodeGen;
6466
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.ReadNativeMemberNodeGen;
6567
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.ToPyObjectNodeGen;
6668
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.WriteNativeMemberNodeGen;
@@ -73,6 +75,7 @@
7375
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
7476
import com.oracle.graal.python.builtins.objects.dict.PDict;
7577
import com.oracle.graal.python.builtins.objects.floats.PFloat;
78+
import com.oracle.graal.python.builtins.objects.ints.PInt;
7679
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
7780
import com.oracle.graal.python.builtins.objects.memoryview.PBuffer;
7881
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
@@ -259,11 +262,13 @@ Object doObStart(PByteArray object, @SuppressWarnings("unused") String key) {
259262
}
260263

261264
@Specialization(guards = "eq(OB_FVAL, key)")
262-
Object doObFval(PythonObject object, @SuppressWarnings("unused") String key,
265+
Object doObFval(Object object, @SuppressWarnings("unused") String key,
263266
@Cached("createClassProfile()") ValueProfile profile) {
264267
Object profiled = profile.profile(object);
265268
if (profiled instanceof PFloat) {
266269
return ((PFloat) profiled).getValue();
270+
} else if (profiled instanceof Double) {
271+
return object;
267272
}
268273
throw UnsupportedMessageException.raise(Message.READ);
269274
}
@@ -442,7 +447,7 @@ Object doState(PString object, @SuppressWarnings("unused") String key) {
442447
}
443448

444449
@Specialization(guards = "eq(MD_DICT, key)")
445-
Object doMdDict(PythonObject object, @SuppressWarnings("unused") String key,
450+
Object doMdDict(Object object, @SuppressWarnings("unused") String key,
446451
@Cached("create(__GETATTRIBUTE__)") LookupAndCallBinaryNode getDictNode) {
447452
return getToSulongNode().execute(getDictNode.executeObject(object, SpecialAttributeNames.__DICT__));
448453
}
@@ -834,29 +839,48 @@ public Object access(Object object) {
834839

835840
@Resolve(message = "TO_NATIVE")
836841
abstract static class ToNativeNode extends Node {
837-
@Child private ToPyObjectNode toPyObjectNode = ToPyObjectNode.create();
838-
@Child private MaterializeDelegateNode materializeNode = MaterializeDelegateNode.create();
842+
@Child private ToPyObjectNode toPyObjectNode;
843+
@Child private MaterializeDelegateNode materializeNode;
844+
@Child private PIsPointerNode pIsPointerNode = PIsPointerNode.create();
839845

840846
Object access(PythonClassInitNativeWrapper obj) {
841-
if (!obj.isNative()) {
842-
obj.setNativePointer(toPyObjectNode.getHandleForObject(materializeNode.execute(obj), 0));
847+
if (!pIsPointerNode.execute(obj)) {
848+
obj.setNativePointer(getToPyObjectNode().getHandleForObject(getMaterializeDelegateNode().execute(obj), 0));
843849
}
844850
return obj;
845851
}
846852

847853
Object access(PythonNativeWrapper obj) {
848854
assert !(obj instanceof PythonClassInitNativeWrapper);
849-
if (!obj.isNative()) {
850-
obj.setNativePointer(toPyObjectNode.execute(materializeNode.execute(obj)));
855+
if (!pIsPointerNode.execute(obj)) {
856+
obj.setNativePointer(getToPyObjectNode().execute(getMaterializeDelegateNode().execute(obj)));
851857
}
852858
return obj;
853859
}
860+
861+
private MaterializeDelegateNode getMaterializeDelegateNode() {
862+
if (materializeNode == null) {
863+
CompilerDirectives.transferToInterpreterAndInvalidate();
864+
materializeNode = insert(MaterializeDelegateNode.create());
865+
}
866+
return materializeNode;
867+
}
868+
869+
private ToPyObjectNode getToPyObjectNode() {
870+
if (toPyObjectNode == null) {
871+
CompilerDirectives.transferToInterpreterAndInvalidate();
872+
toPyObjectNode = insert(ToPyObjectNode.create());
873+
}
874+
return toPyObjectNode;
875+
}
854876
}
855877

856878
@Resolve(message = "IS_POINTER")
857879
abstract static class IsPointerNode extends Node {
880+
@Child private PIsPointerNode pIsPointerNode = PIsPointerNode.create();
881+
858882
boolean access(PythonNativeWrapper obj) {
859-
return obj.isNative();
883+
return pIsPointerNode.execute(obj);
860884
}
861885
}
862886

@@ -869,16 +893,60 @@ long access(PythonNativeWrapper obj) {
869893
}
870894
}
871895

896+
abstract static class PIsPointerNode extends PBaseNode {
897+
898+
public abstract boolean execute(PythonNativeWrapper obj);
899+
900+
@Specialization(guards = "!obj.isNative()")
901+
boolean doBool(BoolNativeWrapper obj) {
902+
// Special case: Booleans are singletons, so we need to check if the singletons have
903+
// native wrappers associated and if they are already native.
904+
PInt boxed = factory().createInt(obj.getValue());
905+
DynamicObjectNativeWrapper nativeWrapper = boxed.getNativeWrapper();
906+
return nativeWrapper != null && nativeWrapper.isNative();
907+
}
908+
909+
@Fallback
910+
boolean doBool(PythonNativeWrapper obj) {
911+
return obj.isNative();
912+
}
913+
914+
private static PIsPointerNode create() {
915+
return PIsPointerNodeGen.create();
916+
}
917+
}
918+
872919
abstract static class PAsPointerNode extends PBaseNode {
873920
@Child private Node asPointerNode;
874921

875922
public abstract long execute(PythonNativeWrapper o);
876923

877-
@Specialization(assumptions = "getSingleNativeContextAssumption()")
924+
@Specialization(assumptions = "getSingleNativeContextAssumption()", guards = "!obj.isNative()")
925+
long doBoolNotNative(BoolNativeWrapper obj,
926+
@Cached("create()") MaterializeDelegateNode materializeNode) {
927+
// special case for True and False singletons
928+
PInt boxed = (PInt) materializeNode.execute(obj);
929+
assert obj.getNativePointer() == boxed.getNativeWrapper().getNativePointer();
930+
return doFast(obj);
931+
}
932+
933+
@Specialization(assumptions = "getSingleNativeContextAssumption()", guards = "obj.isNative()")
934+
long doBoolNative(BoolNativeWrapper obj) {
935+
return doFast(obj);
936+
}
937+
938+
@Specialization(assumptions = "getSingleNativeContextAssumption()", guards = "!isBoolNativeWrapper(obj)")
878939
long doFast(PythonNativeWrapper obj) {
879940
// the native pointer object must either be a TruffleObject or a primitive
880-
Object nativePointer = obj.getNativePointer();
881-
return ensureLong(nativePointer);
941+
return ensureLong(obj.getNativePointer());
942+
}
943+
944+
@Specialization(replaces = {"doFast", "doBoolNotNative", "doBoolNative"})
945+
long doGenericSlow(PythonNativeWrapper obj,
946+
@Cached("create()") MaterializeDelegateNode materializeNode,
947+
@Cached("create()") ToPyObjectNode toPyObjectNode) {
948+
Object materialized = materializeNode.execute(obj);
949+
return ensureLong(toPyObjectNode.execute(materialized));
882950
}
883951

884952
private long ensureLong(Object nativePointer) {
@@ -890,16 +958,15 @@ private long ensureLong(Object nativePointer) {
890958
try {
891959
return ForeignAccess.sendAsPointer(asPointerNode, (TruffleObject) nativePointer);
892960
} catch (UnsupportedMessageException e) {
961+
CompilerDirectives.transferToInterpreter();
893962
throw e.raise();
894963
}
895964
}
896965
return (long) nativePointer;
897966
}
898967

899-
@Specialization(replaces = "doFast")
900-
long doSlow(PythonNativeWrapper obj,
901-
@Cached("create()") ToPyObjectNode toPyObjectNode) {
902-
return ensureLong(toPyObjectNode.execute(obj));
968+
protected static boolean isBoolNativeWrapper(Object obj) {
969+
return obj instanceof BoolNativeWrapper;
903970
}
904971

905972
protected Assumption getSingleNativeContextAssumption() {
@@ -909,7 +976,61 @@ protected Assumption getSingleNativeContextAssumption() {
909976
public static PAsPointerNode create() {
910977
return PAsPointerNodeGen.create();
911978
}
979+
}
980+
981+
abstract static class PToNativeNode extends PBaseNode {
982+
@Child private ToPyObjectNode toPyObjectNode;
983+
@Child private MaterializeDelegateNode materializeNode;
984+
@Child private PIsPointerNode pIsPointerNode = PIsPointerNode.create();
985+
986+
public abstract PythonNativeWrapper execute(PythonNativeWrapper obj);
987+
988+
@Specialization
989+
PythonNativeWrapper doInitClass(PythonClassInitNativeWrapper obj) {
990+
if (!pIsPointerNode.execute(obj)) {
991+
obj.setNativePointer(getToPyObjectNode().getHandleForObject(getMaterializeDelegateNode().execute(obj), 0));
992+
}
993+
return obj;
994+
}
995+
996+
@Specialization
997+
PythonNativeWrapper doBool(BoolNativeWrapper obj) {
998+
if (!pIsPointerNode.execute(obj)) {
999+
PInt materialized = (PInt) getMaterializeDelegateNode().execute(obj);
1000+
obj.setNativePointer(getToPyObjectNode().execute(materialized));
1001+
if (!materialized.getNativeWrapper().isNative()) {
1002+
assert materialized.getNativeWrapper() != obj;
1003+
materialized.getNativeWrapper().setNativePointer(obj.getNativePointer());
1004+
}
1005+
assert obj.getNativePointer() == materialized.getNativeWrapper().getNativePointer();
1006+
}
1007+
return obj;
1008+
}
1009+
1010+
@Fallback
1011+
PythonNativeWrapper doGeneric(PythonNativeWrapper obj) {
1012+
assert !(obj instanceof PythonClassInitNativeWrapper);
1013+
if (!pIsPointerNode.execute(obj)) {
1014+
obj.setNativePointer(getToPyObjectNode().execute(getMaterializeDelegateNode().execute(obj)));
1015+
}
1016+
return obj;
1017+
}
9121018

1019+
private MaterializeDelegateNode getMaterializeDelegateNode() {
1020+
if (materializeNode == null) {
1021+
CompilerDirectives.transferToInterpreterAndInvalidate();
1022+
materializeNode = insert(MaterializeDelegateNode.create());
1023+
}
1024+
return materializeNode;
1025+
}
1026+
1027+
private ToPyObjectNode getToPyObjectNode() {
1028+
if (toPyObjectNode == null) {
1029+
CompilerDirectives.transferToInterpreterAndInvalidate();
1030+
toPyObjectNode = insert(ToPyObjectNode.create());
1031+
}
1032+
return toPyObjectNode;
1033+
}
9131034
}
9141035

9151036
abstract static class ToPyObjectNode extends CExtBaseNode {

0 commit comments

Comments
 (0)