Skip to content

Commit

Permalink
[GR-14731] A clean up centered around LLVMTypedForeignObject.
Browse files Browse the repository at this point in the history
PullRequest: graal/6055
  • Loading branch information
zslajchrt committed May 7, 2020
2 parents 2664180 + 6798fd6 commit b0c297a
Show file tree
Hide file tree
Showing 18 changed files with 289 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -647,7 +647,7 @@ private static final class Pointer extends LLVMDebugObject {
private boolean isPointerToForeign() {
if (value.isManagedPointer()) {
Object base = value.getManagedPointerBase();
return base instanceof LLVMTypedForeignObject;
return LLVMAsForeignLibrary.getFactory().getUncached().isForeign(base);
} else {
return false;
}
Expand All @@ -668,8 +668,8 @@ public String[] getKeysSafe() {
public Object getMemberSafe(String identifier) {
if (FOREIGN_KEYS[0].equals(identifier)) {
Object base = value.getManagedPointerBase();
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!";
}
Expand Down Expand Up @@ -792,8 +792,9 @@ protected Object getMemberSafe(String identifier) {
}

Object obj = value.asInteropValue();
if (obj instanceof LLVMTypedForeignObject) {
obj = ((LLVMTypedForeignObject) obj).getForeign();

if (LLVMAsForeignLibrary.getFactory().getUncached().isForeign(obj)) {
obj = LLVMAsForeignLibrary.getFactory().getUncached().asForeign(obj);
}
return obj;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,18 @@
*/
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)
Expand All @@ -66,27 +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());
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");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -261,42 +261,20 @@ static TruffleObject escapingType(LLVMInteropType escapingValue, @SuppressWarnin
return escapingValue;
}

@Specialization
static Object escapingForeign(LLVMTypedForeignObject escapingValue, @SuppressWarnings("unused") LLVMInteropType.Structured type) {
return escapingValue.getForeign();
static boolean isPrimitiveValue(Object object) {
return object instanceof Long || object instanceof Double;
}

@Specialization
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
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;
}
}
}
}
@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);
}

@Specialization(guards = "!foreigns.isForeign(address)")
static Object escapingManaged(LLVMPointer address, @SuppressWarnings("unused") LLVMInteropType.Structured type,
@SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns,
@Cached ConditionProfile typedProfile) {
// fallthrough: the value escapes as LLVM pointer object

if (typedProfile.profile(address.getExportType() != null)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -837,4 +839,16 @@ static boolean doGeneric(LLVMTypedForeignObject receiver, Object other) {
return false;
}
}

@ExportMessage
@SuppressWarnings("static-method")
public boolean isForeign() {
return true;
}

@ExportMessage
public Object asForeign() {
return foreign;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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;
import com.oracle.truffle.llvm.runtime.except.LLVMException;

@GenerateLibrary
@DefaultExport(LLVMAsForeignLibraryDefaults.ArrayAsForeignLibrary.class)
@DefaultExport(LLVMAsForeignLibraryDefaults.DefaultAsForeignLibrary.class)
public abstract class LLVMAsForeignLibrary extends Library {

static final LibraryFactory<LLVMAsForeignLibrary> FACTORY = LibraryFactory.resolve(LLVMAsForeignLibrary.class);

public static LibraryFactory<LLVMAsForeignLibrary> getFactory() {
return FACTORY;
}

public boolean isForeign(@SuppressWarnings("unused") Object receiver) {
return false;
}

public Object asForeign(@SuppressWarnings("unused") Object receiver) {
throw new NotForeignObjectException();
}

public class NotForeignObjectException extends LLVMException {
private static final long serialVersionUID = 3841115158039517295L;

public NotForeignObjectException() {
super(null);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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;
import com.oracle.truffle.api.library.ExportMessage;

public class LLVMAsForeignLibraryDefaults {

@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;
}

}

@ExportLibrary(value = LLVMAsForeignLibrary.class, receiverType = int[].class)
static class ArrayAsForeignLibrary {
// the inherited isForeign returns false
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit b0c297a

Please sign in to comment.