From 8b5d9378b4141ce3c31677c7da655fb1a3c60a6d Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Fri, 24 Apr 2020 17:51:28 +0200 Subject: [PATCH 1/7] Only wrap foreign objects if we need to add type information --- .../runtime/debug/value/LLVMDebugObject.java | 3 + .../runtime/interop/LLVMAsForeignNode.java | 1 + .../runtime/interop/LLVMDataEscapeNode.java | 1 + .../interop/LLVMTypedForeignObject.java | 14 +++ .../internal/LLVMAsForeignLibrary.java | 51 +++++++++++ .../LLVMAsForeignLibraryDefaults.java | 20 +++++ .../runtime/nodes/func/LLVMDispatchNode.java | 2 + .../func/LLVMLookupDispatchTargetNode.java | 3 + .../interop/LLVMPolyglotAsPrimitive.java | 89 +++++++++++-------- .../interop/LLVMReadStringNode.java | 1 + .../interop/LLVMTruffleDecorateFunction.java | 2 + .../intrinsics/llvm/debug/LLDBConstant.java | 3 + .../llvm/runtime/nodes/vars/LLVMReadNode.java | 1 + .../pointer/ManagedPointerLibraries.java | 14 +++ 14 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java create mode 100644 sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java index c3f7b56a7737..bc24eb32217f 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java @@ -647,6 +647,7 @@ private static final class Pointer extends LLVMDebugObject { private boolean isPointerToForeign() { if (value.isManagedPointer()) { Object base = value.getManagedPointerBase(); + // XYZ return base instanceof LLVMTypedForeignObject; } else { return false; @@ -668,6 +669,7 @@ public String[] getKeysSafe() { public Object getMemberSafe(String identifier) { if (FOREIGN_KEYS[0].equals(identifier)) { Object base = value.getManagedPointerBase(); + // XYZ if (base instanceof LLVMTypedForeignObject) { return ((LLVMTypedForeignObject) base).getForeign(); } else { @@ -792,6 +794,7 @@ protected Object getMemberSafe(String identifier) { } Object obj = value.asInteropValue(); + // XYZ if (obj instanceof LLVMTypedForeignObject) { obj = ((LLVMTypedForeignObject) obj).getForeign(); } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java index e06c259dfb5e..1857a45d1ea9 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java @@ -75,6 +75,7 @@ Object doForeign(Object pointer, LLVMManagedPointer managed = LLVMManagedPointer.cast(pointer); if (managed.getOffset() == 0) { Object object = objectProfile.profile(managed.getObject()); + // XYZ if (foreignProfile.profile(object instanceof LLVMTypedForeignObject)) { return ((LLVMTypedForeignObject) object).getForeign(); } else if (!(object instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(object)) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java index 01e268188ca3..d1e01abc830a 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java @@ -279,6 +279,7 @@ static Object escapingManaged(LLVMPointer address, @SuppressWarnings("unused") L Object object = objectProfile.profile(managed.getObject()); if (managed.getOffset() == 0) { // pointer to the beginning of a managed object + // XYZ if (isTypedForeignObject.profile(object instanceof LLVMTypedForeignObject)) { // foreign object -- unpack it return escapingForeign((LLVMTypedForeignObject) object, type); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java index 7d9c64d3a0ac..1276700019c8 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java @@ -51,6 +51,7 @@ import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType; import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropWriteNode; import com.oracle.truffle.llvm.runtime.interop.convert.ForeignToLLVM.ForeignToLLVMType; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMManagedReadLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMManagedWriteLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; @@ -68,6 +69,7 @@ @ExportLibrary(LLVMManagedWriteLibrary.class) @ExportLibrary(ReferenceLibrary.class) @ExportLibrary(NativeTypeLibrary.class) +@ExportLibrary(LLVMAsForeignLibrary.class) public final class LLVMTypedForeignObject extends LLVMInternalTruffleObject { final Object foreign; @@ -837,4 +839,16 @@ static boolean doGeneric(LLVMTypedForeignObject receiver, Object other) { return false; } } + + @ExportMessage + @SuppressWarnings("static-method") + boolean isForeign() { + return true; + } + + @ExportMessage + Object asForeign() { + return foreign; + } + } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java new file mode 100644 index 000000000000..7560d52634f0 --- /dev/null +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.truffle.llvm.runtime.library.internal; + +import com.oracle.truffle.api.library.GenerateLibrary; +import com.oracle.truffle.api.library.GenerateLibrary.DefaultExport; +import com.oracle.truffle.api.library.Library; +import com.oracle.truffle.api.library.LibraryFactory; + +@GenerateLibrary +@DefaultExport(LLVMAsForeignLibraryDefaults.class) +public abstract class LLVMAsForeignLibrary extends Library { + + static final LibraryFactory FACTORY = LibraryFactory.resolve(LLVMAsForeignLibrary.class); + + public static LibraryFactory getFactory() { + return FACTORY; + } + + public abstract boolean isForeign(Object receiver); + + public abstract Object asForeign(Object receiver); + +} diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java new file mode 100644 index 000000000000..8baa37d0d740 --- /dev/null +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java @@ -0,0 +1,20 @@ +package com.oracle.truffle.llvm.runtime.library.internal; + +import com.oracle.truffle.api.library.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.llvm.runtime.interop.LLVMInternalTruffleObject; +import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer; + +@ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = Object.class) +public class LLVMAsForeignLibraryDefaults { + + @ExportMessage + static boolean isForeign(Object receiver) { + return !(receiver instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(receiver); + } + + @ExportMessage + static Object asForeign(Object receiver) { + return receiver; + } +} diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java index 3dec16c7ac46..22c0f2d51e2d 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java @@ -99,6 +99,7 @@ private String getSignature() { return signature; } + // XYZ /** * {@code function} is expected to be either {@link LLVMFunctionDescriptor}, * {@link LLVMTypedForeignObject} or {@link LLVMNativePointer}, and it needs to be resolved @@ -232,6 +233,7 @@ protected LLVMNativeConvertNode createFromNativeNode() { return LLVMNativeConvertNode.createFromNative(type.getReturnType()); } + // XYZ @Specialization protected Object doForeign(LLVMTypedForeignObject foreign, Object[] arguments, @Cached("create(type)") LLVMLookupDispatchForeignNode lookupDispatchForeignNode) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java index 33c9c6ff4f67..ebfab21aa044 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java @@ -65,6 +65,7 @@ protected static LLVMFunctionDescriptor doDirect(LLVMManagedPointer pointer) { return (LLVMFunctionDescriptor) pointer.getObject(); } + // XYZ @Specialization(guards = {"isForeignFunction(pointer.getObject())", "pointer.getOffset() == 0"}) protected LLVMTypedForeignObject doForeign(LLVMManagedPointer pointer) { return (LLVMTypedForeignObject) pointer.getObject(); @@ -99,6 +100,7 @@ protected Object doLookup(LLVMNativePointer pointer, } } + // XYZ @Specialization(guards = "isAutoDerefHandle(pointer.asNative())") protected LLVMTypedForeignObject doDerefHandle(LLVMNativePointer pointer, @Cached LLVMDerefHandleGetReceiverNode getReceiver) { @@ -110,6 +112,7 @@ protected LLVMFunctionDescriptor lookupFunction(ContextReference ct return ctxRef.get().getFunctionDescriptor(function); } + // XYZ protected static boolean isForeignFunction(Object object) { return object instanceof LLVMTypedForeignObject; } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMPolyglotAsPrimitive.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMPolyglotAsPrimitive.java index 44011956653f..aa634950ad24 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMPolyglotAsPrimitive.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMPolyglotAsPrimitive.java @@ -30,15 +30,15 @@ package com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic; import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException; -import com.oracle.truffle.llvm.runtime.interop.LLVMAsForeignNode; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotAsPrimitiveFactory.AsBooleanNodeGen; import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotAsPrimitiveFactory.AsDoubleNodeGen; @@ -47,22 +47,29 @@ import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotAsPrimitiveFactory.AsI32NodeGen; import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotAsPrimitiveFactory.AsI64NodeGen; import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotAsPrimitiveFactory.AsI8NodeGen; +import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic; -@NodeChild(type = LLVMAsForeignNode.class) +@NodeChild(type = LLVMExpressionNode.class) public abstract class LLVMPolyglotAsPrimitive extends LLVMIntrinsic { + @Fallback + boolean onFallback(@SuppressWarnings("unused") Object receiver) { + throw new LLVMPolyglotException(this, "Pointer does not point to a polyglot value"); + } + public abstract static class AsBoolean extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsBooleanNodeGen.create(LLVMAsForeignNode.create(arg)); + return AsBooleanNodeGen.create(arg); } - @Specialization(limit = "3") - boolean asBoolean(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + boolean asBoolean(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asBoolean(foreign); + return interop.asBoolean(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_boolean can not be converted to boolean."); @@ -73,15 +80,16 @@ boolean asBoolean(Object foreign, public abstract static class AsI8 extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsI8NodeGen.create(LLVMAsForeignNode.create(arg)); + return AsI8NodeGen.create(arg); } - @Specialization(limit = "3") - byte asI8(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + byte asI8(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asByte(foreign); + return interop.asByte(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_i8 can not be converted to i8."); @@ -92,15 +100,16 @@ byte asI8(Object foreign, public abstract static class AsI16 extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsI16NodeGen.create(LLVMAsForeignNode.create(arg)); + return AsI16NodeGen.create(arg); } - @Specialization(limit = "3") - short asI16(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + short asI16(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asShort(foreign); + return interop.asShort(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_i16 can not be converted to i16."); @@ -111,15 +120,16 @@ short asI16(Object foreign, public abstract static class AsI32 extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsI32NodeGen.create(LLVMAsForeignNode.create(arg)); + return AsI32NodeGen.create(arg); } - @Specialization(limit = "3") - int asI32(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + int asI32(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asInt(foreign); + return interop.asInt(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_i32 can not be converted to i32."); @@ -130,15 +140,16 @@ int asI32(Object foreign, public abstract static class AsI64 extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsI64NodeGen.create(LLVMAsForeignNode.create(arg)); + return AsI64NodeGen.create(arg); } - @Specialization(limit = "3") - long asI64(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + long asI64(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asLong(foreign); + return interop.asLong(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_i64 can not be converted to i64."); @@ -149,15 +160,16 @@ long asI64(Object foreign, public abstract static class AsFloat extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsFloatNodeGen.create(LLVMAsForeignNode.create(arg)); + return AsFloatNodeGen.create(arg); } - @Specialization(limit = "3") - float asFloat(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + float asFloat(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asFloat(foreign); + return interop.asFloat(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_float can not be converted to float."); @@ -168,15 +180,16 @@ float asFloat(Object foreign, public abstract static class AsDouble extends LLVMPolyglotAsPrimitive { public static LLVMPolyglotAsPrimitive create(LLVMExpressionNode arg) { - return AsDoubleNodeGen.create(LLVMAsForeignNode.create(arg)); + return AsDoubleNodeGen.create(arg); } - @Specialization(limit = "3") - double asDouble(Object foreign, - @CachedLibrary("foreign") InteropLibrary interop, + @Specialization(guards = "foreigns.isForeign(receiver)", limit = "3") + double asDouble(Object receiver, + @CachedLibrary("receiver") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") InteropLibrary interop, @Cached BranchProfile exception) { try { - return interop.asDouble(foreign); + return interop.asDouble(foreigns.asForeign(receiver)); } catch (UnsupportedMessageException ex) { exception.enter(); throw new LLVMPolyglotException(this, "Argument to polyglot_as_double can not be converted to double."); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java index 90733402e3e3..350cf7498db9 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java @@ -86,6 +86,7 @@ protected static boolean isString(LLVMManagedPointer pointer) { return pointer.getOffset() == 0 && pointer.getObject() instanceof String; } + // XYZ protected static boolean isForeign(LLVMManagedPointer pointer) { return pointer.getOffset() == 0 && pointer.getObject() instanceof LLVMTypedForeignObject; } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java index ada61cf86656..15e7b3ae1b17 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java @@ -181,6 +181,7 @@ protected Object decorateDerefHandle(LLVMNativePointer func, LLVMManagedPointer return doGeneric(func, wrapper); } + // XYZ private Object decorateForeign(LLVMManagedPointer resolved, LLVMManagedPointer wrapper) { LLVMTypedForeignObject foreign = (LLVMTypedForeignObject) resolved.getObject(); return decorateForeign(foreign, (LLVMFunctionDescriptor) wrapper.getObject()); @@ -225,6 +226,7 @@ private Object registerRoot(ExternalLibrary lib, FunctionType newFunctionType, D return LLVMManagedPointer.create(wrappedFunction); } + // XYZ protected static boolean isForeignFunction(Object object) { return object instanceof LLVMTypedForeignObject; } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java index 2a7b2415fe6e..be92865e8168 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java @@ -365,6 +365,7 @@ public Object asInteropValue() { foreign = LLVMManagedPointer.cast(pointer).getObject(); } + // XYZ if (foreign instanceof LLVMTypedForeignObject) { return ((LLVMTypedForeignObject) foreign).getForeign(); } @@ -408,6 +409,7 @@ public boolean isInteropValue() { return false; } else { + // XYZ return !(target instanceof LLVMTypedForeignObject); } } else { @@ -689,6 +691,7 @@ public boolean isInteropValue() { @Override public Object asInteropValue() { + // XYZ if (value instanceof LLVMTypedForeignObject) { return ((LLVMTypedForeignObject) value).getForeign(); } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java index f6c7fdf0d028..3ac1f611a980 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java @@ -205,6 +205,7 @@ public static ForeignAttachInteropTypeNode create() { return ForeignAttachInteropTypeNodeGen.create(); } + // XYZ @Specialization(guards = "object.getType() == null") protected Object doForeign(LLVMTypedForeignObject object, LLVMInteropType.Structured type) { return LLVMTypedForeignObject.create(object.getForeign(), type); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java index 41406d620fc8..6af92d6204f0 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java @@ -36,10 +36,12 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; @ExportLibrary(value = LLVMNativeLibrary.class, receiverType = LLVMPointerImpl.class) @ExportLibrary(value = InteropLibrary.class, receiverType = LLVMPointerImpl.class) +@ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = LLVMPointerImpl.class) abstract class ManagedPointerLibraries extends CommonPointerLibraries { @ExportMessage @@ -98,4 +100,16 @@ static LLVMNativePointer toNativePointer(LLVMPointerImpl receiver, return natives.toNativePointer(receiver.object).increment(receiver.getOffset()); } + @ExportMessage + static boolean isForeign(LLVMPointerImpl receiver, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary asForeigns) { + return asForeigns.isForeign(receiver.object); + } + + @ExportMessage + static Object asForeign(LLVMPointerImpl receiver, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary asForeigns) { + return asForeigns.asForeign(receiver.object); + } + } From 8c45b4687c1e16079f928ff1bc8ba35c19dd5518 Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Mon, 27 Apr 2020 18:57:29 +0200 Subject: [PATCH 2/7] LLVMDataEscapeNode uses LLVMAsForeignLibrary --- .../runtime/interop/LLVMAsForeignNode.java | 1 + .../runtime/interop/LLVMDataEscapeNode.java | 43 ++++--------------- .../LLVMAsForeignLibraryDefaults.java | 10 ++--- .../pointer/ManagedPointerLibraries.java | 39 ++++++++++++++--- 4 files changed, 46 insertions(+), 47 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java index 1857a45d1ea9..7e198a06da83 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java @@ -47,6 +47,7 @@ @GenerateUncached @NodeChild(type = LLVMExpressionNode.class) @NodeField(name = "allowNonForeign", type = boolean.class) +// TODO: Remove and replace with LLVMAsForeignLibrary public abstract class LLVMAsForeignNode extends LLVMNode { public abstract Object execute(VirtualFrame frame); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java index d1e01abc830a..948ed053d6d8 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java @@ -35,7 +35,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.llvm.runtime.interop.LLVMDataEscapeNodeFactory.LLVMDoubleDataEscapeNodeGen; import com.oracle.truffle.llvm.runtime.interop.LLVMDataEscapeNodeFactory.LLVMFloatDataEscapeNodeGen; import com.oracle.truffle.llvm.runtime.interop.LLVMDataEscapeNodeFactory.LLVMI16DataEscapeNodeGen; @@ -47,6 +46,7 @@ import com.oracle.truffle.llvm.runtime.interop.LLVMDataEscapeNodeFactory.LLVMVoidDataEscapeNodeGen; import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType; import com.oracle.truffle.llvm.runtime.interop.convert.ForeignToLLVM.ForeignToLLVMType; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode; import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer; @@ -261,43 +261,16 @@ static TruffleObject escapingType(LLVMInteropType escapingValue, @SuppressWarnin return escapingValue; } - @Specialization - static Object escapingForeign(LLVMTypedForeignObject escapingValue, @SuppressWarnings("unused") LLVMInteropType.Structured type) { - return escapingValue.getForeign(); + @Specialization(guards = "foreigns.isForeign(object)") + static Object escapingForeignNonPointer(Object object, @SuppressWarnings("unused") LLVMInteropType.Structured type, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return foreigns.asForeign(object); } - @Specialization + @Specialization(guards = "!foreigns.isForeign(address)") static Object escapingManaged(LLVMPointer address, @SuppressWarnings("unused") LLVMInteropType.Structured type, - @Cached("createClassProfile()") ValueProfile objectProfile, - @Cached ConditionProfile isManagedPointer, - @Cached ConditionProfile isTypedForeignObject, - @Cached ConditionProfile typedProfile, - @CachedLibrary(limit = "3") LLVMNativeLibrary library) { - - if (isManagedPointer.profile(LLVMManagedPointer.isInstance(address))) { - LLVMManagedPointer managed = LLVMManagedPointer.cast(address); - Object object = objectProfile.profile(managed.getObject()); - if (managed.getOffset() == 0) { - // pointer to the beginning of a managed object - // XYZ - if (isTypedForeignObject.profile(object instanceof LLVMTypedForeignObject)) { - // foreign object -- unpack it - return escapingForeign((LLVMTypedForeignObject) object, type); - } else { - if (library.isInternalObject(object)) { - // internal object -- fallthrough - } else if (object instanceof LLVMInternalTruffleObject) { - // internal object -- fallthrough - } else if (LLVMPointer.isInstance(object)) { - // internal object -- fallthrough - } else { - // foreign object -- unpack it - return object; - } - } - } - } - + @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns, + @Cached ConditionProfile typedProfile) { // fallthrough: the value escapes as LLVM pointer object if (typedProfile.profile(address.getExportType() != null)) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java index 8baa37d0d740..e207b9a94837 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java @@ -2,19 +2,17 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.llvm.runtime.interop.LLVMInternalTruffleObject; -import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer; @ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = Object.class) public class LLVMAsForeignLibraryDefaults { @ExportMessage - static boolean isForeign(Object receiver) { - return !(receiver instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(receiver); + static boolean isForeign(@SuppressWarnings("unused") Object receiver) { + return false; } @ExportMessage - static Object asForeign(Object receiver) { - return receiver; + static Object asForeign(@SuppressWarnings("unused") Object receiver) { + return null; } } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java index 6af92d6204f0..f354f3b8c459 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java @@ -29,6 +29,8 @@ */ package com.oracle.truffle.llvm.runtime.pointer; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; @@ -36,6 +38,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.llvm.runtime.interop.LLVMInternalTruffleObject; import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; @@ -101,15 +104,39 @@ static LLVMNativePointer toNativePointer(LLVMPointerImpl receiver, } @ExportMessage - static boolean isForeign(LLVMPointerImpl receiver, - @CachedLibrary(limit = "3") LLVMAsForeignLibrary asForeigns) { - return asForeigns.isForeign(receiver.object); + static class IsForeign { + + @Specialization(guards = {"isForeignTest(receiver, foreigns)"}) + static boolean isForeignObject(@SuppressWarnings("unused") LLVMPointerImpl receiver, + @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return true; + } + + @Specialization(guards = {"!isForeignTest(receiver, foreigns)"}) + static boolean doFallback(LLVMPointerImpl receiver, + @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns, + @CachedLibrary(limit = "3") LLVMNativeLibrary natives) { + return !(receiver.object instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(receiver.object) && !natives.isInternalObject(receiver.object); + } } @ExportMessage - static Object asForeign(LLVMPointerImpl receiver, - @CachedLibrary(limit = "3") LLVMAsForeignLibrary asForeigns) { - return asForeigns.asForeign(receiver.object); + static class AsForeign { + + @Specialization(guards = {"isForeignTest(receiver, foreigns)"}) + static Object isForeignObject(LLVMPointerImpl receiver, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return foreigns.asForeign(receiver.object); + } + + @Fallback + static Object doFallback(LLVMPointerImpl receiver) { + return receiver.object; + } + } + + static boolean isForeignTest(LLVMPointerImpl receiver, LLVMAsForeignLibrary foreigns) { + return receiver.getOffset() == 0 && foreigns.isForeign(receiver.object); } } From 372c9bd6cacb1818885a4fbe2acf0641f9ba3117 Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Thu, 30 Apr 2020 15:52:22 +0200 Subject: [PATCH 3/7] More LLVMTypedForeignObject replacements --- .../runtime/debug/value/LLVMDebugObject.java | 16 ++++++-------- .../interop/LLVMReadStringNode.java | 22 ++++++------------- .../interop/LLVMTruffleDecorateFunction.java | 16 +++++--------- .../intrinsics/llvm/debug/LLDBConstant.java | 13 +++++------ 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java index bc24eb32217f..389106818b7a 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/value/LLVMDebugObject.java @@ -49,7 +49,7 @@ import com.oracle.truffle.llvm.runtime.debug.type.LLVMSourceStaticMemberType; import com.oracle.truffle.llvm.runtime.debug.type.LLVMSourceType; import com.oracle.truffle.llvm.runtime.floating.LLVM80BitFloat; -import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer; /** @@ -647,8 +647,7 @@ private static final class Pointer extends LLVMDebugObject { private boolean isPointerToForeign() { if (value.isManagedPointer()) { Object base = value.getManagedPointerBase(); - // XYZ - return base instanceof LLVMTypedForeignObject; + return LLVMAsForeignLibrary.getFactory().getUncached().isForeign(base); } else { return false; } @@ -669,9 +668,8 @@ public String[] getKeysSafe() { public Object getMemberSafe(String identifier) { if (FOREIGN_KEYS[0].equals(identifier)) { Object base = value.getManagedPointerBase(); - // XYZ - if (base instanceof LLVMTypedForeignObject) { - return ((LLVMTypedForeignObject) base).getForeign(); + if (LLVMAsForeignLibrary.getFactory().getUncached().isForeign(base)) { + return LLVMAsForeignLibrary.getFactory().getUncached().asForeign(base); } else { return "Cannot get foreign base pointer!"; } @@ -794,9 +792,9 @@ protected Object getMemberSafe(String identifier) { } Object obj = value.asInteropValue(); - // XYZ - if (obj instanceof LLVMTypedForeignObject) { - obj = ((LLVMTypedForeignObject) obj).getForeign(); + + if (LLVMAsForeignLibrary.getFactory().getUncached().isForeign(obj)) { + obj = LLVMAsForeignLibrary.getFactory().getUncached().asForeign(obj); } return obj; } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java index 350cf7498db9..5215450cf325 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMReadStringNode.java @@ -34,15 +34,13 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.llvm.runtime.LLVMLanguage; import com.oracle.truffle.llvm.runtime.global.LLVMGlobal; -import com.oracle.truffle.llvm.runtime.interop.LLVMAsForeignNode; -import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMLoadNode; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode; import com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMReadStringNodeGen.ForeignReadStringNodeGen; @@ -67,10 +65,11 @@ String readString(LLVMManagedPointer foreign) { return (String) foreign.getObject(); } - @Specialization(guards = "isForeign(foreign)") - String readForeign(LLVMManagedPointer foreign, + @Specialization(guards = "foreigns.isForeign(pointer)") + String readForeign(LLVMManagedPointer pointer, + @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns, @Cached("create()") ForeignReadStringNode read) { - return read.execute(foreign); + return read.execute(pointer, foreigns.asForeign(pointer)); } @Fallback @@ -86,21 +85,14 @@ protected static boolean isString(LLVMManagedPointer pointer) { return pointer.getOffset() == 0 && pointer.getObject() instanceof String; } - // XYZ - protected static boolean isForeign(LLVMManagedPointer pointer) { - return pointer.getOffset() == 0 && pointer.getObject() instanceof LLVMTypedForeignObject; - } - abstract static class Dummy extends LLVMNode { protected abstract LLVMManagedPointer execute(); } - @NodeChild(value = "object", type = Dummy.class) - @NodeChild(value = "foreign", type = LLVMAsForeignNode.class, executeWith = "object") abstract static class ForeignReadStringNode extends LLVMNode { - protected abstract String execute(LLVMManagedPointer foreign); + protected abstract String execute(LLVMManagedPointer pointer, Object foreign); @Specialization(limit = "3") String doDefault(@SuppressWarnings("unused") LLVMManagedPointer object, Object foreign, @@ -116,7 +108,7 @@ String doDefault(@SuppressWarnings("unused") LLVMManagedPointer object, Object f } public static ForeignReadStringNode create() { - return ForeignReadStringNodeGen.create(null, LLVMAsForeignNode.createOptional()); + return ForeignReadStringNodeGen.create(); } } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java index 15e7b3ae1b17..33fb502708d0 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/interop/LLVMTruffleDecorateFunction.java @@ -42,6 +42,7 @@ import com.oracle.truffle.api.dsl.NodeChildren; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.profiles.ConditionProfile; @@ -53,7 +54,7 @@ import com.oracle.truffle.llvm.runtime.LLVMLanguage; import com.oracle.truffle.llvm.runtime.LLVMSymbol; import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException; -import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory; import com.oracle.truffle.llvm.runtime.memory.LLVMStack.StackPointer; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; @@ -171,19 +172,19 @@ protected Object decorate(LLVMNativePointer func, LLVMManagedPointer wrapper) { @Specialization(guards = {"isAutoDerefHandle(func)", "isFunctionDescriptor(wrapper.getObject())"}) protected Object decorateDerefHandle(LLVMNativePointer func, LLVMManagedPointer wrapper, @Cached LLVMDerefHandleGetReceiverNode getReceiver, - @Cached ConditionProfile isFunctionDescriptorProfile) { + @Cached ConditionProfile isFunctionDescriptorProfile, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { LLVMManagedPointer resolved = getReceiver.execute(func); if (isFunctionDescriptorProfile.profile(isFunctionDescriptor(resolved.getObject()))) { return decorate(resolved, wrapper); - } else if (isForeignFunction(resolved.getObject())) { + } else if (foreigns.isForeign(resolved.getObject())) { return decorateForeign(resolved, wrapper); } return doGeneric(func, wrapper); } - // XYZ private Object decorateForeign(LLVMManagedPointer resolved, LLVMManagedPointer wrapper) { - LLVMTypedForeignObject foreign = (LLVMTypedForeignObject) resolved.getObject(); + Object foreign = resolved.getObject(); return decorateForeign(foreign, (LLVMFunctionDescriptor) wrapper.getObject()); } @@ -226,11 +227,6 @@ private Object registerRoot(ExternalLibrary lib, FunctionType newFunctionType, D return LLVMManagedPointer.create(wrappedFunction); } - // XYZ - protected static boolean isForeignFunction(Object object) { - return object instanceof LLVMTypedForeignObject; - } - private LLVMContext getContext() { if (contextRef == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java index be92865e8168..2fec4de37992 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java @@ -41,6 +41,7 @@ import com.oracle.truffle.llvm.runtime.debug.value.LLVMDebugValue; import com.oracle.truffle.llvm.runtime.floating.LLVM80BitFloat; import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer; import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer; import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer; @@ -365,9 +366,8 @@ public Object asInteropValue() { foreign = LLVMManagedPointer.cast(pointer).getObject(); } - // XYZ - if (foreign instanceof LLVMTypedForeignObject) { - return ((LLVMTypedForeignObject) foreign).getForeign(); + if (LLVMAsForeignLibrary.getFactory().getUncached().isForeign(foreign)) { + return LLVMAsForeignLibrary.getFactory().getUncached().asForeign(foreign); } } return super.asInteropValue(); @@ -409,7 +409,7 @@ public boolean isInteropValue() { return false; } else { - // XYZ + // Not sure how to replace this LLVMTypedForeignObject occurrence return !(target instanceof LLVMTypedForeignObject); } } else { @@ -691,9 +691,8 @@ public boolean isInteropValue() { @Override public Object asInteropValue() { - // XYZ - if (value instanceof LLVMTypedForeignObject) { - return ((LLVMTypedForeignObject) value).getForeign(); + if (LLVMAsForeignLibrary.getFactory().getUncached().isForeign(value)) { + return LLVMAsForeignLibrary.getFactory().getUncached().asForeign(value); } return value; } From 5cec3711d45690c89d5fe1671844cd7320c160cf Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Thu, 30 Apr 2020 16:56:00 +0200 Subject: [PATCH 4/7] LLVMDispatchNode uses LLVMAsForeignLibrary --- .../runtime/nodes/func/LLVMDispatchNode.java | 26 +++++++++++++++---- .../func/LLVMLookupDispatchTargetNode.java | 21 ++++++--------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java index 22c0f2d51e2d..c89b908f857b 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMDispatchNode.java @@ -99,7 +99,6 @@ private String getSignature() { return signature; } - // XYZ /** * {@code function} is expected to be either {@link LLVMFunctionDescriptor}, * {@link LLVMTypedForeignObject} or {@link LLVMNativePointer}, and it needs to be resolved @@ -233,7 +232,24 @@ protected LLVMNativeConvertNode createFromNativeNode() { return LLVMNativeConvertNode.createFromNative(type.getReturnType()); } - // XYZ + /** + * + * There is a discrepancy between {@code LLVMTypedForeignObject.getType()} and the exported + * message {@code getNativeType}. While the former returns the attached type, the latter first + * asks the wrapped foreign object for its native type using {@code NativeTypeLibrary}. As in + * some cases (in GraalPython tests) the returned types differ, it is impossible to simply + * replace {@code LLVMTypedForeignObject.getType()} by {@code natives.getNativeType(receiver)}. + * + *
+     * @Specialization(guards = {"foreigns.isForeign(receiver)", "natives.hasNativeType(receiver)"})
+     * protected Object doForeign(Object receiver, Object[] arguments,
+     *                 @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns,
+     *                 @CachedLibrary(limit = "3") NativeTypeLibrary natives, @Cached("create(type)") LLVMLookupDispatchForeignNode lookupDispatchForeignNode) {
+     *     return lookupDispatchForeignNode.execute(foreigns.asForeign(receiver),
+     *                     natives.getNativeType(receiver), arguments);
+     * }
+     * 
+ */ @Specialization protected Object doForeign(LLVMTypedForeignObject foreign, Object[] arguments, @Cached("create(type)") LLVMLookupDispatchForeignNode lookupDispatchForeignNode) { @@ -260,13 +276,13 @@ protected LLVMNativeDispatchNode createCachedNativeDispatch() { } abstract static class LLVMLookupDispatchForeignNode extends LLVMNode { - private final FunctionType type; + final FunctionType type; LLVMLookupDispatchForeignNode(FunctionType type) { this.type = type; } - abstract Object execute(Object function, LLVMInteropType.Structured interopType, Object[] arguments); + abstract Object execute(Object function, Object interopType, Object[] arguments); @Specialization(guards = "functionType == cachedType", limit = "5") protected Object doCachedType(TruffleObject function, @SuppressWarnings("unused") LLVMInteropType.Function functionType, Object[] arguments, @@ -306,7 +322,7 @@ protected Object doGeneric(TruffleObject function, LLVMInteropType.Function func } @Specialization(guards = "functionType == null", limit = "5") - protected Object doUnknownType(TruffleObject function, @SuppressWarnings("unused") LLVMInteropType.Structured functionType, Object[] arguments, + protected Object doUnknownType(TruffleObject function, @SuppressWarnings("unused") Object functionType, Object[] arguments, @CachedLibrary("function") InteropLibrary crossLanguageCall, @Cached("createLLVMDataEscapeNodes()") LLVMDataEscapeNode[] dataEscapeNodes, @Cached("createToLLVMNode()") ForeignToLLVM toLLVMNode) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java index ebfab21aa044..406056a19470 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/func/LLVMLookupDispatchTargetNode.java @@ -37,10 +37,11 @@ import com.oracle.truffle.api.dsl.CachedContext; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.llvm.runtime.LLVMContext; import com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor; import com.oracle.truffle.llvm.runtime.LLVMLanguage; -import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; import com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMDerefHandleGetReceiverNode; @@ -65,10 +66,10 @@ protected static LLVMFunctionDescriptor doDirect(LLVMManagedPointer pointer) { return (LLVMFunctionDescriptor) pointer.getObject(); } - // XYZ - @Specialization(guards = {"isForeignFunction(pointer.getObject())", "pointer.getOffset() == 0"}) - protected LLVMTypedForeignObject doForeign(LLVMManagedPointer pointer) { - return (LLVMTypedForeignObject) pointer.getObject(); + @Specialization(guards = {"foreigns.isForeign(pointer.getObject())", "pointer.getOffset() == 0"}) + protected Object doForeign(LLVMManagedPointer pointer, + @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return pointer.getObject(); } @Specialization(limit = "INLINE_CACHE_SIZE", guards = {"pointer.asNative() == cachedAddress", "!isAutoDerefHandle(cachedAddress)", "cachedDescriptor != null"}) @@ -100,23 +101,17 @@ protected Object doLookup(LLVMNativePointer pointer, } } - // XYZ @Specialization(guards = "isAutoDerefHandle(pointer.asNative())") - protected LLVMTypedForeignObject doDerefHandle(LLVMNativePointer pointer, + protected Object doDerefHandle(LLVMNativePointer pointer, @Cached LLVMDerefHandleGetReceiverNode getReceiver) { LLVMManagedPointer foreignFunction = getReceiver.execute(pointer); - return doForeign(foreignFunction); + return foreignFunction.getObject(); } protected LLVMFunctionDescriptor lookupFunction(ContextReference ctxRef, LLVMNativePointer function) { return ctxRef.get().getFunctionDescriptor(function); } - // XYZ - protected static boolean isForeignFunction(Object object) { - return object instanceof LLVMTypedForeignObject; - } - protected boolean isAutoDerefHandle(long addr) { if (languageRef == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); From 80f26479598c638294309df8da600daf5f22605a Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Thu, 30 Apr 2020 17:43:16 +0200 Subject: [PATCH 5/7] LLVMAsForeignNode delegates to LLVMAsForeignLibrary --- .../runtime/interop/LLVMAsForeignNode.java | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java index 7e198a06da83..d868fbe26769 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMAsForeignNode.java @@ -29,25 +29,22 @@ */ package com.oracle.truffle.llvm.runtime.interop; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode; import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer; -import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer; @GenerateUncached @NodeChild(type = LLVMExpressionNode.class) @NodeField(name = "allowNonForeign", type = boolean.class) -// TODO: Remove and replace with LLVMAsForeignLibrary public abstract class LLVMAsForeignNode extends LLVMNode { public abstract Object execute(VirtualFrame frame); @@ -67,28 +64,19 @@ public static LLVMAsForeignNode createOptional() { protected abstract boolean isAllowNonForeign(); - @Specialization + @Specialization(guards = "foreigns.isForeign(pointer)") Object doForeign(Object pointer, - @Cached("createClassProfile()") ValueProfile objectProfile, - @Cached ConditionProfile foreignProfile, - @Cached BranchProfile nonForeignProfile) { - if (LLVMManagedPointer.isInstance(pointer)) { - LLVMManagedPointer managed = LLVMManagedPointer.cast(pointer); - if (managed.getOffset() == 0) { - Object object = objectProfile.profile(managed.getObject()); - // XYZ - if (foreignProfile.profile(object instanceof LLVMTypedForeignObject)) { - return ((LLVMTypedForeignObject) object).getForeign(); - } else if (!(object instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(object)) { - return object; - } - } - } - nonForeignProfile.enter(); + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return foreigns.asForeign(pointer); + } + + @Fallback + Object doNonForeign(@SuppressWarnings("unused") Object pointer) { if (isAllowNonForeign()) { return null; } else { throw new LLVMPolyglotException(this, "Pointer does not point to a polyglot value"); } } + } From f89f8fbc47ebd481a655ed83b3abd470e406053c Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Thu, 30 Apr 2020 19:12:50 +0200 Subject: [PATCH 6/7] LLVMReadNode clean-up --- .../LLVMAsForeignLibraryDefaults.java | 29 +++++++++++++++++++ .../intrinsics/llvm/debug/LLDBConstant.java | 2 +- .../llvm/runtime/nodes/vars/LLVMReadNode.java | 1 - 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java index e207b9a94837..879e973e1b45 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java @@ -1,3 +1,32 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ package com.oracle.truffle.llvm.runtime.library.internal; import com.oracle.truffle.api.library.ExportLibrary; diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java index 2fec4de37992..4b5c8e47d3dd 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/intrinsics/llvm/debug/LLDBConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. * * All rights reserved. * diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java index 3ac1f611a980..f6c7fdf0d028 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/vars/LLVMReadNode.java @@ -205,7 +205,6 @@ public static ForeignAttachInteropTypeNode create() { return ForeignAttachInteropTypeNodeGen.create(); } - // XYZ @Specialization(guards = "object.getType() == null") protected Object doForeign(LLVMTypedForeignObject object, LLVMInteropType.Structured type) { return LLVMTypedForeignObject.create(object.getForeign(), type); From 6798fd6cb6c57b416df49874c56ceb8b3b45d1cf Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt Date: Wed, 6 May 2020 11:10:06 +0200 Subject: [PATCH 7/7] Method isInternalObject removed --- .../llvm/runtime/debug/LLDBSupport.java | 4 +-- .../runtime/interop/LLVMDataEscapeNode.java | 6 +++- .../interop/LLVMInternalTruffleObject.java | 2 ++ .../interop/LLVMTypedForeignObject.java | 4 +-- .../internal/LLVMAsForeignLibrary.java | 20 +++++++++-- .../LLVMAsForeignLibraryDefaults.java | 24 +++++++++---- .../library/internal/LLVMNativeLibrary.java | 4 --- .../internal/LLVMNativeLibraryDefaults.java | 10 ------ .../pointer/ManagedPointerLibraries.java | 36 ++++--------------- .../pointer/NativePointerLibraries.java | 2 ++ 10 files changed, 53 insertions(+), 59 deletions(-) diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/LLDBSupport.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/LLDBSupport.java index 7875e21b18a3..ebcf1eb2b94e 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/LLDBSupport.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/LLDBSupport.java @@ -39,7 +39,7 @@ import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.llvm.runtime.CommonNodeFactory; import com.oracle.truffle.llvm.runtime.LLVMLanguage; -import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMLoadNode; import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer; import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer; @@ -88,7 +88,7 @@ public static boolean pointsToObjectAccess(LLVMPointer pointer) { final LLVMManagedPointer managedPointer = LLVMManagedPointer.cast(pointer); final Object target = managedPointer.getObject(); - return LLVMNativeLibrary.getFactory().getUncached().isInternalObject(target); + return !LLVMAsForeignLibrary.getFactory().getUncached().isForeign(target); } private static boolean isByteAligned(long bits) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java index 948ed053d6d8..b4678eaee2b4 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMDataEscapeNode.java @@ -261,7 +261,11 @@ static TruffleObject escapingType(LLVMInteropType escapingValue, @SuppressWarnin return escapingValue; } - @Specialization(guards = "foreigns.isForeign(object)") + static boolean isPrimitiveValue(Object object) { + return object instanceof Long || object instanceof Double; + } + + @Specialization(guards = {"!isPrimitiveValue(object)", "foreigns.isForeign(object)"}) static Object escapingForeignNonPointer(Object object, @SuppressWarnings("unused") LLVMInteropType.Structured type, @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { return foreigns.asForeign(object); diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMInternalTruffleObject.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMInternalTruffleObject.java index a5417d429acb..4021e592a0b4 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMInternalTruffleObject.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMInternalTruffleObject.java @@ -36,11 +36,13 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.llvm.runtime.LLVMLanguage; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; /** * Base class to mark {@link TruffleObject} implementors that are not considered foreign. */ @ExportLibrary(InteropLibrary.class) +@ExportLibrary(LLVMAsForeignLibrary.class) public abstract class LLVMInternalTruffleObject implements TruffleObject { @ExportMessage diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java index 1276700019c8..f7019a7f8d09 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/interop/LLVMTypedForeignObject.java @@ -842,12 +842,12 @@ static boolean doGeneric(LLVMTypedForeignObject receiver, Object other) { @ExportMessage @SuppressWarnings("static-method") - boolean isForeign() { + public boolean isForeign() { return true; } @ExportMessage - Object asForeign() { + public Object asForeign() { return foreign; } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java index 7560d52634f0..8b94fbf67e51 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibrary.java @@ -33,9 +33,11 @@ import com.oracle.truffle.api.library.GenerateLibrary.DefaultExport; import com.oracle.truffle.api.library.Library; import com.oracle.truffle.api.library.LibraryFactory; +import com.oracle.truffle.llvm.runtime.except.LLVMException; @GenerateLibrary -@DefaultExport(LLVMAsForeignLibraryDefaults.class) +@DefaultExport(LLVMAsForeignLibraryDefaults.ArrayAsForeignLibrary.class) +@DefaultExport(LLVMAsForeignLibraryDefaults.DefaultAsForeignLibrary.class) public abstract class LLVMAsForeignLibrary extends Library { static final LibraryFactory FACTORY = LibraryFactory.resolve(LLVMAsForeignLibrary.class); @@ -44,8 +46,20 @@ public static LibraryFactory getFactory() { return FACTORY; } - public abstract boolean isForeign(Object receiver); + public boolean isForeign(@SuppressWarnings("unused") Object receiver) { + return false; + } + + public Object asForeign(@SuppressWarnings("unused") Object receiver) { + throw new NotForeignObjectException(); + } - public abstract Object asForeign(Object receiver); + public class NotForeignObjectException extends LLVMException { + private static final long serialVersionUID = 3841115158039517295L; + + public NotForeignObjectException() { + super(null); + } + } } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java index 879e973e1b45..303ac8d0952e 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMAsForeignLibraryDefaults.java @@ -32,16 +32,26 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -@ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = Object.class) public class LLVMAsForeignLibraryDefaults { - @ExportMessage - static boolean isForeign(@SuppressWarnings("unused") Object receiver) { - return false; + @ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = Object.class) + static class DefaultAsForeignLibrary { + + @ExportMessage + static boolean isForeign(@SuppressWarnings("unused") Object receiver) { + return true; + } + + @ExportMessage + static Object asForeign(@SuppressWarnings("unused") Object receiver) { + return receiver; + } + } - @ExportMessage - static Object asForeign(@SuppressWarnings("unused") Object receiver) { - return null; + @ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = int[].class) + static class ArrayAsForeignLibrary { + // the inherited isForeign returns false } + } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibrary.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibrary.java index 1149176a5431..a93e2ce14aa3 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibrary.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibrary.java @@ -70,9 +70,5 @@ public long asPointer(Object receiver) throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } - public boolean isInternalObject(Object receiver) { - return true; - } - public abstract LLVMNativePointer toNativePointer(Object receiver); } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibraryDefaults.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibraryDefaults.java index 8c05de0000b6..84a5a3911542 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibraryDefaults.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/library/internal/LLVMNativeLibraryDefaults.java @@ -47,11 +47,6 @@ abstract class LLVMNativeLibraryDefaults { @ExportLibrary(value = LLVMNativeLibrary.class, receiverType = Object.class) static class DefaultLibrary { - @ExportMessage - static boolean isInternalObject(@SuppressWarnings("unused") Object receiver) { - return false; - } - @ExportMessage @SuppressWarnings("unused") static class IsPointer { @@ -130,11 +125,6 @@ static LLVMNativePointer doNotNull(Object receiver, @ExportLibrary(value = LLVMNativeLibrary.class, receiverType = Long.class) static class LongLibrary { - @ExportMessage - static boolean isInternalObject(@SuppressWarnings("unused") Long receiver) { - return false; - } - @ExportMessage @SuppressWarnings("unused") static boolean isPointer(Long receiver) { diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java index f354f3b8c459..557fca6790ea 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/ManagedPointerLibraries.java @@ -29,8 +29,6 @@ */ package com.oracle.truffle.llvm.runtime.pointer; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; @@ -38,7 +36,6 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.llvm.runtime.interop.LLVMInternalTruffleObject; import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; @@ -104,39 +101,18 @@ static LLVMNativePointer toNativePointer(LLVMPointerImpl receiver, } @ExportMessage - static class IsForeign { - - @Specialization(guards = {"isForeignTest(receiver, foreigns)"}) - static boolean isForeignObject(@SuppressWarnings("unused") LLVMPointerImpl receiver, - @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { - return true; - } - - @Specialization(guards = {"!isForeignTest(receiver, foreigns)"}) - static boolean doFallback(LLVMPointerImpl receiver, - @SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns, - @CachedLibrary(limit = "3") LLVMNativeLibrary natives) { - return !(receiver.object instanceof LLVMInternalTruffleObject) && !LLVMPointer.isInstance(receiver.object) && !natives.isInternalObject(receiver.object); - } + static boolean isForeign(LLVMPointerImpl receiver, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return isForeignTest(receiver, foreigns); } @ExportMessage - static class AsForeign { - - @Specialization(guards = {"isForeignTest(receiver, foreigns)"}) - static Object isForeignObject(LLVMPointerImpl receiver, - @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { - return foreigns.asForeign(receiver.object); - } - - @Fallback - static Object doFallback(LLVMPointerImpl receiver) { - return receiver.object; - } + static Object asForeign(LLVMPointerImpl receiver, + @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) { + return foreigns.asForeign(receiver.object); } static boolean isForeignTest(LLVMPointerImpl receiver, LLVMAsForeignLibrary foreigns) { return receiver.getOffset() == 0 && foreigns.isForeign(receiver.object); } - } diff --git a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/NativePointerLibraries.java b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/NativePointerLibraries.java index fd8fe23b3207..ac2576a727c2 100644 --- a/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/NativePointerLibraries.java +++ b/sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/pointer/NativePointerLibraries.java @@ -44,9 +44,11 @@ import com.oracle.truffle.llvm.runtime.LLVMContext; import com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor; import com.oracle.truffle.llvm.runtime.LLVMLanguage; +import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary; import com.oracle.truffle.llvm.runtime.library.internal.LLVMNativeLibrary; @ExportLibrary(value = LLVMNativeLibrary.class, receiverType = LLVMPointerImpl.class) +@ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = LLVMPointerImpl.class) @ExportLibrary(value = InteropLibrary.class, receiverType = LLVMPointerImpl.class) abstract class NativePointerLibraries extends CommonPointerLibraries {