diff --git a/ci.hocon b/ci.hocon index 259a0e142ed2dc363b896a521cd05bed462b7e61..4c97461fc140d1de63becdf5323cd0dcb8e08801 100644 --- a/ci.hocon +++ b/ci.hocon @@ -6,7 +6,7 @@ # java 7 is needed by Truffle (for now) java7 : {name : oraclejdk, version : "7", platformspecific: true} # java 8 must be a jvmci enabled variant -java8 : {name : labsjdk, version : "8-jvmci-latest", platformspecific: true} +java8 : {name : labsjdk, version : "8u161-jvmci-0.41", platformspecific: true} java9 : {name : labsjdk, version : "9-ea+168", platformspecific: true} java8Downloads : { @@ -146,7 +146,7 @@ gateTestLinuxLLVM : ${common} ${requireGCC} { environment : { TZDIR: "/usr/share/zoneinfo" FASTR_RFFI : "llvm" - FASTR_LLVM_HOME : "$DRAGONEGG_LLVM/bin" + FASTR_LLVM_TOOLS : "$DRAGONEGG_LLVM/bin" FASTR_LLVM_GFORTRAN_LLVM_AS : "$DRAGONEGG_LLVM/bin/llvm-as" FASTR_LLVM_GFORTRAN : "$DRAGONEGG_GCC/bin/gfortran" FASTR_LLVM_DRAGONEGG : "$DRAGONEGG_GCC/lib/dragonegg.so" @@ -192,7 +192,7 @@ gateTestDarwinLLVM: ${common} ${darwinEnvironment} ${requireGCC} { environment : { FASTR_RFFI : "llvm" - FASTR_LLVM_HOME : "$DRAGONEGG_LLVM/bin" + FASTR_LLVM_TOOLS : "$DRAGONEGG_LLVM/bin" FASTR_LLVM_GFORTRAN_LLVM_AS : "$DRAGONEGG_LLVM/bin/llvm-as" FASTR_LLVM_GFORTRAN : "$DRAGONEGG_GCC/bin/gfortran" FASTR_LLVM_DRAGONEGG : "$DRAGONEGG_GCC/lib/dragonegg.so" diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index c7984a2e4953a5c1b80e11efebc6db76bc7f5180..523b80e3b1e3fd1e07026931e2e2f47a1c1caffa 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -31,7 +31,6 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.IdentityHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -234,18 +233,14 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { @Override @TruffleBoundary - public Object R_getClassDef(String clazz) { - String name = "getClassDef"; - RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); - return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), true, null, clazz); + public Object R_getClassDef(Object clazz) { + throw implementedAsNode(); } @Override @TruffleBoundary - public Object R_do_MAKE_CLASS(String clazz) { - String name = "getClass"; - RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); - return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), true, null, clazz); + public Object R_do_MAKE_CLASS(Object clazz) { + throw implementedAsNode(); } @Override @@ -1517,48 +1512,10 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } } - private static HashMap<String, Integer> name2typeTable; - - static { - name2typeTable = new HashMap<>(26); - name2typeTable.put("NULL", SEXPTYPE.NILSXP.code); - /* real types */ - name2typeTable.put("symbol", SEXPTYPE.SYMSXP.code); - name2typeTable.put("pairlist", SEXPTYPE.LISTSXP.code); - name2typeTable.put("closure", SEXPTYPE.CLOSXP.code); - name2typeTable.put("environment", SEXPTYPE.ENVSXP.code); - name2typeTable.put("promise", SEXPTYPE.PROMSXP.code); - name2typeTable.put("language", SEXPTYPE.LANGSXP.code); - name2typeTable.put("special", SEXPTYPE.SPECIALSXP.code); - name2typeTable.put("builtin", SEXPTYPE.BUILTINSXP.code); - name2typeTable.put("char", SEXPTYPE.CHARSXP.code); - name2typeTable.put("logical", SEXPTYPE.LGLSXP.code); - name2typeTable.put("integer", SEXPTYPE.INTSXP.code); - name2typeTable.put("double", SEXPTYPE.REALSXP.code); - /*- "real", for R <= 0.61.x */ - name2typeTable.put("complex", SEXPTYPE.CPLXSXP.code); - name2typeTable.put("character", SEXPTYPE.STRSXP.code); - name2typeTable.put("...", SEXPTYPE.DOTSXP.code); - name2typeTable.put("any", SEXPTYPE.ANYSXP.code); - name2typeTable.put("expression", SEXPTYPE.EXPRSXP.code); - name2typeTable.put("list", SEXPTYPE.VECSXP.code); - name2typeTable.put("externalptr", SEXPTYPE.EXTPTRSXP.code); - name2typeTable.put("bytecode", SEXPTYPE.BCODESXP.code); - name2typeTable.put("weakref", SEXPTYPE.WEAKREFSXP.code); - name2typeTable.put("raw", SEXPTYPE.RAWSXP.code); - name2typeTable.put("S4", SEXPTYPE.S4SXP.code); - name2typeTable.put("numeric", SEXPTYPE.REALSXP.code); - name2typeTable.put("name", SEXPTYPE.SYMSXP.code); - } - - @Override - @TruffleBoundary - public int Rf_str2type(String name) { - if (name == null) { - return -1; - } - Integer result = name2typeTable.get(name); - return result != null ? result : -1; + @Override + @TruffleBoundary + public int Rf_str2type(Object name) { + throw implementedAsNode(); } @Override @@ -1949,7 +1906,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { protected Object access(VectorWrapper receiver, Object[] arguments) { try { - // Currently, there is only one "executable" object, which is CharSXPWrapper. + // Currently, there is only one "executable" object, which is + // CharSXPWrapper. // See CharSXPWrapperMR for the EXECUTABLE message handler. assert arguments.length == 0 && receiver.vector instanceof CharSXPWrapper; return ForeignAccess.sendExecute(execMsg, receiver.vector); @@ -1972,7 +1930,22 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { private final TruffleObject vector; public VectorWrapper(TruffleObject vector) { + assert vector instanceof RObject; this.vector = vector; + NativeDataAccess.setNativeWrapper((RObject) vector, this); + } + + static Object get(TruffleObject x) { + assert x instanceof RObject; + Object wrapper = NativeDataAccess.getNativeWrapper((RObject) x); + if (wrapper != null) { + return wrapper; + } else { + wrapper = new VectorWrapper(x); + // Establish the 1-1 relationship between the object and its native wrapper + NativeDataAccess.setNativeWrapper((RObject) x, wrapper); + return wrapper; + } } public TruffleObject getVector() { @@ -1983,38 +1956,44 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { public ForeignAccess getForeignAccess() { return VectorWrapperMRForeign.ACCESS; } + + @Override + public int hashCode() { + return vector.hashCode(); + } + } @Override public Object INTEGER(Object x) { // also handles LOGICAL assert x instanceof RIntVector || x instanceof RLogicalVector || x == RNull.instance; - return new VectorWrapper(guaranteeVectorOrNull(x, RVector.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, RVector.class)); } @Override public Object LOGICAL(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RLogicalVector.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, RLogicalVector.class)); } @Override public Object REAL(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RDoubleVector.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, RDoubleVector.class)); } @Override public Object RAW(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RRawVector.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, RRawVector.class)); } @Override public Object COMPLEX(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RComplexVector.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, RComplexVector.class)); } @Override public Object R_CHAR(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, CharSXPWrapper.class)); + return VectorWrapper.get(guaranteeVectorOrNull(x, CharSXPWrapper.class)); } @Override diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/package-info.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/package-info.java index 19ebc60087b43aa9e717c0a82e3ff6f7027e67be..fc661a180f319a6b2b04c8bccec9318a9bd04788 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/package-info.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,5 @@ /** * A collection of types and {@link com.oracle.truffle.api.interop.MessageResolution} classes that * support the implementations. - * - * See {@link com.oracle.truffle.r.ffi.impl.interop.base} and - * {@link com.oracle.truffle.r.ffi.impl.interop.pcre} for similar classes specific to the - * {@link com.oracle.truffle.r.runtime.ffi.BaseRFFI} and - * {@link com.oracle.truffle.r.runtime.ffi.PCRERFFI} interfaces. */ package com.oracle.truffle.r.ffi.impl.interop; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java index 1075ab3f6368df16c2638431abd54e1193c5e20b..27448accd62d39405390e1353a3fe5ea079a1d5f 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java @@ -41,6 +41,7 @@ import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall; import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall; import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks; import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode; +import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; @@ -162,12 +163,12 @@ final class TruffleLLVM_Call implements CallRFFI { @Specialization protected static Object convert(int value) { - return RDataFactory.createIntVector(new int[]{value}, RRuntime.isNA(value)); + return RDataFactory.createIntVector(new int[]{value}, !RRuntime.isNA(value)); } @Specialization protected static Object convert(double value) { - return RDataFactory.createDoubleVector(new double[]{value}, RRuntime.isNA(value)); + return RDataFactory.createDoubleVector(new double[]{value}, !RRuntime.isNA(value)); } @Specialization @@ -182,12 +183,12 @@ final class TruffleLLVM_Call implements CallRFFI { @Specialization protected static Object convert(byte value) { - return RDataFactory.createLogicalVector(new byte[]{value}, RRuntime.isNA(value)); + return RDataFactory.createLogicalVector(new byte[]{value}, !RRuntime.isNA(value)); } @Specialization protected static Object convert(String value) { - return RDataFactory.createStringVector(new String[]{value}, RRuntime.isNA(value)); + return RDataFactory.createStringVector(new String[]{value}, !RRuntime.isNA(value)); } @Fallback @@ -259,6 +260,14 @@ final class TruffleLLVM_Call implements CallRFFI { return result; } catch (InteropException ex) { throw RInternalError.shouldNotReachHere(ex); + } catch (Exception ex) { + if (ex.getCause() instanceof RError) { + // Sulong wraps an error having occurred in an upcall, so let's propagate the + // wrapped one instead of the Sulong one. + throw (RError) ex.getCause(); + } else { + throw ex; + } } finally { RContext.getRForeignAccessFactory().setIsNull(isNullSetting); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java index 568b273a72b0de402d520a02798a4940a67f643b..f934408376f508f80b0035af089d84c9f1622f2f 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java @@ -23,14 +23,22 @@ package com.oracle.truffle.r.ffi.impl.llvm; import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -39,6 +47,8 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RPlatform; +import com.oracle.truffle.r.runtime.RPlatform.OSInfo; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ContextState; import com.oracle.truffle.r.runtime.ffi.DLL; @@ -63,6 +73,18 @@ import com.oracle.truffle.r.runtime.ffi.DLLRFFI; * */ public class TruffleLLVM_DLL implements DLLRFFI { + /* + * The LIBS file, which is included in the LLVM archive, enumerates native dynamic libraries to + * be linked with the LLVM library in the archive. + */ + private static final String LIBS = "LIBS"; + + private static final Set<String> ignoredNativeLibs = new HashSet<>(); + static { + ignoredNativeLibs.add("Rblas"); + ignoredNativeLibs.add("Rlapack"); + } + static class ContextStateImpl implements RContext.ContextState { /** * When a new {@link RContext} is created we have to re-parse the libR modules, @@ -121,7 +143,19 @@ public class TruffleLLVM_DLL implements DLLRFFI { boolean match(String name); } - public static LLVM_IR[] getZipLLVMIR(String path) { + public static final class LLVMArchive { + public final LLVM_IR[] irs; + public final List<String> nativeLibs; + + private LLVMArchive(LLVM_IR[] irs, List<String> nativeLibs) { + super(); + this.irs = irs; + this.nativeLibs = nativeLibs; + } + } + + public static LLVMArchive getZipLLVMIR(String path) { + List<String> nativeLibs = Collections.emptyList(); try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(path)))) { ArrayList<LLVM_IR> irList = new ArrayList<>(); while (true) { @@ -130,24 +164,28 @@ public class TruffleLLVM_DLL implements DLLRFFI { break; } int size = (int) entry.getSize(); - byte[] bc = new byte[size]; + byte[] bytes = new byte[size]; int n; int totalRead = 0; - while (totalRead < size && (n = zis.read(bc, totalRead, size - totalRead)) != -1) { + while (totalRead < size && (n = zis.read(bytes, totalRead, size - totalRead)) != -1) { totalRead += n; } + if (LIBS.equals(entry.getName())) { + nativeLibs = getNativeLibs(bytes); + continue; + } Path zipName = Paths.get(entry.getName()); String name = zipName.getFileName().toString(); int ix = name.indexOf('.'); if (ix > 0) { name = name.substring(0, ix); } - LLVM_IR.Binary ir = new LLVM_IR.Binary(name, bc); + LLVM_IR.Binary ir = new LLVM_IR.Binary(name, bytes); irList.add(ir); // debugging if (System.getenv("FASTR_LLVM_DEBUG") != null) { try (FileOutputStream bs = new FileOutputStream(Paths.get("tmpzip", name).toString())) { - bs.write(bc); + bs.write(bytes); } try (PrintStream bs = new PrintStream(new FileOutputStream(Paths.get("tmpb64", name).toString()))) { bs.print(ir.base64); @@ -156,13 +194,24 @@ public class TruffleLLVM_DLL implements DLLRFFI { } LLVM_IR[] result = new LLVM_IR[irList.size()]; irList.toArray(result); - return result; + return new LLVMArchive(result, nativeLibs); } catch (IOException ex) { // not a zip file return null; } } + private static List<String> getNativeLibs(byte[] bytes) throws IOException { + List<String> libs = new LinkedList<>(); + try (BufferedReader libReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)))) { + String lib = null; + while ((lib = libReader.readLine()) != null) { + libs.add(lib); + } + } + return libs; + } + private static class TruffleLLVM_DLOpenNode extends Node implements DLOpenNode { @Child private TruffleLLVM_NativeDLL.TruffleLLVM_NativeDLOpen nativeDLLOpenNode; @@ -175,7 +224,8 @@ public class TruffleLLVM_DLL implements DLLRFFI { @Override public Object execute(String path, boolean local, boolean now) { try { - LLVM_IR[] irs = getZipLLVMIR(path); + LLVMArchive ar = getZipLLVMIR(path); + LLVM_IR[] irs = ar.irs; if (irs == null) { return tryOpenNative(path, local, now); } @@ -183,6 +233,8 @@ public class TruffleLLVM_DLL implements DLLRFFI { if (libName.equals("libR")) { // save for new RContexts truffleDLL.libRModules = irs; + } else { + loadNativeLibs(ar.nativeLibs); } for (LLVM_IR ir : irs) { parseLLVM(libName, ir); @@ -199,10 +251,22 @@ public class TruffleLLVM_DLL implements DLLRFFI { sb.append(t.getMessage()); t = t.getCause(); } + ex.printStackTrace(); throw new UnsatisfiedLinkError(sb.toString()); } } + private void loadNativeLibs(List<String> nativeLibs) { + OSInfo osInfo = RPlatform.getOSInfo(); + for (String nativeLib : nativeLibs) { + if (ignoredNativeLibs.contains(nativeLib)) { + continue; + } + String nativeLibName = "lib" + nativeLib + "." + osInfo.libExt; + tryOpenNative(nativeLibName, false, true); + } + } + private long tryOpenNative(String path, boolean local, boolean now) throws UnsatisfiedLinkError { if (nativeDLLOpenNode == null) { nativeDLLOpenNode = insert(new TruffleLLVM_NativeDLL.TruffleLLVM_NativeDLOpen()); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java index d6a1f4b67f5d8153fc01a3d1bf6abb775ef4b247..ad6eed382d4b3c7322dc5fbefc3d4fddc11ec70c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java @@ -40,6 +40,7 @@ import com.oracle.truffle.r.runtime.data.RDouble; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RScalar; +import com.oracle.truffle.r.runtime.data.RString; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.CEntry; @@ -108,6 +109,8 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { return RInteger.valueOf((int) x); } else if (x instanceof Byte) { return RLogical.valueOf((byte) x); + } else if (x instanceof String) { + return RString.valueOf((String) x); } else { throw RInternalError.shouldNotReachHere(); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/tools/ShowLLVMIR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/tools/ShowLLVMIR.java index 91acc85892f4595697ed8dc15351271b23478039..a606291213ba4c953413408904d4b63850e00cdb 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/tools/ShowLLVMIR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/tools/ShowLLVMIR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.io.OutputStream; import com.oracle.truffle.r.ffi.impl.llvm.LLVM_IR; import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL; +import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVMArchive; import com.oracle.truffle.r.runtime.ProcessOutputManager; public class ShowLLVMIR { @@ -64,7 +65,8 @@ public class ShowLLVMIR { usage(); } try { - LLVM_IR[] irs = TruffleLLVM_DLL.getZipLLVMIR(objPath); + LLVMArchive ar = TruffleLLVM_DLL.getZipLLVMIR(objPath); + LLVM_IR[] irs = ar.irs; if (irs == null) { System.out.printf("no llvm ir in %s\n", objPath); System.exit(1); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/BytesToNativeCharArrayCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/BytesToNativeCharArrayCallMR.java index dc51516b4fccfc8c95208324e32a5781c659ed12..96e7f6e18b8d8a2fc17ed4597feaf5211878d49b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/BytesToNativeCharArrayCallMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/BytesToNativeCharArrayCallMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import com.oracle.truffle.api.nodes.Node; @MessageResolution(receiverType = BytesToNativeCharArrayCall.class) public class BytesToNativeCharArrayCallMR { + @Resolve(message = "EXECUTE") public abstract static class BytesToNativeCharArrayCallExecute extends Node { protected java.lang.Object access(BytesToNativeCharArrayCall receiver, Object[] arguments) { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DoMakeClassNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DoMakeClassNode.java new file mode 100644 index 0000000000000000000000000000000000000000..1abceefaded81c425d756a971bee4a98a59e020b --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DoMakeClassNode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.ffi.impl.nodes; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.env.REnvironment; + +public abstract class DoMakeClassNode extends FFIUpCallNode.Arg1 { + + public static DoMakeClassNode create() { + return DoMakeClassNodeGen.create(); + } + + @Specialization + @TruffleBoundary + Object handleString(Object cls, @Cached("create()") NativeStringCastNode nscn) { + String clazz = nscn.executeObject(cls); + String name = "getClass"; + RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); + return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), true, null, clazz); + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/GetClassDefNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/GetClassDefNode.java new file mode 100644 index 0000000000000000000000000000000000000000..05f10669c977a2aa5206913e784749c7f3064553 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/GetClassDefNode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.ffi.impl.nodes; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.env.REnvironment; + +public abstract class GetClassDefNode extends FFIUpCallNode.Arg1 { + + public static GetClassDefNode create() { + return GetClassDefNodeGen.create(); + } + + @Specialization + @TruffleBoundary + Object handleString(Object cls, @Cached("create()") NativeStringCastNode nscn) { + String clazz = nscn.executeObject(cls); + String name = "getClassDef"; + RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); + return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), true, null, clazz); + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NativeStringCastNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NativeStringCastNode.java new file mode 100644 index 0000000000000000000000000000000000000000..92d7e734174965433a9a453dff0308b3106c4968 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NativeStringCastNode.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.ffi.impl.nodes; + +import static com.oracle.truffle.r.runtime.data.NativeDataAccess.readNativeString; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; + +public abstract class NativeStringCastNode extends Node { + + @Child private Node isPtrNode; + + public static NativeStringCastNode create() { + return NativeStringCastNodeGen.create(); + } + + public abstract String executeObject(Object s); + + @Specialization + @TruffleBoundary + String handleString(String s) { + return s; + } + + protected static Node createAsPointerNode() { + return Message.AS_POINTER.createNode(); + } + + protected static Node createToNativeNode() { + return Message.TO_NATIVE.createNode(); + } + + protected boolean isPointerNode(TruffleObject s) { + if (isPtrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + isPtrNode = insert(Message.IS_POINTER.createNode()); + } + return ForeignAccess.sendIsPointer(isPtrNode, s); + } + + @Specialization(guards = "isPointerNode(s)") + String handlePointerAddress(TruffleObject s, @Cached("createAsPointerNode()") Node sAsPtrNode) { + try { + return readNativeString(ForeignAccess.sendAsPointer(sAsPtrNode, s)); + } catch (UnsupportedMessageException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + + @Specialization(guards = "!isPointerNode(s)") + String handleNonPointerAddress(TruffleObject s, @Cached("createToNativeNode()") Node sToNativeNode, @Cached("createAsPointerNode()") Node sAsPtrNode) { + try { + Object sNative = ForeignAccess.sendToNative(sToNativeNode, s); + return readNativeString(ForeignAccess.sendAsPointer(sAsPtrNode, (TruffleObject) sNative)); + } catch (UnsupportedMessageException e) { + throw RInternalError.shouldNotReachHere(e); + } + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java index dc8e816a7d5ae6cf967e8facb8c3683e1b13f0c8..6378bf00df6df13562e6ff0e3f66194cd0bfb477 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java @@ -22,19 +22,11 @@ */ package com.oracle.truffle.r.ffi.impl.nodes; -import static com.oracle.truffle.r.runtime.data.NativeDataAccess.readNativeString; - import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.conn.ConnectionSupport.InvalidConnection; import com.oracle.truffle.r.runtime.conn.NativeConnections.NativeRConnection; import com.oracle.truffle.r.runtime.data.RExternalPtr; @@ -47,36 +39,11 @@ public abstract class NewCustomConnectionNode extends FFIUpCallNode.Arg4 { @Specialization @TruffleBoundary - Object handleStrings(String description, String mode, String className, RExternalPtr connAddr) { - try { - return new NativeRConnection(description, mode, className, connAddr).asVector(); - } catch (IOException e) { - return InvalidConnection.instance.asVector(); - } - } - - protected static Node createAsPointerNode() { - return Message.AS_POINTER.createNode(); - } - - @Specialization - @TruffleBoundary - Object handleAddresses(TruffleObject description, TruffleObject mode, TruffleObject className, RExternalPtr connAddr, - @Cached("createAsPointerNode()") Node descriptionAsPtrNode, @Cached("createAsPointerNode()") Node modeAsPtrNode, @Cached("createAsPointerNode()") Node classNameAsPtrNode) { - try { - return handleAddresses(ForeignAccess.sendAsPointer(descriptionAsPtrNode, description), ForeignAccess.sendAsPointer(modeAsPtrNode, mode), - ForeignAccess.sendAsPointer(classNameAsPtrNode, className), connAddr); - } catch (UnsupportedMessageException e) { - throw RInternalError.shouldNotReachHere(e); - } - } - - private static Object handleAddresses(long description, long mode, long className, RExternalPtr connAddr) { + Object handleStrings(Object description, Object mode, Object className, RExternalPtr connAddr, @Cached("create()") NativeStringCastNode nscn) { try { - return new NativeRConnection(readNativeString(description), readNativeString(mode), readNativeString(className), connAddr).asVector(); + return new NativeRConnection(nscn.executeObject(description), nscn.executeObject(mode), nscn.executeObject(className), connAddr).asVector(); } catch (IOException e) { return InvalidConnection.instance.asVector(); } } - } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/Str2TypeNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/Str2TypeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..cbc29c664e479ce754ebd79f06161476eb6e0200 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/Str2TypeNode.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.ffi.impl.nodes; + +import java.util.HashMap; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; + +public abstract class Str2TypeNode extends FFIUpCallNode.Arg1 { + + private static HashMap<String, Integer> name2typeTable; + + static { + name2typeTable = new HashMap<>(26); + name2typeTable.put("NULL", SEXPTYPE.NILSXP.code); + /* real types */ + name2typeTable.put("symbol", SEXPTYPE.SYMSXP.code); + name2typeTable.put("pairlist", SEXPTYPE.LISTSXP.code); + name2typeTable.put("closure", SEXPTYPE.CLOSXP.code); + name2typeTable.put("environment", SEXPTYPE.ENVSXP.code); + name2typeTable.put("promise", SEXPTYPE.PROMSXP.code); + name2typeTable.put("language", SEXPTYPE.LANGSXP.code); + name2typeTable.put("special", SEXPTYPE.SPECIALSXP.code); + name2typeTable.put("builtin", SEXPTYPE.BUILTINSXP.code); + name2typeTable.put("char", SEXPTYPE.CHARSXP.code); + name2typeTable.put("logical", SEXPTYPE.LGLSXP.code); + name2typeTable.put("integer", SEXPTYPE.INTSXP.code); + name2typeTable.put("double", SEXPTYPE.REALSXP.code); + /*- "real", for R <= 0.61.x */ + name2typeTable.put("complex", SEXPTYPE.CPLXSXP.code); + name2typeTable.put("character", SEXPTYPE.STRSXP.code); + name2typeTable.put("...", SEXPTYPE.DOTSXP.code); + name2typeTable.put("any", SEXPTYPE.ANYSXP.code); + name2typeTable.put("expression", SEXPTYPE.EXPRSXP.code); + name2typeTable.put("list", SEXPTYPE.VECSXP.code); + name2typeTable.put("externalptr", SEXPTYPE.EXTPTRSXP.code); + name2typeTable.put("bytecode", SEXPTYPE.BCODESXP.code); + name2typeTable.put("weakref", SEXPTYPE.WEAKREFSXP.code); + name2typeTable.put("raw", SEXPTYPE.RAWSXP.code); + name2typeTable.put("S4", SEXPTYPE.S4SXP.code); + name2typeTable.put("numeric", SEXPTYPE.REALSXP.code); + name2typeTable.put("name", SEXPTYPE.SYMSXP.code); + } + + @Child private Node clazzIsPtrNode; + + public static Str2TypeNode create() { + return Str2TypeNodeGen.create(); + } + + @Specialization + Object handleString(Object n, @Cached("create()") NativeStringCastNode sc) { + String name = sc.executeObject(n); + if (name == null) { + return -1; + } + Integer result = name2typeTable.get(name); + return result != null ? result : -1; + } + +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java index 115713fabac830b3415f1a145e1abde714fb6d5a..e6d51dbe8cf31523fe99b9882a4e1a984b8691ac 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java @@ -38,6 +38,7 @@ import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RScalarList; import com.oracle.truffle.r.runtime.data.RScalarVector; import com.oracle.truffle.r.runtime.data.RSequence; +import com.oracle.truffle.r.runtime.data.RString; public abstract class FFIWrapNode extends Node { @@ -63,6 +64,11 @@ public abstract class FFIWrapNode extends Node { return wrap(RDataFactory.createStringVectorFromScalar(value)); } + @Specialization + protected static Object wrap(RString value) { + return wrap(RDataFactory.createStringVectorFromScalar(value.getValue())); + } + @Specialization protected static Object wrap(RInteger value) { return wrap(RDataFactory.createIntVectorFromScalar(value.getValue())); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index 7151f48559114fb8d46b16b17ced7a418ab8e13e..a576084b4f92e967c536c75f70d17c849d4f3745 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -32,7 +32,9 @@ import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.GetAttrib; import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.TAG; import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.CoerceVectorNode; import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.VectorToPairListNode; +import com.oracle.truffle.r.ffi.impl.nodes.DoMakeClassNode; import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes; +import com.oracle.truffle.r.ffi.impl.nodes.GetClassDefNode; import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.LockBindingNode; import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.UnlockBindingNode; import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAARNode; @@ -57,6 +59,7 @@ import com.oracle.truffle.r.ffi.impl.nodes.NewCustomConnectionNode; import com.oracle.truffle.r.ffi.impl.nodes.RMakeExternalPtrNode; import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodes; import com.oracle.truffle.r.ffi.impl.nodes.RfEvalNode; +import com.oracle.truffle.r.ffi.impl.nodes.Str2TypeNode; import com.oracle.truffle.r.ffi.impl.nodes.TryRfEvalNode; import com.oracle.truffle.r.ffi.processor.RFFICpointer; import com.oracle.truffle.r.ffi.processor.RFFICstring; @@ -111,9 +114,11 @@ public interface StdUpCallsRFFI { void Rf_defineVar(Object symbolArg, Object value, Object envArg); - Object R_getClassDef(@RFFICstring String clazz); + @RFFIUpCallNode(GetClassDefNode.class) + Object R_getClassDef(@RFFICstring(convert = false) Object clazz); - Object R_do_MAKE_CLASS(@RFFICstring String clazz); + @RFFIUpCallNode(DoMakeClassNode.class) + Object R_do_MAKE_CLASS(@RFFICstring(convert = false) Object clazz); @RFFIUpCallNode(MiscNodes.RDoNewObjectNode.class) Object R_do_new_object(Object classDef); @@ -403,7 +408,8 @@ public interface StdUpCallsRFFI { Object R_MethodsNamespace(); - int Rf_str2type(@RFFICstring String name); + @RFFIUpCallNode(Str2TypeNode.class) + int Rf_str2type(@RFFICstring(convert = false) Object name); int FASTR_getConnectionChar(Object obj); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java index e343e52ff66e7b26db4353a73881efad020312f3..921e6b763a09c3382814df79a335406a8b2c3b23 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements MemoryC SourceSectionFilter.Builder builder = SourceSectionFilter.newBuilder(); builder.tagIs(StandardTags.StatementTag.class); SourceSectionFilter filter = builder.build(); - RInstrumentation.getInstrumenter().attachListener(filter, this); + RInstrumentation.getInstrumenter().attachExecutionEventListener(filter, this); } private void intervalElapsed() { diff --git a/com.oracle.truffle.r.native/Makefile b/com.oracle.truffle.r.native/Makefile index 514fd0857f73d08e6155749f40f68344b75049ce..159c2720d3a39a7032180944bd783e3d5d77db06 100644 --- a/com.oracle.truffle.r.native/Makefile +++ b/com.oracle.truffle.r.native/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ # questions. # -.PHONY: all clean +.PHONY: all clean export TOPDIR = $(CURDIR) export FASTR_R_HOME=$(abspath $(TOPDIR)/..) @@ -30,6 +30,15 @@ export FASTR_NATIVE_DIR = $(TOPDIR) export R_VERSION = 3.4.0 export GNUR_HOME = $(TOPDIR)/gnur/patch-build +ifeq ($(FASTR_RFFI),llvm) +ifndef FASTR_LLVM_TOOLS +ifdef FASTR_LLVM_FOR_DRAGONEGG_HOME +export FASTR_LLVM_TOOLS = $(FASTR_LLVM_FOR_DRAGONEGG_HOME)/bin +$(info FASTR_LLVM_TOOLS set to $(FASTR_LLVM_TOOLS)) +endif +endif +endif + $(info R_VERSION: $(R_VERSION)) $(info GNUR_HOME: $(GNUR_HOME)) @@ -43,7 +52,7 @@ $(info GNUR_HOME_BINARY not set. Assuming the default location at $(GNUR_HOME_BI endif # Completely accurate dependency analysis is very difficult for this project, so use a version number -# to force a clean build, and elsewhere use sentinels to avoid rebuilding when we can't compute the +# to force a clean build, and elsewhere use sentinels to avoid rebuilding when we can't compute the # dependencies accurately. all: checkversion @@ -54,7 +63,7 @@ all: checkversion $(MAKE) -C run cp version.source version.built -clean: +clean: $(MAKE) -C include clean $(MAKE) -C fficall clean $(MAKE) -C run clean diff --git a/com.oracle.truffle.r.native/fficall/Makefile b/com.oracle.truffle.r.native/fficall/Makefile index f6176fd2d0aa5d3f78ee729487b1dfa2c7a38ecf..e6e0b6a202f5e7ebfec8c341944fe6501e0b5d8d 100644 --- a/com.oracle.truffle.r.native/fficall/Makefile +++ b/com.oracle.truffle.r.native/fficall/Makefile @@ -57,7 +57,7 @@ ifeq ($(FASTR_RFFI),managed) else ifeq ($(OS_NAME),Darwin) $(DYLIB_LD) $(DYLIB_LDFLAGS) -Wl,-rpath,@loader_path/ -o $(R_LIB) $(wildcard lib/*.o) -L$(FASTR_LIB_DIR) -ldl -lRblas -lRlapack -lpcre -lz $(VERSION_FLAGS) -ifneq ($(FASTR_RFFI),llvm) +ifneq ($(FASTR_RFFI),llvm) install_name_tool -change libRblas.dylib @rpath/libRblas.dylib $(R_LIB) install_name_tool -change libRlapack.dylib @rpath/libRlapack.dylib $(R_LIB) install_name_tool -id @rpath/libR.dylib $(R_LIB) @@ -80,6 +80,7 @@ fficall.done: common.done else ifeq ($(FASTR_RFFI),llvm) +export R_PACKAGE_DIR="lib" fficall.done: common.done $(MAKE) -C src/truffle_llvm all touch fficall.done @@ -90,7 +91,7 @@ endif #nfi endif #managed common.done: - $(MAKE) -C src/common all + $(MAKE) -C src/common all touch common.done clean: @@ -109,4 +110,3 @@ endif rm -rf $(R_LIB) rm -rf fficall.done rm -rf common.done - diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index 307b1d2fcd52091e8055fa8d94262cfc8684ea77..1a6bc2c49b7a21559098ea7126a3d1a70ec9c902 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -288,9 +288,7 @@ typedef Rboolean (*call_Rf_NonNullStringMatch)(SEXP s, SEXP t); typedef SEXP (*call_getvar)(); typedef SEXP (*call_R_ParseVector)(SEXP text, int n, SEXP srcFile); typedef SEXPTYPE (*call_Rf_str2type)(const char *s); -typedef SEXP (*call_CLOENV)(SEXP closure); typedef SEXP (*call_octsize)(SEXP size); -typedef void (*call_Rf_PrintValue)(SEXP x); // connections diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Memory.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Memory.c index 1f8079ac7515c46a009fe93d244ab87af3d2020d..734c99bdd75b19f40c5ac23027972176eedcb324 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Memory.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Memory.c @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2015, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -19,22 +19,25 @@ // The table of transient objects that have been allocated dur the current FFI call static void **tMemTable; // hwm of tMemTable -static int tMemTableIndex; +static int tMemTableIndex = -1; static int tMemTableLength; void *R_chk_calloc(size_t nelem, size_t elsize); // Memory that is auto-reclaimed across FFI calls char *R_alloc(size_t n, int size) { + tMemTableIndex++; void *p = R_chk_calloc(n, size); if (tMemTableIndex >= tMemTableLength) { - int newLength = 2 * tMemTableLength; + int newLength = tMemTableLength == 0 ? 1 : 2 * tMemTableLength; void *newtMemTable = malloc(sizeof(void*) * newLength); if (newtMemTable == NULL) { fatalError("malloc failure"); } - memcpy(newtMemTable, tMemTable, tMemTableLength * sizeof(void*)); - free(tMemTable); + if (tMemTableLength > 0) { + memcpy(newtMemTable, tMemTable, tMemTableLength * sizeof(void*)); + free(tMemTable); + } tMemTable = newtMemTable; tMemTableLength = newLength; } @@ -54,9 +57,10 @@ char* S_realloc(char *p, long a, long b, int size) { void allocExit() { int i; - for (i = 0; i < tMemTableIndex; i++) { + for (i = 0; i <= tMemTableIndex; i++) { free(tMemTable[i]); } + tMemTableIndex = 0; } void *R_chk_calloc(size_t nelem, size_t elsize) { @@ -116,4 +120,3 @@ SEXP Rf_allocS4Object() { unimplemented("Rf_allocS4Object unimplemented"); return NULL; } - diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/Makefile b/com.oracle.truffle.r.native/gnur/patch/src/library/Makefile index 7c53c00be0dd72304ec050614f070433a4c29214..6861f1ebc71f116b02a5461391cfce1a6ad9fbfd 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/Makefile +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ SUBDIRS = base compiler datasets utils grDevices graphics grid parallel splines stats stats4 methods tools export FASTR_LIBRARY_DIR = $(abspath $(TOPDIR)/../library) +export R_PACKAGE_DIR="." all: libdir make_subdirs @@ -39,6 +40,6 @@ clean_subdirs: for dir in $(SUBDIRS); do \ $(MAKE) PACKAGE=$$dir -C $$dir clean || exit 1; \ done - + libdir: mkdir -p $(FASTR_LIBRARY_DIR) diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/stats/Makefile b/com.oracle.truffle.r.native/gnur/patch/src/library/stats/Makefile index 20981356dc097eca04fb87403d78872f5ff8c180..ed0b9d2ac4dced1d261355f019cbb3d9b048894a 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/stats/Makefile +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/stats/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -33,5 +33,4 @@ endif PKG_LIBS := $(LAPACK_LIBS) $(BLAS_LIBS) -L$(FASTR_LIB_DIR) $(FLIBS) PKG_INCLUDES = -I src - include ../lib.mk diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-ar b/com.oracle.truffle.r.native/llvm_tools/llvm-ar index 2462ea65edb0de5e818c42ebd2f05d7cb4263696..2045a4ef823ca58a12b1c07b6892882f551b0739 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-ar +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-ar @@ -25,13 +25,6 @@ SOURCE="$0" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" -while [[ $# -gt 0 ]] -do - f=`basename $1` - ext=${f##*.} - if [ $ext == 'o' ] - then - echo $1 >> $R_PACKAGE_DIR/libobjects - fi - shift -done +. $DIR/llvm-helper + +create_bc_archive $@ diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-c++ b/com.oracle.truffle.r.native/llvm_tools/llvm-c++ index ee6af85450f4d49ce68115f66c972da8fd3e8db7..ec93f97e3d15ef4168b0221b2e714401f2ef4b28 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-c++ +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-c++ @@ -31,12 +31,23 @@ analyze_args "$@" if [ $is_link -eq 1 ] then - extraObj=`cat $R_PACKAGE_DIR/libobjects` + extraObj="" + if [ -f "$R_PACKAGE_DIR/libobjects" ]; then + extraObj=`cat "$R_PACKAGE_DIR/libobjects"` + fi create_bc_lib $@ $extraObj else llvm_tool=clang++ get_llvm_tool + unamestr=`uname` + if [[ "$unamestr" == 'Linux' ]]; then + llvm_args="-stdlib=libc++ -I/usr/include/libcxxabi $llvm_args" + fi runit $llvm_tool_bin $llvm_args - mem2reg_opt - fake_obj + + # the llvm_ir_file is empty if the result is sent to stdout + if [ -n "$llvm_ir_file" ]; then + mem2reg_opt + fake_obj + fi fi diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-cc b/com.oracle.truffle.r.native/llvm_tools/llvm-cc index 1d88276ba548d5963757f5e6d168930e76822097..42acf7a3271e7f3dc4c266c76d8928ce8940ae91 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-cc +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-cc @@ -29,15 +29,20 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" fortran=0 analyze_args "$@" - if [ $is_link -eq 1 ] then - extraObj=`cat $R_PACKAGE_DIR/libobjects` + extraObj="" + if [ -f "$R_PACKAGE_DIR/libobjects" ]; then + extraObj=`cat "$R_PACKAGE_DIR/libobjects"` + fi create_bc_lib $@ $extraObj else llvm_tool=clang get_llvm_tool runit $llvm_tool_bin $llvm_args - mem2reg_opt - fake_obj + # the llvm_ir_file is empty if the result is sent to stdout + if [ -n "$llvm_ir_file" ]; then + mem2reg_opt + fake_obj + fi fi diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-fc b/com.oracle.truffle.r.native/llvm_tools/llvm-fc index 084f68d2df945ab446df70d3df1a56f090f34770..03bd793753a3789d904cdb23a54af2d4c1d759e6 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-fc +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-fc @@ -59,5 +59,8 @@ ll_to_bc runit $FASTR_LLVM_GFORTRAN_LLVM_AS $llvm_ir_file -o $llvm_ir_bc_file runit rm $llvm_ir_file llvm_ir_file=$llvm_ir_bc_file -mem2reg_opt -fake_obj +# the llvm_ir_file is empty if the result is sent to stdout +if [ -n "$llvm_ir_file" ]; then + mem2reg_opt + fake_obj +fi diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-helper b/com.oracle.truffle.r.native/llvm_tools/llvm-helper index 598bb39e4058d6469a6d9d94fb69e5e0af4cb252..2f06ecefc74eeeb388e7254d19e9f884609e2195 100644 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-helper +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-helper @@ -62,26 +62,26 @@ function analyze_args() { is_link=0 llvm_ir_file="" - + while [[ $# -gt 0 ]] do llvm_args+="$1 " case $1 in -o) shift - p=$1 - f=`basename $p` - d=`dirname $p` - ext=${f##*.} - if [ $ext == 'so' ] || [ $ext == 'dylib' ] - then - is_link=1 - elif [ $ext == 'o' ] - then - llvm_ir_file=${d}/${f%%.*} - llvm_ir_file+=$llvm_file_ext - llvm_args+="$llvm_ir_file " - fi + p=$1 + f=`basename $p` + d=`dirname $p` + ext=${f##*.} + if [ $ext == 'so' ] || [ $ext == 'dylib' ] + then + is_link=1 + elif [ $ext == 'o' ] + then + llvm_ir_file=${d}/${f%%.*} + llvm_ir_file+=$llvm_file_ext + llvm_args+="$llvm_ir_file " + fi ;; *) ;; @@ -96,9 +96,9 @@ function analyze_args() { # path to tool (defaults to plain ${llvm_tool}, assumed to be on the PATH) function get_llvm_tool() { - if [ -n "${FASTR_LLVM_HOME}" ] + if [ -n "${FASTR_LLVM_TOOLS}" ] then - llvm_tool_bin=${FASTR_LLVM_HOME}/${llvm_tool} + llvm_tool_bin=${FASTR_LLVM_TOOLS}/${llvm_tool} else llvm_tool_uc=`echo ${llvm_tool} | tr /a-z/ /A-Z/ | tr /+/ /P/` x=FASTR_LLVM_${llvm_tool_uc} @@ -111,7 +111,6 @@ function get_llvm_tool() { fi } - function mem2reg_opt() { llvm_tool="opt" get_llvm_tool @@ -126,40 +125,118 @@ function mem2reg_opt() { function fake_obj() { f=`basename $llvm_ir_file` d=`dirname $llvm_ir_file` - runit touch ${d}/${f%%.*}.o + runit touch ${d}/${f%%.*}.o } # Input: all the arguments to the original command line function create_bc_lib() { bcfiles="" lib="" + statlibs="$R_PACKAGE_DIR/statlibs" + linkedLibs="LIBS" + > $linkedLibs while [[ $# -gt 0 ]] do case $1 in -o) shift - lib=$1 - ;; + lib=$1 + ;; + -l*) + linkedLib=`echo $1 | cut -c 3-` + statLibFound='0' + if [ -f "$statlibs" ]; then + statLibFound=`cat "$statlibs" | grep "lib${linkedLib}.a" | wc -l` + fi + if [ $statLibFound == '0' ] + then + echo $linkedLib >> $linkedLibs + fi + ;; + -*) + # ignore other options + ;; + *) + f=$(basename $1) + ext=${f##*.} + if [ $ext == 'o' ] + then + fn="$(dirname $1)/${f%%.*}.bc" + bcfiles+="$fn " + fi + ;; + esac + shift + done + +# we do not have the luxury of controlling the name of the entry (unlike in python) +# it will be the pathname, which we will reduce to a module name on input in FastR + +# link the bitcode files into a single one using llvm-link before zipping it + llvm_tool=llvm-link + get_llvm_tool + echo "Linking $lib.bc from LLVM modules: $bcfiles" + runit $llvm_tool_bin $bcfiles -o $lib.bc + runit zip -r $lib $lib.bc $linkedLibs + rm $lib.bc +} + +# It appends objects constituting a static library to the list of extra object files. +# This list is maintained in $R_PACKAGE_DIR/libobjects and is later read in llvm-cc and +# llvm-c++ to append the object files from the list to other objects when making +# the package dynamic library. This mechanism is a workaround for the fact that the llvm +# linker does not support linking to static libraries, as the standard linker does +# through the -l and -L options. +function create_bc_archive() { + + # Create a CSV file containing all object files constituting the archive (i.e. the static library). + # The CSV has two columns: the object name in the archive and the full path of the object file. + # The object name columns serves as the join column when joining with the set of unique + # symbols objects (see below) to get the final list of objects to be linked with + # the package dynamic library in the end. + shift + archname=$1 + arargs="rcs $archname " + shift + + archObjCSVtmp="archived_objects.tmp" + archObjCSV="archived_objects.csv" + exportedObjCSV="exported_objects.csv" + > $archObjCSV + + while [[ $# -gt 0 ]] + do + case $1 in *) f=$1 ext=${f##*.} if [ $ext == 'o' ] then + fullPath=`echo $(cd $(dirname $1) && pwd -P)/$(basename $1)` fn=${f%%.*}.bc - bcfiles+="$fn " + arargs+="$fn " + echo "$(basename $fn) $fullPath" >> $archObjCSVtmp + else + arargs+="$1 " fi ;; esac shift done -# we do not have the luxury of controlling the name of the entry (unlike in python) -# it will be the pathname, which we will reduce to a module name on input in FastR + sort -d --field-separator=' ' --key=1 $archObjCSVtmp > $archObjCSV -# link the bitcode files into a single one using llvm-link before zipping it - llvm_tool=llvm-link - get_llvm_tool - runit $llvm_tool_bin $bcfiles -o $lib.bc - runit zip -r $lib $lib.bc - rm $lib.bc + # Create the archive (via llvm-ar) that is then used to read the symbol table via llvm-nm. + # The symbol table allows for selecting a set of objects exporting unique symbols. + llvm-ar $arargs + + # This command extracts a set of objects from the archive that do not export duplicate symbols + llvm-nm -print-file-name $archname | grep "\-\-\-\-" | awk -F ' ' '{print $1" "$4}' | sort -d --field-separator=' ' --key=2 -u | awk -F ':' '{print $2}' | sort -d -u > $exportedObjCSV + + # Join the archived objects CSV with the unique symbols objects CSV to get the list of objects to be statically linked to the package dynamic library. + # Append the result to the global list of extra object files. + join -t " " -1 1 -2 1 $archObjCSV $exportedObjCSV | awk -F ' ' '{print $2}' >> "$R_PACKAGE_DIR/libobjects" + + # Record the archive (static library) name to distinguish between LLVM static libs and native libs when linking (via -l) + echo $archname >> "$R_PACKAGE_DIR/statlibs" } diff --git a/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm b/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm index d9a5864d77d6d0115a2d5ab58a250f6e39a18487..c4972785f1b97ace17efcf41e7d9d36f203e2910 100644 --- a/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm +++ b/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm @@ -8,6 +8,11 @@ d i CXX = $(R_HOME)/bin/llvm-c++ . +/^CXX11 =/ +d +i +CXX11 = $(R_HOME)/bin/llvm-c++ +. /^FC =/ d i diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java index 0ca769eaa5f61d79ae53d718546f80371122e906..3fff34c2ad43ad22a05ba966c305c843cb4c8bfc 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeVisitor; import com.oracle.truffle.api.source.SourceSection; @@ -226,8 +227,8 @@ public abstract class FastRSyntaxTree extends RBuiltinNode.Arg4 { private static void printTags(RNode node) { writeString(" # tags [ ", false); for (int i = 0; i < RSyntaxTags.ALL_TAGS.length; i++) { - Class<?> tag = RSyntaxTags.ALL_TAGS[i]; - if (node.isTaggedWith(tag)) { + Class<? extends Tag> tag = RSyntaxTags.ALL_TAGS[i]; + if (node.hasTag(tag)) { writeString(tag.getSimpleName(), false); writeString(" ", false); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/DebugHandling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/DebugHandling.java index 90e5649085cbc0b8717a5aa7c1d454462b6a2679..70bda866deda77c3008f5519f9c85339645824ce 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/DebugHandling.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/DebugHandling.java @@ -169,7 +169,7 @@ public class DebugHandling { SourceSection lineSourceSection = fdn.createSection(line); SourceSectionFilter.Builder functionBuilder = RInstrumentation.createLineFilter(fdn, line, StandardTags.StatementTag.class); LineBreakpointEventListener listener = new LineBreakpointEventListener(lineSourceSection); - listener.setBinding(instrumenter.attachListener(functionBuilder.build(), listener)); + listener.setBinding(instrumenter.attachExecutionEventListener(functionBuilder.build(), listener)); RContext.getInstance().stateInstrumentation.putDebugListener(lineSourceSection, listener); } @@ -317,7 +317,7 @@ public class DebugHandling { @TruffleBoundary private void attachStepInto() { FunctionStatementsEventListener parentListener = getFunctionStatementsEventListener(functionDefinitionNode); - parentListener.stepIntoInstrument = RInstrumentation.getInstrumenter().attachListener(SourceSectionFilter.newBuilder().tagIs(StandardTags.RootTag.class).build(), + parentListener.stepIntoInstrument = RInstrumentation.getInstrumenter().attachExecutionEventListener(SourceSectionFilter.newBuilder().tagIs(StandardTags.RootTag.class).build(), new StepIntoInstrumentListener(parentListener)); } @@ -400,7 +400,7 @@ public class DebugHandling { SourceSectionFilter.Builder statementBuilder = RInstrumentation.createFunctionStatementFilter(functionDefinitionNode); statementBuilder.tagIsNot(RSyntaxTags.LoopTag.class); Instrumenter instrumenter = RInstrumentation.getInstrumenter(); - statementListener.setBinding(instrumenter.attachListener(statementBuilder.build(), statementListener)); + statementListener.setBinding(instrumenter.attachExecutionEventListener(statementBuilder.build(), statementListener)); } } @@ -408,7 +408,7 @@ public class DebugHandling { LoopStatementEventListener lser = new LoopStatementEventListener(functionDefinitionNode, text, condition, loopNode, this); loopStatementListeners.add(lser); Instrumenter instrumenter = RInstrumentation.getInstrumenter(); - lser.setBinding(instrumenter.attachListener(ssf, lser)); + lser.setBinding(instrumenter.attachExecutionEventListener(ssf, lser)); return lser; } @@ -432,7 +432,7 @@ public class DebugHandling { Instrumenter instrumenter = RInstrumentation.getInstrumenter(); SourceSectionFilter.Builder functionBuilder = RInstrumentation.createFunctionFilter(functionDefinitionNode, StandardTags.RootTag.class); - setBinding(instrumenter.attachListener(functionBuilder.build(), this)); + setBinding(instrumenter.attachExecutionEventListener(functionBuilder.build(), this)); // Next attach statement handler to all STATEMENTs except LOOPs attachStatementListener(); @@ -621,7 +621,7 @@ public class DebugHandling { // in case we did a step into that never called a function clearStepInstrument(); RBaseNode node = (RBaseNode) context.getInstrumentedNode(); - if (node.isTaggedWith(StandardTags.RootTag.class)) { + if (node.hasTag(StandardTags.RootTag.class)) { // already handled return; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java index 2bfa09ae8d6570b1fe0e5df1b21f91527c6ec625..2d2ff936bc88918e43e503817ddc5e9a77538703 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java @@ -90,7 +90,7 @@ public class TraceHandling { SourceSectionFilter.Builder builder = SourceSectionFilter.newBuilder(); builder.tagIs(StandardTags.RootTag.class); SourceSectionFilter filter = builder.build(); - RInstrumentation.getInstrumenter().attachListener(filter, fser); + RInstrumentation.getInstrumenter().attachExecutionEventListener(filter, fser); setOutputHandler(); } } @@ -105,7 +105,7 @@ public class TraceHandling { if (at == RMissing.instance) { // simple case TracerFunctionEntryEventListener listener = new TracerFunctionEntryEventListener(tracer, print); - binding = RInstrumentation.getInstrumenter().attachListener(RInstrumentation.createFunctionStartFilter(func).build(), listener); + binding = RInstrumentation.getInstrumenter().attachExecutionEventListener(RInstrumentation.createFunctionStartFilter(func).build(), listener); setOutputHandler(); RContext.getInstance().stateInstrumentation.putTraceBinding(RInstrumentation.getSourceSection(func), binding); } @@ -114,7 +114,7 @@ public class TraceHandling { private static void attachPrimitiveTraceHandler(RFunction func) { PrimitiveFunctionEntryEventListener fser = new PrimitiveFunctionEntryEventListener(); - EventBinding<TraceEventListener> binding = RInstrumentation.getInstrumenter().attachListener(RInstrumentation.createFunctionStartFilter(func).build(), fser); + EventBinding<TraceEventListener> binding = RInstrumentation.getInstrumenter().attachExecutionEventListener(RInstrumentation.createFunctionStartFilter(func).build(), fser); setOutputHandler(); RContext.getInstance().stateInstrumentation.putTraceBinding(RInstrumentation.getSourceSection(func), binding); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java index 7a8ffc3795c5d8b0b2d4a18ca4e7ead80dca0a6a..ed58d2311b2c90105134cad2a1fd45e97ce7c9cd 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java @@ -27,7 +27,7 @@ import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode; +import com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeUtil; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java index cc5a512ce2d6e324aeb8f00b5fbe3ace18c80135..f6a7f0db7d59992d0a2e306febecd6b53d6d05b5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package com.oracle.truffle.r.nodes.control; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode; +import com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RepeatingNode; import com.oracle.truffle.api.nodes.RootNode; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNode.java index 3b6ea6ba9905dfe5e19850e8b53ca7c302252a8e..c97c5fcd38bcca9e555c3f3d4f1037ac7af3edd9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNode.java @@ -24,7 +24,7 @@ package com.oracle.truffle.r.nodes.function; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrumentation.Instrumentable; +import com.oracle.truffle.api.instrumentation.ProbeNode; import com.oracle.truffle.r.runtime.Arguments; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.nodes.RInstrumentableNode; @@ -32,9 +32,13 @@ import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @TypeSystemReference(RTypes.class) -@Instrumentable(factory = com.oracle.truffle.r.nodes.function.RCallBaseNodeWrapperFactory.class) public abstract class RCallBaseNode extends RNode implements RInstrumentableNode { + @Override + public WrapperNode createWrapper(ProbeNode probe) { + return new RCallBaseNodeWrapper(this, probe); + } + public abstract Object execute(VirtualFrame frame, Object function); public abstract Arguments<RSyntaxNode> getArguments(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..3b90fa8871ecbaffbf190d3e2a1ddd3caeda14e5 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapper.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.function; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode; +import com.oracle.truffle.api.instrumentation.ProbeNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.runtime.Arguments; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; + +@NodeInfo(cost = NodeCost.NONE) +public final class RCallBaseNodeWrapper extends RCallBaseNode implements WrapperNode { + @Child private RCallBaseNode delegate; + @Child private ProbeNode probeNode; + + public RCallBaseNodeWrapper(RCallBaseNode delegate, ProbeNode probeNode) { + assert delegate != null; + this.delegate = delegate; + this.probeNode = probeNode; + } + + @Override + public Arguments<RSyntaxNode> getArguments() { + return delegate.getArguments(); + } + + @Override + public RNode getFunction() { + return delegate.getFunction(); + } + + @Override + public Node getDelegateNode() { + return delegate; + } + + @Override + public ProbeNode getProbeNode() { + return probeNode; + } + + @Override + public Object execute(VirtualFrame frame) { + Object returnValue; + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + returnValue = delegate.execute(frame); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, returnValue); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + returnValue = result; + break; + } + throw t; + } + } + return returnValue; + } + + @Override + public Object visibleExecute(VirtualFrame frame) { + Object returnValue; + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + returnValue = delegate.visibleExecute(frame); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, returnValue); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + returnValue = result; + break; + } + throw t; + } + } + return returnValue; + } + + @Override + public Object execute(VirtualFrame frame, Object function) { + Object returnValue; + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + returnValue = delegate.execute(frame, function); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, returnValue); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + returnValue = result; + break; + } + throw t; + } + } + return returnValue; + } + + @Override + public RSyntaxNode getRSyntaxNode() { + return delegate.asRSyntaxNode(); + } + + @Override + public SourceSection getSourceSection() { + return delegate.getSourceSection(); + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapperFactory.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapperFactory.java deleted file mode 100644 index a3b54e872e40f1b8ba9ae3a81d7c5c6fad7f5fd6..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallBaseNodeWrapperFactory.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.nodes.function; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrumentation.InstrumentableFactory; -import com.oracle.truffle.api.instrumentation.ProbeNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.runtime.Arguments; -import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; - -public class RCallBaseNodeWrapperFactory implements InstrumentableFactory<RCallBaseNode> { - - @NodeInfo(cost = NodeCost.NONE) - public static final class RCallBaseNodeWrapper extends RCallBaseNode implements InstrumentableFactory.WrapperNode { - @Child private RCallBaseNode delegate; - @Child private ProbeNode probeNode; - - public RCallBaseNodeWrapper(RCallBaseNode delegate, ProbeNode probeNode) { - assert delegate != null; - this.delegate = delegate; - this.probeNode = probeNode; - } - - @Override - public Arguments<RSyntaxNode> getArguments() { - return delegate.getArguments(); - } - - @Override - public RNode getFunction() { - return delegate.getFunction(); - } - - @Override - public Node getDelegateNode() { - return delegate; - } - - @Override - public ProbeNode getProbeNode() { - return probeNode; - } - - @Override - public Object execute(VirtualFrame frame) { - Object returnValue; - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - returnValue = delegate.execute(frame); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, returnValue); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - returnValue = result; - break; - } - throw t; - } - } - return returnValue; - } - - @Override - public Object visibleExecute(VirtualFrame frame) { - Object returnValue; - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - returnValue = delegate.visibleExecute(frame); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, returnValue); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - returnValue = result; - break; - } - throw t; - } - } - return returnValue; - } - - @Override - public Object execute(VirtualFrame frame, Object function) { - Object returnValue; - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - returnValue = delegate.execute(frame, function); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, returnValue); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - returnValue = result; - break; - } - throw t; - } - } - return returnValue; - } - - @Override - public RSyntaxNode getRSyntaxNode() { - return delegate.asRSyntaxNode(); - } - - @Override - public SourceSection getSourceSection() { - return delegate.getSourceSection(); - } - } - - @Override - public InstrumentableFactory.WrapperNode createWrapper(RCallBaseNode node, ProbeNode probe) { - return new RCallBaseNodeWrapper(node, probe); - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrumentation/RSyntaxTags.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrumentation/RSyntaxTags.java index 7f5b694b06537f899f0304c8765607aed29d9f80..75e32fd0802a978710322964a28bb756e54b5277 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrumentation/RSyntaxTags.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrumentation/RSyntaxTags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,16 @@ package com.oracle.truffle.r.nodes.instrumentation; import com.oracle.truffle.api.instrumentation.StandardTags; +import com.oracle.truffle.api.instrumentation.Tag; public class RSyntaxTags { - public final class LoopTag { + public final class LoopTag extends Tag { private LoopTag() { } } - public static final Class<?>[] ALL_TAGS = new Class<?>[]{StandardTags.CallTag.class, StandardTags.StatementTag.class, StandardTags.RootTag.class, RSyntaxTags.LoopTag.class}; + @SuppressWarnings("unchecked") public static final Class<? extends Tag>[] ALL_TAGS = (Class<? extends Tag>[]) new Class<?>[]{StandardTags.CallTag.class, StandardTags.StatementTag.class, + StandardTags.RootTag.class, LoopTag.class}; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java index e8738cd70ba23d5d831d231cf4b7597f037b8a7d..7bef648d8b4e38b0ad54d4f1de55b92c1c9b929b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java @@ -15,6 +15,7 @@ import static java.nio.file.StandardOpenOption.CREATE_NEW; import static java.nio.file.StandardOpenOption.WRITE; import java.io.BufferedWriter; +import java.io.File; import java.io.IOException; import java.nio.file.AccessDeniedException; import java.nio.file.FileAlreadyExistsException; @@ -368,7 +369,7 @@ public class RDeparse { // just use the first 10 hex digits to have a nicer file name if (qualifiedFunctionName != null && !qualifiedFunctionName.isEmpty() && !qualifiedFunctionName.equals("<no source>")) { - path = tmpDir.resolve(qualifiedFunctionName + "-" + printHexBinary.substring(0, 10) + ".r"); + path = tmpDir.resolve(qualifiedFunctionName.replace(File.separatorChar, '_') + "-" + printHexBinary.substring(0, 10) + ".r"); } else { path = tmpDir.resolve(printHexBinary.substring(0, 10) + ".r"); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java index 1f7f724a112834a8b6167f6033fd92acd594c93b..cf4b856b0a456b684d605d25c2fb3a05fdcec023 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java @@ -41,7 +41,6 @@ import com.oracle.truffle.r.runtime.RRuntime; */ public final class CharSXPWrapper extends RObject implements RTruffleObject { private static final CharSXPWrapper NA = new CharSXPWrapper(RRuntime.STRING_NA); - private String contents; private byte[] bytes; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java index 970c53a91db9977ee5094312eddea7c689293683..09b82c05c43a5a1e6f9dbf57cceae1b0c579f59b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java @@ -114,6 +114,16 @@ public final class NativeDataAccess { */ private long length; + /** + * It maintains the <code>1-?</code> relationship between this object and its native wrapper + * through which the native code accesses it. For instance, Sulong implements the "pointer" + * equality of two objects that are not pointers (i.e. <code>IS_POINTER</code> returns + * <code>false</code>) as the reference equality of the objects. It follows that the pointer + * comparison would fail if the same <code>RObject</code> instance were wrapped by two + * different native wrappers. + */ + private Object nativeWrapper; + NativeMirror() { this.id = counter.incrementAndGet(); } @@ -204,8 +214,8 @@ public final class NativeDataAccess { if (arg instanceof RObject) { RObject obj = (RObject) arg; NativeMirror mirror = (NativeMirror) obj.getNativeMirror(); - if (mirror == null) { - mirror = putMirrorObject(arg, obj); + if (mirror == null || mirror.id == 0) { + mirror = putMirrorObject(arg, obj, mirror); } return mirror.id; } @@ -213,16 +223,19 @@ public final class NativeDataAccess { } @TruffleBoundary - private static NativeMirror putMirrorObject(Object arg, RObject obj) { - NativeMirror mirror; - obj.setNativeMirror(mirror = arg instanceof CustomNativeMirror ? new NativeMirror(((CustomNativeMirror) arg).getCustomMirrorAddress()) : new NativeMirror()); + private static NativeMirror putMirrorObject(Object arg, RObject obj, NativeMirror oldMirror) { + NativeMirror newMirror; + obj.setNativeMirror(newMirror = arg instanceof CustomNativeMirror ? new NativeMirror(((CustomNativeMirror) arg).getCustomMirrorAddress()) : new NativeMirror()); + if (oldMirror != null) { + newMirror.nativeWrapper = oldMirror.nativeWrapper; + } // System.out.println(String.format("adding %16x = %s", mirror.id, // obj.getClass().getSimpleName())); - nativeMirrors.put(mirror.id, new WeakReference<>(obj)); + nativeMirrors.put(newMirror.id, new WeakReference<>(obj)); if (TRACE_MIRROR_ALLOCATION_SITES) { - registerAllocationSite(arg, mirror); + registerAllocationSite(arg, newMirror); } - return mirror; + return newMirror; } @TruffleBoundary @@ -662,6 +675,7 @@ public final class NativeDataAccess { return mirror.dataAddress; } + @TruffleBoundary public static String readNativeString(long addr) { int len; for (len = 0; UnsafeAdapter.UNSAFE.getByte(addr + len) != 0; len++) { @@ -691,4 +705,23 @@ public final class NativeDataAccess { mirror.length = length; } + + public static void setNativeWrapper(RObject obj, Object wrapper) { + NativeMirror mirror = (NativeMirror) obj.getNativeMirror(); + if (mirror == null) { + mirror = new NativeMirror(0); + obj.setNativeMirror(mirror); + } + mirror.nativeWrapper = wrapper; + } + + public static Object getNativeWrapper(RObject obj) { + NativeMirror mirror = (NativeMirror) obj.getNativeMirror(); + if (mirror == null) { + return null; + } else { + return mirror.nativeWrapper; + } + } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java index 1b3555e35bade73c1fea251848d3169a5205df5d..d80f67f4bfb92aa100155117965e7870442e499f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,4 +33,5 @@ public abstract class RObject { public final Object getNativeMirror() { return nativeMirror; } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index e3be9c96ea3e37a40fd7df240ff2bfbe95fa3640..8ba6f70a6a9a78a99fd0fcf5609becef434cf1af 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -390,6 +390,9 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra @Override public RPairList next() { + if (plt instanceof RLanguage) { + plt = ((RLanguage) plt).getPairList(); + } assert plt instanceof RPairList; RPairList curr = (RPairList) plt; plt = curr.cdr; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerInstrument.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerInstrument.java index 3237a99b260e4bb22c8ab79d99a8e7e38f1c1110..9d3ea450bc17547d7f86ed6c4e782e227e6e8558 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerInstrument.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerInstrument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public class MemAllocProfilerInstrument extends TruffleInstrument { MemAllocEventFactory eventFactory = new MemAllocEventFactory(env); SourceSectionFilter.Builder builder = SourceSectionFilter.newBuilder(); SourceSectionFilter filter = builder.tagIs(StandardTags.StatementTag.class).build(); - instrumenter.attachFactory(filter, eventFactory); + instrumenter.attachExecutionEventFactory(filter, eventFactory); allocationEventBinding = instrumenter.attachAllocationListener(AllocationEventFilter.newBuilder().build(), eventFactory); env.registerService(eventFactory.memAllocStacks); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java index b5ca21981bfe53d4b6a49a9e5651c54fe5a52bd6..c42a6dbd1eece79cc3d085fc7fbb8901d62a8ed8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.nodes; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeVisitor; @@ -184,9 +185,9 @@ public abstract class RBaseNode extends Node { return getRSyntaxNode().getSourceSection(); } - @Override - public boolean isTaggedWith(Class<?> tag) { - return RContext.getRRuntimeASTAccess().isTaggedWith(this, tag); + public boolean hasTag(Class<? extends Tag> tag) { + // RNode, which is instrumentable, overrides this to actually check if the node has the tag + return false; } private static final long WORK_SCALE_FACTOR = 100; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RInstrumentableNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RInstrumentableNode.java index 063887490c149cf79700490b6a29fe3796f5754e..333fbe9f21a37cc6b34b24ee6b7d8d5bce7b3fa2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RInstrumentableNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RInstrumentableNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,17 @@ */ package com.oracle.truffle.r.runtime.nodes; -import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode; +import com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode; +import com.oracle.truffle.api.instrumentation.InstrumentableNode; +import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RRuntimeASTAccess; +import com.oracle.truffle.r.runtime.context.RContext; /** * Some additional support for instrumentable nodes. */ -public interface RInstrumentableNode { +public interface RInstrumentableNode extends InstrumentableNode { /** * Unwrap a (potentially) wrapped node, returning the child. Since an AST may contain wrapper diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java index 76d4203238bc32d70b2ea1fa11c66df3a36834e4..d585d0de6206aa59094ed82bbaffe231a7aae8ce 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,17 +25,33 @@ package com.oracle.truffle.r.runtime.nodes; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrumentation.Instrumentable; +import com.oracle.truffle.api.instrumentation.ProbeNode; +import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.RTypesGen; -import com.oracle.truffle.r.runtime.nodes.instrumentation.RNodeWrapperFactory; +import com.oracle.truffle.r.runtime.nodes.instrumentation.RNodeWrapper; @TypeSystemReference(RTypes.class) -@Instrumentable(factory = RNodeWrapperFactory.class) public abstract class RNode extends RBaseNode implements RInstrumentableNode { + @Override + public boolean isInstrumentable() { + return true; + } + + @Override + public boolean hasTag(Class<? extends Tag> tag) { + return RContext.getRRuntimeASTAccess().isTaggedWith(this, tag); + } + + @Override + public WrapperNode createWrapper(ProbeNode probe) { + return new RNodeWrapper(this, probe); + } + /** * Normal execute function that is called when the return value, but not its visibility is * needed. diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f19f9fb1e8ac8b75f5e0576f7aaa846be78670fc --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapper.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.runtime.nodes.instrumentation; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrumentation.InstrumentableNode; +import com.oracle.truffle.api.instrumentation.ProbeNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; + +@NodeInfo(cost = NodeCost.NONE) +public final class RNodeWrapper extends RNode implements InstrumentableNode.WrapperNode { + @Child private RNode delegate; + @Child private ProbeNode probeNode; + + public RNodeWrapper(RNode delegate, ProbeNode probeNode) { + assert delegate != null; + assert !(delegate instanceof RNodeWrapper); + this.delegate = delegate; + this.probeNode = probeNode; + } + + @Override + public Node getDelegateNode() { + return delegate; + } + + @Override + public ProbeNode getProbeNode() { + return probeNode; + } + + @Override + public Object execute(VirtualFrame frame) { + Object returnValue; + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + returnValue = delegate.execute(frame); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, returnValue); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + returnValue = result; + break; + } + throw t; + } + } + return returnValue; + } + + @Override + public void voidExecute(VirtualFrame frame) { + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + delegate.voidExecute(frame); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, null); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + break; + } + throw t; + } + } + } + + @Override + public Object visibleExecute(VirtualFrame frame) { + Object returnValue; + for (;;) { + boolean wasOnReturnExecuted = false; + try { + probeNode.onEnter(frame); + returnValue = delegate.visibleExecute(frame); + wasOnReturnExecuted = true; + probeNode.onReturnValue(frame, returnValue); + break; + } catch (Throwable t) { + Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); + if (result == ProbeNode.UNWIND_ACTION_REENTER) { + continue; + } else if (result != null) { + returnValue = result; + break; + } + throw t; + } + } + return returnValue; + } + + @Override + public RSyntaxNode getRSyntaxNode() { + return delegate.asRSyntaxNode(); + } + + @Override + public SourceSection getSourceSection() { + return delegate.getSourceSection(); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapperFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapperFactory.java deleted file mode 100644 index fcc303d1a5dc57b82b70640a6330428418a5b24c..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/instrumentation/RNodeWrapperFactory.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.runtime.nodes.instrumentation; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrumentation.InstrumentableFactory; -import com.oracle.truffle.api.instrumentation.ProbeNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; - -public final class RNodeWrapperFactory implements InstrumentableFactory<RNode> { - - @NodeInfo(cost = NodeCost.NONE) - public static final class RNodeWrapper extends RNode implements InstrumentableFactory.WrapperNode { - @Child private RNode delegate; - @Child private ProbeNode probeNode; - - public RNodeWrapper(RNode delegate, ProbeNode probeNode) { - assert delegate != null; - assert !(delegate instanceof RNodeWrapper); - this.delegate = delegate; - this.probeNode = probeNode; - } - - @Override - public Node getDelegateNode() { - return delegate; - } - - @Override - public ProbeNode getProbeNode() { - return probeNode; - } - - @Override - public Object execute(VirtualFrame frame) { - Object returnValue; - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - returnValue = delegate.execute(frame); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, returnValue); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - returnValue = result; - break; - } - throw t; - } - } - return returnValue; - } - - @Override - public void voidExecute(VirtualFrame frame) { - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - delegate.voidExecute(frame); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, null); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - break; - } - throw t; - } - } - } - - @Override - public Object visibleExecute(VirtualFrame frame) { - Object returnValue; - for (;;) { - boolean wasOnReturnExecuted = false; - try { - probeNode.onEnter(frame); - returnValue = delegate.visibleExecute(frame); - wasOnReturnExecuted = true; - probeNode.onReturnValue(frame, returnValue); - break; - } catch (Throwable t) { - Object result = probeNode.onReturnExceptionalOrUnwind(frame, t, wasOnReturnExecuted); - if (result == ProbeNode.UNWIND_ACTION_REENTER) { - continue; - } else if (result != null) { - returnValue = result; - break; - } - throw t; - } - } - return returnValue; - } - - @Override - public RSyntaxNode getRSyntaxNode() { - return delegate.asRSyntaxNode(); - } - - @Override - public SourceSection getSourceSection() { - return delegate.getSourceSection(); - } - } - - @Override - public com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode createWrapper(RNode node, ProbeNode probe) { - return new RNodeWrapper(node, probe); - } -} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 1b4bb7f3dbce5b9f8fd9783639ea61f2b818e9ba..1a21c8090a5a601bfb60f3d7df41906514cd2d50 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -150925,8 +150925,8 @@ NULL [1] "field" "method" "staticField" "staticMethod" ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testNamesForForeignObject# -#if (!any(R.version$engine == "FastR")) { c('staticField', 'staticMethod') } else { tc <- new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestNamesClass'); sort(names(tc)) } -[1] "staticField" "staticMethod" +#if (!any(R.version$engine == "FastR")) { c(TRUE, TRUE) } else { tc <- new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestNamesClass'); c('staticField', 'staticMethod') %in% names(tc) } +[1] TRUE TRUE ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testNewArray# #if (!any(R.version$engine == "FastR")) { '[B' } else { a <- new.java.array('byte', 10L); java.class(a); } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java index 1782f4b2ef57276d7ccc638f17c53ac1acb80cd1..e37ea7538097fd365f84645c4c9845dbbe46919e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java @@ -134,7 +134,7 @@ public final class FastRSession implements RSession { ChildContextInfo ctx = ChildContextInfo.create(params, env, contextKind, contextKind == ContextKind.SHARE_NOTHING ? null : mainRContext, input, output, output); RContext.childInfo = ctx; - return Context.newBuilder("R").engine(mainEngine).build(); + return Context.newBuilder("R", "llvm").engine(mainEngine).build(); } private FastRSession() { @@ -154,7 +154,7 @@ public final class FastRSession implements RSession { ChildContextInfo info = ChildContextInfo.create(params, null, ContextKind.SHARE_NOTHING, null, input, output, output); RContext.childInfo = info; mainEngine = Engine.newBuilder().in(input).out(output).err(output).build(); - mainContext = Context.newBuilder("R").engine(mainEngine).build(); + mainContext = Context.newBuilder("R", "llvm").engine(mainEngine).build(); mainRContext = mainContext.eval(GET_CONTEXT).asHostObject(); } finally { try { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java index b193df39c62b14f5ae9334ad9b60e32b5e7b2087..d232a891eb95bd3ecd01371eaadc88e6dd457806 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java @@ -557,7 +557,7 @@ public class TestJavaInterop extends TestBase { public void testNamesForForeignObject() { assertEvalFastR("tc <- new.java.class('" + TestNamesClassNoMembers.class.getName() + "'); t <- new.external(tc); names(t)", "NULL"); assertEvalFastR("tc <- new.java.class('" + TestNamesClassNoPublicMembers.class.getName() + "'); t <- new.external(tc); names(t)", "NULL"); - assertEvalFastR("tc <- new.java.class('" + TestNamesClass.class.getName() + "'); sort(names(tc))", "c('staticField', 'staticMethod')"); + assertEvalFastR("tc <- new.java.class('" + TestNamesClass.class.getName() + "'); c('staticField', 'staticMethod') %in% names(tc)", "c(TRUE, TRUE)"); assertEvalFastR("tc <- new.java.class('" + TestNamesClass.class.getName() + "'); names(tc$staticField)", "NULL"); assertEvalFastR("tc <- new.java.class('" + TestNamesClass.class.getName() + "'); names(tc$staticMethod)", "NULL"); assertEvalFastR("tc <- new.java.class('" + TestNamesClass.class.getName() + "'); t <- new.external(tc); sort(names(t))", "c('field', 'method', 'staticField', 'staticMethod')"); diff --git a/documentation/dev/truffle_llvm_ffi.md b/documentation/dev/truffle_llvm_ffi.md index c0cbb908c0ec77477037ff3386533ea9fb05fa80..bff8c9114a7b862b5262873317c8832898a08391 100644 --- a/documentation/dev/truffle_llvm_ffi.md +++ b/documentation/dev/truffle_llvm_ffi.md @@ -65,7 +65,7 @@ FastR necessarily provides very fine control over the versions of the llvm tools The tools needed to build FastR and to install packages containing native code are `clang`, `clang++` and `opt`. Precisely which versions of these tools are used can be controlled in two ways. -1. Set `FASTR_LLVM_HOME` to a directory containing the tools, named as above. N.B. Since MacPorts uses names of the form `clang-mp-3.8` this requires using symbolic links. E.g. create a directory called, say, `llvm-3.8` and symlink to the MacPorts binary, e.g., `clang-mp-3.8` and name it as `clang`. Then set `FASTR_LLVM_HOME` to that directory. +1. Set `FASTR_LLVM_TOOLS` to a directory containing the tools, named as above. N.B. Since MacPorts uses names of the form `clang-mp-3.8` this requires using symbolic links. E.g. create a directory called, say, `llvm-3.8` and symlink to the MacPorts binary, e.g., `clang-mp-3.8` and name it as `clang`. Then set `FASTR_LLVM_TOOLS` to that directory. 2. Set `FASTR_LLVM_CLANG`, `FASTR_LLVM_CLANGPP` and `FASTR_LLVM_OPT` to the actual binary images, e.g., `export FASTR_LLVM_CLANG=/opt/local/bin/clang-mp-3.8`. Not all versions of the llvm tools can compile FastR. `clang-3.2` that is downloaded as part of the DragonEgg build is known to work. This currently is placed in `sulong/cache/tools/llvm/bin` by the DragonEgg build and, again, can be copied to a shared location. `clang-3.8` and `clang-4.0` are known not to work, but `clang-3.9` does. diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index d3b790160193fc0f5e3a94d2849209ec7f9d7f90..e83bac692d6eff3c9784b117838ac20a6aa7e46c 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -7,7 +7,7 @@ suite = { { "name" : "truffle", "subdir" : True, - "version" : "3e12bec05f7a74f9fbdcd2d2f45f262492fd1306", + "version" : "440d89a72cdeb7bc7951e37462cd30bf12fa3ae6", "urls" : [ {"url" : "https://github.com/graalvm/graal", "kind" : "git"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},