truffle-0.6.orig/0000755000000000000000000000000012460741021010650 5ustar truffle-0.6.orig/com/0000755000000000000000000000000012460741021011426 5ustar truffle-0.6.orig/com/oracle/0000755000000000000000000000000012460741021012673 5ustar truffle-0.6.orig/com/oracle/nfi/0000755000000000000000000000000012460741021013447 5ustar truffle-0.6.orig/com/oracle/nfi/NativeFunctionInterfaceRuntime.java0000644000000000000000000000406712445312576022456 0ustar /* * Copyright (c) 2013, 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.nfi; import com.oracle.nfi.api.*; /** * Class for obtaining the {@link NativeFunctionInterface} (if any) provided by the VM. */ public final class NativeFunctionInterfaceRuntime { private static final NativeFunctionInterface INSTANCE; /** * Creates a new {@link NativeFunctionInterface}. * * @throws UnsatisfiedLinkError if not running on a VM that provides a * {@link NativeFunctionInterface} */ private static native NativeFunctionInterface createInterface(); /** * Gets the {@link NativeFunctionInterface} (if any) provided by the VM. * * @return null if the VM does not provide a {@link NativeFunctionInterface} */ public static NativeFunctionInterface getNativeFunctionInterface() { return INSTANCE; } static { NativeFunctionInterface instance; try { instance = createInterface(); } catch (UnsatisfiedLinkError e) { instance = null; } INSTANCE = instance; } } truffle-0.6.orig/com/oracle/nfi/api/0000755000000000000000000000000012460741021014220 5ustar truffle-0.6.orig/com/oracle/nfi/api/NativeFunctionInterface.java0000644000000000000000000001357012445312576021662 0ustar /* * Copyright (c) 2013, 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.nfi.api; /** * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native * library. */ public interface NativeFunctionInterface { /** * Resolves and returns a handle to an open native library. This method will open the library * only if it is not already open. * * @param libPath the absolute path to the library * @return the resolved library handle * @throws UnsatisfiedLinkError if the library could not be found or opened */ NativeLibraryHandle getLibraryHandle(String libPath); /** * Determines if the underlying platform/runtime supports the notion of a default library search * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH} * environment variable. */ boolean isDefaultLibrarySearchSupported(); /** * Resolves the function pointer {@code NativeFunctionPointer} of a native function. * * @param libraries the ordered list of libraries to search for the function * @param name the name of the function to be resolved * @return a pointer to the native function, or null if the function pointer could * not be resolved */ NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name); /** * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. * * @param library the handle to a resolved library * @param name the name of the function to be resolved * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the function handle of the native function, or null if the function * handle could not be resolved */ NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes); /** * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. * * @param functionPointer a function pointer * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the function handle of the native function, or null if the function * handle could not be resolved */ NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes); /** * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. * * @param libraries the ordered list of libraries to search for the function * @param name the name of the function to be resolved * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the function handle of the native function, or null if the function * handle could not be resolved */ NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes); /** * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. * * @param name the name of the function to be resolved * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the function handle of the native function, or null if default library * searching is not {@linkplain #isDefaultLibrarySearchSupported() supported} or if the * function could not be resolved */ NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes); /** * Creates a {@link NativeFunctionPointer} from a raw value. * * @param rawValue raw function pointer * @return {@code NativeFunctionPointer} for {@code rawValue} */ NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue); } truffle-0.6.orig/com/oracle/nfi/api/NativeFunctionPointer.java0000644000000000000000000000320612445312576021375 0ustar /* * Copyright (c) 2013, 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.nfi.api; /** * An opaque representation of a native function pointer. *

* Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...) * called}. */ public interface NativeFunctionPointer { /** * Returns the name of the function. * * @return name of the function */ String getName(); /** * Returns the raw function pointer value. * * @return raw function pointer value */ long getRawValue(); } truffle-0.6.orig/com/oracle/nfi/api/NativeLibraryHandle.java0000644000000000000000000000317012445312576020767 0ustar /* * Copyright (c) 2013, 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.nfi.api; /** * An opaque representation of a native library handle. A handle is obtained via * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}. */ public interface NativeLibraryHandle { /** * Gets a name for this library. This may be the path for the file from which the library was * loaded. */ String getName(); } truffle-0.6.orig/com/oracle/nfi/api/NativeFunctionHandle.java0000644000000000000000000000333012445312576021146 0ustar /* * Copyright (c) 2013, 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.nfi.api; /** * A handle that can be used to {@linkplain #call(Object[]) call} a native function. */ public interface NativeFunctionHandle { /** * Calls the native function. *

* The caller is responsible for ensuring {@code args} comply with the platform ABI (e.g. Unix AMD64 ABI). If the library * function has struct parameters, the fields of the struct must be passed as individual * arguments. * * @param args the arguments that will be passed to the native function * @return boxed return value of the function call */ Object call(Object... args); } truffle-0.6.orig/com/oracle/truffle/0000755000000000000000000000000012460741021014342 5ustar truffle-0.6.orig/com/oracle/truffle/api/0000755000000000000000000000000012460741021015113 5ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/0000755000000000000000000000000012460741021016223 5ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeCost.java0000644000000000000000000000521112445312576020617 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.*; /** * Represents a rough estimate for the cost of a {@link Node}. This estimate can be used by runtime * systems or guest languages to implement heuristics based on Truffle ASTs. * * @see Node#getCost() */ public enum NodeCost { /** * This node has literally no costs and should be ignored for heuristics. This is particularly * useful for wrapper and profiling nodes which should not influence the heuristics. */ NONE, /** * This node has a {@link CompilerDirectives#transferToInterpreter()} or * {@link CompilerDirectives#transferToInterpreterAndInvalidate()} as its first unconditional * statement. */ UNINITIALIZED, /** * This node represents a specialized monomorphic version of an operation. */ MONOMORPHIC, /** * This node represents a polymorphic version of an operation. For multiple chained polymorphic * nodes the first may return {@link #MONOMORPHIC} and all additional nodes should return * {@link #POLYMORPHIC}. */ POLYMORPHIC, /** * This node represents a megamorphic version of an operation. This value should only be used if * the operation implementation supports monomorphism and polymorphism otherwise * {@link #MONOMORPHIC} should be used instead. */ MEGAMORPHIC; public boolean isTrivial() { return this == NONE || this == UNINITIALIZED; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/RepeatingNode.java0000644000000000000000000000265112445312576021632 0ustar /* * Copyright (c) 2012, 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.frame.*; /** * Experimental API: may change significantly without notice. */ public interface RepeatingNode { boolean executeRepeating(VirtualFrame frame); } truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeInfo.java0000644000000000000000000000474112445312576020611 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import java.lang.annotation.*; /** * Annotation for providing additional information on nodes. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface NodeInfo { /** * Short name representing the node that can be used for debugging. * * @return the short name */ String shortName() default ""; /** * Provides a rough estimate for the cost of the annotated {@link Node}. This estimate can be * used by runtime systems or guest languages to implement heuristics based on Truffle ASTs. * * @see Node#getCost() * @see NodeCost */ NodeCost cost() default NodeCost.MONOMORPHIC; /** * A human readable explanation of the purpose of the annotated {@link Node}. Can be used e.g. * for debugging or visualization purposes. * * @return the description */ String description() default ""; /** * A description, providing a user-readable explanation of the source language of the annotated * {@link Node}. Can be used e.g. for debugging or visualization purposes. Typically this * information is set only in an abstract base node for the language implementation. * * @return the description */ String language() default ""; } truffle-0.6.orig/com/oracle/truffle/api/nodes/ExplodeLoop.java0000644000000000000000000000272212445312576021337 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import java.lang.annotation.*; /** * Specifies for a method that the loops with constant number of invocations should be fully * unrolled. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ExplodeLoop { } truffle-0.6.orig/com/oracle/truffle/api/nodes/DirectCallNode.java0000644000000000000000000001634412445312576021726 0ustar /* * Copyright (c) 2012, 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; /** * Represents a direct call to a {@link CallTarget}. Direct calls are calls for which the * {@link CallTarget} remains the same for each consecutive call. This part of the Truffle API * enables the runtime system to perform additional optimizations on direct calls. * * Optimizations that can be applied to a {@link DirectCallNode} are inlining and call site * sensitive AST duplication. Inlining inlines this call site into the call graph of the parent * {@link CallTarget}. Call site sensitive AST duplication duplicates the {@link CallTarget} in an * uninitialized state to collect call site sensitive profiling information. * * Please note: This class is not intended to be subclassed by guest language implementations. * * @see IndirectCallNode for calls with a non-constant target * @see TruffleRuntime#createDirectCallNode(CallTarget) * @see #forceInlining() * @see #cloneCallTarget() */ public abstract class DirectCallNode extends Node { protected final CallTarget callTarget; protected DirectCallNode(CallTarget callTarget) { this.callTarget = callTarget; } /** * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}. * * @param arguments the arguments that should be passed to the callee * @return the return result of the call */ public abstract Object call(VirtualFrame frame, Object[] arguments); /** * Returns the originally supplied {@link CallTarget} when this call node was created. Please * note that the returned {@link CallTarget} is not necessarily the {@link CallTarget} that is * called. For that use {@link #getCurrentCallTarget()} instead. * * @return the {@link CallTarget} provided. */ public CallTarget getCallTarget() { return callTarget; } /** * Returns true if the underlying runtime system supports inlining for the * {@link CallTarget} in this {@link DirectCallNode}. * * @return true if inlining is supported. */ public abstract boolean isInlinable(); /** * Returns true if the {@link CallTarget} is forced to be inlined. A * {@link DirectCallNode} can either be inlined manually by invoking {@link #forceInlining()} or * by the runtime system which may at any point decide to inline. * * @return true if this method was inlined else false. */ public abstract boolean isInliningForced(); /** * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the * runtime system does not support inlining or it is already inlined this method has no effect. * The runtime system may decide to not inline calls which were forced to inline. */ public abstract void forceInlining(); /** * Returns true if the runtime system has decided to inline this call-site. If the * {@link DirectCallNode} was forced to inline then this does not necessarily mean that the * {@link DirectCallNode} is really going to be inlined. This depends on whether or not the * runtime system supports inlining. The runtime system may also decide to not inline calls * which were forced to inline. * * @deprecated we do not expose this information any longer. returns always false. */ @SuppressWarnings("static-method") @Deprecated public final boolean isInlined() { return false; } /** * Returns true if the runtime system supports cloning and the {@link RootNode} * returns true in {@link RootNode#isCloningAllowed()}. * * @return true if the target is allowed to be cloned. */ public abstract boolean isCallTargetCloningAllowed(); /** * Clones the {@link CallTarget} instance returned by {@link #getCallTarget()} in an * uninitialized state for this {@link DirectCallNode}. This can be sensible to gather call site * sensitive profiling information for this {@link DirectCallNode}. If * {@link #isCallTargetCloningAllowed()} returns false this method has no effect * and returns false. */ public abstract boolean cloneCallTarget(); /** * Returns true if the target of the {@link DirectCallNode} was cloned by the * runtime system or by the guest language implementation. * * @return if the target was split */ public final boolean isCallTargetCloned() { return getClonedCallTarget() != null; } /** * Returns the split {@link CallTarget} if this call site's {@link CallTarget} is cloned. * * @return the split {@link CallTarget} */ public abstract CallTarget getClonedCallTarget(); /** * Returns the used call target when {@link #call(VirtualFrame, Object[])} is invoked. If the * {@link CallTarget} was split this method returns the {@link CallTarget} returned by * {@link #getClonedCallTarget()}. * * @return the used {@link CallTarget} when node is called */ public CallTarget getCurrentCallTarget() { CallTarget split = getClonedCallTarget(); if (split != null) { return split; } else { return getCallTarget(); } } /** * Returns the {@link RootNode} associated with {@link CallTarget} returned by * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a * {@link RootNode} this method returns null. * * @see #getCurrentCallTarget() * @return the root node of the used call target */ public final RootNode getCurrentRootNode() { CallTarget target = getCurrentCallTarget(); if (target instanceof RootCallTarget) { return ((RootCallTarget) target).getRootNode(); } return null; } @Override public String toString() { return String.format("%s(target=%s)", getClass().getSimpleName(), getCurrentCallTarget()); } } truffle-0.6.orig/com/oracle/truffle/api/nodes/InvalidAssumptionException.java0000644000000000000000000000314412445312576024434 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; /** * An exception that should be thrown if an assumption is checked and the check fails. The Truffle * optimizer has special knowledge of this exception class and will never compile a catch block that * catches this exception type. */ public final class InvalidAssumptionException extends SlowPathException { private static final long serialVersionUID = -6801338218909717979L; } truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeUtil.java0000644000000000000000000011054412445312576020632 0ustar /* * Copyright (c) 2012, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import java.io.*; import java.lang.annotation.*; import java.lang.reflect.*; import java.security.*; import java.util.*; import sun.misc.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; import com.oracle.truffle.api.source.*; /** * Utility class that manages the special access methods for node instances. */ public final class NodeUtil { /** * Interface that allows the customization of field offsets used for {@link Unsafe} field * accesses. */ public interface FieldOffsetProvider { long objectFieldOffset(Field field); int getTypeSize(Class clazz); } private static final FieldOffsetProvider unsafeFieldOffsetProvider = new FieldOffsetProvider() { @Override public long objectFieldOffset(Field field) { return unsafe.objectFieldOffset(field); } @Override public int getTypeSize(Class clazz) { if (!clazz.isPrimitive()) { return Unsafe.ARRAY_OBJECT_INDEX_SCALE; } else if (clazz == int.class) { return Unsafe.ARRAY_INT_INDEX_SCALE; } else { throw new UnsupportedOperationException("unsupported field type: " + clazz); } } }; public static enum NodeFieldKind { /** The single {@link Node#getParent() parent} field. */ PARENT, /** A field annotated with {@link Child}. */ CHILD, /** A field annotated with {@link Children}. */ CHILDREN, /** A normal non-child data field of the node. */ DATA } /** * Information about a field in a {@link Node} class. */ public static final class NodeField { private final NodeFieldKind kind; private final Class type; private final String name; private long offset; protected NodeField(NodeFieldKind kind, Class type, String name, long offset) { this.kind = kind; this.type = type; this.name = name; this.offset = offset; } public NodeFieldKind getKind() { return kind; } public Class getType() { return type; } public String getName() { return name; } public long getOffset() { return offset; } public Object loadValue(Node node) { if (type == boolean.class) { return unsafe.getBoolean(node, offset); } else if (type == byte.class) { return unsafe.getByte(node, offset); } else if (type == short.class) { return unsafe.getShort(node, offset); } else if (type == char.class) { return unsafe.getChar(node, offset); } else if (type == int.class) { return unsafe.getInt(node, offset); } else if (type == long.class) { return unsafe.getLong(node, offset); } else if (type == float.class) { return unsafe.getFloat(node, offset); } else if (type == double.class) { return unsafe.getDouble(node, offset); } else { return unsafe.getObject(node, offset); } } @Override public int hashCode() { return kind.hashCode() | type.hashCode() | name.hashCode() | ((Long) offset).hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof NodeField) { NodeField other = (NodeField) obj; return offset == other.offset && name.equals(other.name) && type.equals(other.type) && kind.equals(other.kind); } return false; } } /** * Information about a {@link Node} class. A single instance of this class is allocated for * every subclass of {@link Node} that is used. */ public static final class NodeClass { private static final ClassValue nodeClasses = new ClassValue() { @SuppressWarnings("unchecked") @Override protected NodeClass computeValue(final Class clazz) { assert Node.class.isAssignableFrom(clazz); return AccessController.doPrivileged(new PrivilegedAction() { public NodeClass run() { return new NodeClass((Class) clazz, unsafeFieldOffsetProvider); } }); } }; // The comprehensive list of all fields. private final NodeField[] fields; // Separate arrays for the frequently accessed field offsets. private final long parentOffset; private final long[] childOffsets; private final long[] childrenOffsets; private final long[] cloneableOffsets; private final Class clazz; public static NodeClass get(Class clazz) { return nodeClasses.get(clazz); } public NodeClass(Class clazz, FieldOffsetProvider fieldOffsetProvider) { List fieldsList = new ArrayList<>(); long parentFieldOffset = -1; List childOffsetsList = new ArrayList<>(); List childrenOffsetsList = new ArrayList<>(); List cloneableOffsetsList = new ArrayList<>(); for (Field field : getAllFields(clazz)) { if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { continue; } NodeFieldKind kind; if (field.getDeclaringClass() == Node.class && field.getName().equals("parent")) { assert Node.class.isAssignableFrom(field.getType()); kind = NodeFieldKind.PARENT; parentFieldOffset = fieldOffsetProvider.objectFieldOffset(field); } else if (field.getAnnotation(Child.class) != null) { checkChildField(field); kind = NodeFieldKind.CHILD; childOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); } else if (field.getAnnotation(Children.class) != null) { checkChildrenField(field); kind = NodeFieldKind.CHILDREN; childrenOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); } else if (NodeCloneable.class.isAssignableFrom(field.getType())) { kind = NodeFieldKind.DATA; cloneableOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); } else { kind = NodeFieldKind.DATA; } fieldsList.add(new NodeField(kind, field.getType(), field.getName(), fieldOffsetProvider.objectFieldOffset(field))); } if (parentFieldOffset < 0) { throw new AssertionError("parent field not found"); } this.fields = fieldsList.toArray(new NodeField[fieldsList.size()]); this.parentOffset = parentFieldOffset; this.childOffsets = toLongArray(childOffsetsList); this.childrenOffsets = toLongArray(childrenOffsetsList); this.cloneableOffsets = toLongArray(cloneableOffsetsList); this.clazz = clazz; } private static boolean isNodeType(Class clazz) { return Node.class.isAssignableFrom(clazz) || (clazz.isInterface() && NodeInterface.class.isAssignableFrom(clazz)); } private static void checkChildField(Field field) { if (!isNodeType(field.getType())) { throw new AssertionError("@Child field type must be a subclass of Node or an interface extending NodeInterface (" + field + ")"); } if (Modifier.isFinal(field.getModifiers())) { throw new AssertionError("@Child field must not be final (" + field + ")"); } } private static void checkChildrenField(Field field) { if (!(field.getType().isArray() && isNodeType(field.getType().getComponentType()))) { throw new AssertionError("@Children field type must be an array of a subclass of Node or an interface extending NodeInterface (" + field + ")"); } if (!Modifier.isFinal(field.getModifiers())) { throw new AssertionError("@Children field must be final (" + field + ")"); } } public NodeField[] getFields() { return fields; } public long getParentOffset() { return parentOffset; } public long[] getChildOffsets() { return childOffsets; } public long[] getChildrenOffsets() { return childrenOffsets; } @Override public int hashCode() { return Arrays.hashCode(fields) ^ Arrays.hashCode(childOffsets) ^ Arrays.hashCode(childrenOffsets) ^ ((Long) parentOffset).hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof NodeClass) { NodeClass other = (NodeClass) obj; return Arrays.equals(fields, other.fields) && Arrays.equals(childOffsets, other.childOffsets) && Arrays.equals(childrenOffsets, other.childrenOffsets) && parentOffset == other.parentOffset; } return false; } public Iterator makeIterator(Node node) { assert clazz.isInstance(node); return new NodeIterator(node); } private final class NodeIterator implements Iterator { private final Node node; private final int childrenCount; private int index; protected NodeIterator(Node node) { this.node = node; this.index = 0; this.childrenCount = childrenCount(); } private int childrenCount() { int nodeCount = childOffsets.length; for (long fieldOffset : childrenOffsets) { Object[] children = ((Object[]) unsafe.getObject(node, fieldOffset)); if (children != null) { nodeCount += children.length; } } return nodeCount; } private Node nodeAt(int idx) { int nodeCount = childOffsets.length; if (idx < nodeCount) { return (Node) unsafe.getObject(node, childOffsets[idx]); } else { for (long fieldOffset : childrenOffsets) { Object[] nodeArray = (Object[]) unsafe.getObject(node, fieldOffset); if (idx < nodeCount + nodeArray.length) { return (Node) nodeArray[idx - nodeCount]; } nodeCount += nodeArray.length; } } return null; } private void forward() { if (index < childrenCount) { index++; } } public boolean hasNext() { return index < childrenCount; } public Node next() { try { return nodeAt(index); } finally { forward(); } } public void remove() { throw new UnsupportedOperationException(); } } } static Iterator makeIterator(Node node) { return NodeClass.get(node.getClass()).makeIterator(node); } public static Iterator makeRecursiveIterator(Node node) { return new RecursiveNodeIterator(node); } private static final class RecursiveNodeIterator implements Iterator { private final List> iteratorStack = new ArrayList<>(); public RecursiveNodeIterator(final Node node) { iteratorStack.add(new Iterator() { private boolean visited; public void remove() { throw new UnsupportedOperationException(); } public Node next() { if (visited) { throw new NoSuchElementException(); } visited = true; return node; } public boolean hasNext() { return !visited; } }); } public boolean hasNext() { return peekIterator() != null; } public Node next() { Iterator iterator = peekIterator(); if (iterator == null) { throw new NoSuchElementException(); } Node node = iterator.next(); if (node != null) { Iterator childIterator = makeIterator(node); if (childIterator.hasNext()) { iteratorStack.add(childIterator); } } return node; } private Iterator peekIterator() { int tos = iteratorStack.size() - 1; while (tos >= 0) { Iterator iterable = iteratorStack.get(tos); if (iterable.hasNext()) { return iterable; } else { iteratorStack.remove(tos--); } } return null; } public void remove() { throw new UnsupportedOperationException(); } } private static long[] toLongArray(List list) { long[] array = new long[list.size()]; for (int i = 0; i < list.size(); i++) { array[i] = list.get(i); } return array; } private static final Unsafe unsafe = getUnsafe(); private static Unsafe getUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException e) { } try { Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class); } catch (Exception e) { throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); } } @SuppressWarnings("unchecked") public static T cloneNode(T orig) { final Node clone = orig.copy(); NodeClass nodeClass = NodeClass.get(clone.getClass()); unsafe.putObject(clone, nodeClass.parentOffset, null); for (long fieldOffset : nodeClass.childOffsets) { Node child = (Node) unsafe.getObject(orig, fieldOffset); if (child != null) { Node clonedChild = cloneNode(child); unsafe.putObject(clonedChild, nodeClass.parentOffset, clone); unsafe.putObject(clone, fieldOffset, clonedChild); } } for (long fieldOffset : nodeClass.childrenOffsets) { Object[] children = (Object[]) unsafe.getObject(orig, fieldOffset); if (children != null) { Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); for (int i = 0; i < children.length; i++) { if (children[i] != null) { Node clonedChild = cloneNode((Node) children[i]); clonedChildren[i] = clonedChild; unsafe.putObject(clonedChild, nodeClass.parentOffset, clone); } } unsafe.putObject(clone, fieldOffset, clonedChildren); } } for (long fieldOffset : nodeClass.cloneableOffsets) { Object cloneable = unsafe.getObject(clone, fieldOffset); if (cloneable != null && cloneable == unsafe.getObject(orig, fieldOffset)) { unsafe.putObject(clone, fieldOffset, ((NodeCloneable) cloneable).clone()); } } return (T) clone; } public static List findNodeChildren(Node node) { List nodes = new ArrayList<>(); NodeClass nodeClass = NodeClass.get(node.getClass()); for (long fieldOffset : nodeClass.childOffsets) { Object child = unsafe.getObject(node, fieldOffset); if (child != null) { nodes.add((Node) child); } } for (long fieldOffset : nodeClass.childrenOffsets) { Object[] children = (Object[]) unsafe.getObject(node, fieldOffset); if (children != null) { for (Object child : children) { if (child != null) { nodes.add((Node) child); } } } } return nodes; } public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { NodeClass nodeClass = NodeClass.get(parent.getClass()); for (long fieldOffset : nodeClass.getChildOffsets()) { if (unsafe.getObject(parent, fieldOffset) == oldChild) { assert assertAssignable(nodeClass, fieldOffset, newChild); unsafe.putObject(parent, fieldOffset, newChild); return true; } } for (long fieldOffset : nodeClass.getChildrenOffsets()) { Object arrayObject = unsafe.getObject(parent, fieldOffset); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { if (array[i] == oldChild) { assert assertAssignable(nodeClass, fieldOffset, newChild); array[i] = newChild; return true; } } } } return false; } private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) { if (newValue == null) { return true; } for (NodeField field : clazz.getFields()) { if (field.getOffset() == fieldOffset) { if (field.getKind() == NodeFieldKind.CHILD) { if (field.getType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } else if (field.getKind() == NodeFieldKind.CHILDREN) { if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } } } throw new IllegalArgumentException(); } /** Returns all declared fields in the class hierarchy. */ private static Field[] getAllFields(Class clazz) { Field[] declaredFields = clazz.getDeclaredFields(); if (clazz.getSuperclass() != null) { return concat(getAllFields(clazz.getSuperclass()), declaredFields); } return declaredFields; } public static T[] concat(T[] first, T[] second) { T[] result = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, result, first.length, second.length); return result; } /** * Get the nth parent of a node, where the 0th parent is the node itself. Returns null if there * are less than n ancestors. */ public static Node getNthParent(Node node, int n) { Node parent = node; for (int i = 0; i < n; i++) { parent = parent.getParent(); if (parent == null) { return null; } } return parent; } /** find annotation in class/interface hierarchy. */ public static T findAnnotation(Class clazz, Class annotationClass) { if (clazz.getAnnotation(annotationClass) != null) { return clazz.getAnnotation(annotationClass); } else { for (Class intf : clazz.getInterfaces()) { if (intf.getAnnotation(annotationClass) != null) { return intf.getAnnotation(annotationClass); } } if (clazz.getSuperclass() != null) { return findAnnotation(clazz.getSuperclass(), annotationClass); } } return null; } public static T findParent(Node start, Class clazz) { Node parent = start.getParent(); if (parent == null) { return null; } else if (clazz.isInstance(parent)) { return clazz.cast(parent); } else { return findParent(parent, clazz); } } public static List findAllParents(Node start, Class clazz) { List parents = new ArrayList<>(); T parent = findParent(start, clazz); while (parent != null) { parents.add(parent); parent = findParent((Node) parent, clazz); } return parents; } public static List collectNodes(Node parent, Node child) { List nodes = new ArrayList<>(); Node current = child; while (current != null) { nodes.add(current); if (current == parent) { return nodes; } current = current.getParent(); } throw new IllegalArgumentException("Node " + parent + " is not a parent of " + child + "."); } public static T findFirstNodeInstance(Node root, Class clazz) { for (Node childNode : findNodeChildren(root)) { if (clazz.isInstance(childNode)) { return clazz.cast(childNode); } else { T node = findFirstNodeInstance(childNode, clazz); if (node != null) { return node; } } } return null; } public static List findAllNodeInstances(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { public boolean visit(Node node) { if (clazz.isInstance(node)) { nodeList.add(clazz.cast(node)); } return true; } }); return nodeList; } /** * Like {@link #findAllNodeInstances(Node, Class)} but do not visit children of found nodes. */ public static List findNodeInstancesShallow(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { public boolean visit(Node node) { if (clazz.isInstance(node)) { nodeList.add(clazz.cast(node)); return false; } return true; } }); return nodeList; } public static int countNodes(Node root) { Iterator nodeIterator = makeRecursiveIterator(root); int count = 0; while (nodeIterator.hasNext()) { nodeIterator.next(); count++; } return count; } public static int countNodes(Node root, NodeCountFilter filter) { Iterator nodeIterator = makeRecursiveIterator(root); int count = 0; while (nodeIterator.hasNext()) { Node node = nodeIterator.next(); if (node != null && filter.isCounted(node)) { count++; } } return count; } public interface NodeCountFilter { boolean isCounted(Node node); } public static String printCompactTreeToString(Node node) { StringWriter out = new StringWriter(); printCompactTree(new PrintWriter(out), null, node, 1); return out.toString(); } public static void printCompactTree(OutputStream out, Node node) { printCompactTree(new PrintWriter(out), null, node, 1); } private static void printCompactTree(PrintWriter p, Node parent, Node node, int level) { if (node == null) { return; } for (int i = 0; i < level; i++) { p.print(" "); } if (parent == null) { p.println(nodeName(node)); } else { p.print(getNodeFieldName(parent, node, "unknownField")); p.print(" = "); p.println(nodeName(node)); } for (Node child : node.getChildren()) { printCompactTree(p, node, child, level + 1); } p.flush(); } public static String printSourceAttributionTree(Node node) { StringWriter out = new StringWriter(); printSourceAttributionTree(new PrintWriter(out), null, node, 1); return out.toString(); } public static void printSourceAttributionTree(OutputStream out, Node node) { printSourceAttributionTree(new PrintWriter(out), null, node, 1); } private static void printSourceAttributionTree(PrintWriter p, Node parent, Node node, int level) { if (node == null) { return; } if (parent == null) { // Add some preliminary information before starting with the root node final SourceSection sourceSection = node.getSourceSection(); if (sourceSection != null) { final String txt = sourceSection.getSource().getCode(); p.println("Full source len=(" + txt.length() + ") ___" + txt + "___"); p.println("AST source attribution:"); } } final StringBuilder sb = new StringBuilder(); for (int i = 0; i < level; i++) { sb.append("| "); } if (parent != null) { sb.append(getNodeFieldName(parent, node, "")); } sb.append(" (" + node.getClass().getSimpleName() + ") "); sb.append(printSyntaxTags(node)); sb.append(displaySourceAttribution(node)); p.println(sb.toString()); for (Node child : node.getChildren()) { printSourceAttributionTree(p, node, child, level + 1); } p.flush(); } private static String getNodeFieldName(Node parent, Node node, String defaultName) { NodeField[] fields = NodeClass.get(parent.getClass()).fields; for (NodeField field : fields) { Object value = field.loadValue(parent); if (field.getKind() == NodeFieldKind.CHILD && value == node) { return field.getName(); } else if (field.getKind() == NodeFieldKind.CHILDREN) { int index = 0; for (Object arrayNode : (Object[]) value) { if (arrayNode == node) { return field.getName() + "[" + index + "]"; } index++; } } } return defaultName; } /** * Returns a string listing the {@linkplain SyntaxTag syntax tags}, if any, associated with a * node: *

*/ public static String printSyntaxTags(final Object node) { if (node instanceof WrapperNode) { final Probe probe = ((WrapperNode) node).getProbe(); final Collection syntaxTags = probe.getSyntaxTags(); final StringBuilder sb = new StringBuilder(); String prefix = ""; sb.append("["); for (SyntaxTag tag : syntaxTags) { sb.append(prefix); prefix = ","; sb.append(tag.toString()); } sb.append("]"); return sb.toString(); } return ""; } /** * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This * print method does not check for cycles in the node structure. * * @param out the stream to print to. * @param node the root node to write */ public static void printTree(OutputStream out, Node node) { printTree(new PrintWriter(out), node); } public static String printTreeToString(Node node) { StringWriter out = new StringWriter(); printTree(new PrintWriter(out), node); return out.toString(); } public static void printTree(PrintWriter p, Node node) { printTree(p, node, 1); p.println(); p.flush(); } private static void printTree(PrintWriter p, Node node, int level) { if (node == null) { p.print("null"); return; } p.print(nodeName(node)); ArrayList childFields = new ArrayList<>(); String sep = ""; p.print("("); for (NodeField field : NodeClass.get(node.getClass()).fields) { if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { childFields.add(field); } else if (field.getKind() == NodeFieldKind.DATA) { p.print(sep); sep = ", "; p.print(field.getName()); p.print(" = "); p.print(field.loadValue(node)); } } p.print(")"); if (childFields.size() != 0) { p.print(" {"); for (NodeField field : childFields) { printNewLine(p, level); p.print(field.getName()); Object value = field.loadValue(node); if (value == null) { p.print(" = null "); } else if (field.getKind() == NodeFieldKind.CHILD) { p.print(" = "); printTree(p, (Node) value, level + 1); } else if (field.getKind() == NodeFieldKind.CHILDREN) { printChildren(p, level, value); } } printNewLine(p, level - 1); p.print("}"); } } private static void printChildren(PrintWriter p, int level, Object value) { String sep; Object[] children = (Object[]) value; p.print(" = ["); sep = ""; for (Object child : children) { p.print(sep); sep = ", "; printTree(p, (Node) child, level + 1); } p.print("]"); } private static void printNewLine(PrintWriter p, int level) { p.println(); for (int i = 0; i < level; i++) { p.print(" "); } } private static String nodeName(Node node) { return node.getClass().getSimpleName(); } private static String displaySourceAttribution(Node node) { final SourceSection section = node.getSourceSection(); if (section instanceof NullSourceSection) { return "source: " + section.getShortDescription(); } if (section != null) { final String srcText = section.getCode(); final StringBuilder sb = new StringBuilder(); sb.append("source:"); sb.append(" (" + section.getCharIndex() + "," + (section.getCharEndIndex() - 1) + ")"); sb.append(" len=" + srcText.length()); sb.append(" text=\"" + srcText + "\""); return sb.toString(); } return ""; } public static boolean verify(Node root) { Iterable children = root.getChildren(); for (Node child : children) { if (child != null) { if (child.getParent() != root) { throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root)); } verify(child); } } return true; } private static String toStringWithClass(Object obj) { return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")"; } static void traceRewrite(Node oldNode, Node newNode, CharSequence reason) { if (TruffleOptions.TraceRewritesFilterFromCost != null) { if (filterByKind(oldNode, TruffleOptions.TraceRewritesFilterFromCost)) { return; } } if (TruffleOptions.TraceRewritesFilterToCost != null) { if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { return; } } String filter = TruffleOptions.TraceRewritesFilterClass; Class from = oldNode.getClass(); Class to = newNode.getClass(); if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { return; } final SourceSection reportedSourceSection = oldNode.getEncapsulatingSourceSection(); PrintStream out = System.out; out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", oldNode.toString(), formatNodeInfo(oldNode), formatNodeInfo(newNode), reason != null && reason.length() > 0 ? reason : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); } private static String formatNodeInfo(Node node) { String cost = "?"; switch (node.getCost()) { case NONE: cost = "G"; break; case MONOMORPHIC: cost = "M"; break; case POLYMORPHIC: cost = "P"; break; case MEGAMORPHIC: cost = "G"; break; default: cost = "?"; break; } return cost + " " + node.getClass().getSimpleName(); } private static boolean filterByKind(Node node, NodeCost cost) { return node.getCost() == cost; } private static boolean filterByContainsClassName(Class from, String filter) { Class currentFrom = from; while (currentFrom != null) { if (currentFrom.getName().contains(filter)) { return false; } currentFrom = currentFrom.getSuperclass(); } return true; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/SlowPathException.java0000644000000000000000000000510412445312576022522 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.*; /** * An exception thrown to enter a slow path. The Truffle optimizer has special knowledge of this * exception class and will never compile a catch block that catches this exception type. */ public class SlowPathException extends Exception { private static final long serialVersionUID = 3676602078425211386L; /** * Creates an exception thrown to enter a slow path. */ public SlowPathException() { CompilerDirectives.transferToInterpreter(); } /** * Creates an exception thrown to enter a slow path. */ public SlowPathException(String message, Throwable cause) { super(message, cause); CompilerDirectives.transferToInterpreter(); } /** * Creates an exception thrown to enter a slow path. */ public SlowPathException(String message) { super(message); CompilerDirectives.transferToInterpreter(); } /** * Creates an exception thrown to enter a slow path. */ public SlowPathException(Throwable cause) { super(cause); CompilerDirectives.transferToInterpreter(); } /** * For performance reasons, this exception does not record any stack trace information. */ @SuppressWarnings("sync-override") @Override public Throwable fillInStackTrace() { return null; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/IndirectCallNode.java0000644000000000000000000000432012445312576022244 0ustar /* * Copyright (c) 2012, 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; /** * Represents an indirect call to a {@link CallTarget}. Indirect calls are calls for which the * {@link CallTarget} may change dynamically for each consecutive call. This part of the Truffle API * enables the runtime system to perform additional optimizations on indirect calls. * * Please note: This class is not intended to be sub classed by guest language implementations. * * @see DirectCallNode for faster calls with a constantly known {@link CallTarget}. */ public abstract class IndirectCallNode extends Node { /** * Performs an indirect call to the given {@link CallTarget} target with the provided arguments. * * @param frame the caller frame * @param target the {@link CallTarget} to call * @param arguments the arguments to provide * @return the return value of the call */ public abstract Object call(VirtualFrame frame, CallTarget target, Object[] arguments); } truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeVisitor.java0000644000000000000000000000322412445312576021350 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; /** * Visitor for trees of nodes. */ public interface NodeVisitor { /** * This visitor method is called for every node in the tree. Its return value determines if the * children of this node should be excluded in the iteration. * * @param node the node that is currently visited * @return {@code true} if the children should be visited too, {@code false} otherwise */ boolean visit(Node node); } truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeInterface.java0000644000000000000000000000251712445312576021615 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; /** * Common base interface for all Truffle nodes. * * @see Node */ public interface NodeInterface { } truffle-0.6.orig/com/oracle/truffle/api/nodes/UnexpectedResultException.java0000644000000000000000000000417412445312576024272 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.*; /** * An exception that should be thrown if the return value cannot be represented as a value of the * return type. The Truffle optimizer has special knowledge of this exception class and will never * compile a catch block that catches this exception type. */ public final class UnexpectedResultException extends SlowPathException { private static final long serialVersionUID = 3676602078425211386L; private final Object result; /** * Creates the exception with the alternative result that cannot be represented as a value of * the return type. * * @param result the alternative result */ public UnexpectedResultException(Object result) { CompilerDirectives.transferToInterpreter(); this.result = result; } /** * @return the unexpected result */ public Object getResult() { return result; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/GraphPrintVisitor.java0000644000000000000000000003574712445312576022560 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import java.io.*; import java.lang.annotation.*; import java.net.*; import java.util.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import org.w3c.dom.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; import com.oracle.truffle.api.nodes.NodeUtil.NodeField; import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; /** * Utility class for creating output for the ideal graph visualizer. */ public class GraphPrintVisitor { public static final String GraphVisualizerAddress = "127.0.0.1"; public static final int GraphVisualizerPort = 4444; private Document dom; private Map nodeMap; private List edgeList; private Map prevNodeMap; private int id; private Element graphDocument; private Element groupElement; private Element graphElement; private Element nodesElement; private Element edgesElement; public GraphPrintVisitor() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); dom = db.newDocument(); } catch (ParserConfigurationException ex) { throw new RuntimeException(ex); } graphDocument = dom.createElement("graphDocument"); dom.appendChild(graphDocument); } public GraphPrintVisitor beginGroup(String groupName) { groupElement = dom.createElement("group"); graphDocument.appendChild(groupElement); Element properties = dom.createElement("properties"); groupElement.appendChild(properties); if (!groupName.isEmpty()) { // set group name Element propName = dom.createElement("p"); propName.setAttribute("name", "name"); propName.setTextContent(groupName); properties.appendChild(propName); } // forget old nodes nodeMap = prevNodeMap = null; edgeList = null; return this; } public GraphPrintVisitor beginGraph(String graphName) { if (null == groupElement) { beginGroup(""); } else if (null != prevNodeMap) { // TODO: difference (create removeNode,removeEdge elements) } graphElement = dom.createElement("graph"); groupElement.appendChild(graphElement); Element properties = dom.createElement("properties"); graphElement.appendChild(properties); nodesElement = dom.createElement("nodes"); graphElement.appendChild(nodesElement); edgesElement = dom.createElement("edges"); graphElement.appendChild(edgesElement); // set graph name Element propName = dom.createElement("p"); propName.setAttribute("name", "name"); propName.setTextContent(graphName); properties.appendChild(propName); // save old nodes prevNodeMap = nodeMap; nodeMap = new HashMap<>(); edgeList = new ArrayList<>(); return this; } @Override public String toString() { if (null != dom) { try { Transformer tr = TransformerFactory.newInstance().newTransformer(); tr.setOutputProperty(OutputKeys.INDENT, "yes"); tr.setOutputProperty(OutputKeys.METHOD, "xml"); tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); StringWriter strWriter = new StringWriter(); tr.transform(new DOMSource(dom), new StreamResult(strWriter)); return strWriter.toString(); } catch (TransformerException e) { e.printStackTrace(); } } return ""; } public void printToFile(File f) { try { Transformer tr = TransformerFactory.newInstance().newTransformer(); tr.setOutputProperty(OutputKeys.INDENT, "yes"); tr.setOutputProperty(OutputKeys.METHOD, "xml"); tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); tr.transform(new DOMSource(dom), new StreamResult(new FileOutputStream(f))); } catch (TransformerException | FileNotFoundException e) { e.printStackTrace(); } } public void printToSysout() { try { Transformer tr = TransformerFactory.newInstance().newTransformer(); tr.setOutputProperty(OutputKeys.INDENT, "yes"); tr.setOutputProperty(OutputKeys.METHOD, "xml"); tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); tr.transform(new DOMSource(dom), new StreamResult(System.out)); } catch (TransformerException e) { e.printStackTrace(); } } public void printToNetwork(boolean ignoreErrors) { try { Transformer tr = TransformerFactory.newInstance().newTransformer(); tr.setOutputProperty(OutputKeys.METHOD, "xml"); Socket socket = new Socket(GraphVisualizerAddress, GraphVisualizerPort); BufferedOutputStream stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000); tr.transform(new DOMSource(dom), new StreamResult(stream)); } catch (TransformerException | IOException e) { if (!ignoreErrors) { e.printStackTrace(); } } } private String nextId() { return String.valueOf(id++); } private String oldOrNextId(Object node) { if (null != prevNodeMap && prevNodeMap.containsKey(node)) { Element nodeElem = prevNodeMap.get(node); return nodeElem.getAttribute("id"); } else { return nextId(); } } protected Element getElementByObject(Object op) { return nodeMap.get(op); } protected void createElementForNode(Object node) { boolean exists = nodeMap.containsKey(node); if (!exists || NodeUtil.findAnnotation(node.getClass(), GraphDuplicate.class) != null) { Element nodeElem = dom.createElement("node"); nodeElem.setAttribute("id", !exists ? oldOrNextId(node) : nextId()); nodeMap.put(node, nodeElem); Element properties = dom.createElement("properties"); nodeElem.appendChild(properties); nodesElement.appendChild(nodeElem); setNodeProperty(node, "name", node.getClass().getSimpleName().replaceFirst("Node$", "")); NodeInfo nodeInfo = node.getClass().getAnnotation(NodeInfo.class); if (nodeInfo != null) { setNodeProperty(node, "cost", nodeInfo.cost()); if (!nodeInfo.shortName().isEmpty()) { setNodeProperty(node, "shortName", nodeInfo.shortName()); } } setNodeProperty(node, "class", node.getClass().getSimpleName()); if (node instanceof Node) { readNodeProperties((Node) node); copyDebugProperties((Node) node); } } } private Element getPropertyElement(Object node, String propertyName) { Element nodeElem = getElementByObject(node); Element propertiesElem = (Element) nodeElem.getElementsByTagName("properties").item(0); if (propertiesElem == null) { return null; } NodeList propList = propertiesElem.getElementsByTagName("p"); for (int i = 0; i < propList.getLength(); i++) { Element p = (Element) propList.item(i); if (propertyName.equals(p.getAttribute("name"))) { return p; } } return null; } protected void setNodeProperty(Object node, String propertyName, Object value) { Element nodeElem = getElementByObject(node); Element propElem = getPropertyElement(node, propertyName); // if property exists, replace // its value if (null == propElem) { // if property doesn't exist, create one propElem = dom.createElement("p"); propElem.setAttribute("name", propertyName); nodeElem.getElementsByTagName("properties").item(0).appendChild(propElem); } propElem.setTextContent(String.valueOf(value)); } private void copyDebugProperties(Node node) { Map debugProperties = node.getDebugProperties(); for (Map.Entry property : debugProperties.entrySet()) { setNodeProperty(node, property.getKey(), property.getValue()); } } private void readNodeProperties(Node node) { NodeField[] fields = NodeClass.get(node.getClass()).getFields(); for (NodeField field : fields) { if (field.getKind() == NodeFieldKind.DATA) { String key = field.getName(); if (getPropertyElement(node, key) == null) { Object value = field.loadValue(node); setNodeProperty(node, key, value); } } } } protected void connectNodes(Object a, Object b, String label) { if (nodeMap.get(a) == null || nodeMap.get(b) == null) { return; } String fromId = nodeMap.get(a).getAttribute("id"); String toId = nodeMap.get(b).getAttribute("id"); // count existing to-edges int count = 0; for (Element e : edgeList) { if (e.getAttribute("to").equals(toId)) { ++count; } } Element edgeElem = dom.createElement("edge"); edgeElem.setAttribute("from", fromId); edgeElem.setAttribute("to", toId); edgeElem.setAttribute("index", String.valueOf(count)); if (label != null) { edgeElem.setAttribute("label", label); } edgesElement.appendChild(edgeElem); edgeList.add(edgeElem); } public GraphPrintVisitor visit(Object node) { if (null == graphElement) { beginGraph("truffle tree"); } // if node is visited once again, skip if (getElementByObject(node) != null && NodeUtil.findAnnotation(node.getClass(), GraphDuplicate.class) == null) { return this; } // respect node's custom handler if (NodeUtil.findAnnotation(node.getClass(), CustomGraphPrintHandler.class) != null) { Class customHandlerClass = NodeUtil.findAnnotation(node.getClass(), CustomGraphPrintHandler.class).handler(); try { GraphPrintHandler customHandler = customHandlerClass.newInstance(); customHandler.visit(node, new GraphPrintAdapter()); } catch (InstantiationException | IllegalAccessException e) { assert false : e; } } else if (NodeUtil.findAnnotation(node.getClass(), NullGraphPrintHandler.class) != null) { // ignore } else { // default handler createElementForNode(node); if (node instanceof Node) { for (Map.Entry child : findNamedNodeChildren((Node) node).entrySet()) { visit(child.getValue()); connectNodes(node, child.getValue(), child.getKey()); } } } return this; } private static LinkedHashMap findNamedNodeChildren(Node node) { LinkedHashMap nodes = new LinkedHashMap<>(); NodeClass nodeClass = NodeClass.get(node.getClass()); for (NodeField field : nodeClass.getFields()) { NodeFieldKind kind = field.getKind(); if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) { Object value = field.loadValue(node); if (value != null) { if (kind == NodeFieldKind.CHILD) { nodes.put(field.getName(), (Node) value); } else if (kind == NodeFieldKind.CHILDREN) { Object[] children = (Object[]) value; for (int i = 0; i < children.length; i++) { if (children[i] != null) { nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); } } } } } } return nodes; } public class GraphPrintAdapter { public void createElementForNode(Object node) { GraphPrintVisitor.this.createElementForNode(node); } public void visit(Object node) { GraphPrintVisitor.this.visit(node); } public void connectNodes(Object node, Object child) { GraphPrintVisitor.this.connectNodes(node, child, null); } public void setNodeProperty(Object node, String propertyName, Object value) { GraphPrintVisitor.this.setNodeProperty(node, propertyName, value); } } public interface GraphPrintHandler { void visit(Object node, GraphPrintAdapter gPrinter); } public interface ChildSupplier { /** Supplies an additional child if available. */ Object startNode(Object callNode); void endNode(Object callNode); } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CustomGraphPrintHandler { Class handler(); } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface NullGraphPrintHandler { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface GraphDuplicate { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface HiddenField { } } truffle-0.6.orig/com/oracle/truffle/api/nodes/ControlFlowException.java0000644000000000000000000000424012445312576023231 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; /** * An exception thrown to model control flow in a Truffle interpreter. The Truffle optimizer has * special knowledge of this exception class for performance optimizations. */ public class ControlFlowException extends RuntimeException { private static final long serialVersionUID = 3676602078425211386L; /** * Creates an exception thrown to model control flow. */ public ControlFlowException() { /* * We use the super constructor that initializes the cause to null. Without that, the cause * would be this exception itself. This helps escape analysis: it avoids the circle of an * object pointing to itself. */ super((Throwable) null); } /** * For performance reasons, this exception does not record any stack trace information. */ @SuppressWarnings("sync-override") @Override public final Throwable fillInStackTrace() { return null; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeCloneable.java0000644000000000000000000000312212445312576021572 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; /** * Declarative base class for node fields that are to be cloned together with the containing node. */ public abstract class NodeCloneable implements Cloneable { @Override protected Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(); } } } truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/0000755000000000000000000000000012460741021017502 5ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java0000644000000000000000000000667112445312576025067 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes.serial; import java.nio.*; /** * Experimental API. May change without notice. Simple variable length unsigned int buffer backed by * a byte buffer. */ public class VariableLengthIntBuffer { public static final int NULL = -1; private ByteBuffer buffer; public VariableLengthIntBuffer(ByteBuffer buffer) { this.buffer = buffer; } public VariableLengthIntBuffer(byte[] array) { buffer = ByteBuffer.wrap(array); } /** * Returns the backing byte buffer. */ public ByteBuffer getBuffer() { return buffer; } public byte[] getBytes() { int pos = buffer.position(); byte[] bytes = new byte[buffer.position()]; buffer.rewind(); buffer.get(bytes); buffer.position(pos); return bytes; } public int get() { byte peekByte = buffer.get(buffer.position()); if ((peekByte & 0x80) == 0) { // single byte encoding with prefix 0 (range 127) return buffer.get(); // no bit to be masked } else { if (peekByte == (byte) 0xFF) { buffer.get(); // skip one byte return NULL; } int result = buffer.getInt() & 0x7FFF_FFFF; // first bit masked out assert (result & 0x4000_0000) == 0; return result; } } public void put(int i) { ensureCapacity(); if (i == NULL) { buffer.put((byte) 0xFF); } else if ((i & 0xFFFF_FF80) == 0) { // 7 bits data buffer.put((byte) i); } else if ((i & 0xC000_0000) == 0) { // 32 bits data buffer.putInt(i | 0x8000_0000); // append leading 1 } else { throw new IllegalArgumentException("Integer out of encodeable " + i); } } private void ensureCapacity() { if (buffer.position() + 4 > buffer.capacity()) { ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() * 2); int pos = buffer.position(); buffer.rewind(); newBuffer.put(buffer); newBuffer.position(pos); buffer = newBuffer; } } public boolean hasRemaining() { return buffer.hasRemaining(); } } truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/PostOrderSerializer.java0000644000000000000000000002071312445312576024337 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes.serial; import java.lang.reflect.*; import java.nio.*; import sun.misc.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; import com.oracle.truffle.api.nodes.NodeUtil.NodeField; import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; import com.oracle.truffle.api.source.*; /** * Experimental API. May change without notice. */ public final class PostOrderSerializer { private static final Unsafe unsafe = loadUnsafe(); private final SerializerConstantPool cp; /** * Constructs a new deserializer using a custom {@link SerializerConstantPool} implementation. * For the {@link SerializerConstantPool} implementation at least the following methods must be * implemented: *
    *
  • {@link SerializerConstantPool#putInt(int)}
  • *
  • {@link SerializerConstantPool#putClass(Class)}
  • *
*/ public PostOrderSerializer(SerializerConstantPool cp) { this.cp = cp; } /** * Serializes the node AST and returns the serialized data as byte array. * * @param node the root node that represents the Truffle AST that should be serialized. * @return a trimmed byte array that contains the serialized data. * * @throws UnsupportedConstantPoolTypeException thrown if a type is encountered that is not * supported by the constant pool implementation. */ public byte[] serialize(Node node) throws UnsupportedConstantPoolTypeException { VariableLengthIntBuffer buffer = new VariableLengthIntBuffer(ByteBuffer.allocate(512)); serialize(buffer, node); return buffer.getBytes(); } private void serialize(VariableLengthIntBuffer buffer, Node node) throws UnsupportedConstantPoolTypeException { if (node == null) { buffer.put(VariableLengthIntBuffer.NULL); return; } Class nodeClass = node.getClass(); NodeField[] nodeFields = NodeClass.get(nodeClass).getFields(); serializeChildFields(buffer, node, nodeFields); serializeChildrenFields(buffer, node, nodeFields); buffer.put(cp.putClass(node.getClass())); serializeDataFields(buffer, node, nodeFields); } private void serializeDataFields(VariableLengthIntBuffer buffer, Node node, NodeField[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.DATA) { Class fieldClass = field.getType(); long offset = field.getOffset(); int cpi; if (field.getType().isAssignableFrom(SourceSection.class)) { continue; } if (fieldClass == int.class) { cpi = cp.putInt(unsafe.getInt(node, offset)); } else if (fieldClass == long.class) { cpi = cp.putLong(unsafe.getLong(node, offset)); } else if (fieldClass == float.class) { cpi = cp.putFloat(unsafe.getFloat(node, offset)); } else if (fieldClass == double.class) { cpi = cp.putDouble(unsafe.getDouble(node, offset)); } else if (fieldClass == byte.class) { cpi = cp.putInt(unsafe.getByte(node, offset)); } else if (fieldClass == short.class) { cpi = cp.putInt(unsafe.getShort(node, offset)); } else if (fieldClass == char.class) { cpi = cp.putInt(unsafe.getChar(node, offset)); } else if (fieldClass == boolean.class) { cpi = cp.putInt(unsafe.getBoolean(node, offset) ? 1 : 0); } else { cpi = serializeDataFieldsObject(node, fieldClass, offset); } buffer.put(cpi); } } } private int serializeDataFieldsObject(Node node, Class fieldClass, long offset) { Object value = unsafe.getObject(node, offset); if (value == null) { return VariableLengthIntBuffer.NULL; } else if (fieldClass == Integer.class) { return cp.putInt((Integer) value); } else if (fieldClass == Long.class) { return cp.putLong((Long) value); } else if (fieldClass == Float.class) { return cp.putFloat((Float) value); } else if (fieldClass == Double.class) { return cp.putDouble((Double) value); } else if (fieldClass == Byte.class) { return cp.putInt((Byte) value); } else if (fieldClass == Short.class) { return cp.putInt((Short) value); } else if (fieldClass == Character.class) { return cp.putInt((Character) value); } else if (fieldClass == Boolean.class) { return cp.putInt((Boolean) value ? 1 : 0); } else { return cp.putObject(fieldClass, value); } } private void serializeChildrenFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeField[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILDREN) { Object childArrayObject = unsafe.getObject(nodeInstance, field.getOffset()); if (childArrayObject != null && !(childArrayObject instanceof Node[])) { throw new AssertionError("Node children must be instanceof Node[]"); } buffer.put(cp.putClass(field.getType())); Node[] childArray = (Node[]) childArrayObject; if (childArray == null) { buffer.put(VariableLengthIntBuffer.NULL); } else { buffer.put(cp.putInt(childArray.length)); for (int j = 0; j < childArray.length; j++) { serialize(buffer, childArray[j]); } } } } } private void serializeChildFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeField[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILD) { Object childObject = unsafe.getObject(nodeInstance, field.getOffset()); if (childObject != null && !(childObject instanceof Node)) { throw new AssertionError("Node children must be instanceof Node"); } serialize(buffer, (Node) childObject); } } } private static Unsafe loadUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException e) { } try { Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class); } catch (Exception e) { throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); } } } truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/PostOrderDeserializer.java0000644000000000000000000003407412445312576024655 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes.serial; import java.lang.reflect.*; import java.util.*; import sun.misc.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; import com.oracle.truffle.api.nodes.NodeUtil.NodeField; import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; import com.oracle.truffle.api.source.*; /** * Experimental API. May change without notice. */ public final class PostOrderDeserializer { private static final Unsafe unsafe = loadUnsafe(); private final SerializerConstantPool cp; private final HierarchicalStack stack = new HierarchicalStack(); /** * Constructs a new serializer using a custom {@link SerializerConstantPool} implementation. For * the {@link SerializerConstantPool} implementation at least the following methods must be * implemented: *
    *
  • {@link SerializerConstantPool#getInt(int)}
  • *
  • {@link SerializerConstantPool#getClass(int)}
  • *
*/ public PostOrderDeserializer(SerializerConstantPool cp) { this.cp = cp; } /** * Deserializes the byte stream and returns the deserialized Truffle AST node. * * @param bytes the trimmed byte array containing the serialized data * @param expectedType the expected root node type. Throws an exception if the root node is not * assignable from this type. * @return the deserialized Truffle AST represented by the root Node. * * @throws UnsupportedConstantPoolTypeException thrown if a type is encountered that is not * supported by the constant pool implementation. */ @SuppressWarnings("unchecked") public T deserialize(byte[] bytes, Class expectedType) throws UnsupportedConstantPoolTypeException { VariableLengthIntBuffer buffer = new VariableLengthIntBuffer(bytes); while (buffer.hasRemaining()) { int classCPI = buffer.get(); if (classCPI == VariableLengthIntBuffer.NULL) { pushNode(null); } else { Class clazz = cp.getClass(classCPI); if (clazz.isArray()) { int lengthCPI = buffer.get(); if (lengthCPI == VariableLengthIntBuffer.NULL) { pushArray(null); } else { pushArray((Node[]) Array.newInstance(clazz.getComponentType(), cp.getInt(lengthCPI))); } } else { pushNode(invokeDeserialize(buffer, clazz.asSubclass(Node.class))); } } } T returnNode = (T) popNode(null, expectedType); assert stack.dynamicStack.isEmpty(); return returnNode; } private void pushNode(Node node) { stack.push(node); } private void pushArray(Node[] array) { stack.pushStack(array); } private Node[] popArray(Node parent, Class expectedType) { Node[] array = (Node[]) stack.popStack(); if (array != null) { assertType(array, expectedType); for (int i = 0; i < array.length; i++) { updateParent(parent, array[i]); } } return array; } private Node popNode(Node parent, Class expectedType) { Object o = stack.pop(); assertType(o, expectedType); updateParent(parent, (Node) o); return (Node) o; } private static void assertType(Object o, Class expectedType) { if (o != null && !expectedType.isAssignableFrom(o.getClass())) { throw new AssertionError("Expected element type '" + expectedType.getName() + "' but was '" + o.getClass().getName() + "'."); } } private Node invokeDeserialize(VariableLengthIntBuffer buffer, Class nodeClass) throws UnsupportedConstantPoolTypeException { if (nodeClass == null) { return null; } Object object; try { object = unsafe.allocateInstance(nodeClass); } catch (InstantiationException e) { throw new RuntimeException("Unable to allocate truffle node " + nodeClass, e); } if (!(object instanceof Node)) { throw new RuntimeException("Class is not a truffle node " + nodeClass); } Node node = (Node) object; NodeField[] nodeFields = NodeClass.get(nodeClass).getFields(); deserializeChildrenFields(node, nodeFields); deserializeChildFields(node, nodeFields); deserializeDataFields(buffer, node, nodeFields); return node; } private void deserializeDataFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeField[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.DATA) { Class fieldClass = field.getType(); long offset = field.getOffset(); // source sections are not serialized // TODO add support for source sections if (field.getType().isAssignableFrom(SourceSection.class)) { continue; } int cpi = buffer.get(); if (cpi == VariableLengthIntBuffer.NULL) { deserializeDataFieldsLengthNull(nodeInstance, fieldClass, offset); } else { deserializeDataFieldsDefault(nodeInstance, fieldClass, offset, cpi); } } } } private void deserializeDataFieldsDefault(Node nodeInstance, Class fieldClass, long offset, int cpi) { if (fieldClass == int.class) { unsafe.putInt(nodeInstance, offset, cp.getInt(cpi)); } else if (fieldClass == long.class) { unsafe.putLong(nodeInstance, offset, cp.getLong(cpi)); } else if (fieldClass == float.class) { unsafe.putFloat(nodeInstance, offset, cp.getFloat(cpi)); } else if (fieldClass == double.class) { unsafe.putDouble(nodeInstance, offset, cp.getDouble(cpi)); } else if (fieldClass == byte.class) { unsafe.putByte(nodeInstance, offset, (byte) cp.getInt(cpi)); } else if (fieldClass == short.class) { unsafe.putShort(nodeInstance, offset, (short) cp.getInt(cpi)); } else if (fieldClass == char.class) { unsafe.putChar(nodeInstance, offset, (char) cp.getInt(cpi)); } else if (fieldClass == boolean.class) { unsafe.putBoolean(nodeInstance, offset, cp.getInt(cpi) == 1 ? true : false); } else if (fieldClass == Integer.class) { unsafe.putObject(nodeInstance, offset, cp.getInt(cpi)); } else if (fieldClass == Long.class) { unsafe.putObject(nodeInstance, offset, cp.getLong(cpi)); } else if (fieldClass == Float.class) { unsafe.putObject(nodeInstance, offset, cp.getFloat(cpi)); } else if (fieldClass == Double.class) { unsafe.putObject(nodeInstance, offset, cp.getDouble(cpi)); } else if (fieldClass == Byte.class) { unsafe.putObject(nodeInstance, offset, (byte) cp.getInt(cpi)); } else if (fieldClass == Short.class) { unsafe.putObject(nodeInstance, offset, (short) cp.getInt(cpi)); } else if (fieldClass == Character.class) { unsafe.putObject(nodeInstance, offset, (char) cp.getInt(cpi)); } else if (fieldClass == Boolean.class) { unsafe.putObject(nodeInstance, offset, cp.getInt(cpi) == 1 ? Boolean.TRUE : Boolean.FALSE); } else { unsafe.putObject(nodeInstance, offset, cp.getObject(fieldClass, cpi)); } } private static void deserializeDataFieldsLengthNull(Node nodeInstance, Class fieldClass, long offset) { if (fieldClass == int.class) { unsafe.putInt(nodeInstance, offset, 0); } else if (fieldClass == long.class) { unsafe.putLong(nodeInstance, offset, 0L); } else if (fieldClass == float.class) { unsafe.putFloat(nodeInstance, offset, 0.0F); } else if (fieldClass == double.class) { unsafe.putDouble(nodeInstance, offset, 0.0D); } else if (fieldClass == byte.class) { unsafe.putByte(nodeInstance, offset, (byte) 0); } else if (fieldClass == short.class) { unsafe.putShort(nodeInstance, offset, (short) 0); } else if (fieldClass == char.class) { unsafe.putChar(nodeInstance, offset, (char) 0); } else if (fieldClass == boolean.class) { unsafe.putBoolean(nodeInstance, offset, false); } else { unsafe.putObject(nodeInstance, offset, null); } } private void deserializeChildFields(Node parent, NodeField[] nodeFields) { for (int i = nodeFields.length - 1; i >= 0; i--) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILD) { unsafe.putObject(parent, field.getOffset(), popNode(parent, field.getType())); } } } private void deserializeChildrenFields(Node parent, NodeField[] nodeFields) { for (int i = nodeFields.length - 1; i >= 0; i--) { NodeField field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILDREN) { unsafe.putObject(parent, field.getOffset(), popArray(parent, field.getType())); } } } private static Node updateParent(Node parent, Node child) { if (child != null) { long parentOffset = NodeClass.get(child.getClass()).getParentOffset(); unsafe.putObject(child, parentOffset, parent); } return child; } private static Unsafe loadUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException e) { } try { Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class); } catch (Exception e) { throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); } } private static class HierarchicalStack { private static final Object NULL_STACK = new Object(); private final List dynamicStack = new ArrayList<>(); void pushStack(Object[] array) { if (array == null) { dynamicStack.add(NULL_STACK); } else { dynamicStack.add(new FixedSizeNodeStack(array)); } } private FixedSizeNodeStack getTosStack() { if (dynamicStack.isEmpty()) { return null; } Object peekTos = dynamicStack.get(dynamicStack.size() - 1); if (peekTos != null && peekTos.getClass() == FixedSizeNodeStack.class) { return (FixedSizeNodeStack) peekTos; } return null; } Object[] popStack() { Object tos = dynamicStack.remove(dynamicStack.size() - 1); if (tos == NULL_STACK) { return null; } return ((FixedSizeNodeStack) tos).getArray(); } void push(Object o) { FixedSizeNodeStack tosStack = getTosStack(); if (tosStack != null && !tosStack.isFull()) { tosStack.push(o); } else { dynamicStack.add(o); } } Object pop() { FixedSizeNodeStack tosStack = getTosStack(); Object value; if (tosStack != null) { assert !tosStack.isEmpty(); value = tosStack.pop(); } else { value = dynamicStack.remove(dynamicStack.size() - 1); } assert value != NULL_STACK; return value; } } private static class FixedSizeNodeStack { private final Object[] array; private int tos; FixedSizeNodeStack(Object[] array) { this.array = array; } boolean isFull() { return tos == array.length; } boolean isEmpty() { return tos == 0; } private void push(Object node) { if (tos >= array.length) { throw new ArrayIndexOutOfBoundsException(); } unsafe.putObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * (long) (tos++), node); } private Object pop() { if (tos <= 0) { throw new ArrayIndexOutOfBoundsException(); } return unsafe.getObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * (long) (--tos)); } private Object[] getArray() { return array; } } } truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/UnsupportedConstantPoolTypeException.java0000644000000000000000000000345112445312576030001 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes.serial; /** * Experimental API. May change without notice. */ public class UnsupportedConstantPoolTypeException extends RuntimeException { private static final long serialVersionUID = 1L; public UnsupportedConstantPoolTypeException() { super(); } public UnsupportedConstantPoolTypeException(String message, Throwable cause) { super(message, cause); } public UnsupportedConstantPoolTypeException(String message) { super(message); } public UnsupportedConstantPoolTypeException(Throwable cause) { super(cause); } } truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/SerializerConstantPool.java0000644000000000000000000001421612445312576025042 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes.serial; /** * Experimental API. May change without notice. This interface is used as bridge between the * {@link PostOrderDeserializer}, {@link PostOrderSerializer} and underlying constant pool * implementation. A constant pool stores a value and returns an identifying index, with which the * object can later be returned from the pool again. All methods of this class are optional and may * throw a {@link UnsupportedOperationException}. */ public interface SerializerConstantPool { /** * Returns the constant pool index of a value that is not a java native type, a java * native-wrapper class or a {@link Class} instance. The implementor should support all * additional types that are necessary to serialize a truffle AST for a specific truffle * implementation. If a type is not supported by this constant pool implementation a * {@link UnsupportedConstantPoolTypeException} should be thrown. * * @param clazz the {@link Class} of the value * @param value the value to be stored. Must be at least a subclass of the given clazz. * @return the constant pool index * @throws UnsupportedConstantPoolTypeException if a type is not supported for persistence in * the constant pool. */ int putObject(Class clazz, Object value) throws UnsupportedConstantPoolTypeException; /** * Stores a value in the constant pool that is not a java native type, a java native-wrapper * class or a {@link Class} instance. The implementor should support all additional types that * are necessary to serialize a truffle AST for a specific truffle implementation. If a type is * not supported by this constant pool implementation a * {@link UnsupportedConstantPoolTypeException} should be thrown. * * @param clazz the {@link Class} of the value in the constant pool. * @param cpi the previously returned index * @return the value stored inside the constant pool * @throws UnsupportedConstantPoolTypeException if a type is not supported for persistence in * the constant pool. * @throws IllegalArgumentException if the provided cpi is not a valid constant pool index. */ Object getObject(Class clazz, int cpi) throws UnsupportedConstantPoolTypeException; /** * Stores a Class instance in the constant pool and returns the constant pool index. * * @param value the class to store * @return the new or existing constant pool index of the Class */ int putClass(Class value); /** * Returns the {@link Class} instance to the given constant pool index. * * @param cpi the constant pool index * @return stored value * @throws IllegalArgumentException if the constant pool indes is invalid. */ Class getClass(int cpi); /** * Stores an int value in the constant pool and returns the constant pool index. * * @param value the value to store * @return the new or existing constant pool index of the value */ int putInt(int value); /** * Returns the stored int value to the given constant pool index from the constant pool. * * @param cpi the constant pool index * @return stored value * @throws IllegalArgumentException if the constant pool index is invalid. */ int getInt(int cpi); /** * Stores a long value in the constant pool and returns the constant pool index. * * @param value the value to store * @return the new or existing constant pool index of the value */ int putLong(long value); /** * Returns the stored long value to the given constant pool index from the constant pool. * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid. */ long getLong(int cpi); /** * Stores a double value in the constant pool and returns the constant pool index. * * @param value the value to store * @return the new or existing constant pool index of the value */ int putDouble(double value); /** * Returns the stored double value to the given constant pool index from the constant pool. * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid. */ double getDouble(int cpi); /** * Stores a float value in the constant pool and returns the constant pool index. * * @param value the value to store * @return the new or existing constant pool index of the value */ int putFloat(float value); /** * Returns the stored float value to the given constant pool index from the constant pool. * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid. */ float getFloat(int cpi); } truffle-0.6.orig/com/oracle/truffle/api/nodes/RootNode.java0000644000000000000000000001351212445312576020635 0ustar /* * Copyright (c) 2012, 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.source.*; /** * A root node is a node with a method to execute it given only a frame as a parameter. Therefore, a * root node can be used to create a call target using * {@link TruffleRuntime#createCallTarget(RootNode)}. */ public abstract class RootNode extends Node { private RootCallTarget callTarget; @CompilationFinal private FrameDescriptor frameDescriptor; protected RootNode() { this(null, null); } protected RootNode(SourceSection sourceSection) { this(sourceSection, null); } protected RootNode(SourceSection sourceSection, FrameDescriptor frameDescriptor) { super(sourceSection); if (frameDescriptor == null) { this.frameDescriptor = new FrameDescriptor(); } else { this.frameDescriptor = frameDescriptor; } } @Override public Node copy() { RootNode root = (RootNode) super.copy(); root.frameDescriptor = frameDescriptor; return root; } /** * Returns true if this {@link RootNode} is allowed to be cloned. The runtime * system might decide to create deep copies of the {@link RootNode} in order to gather context * sensitive profiling feedback. The default implementation returns false. Guest * language specific implementations may want to return true here to indicate that * gathering call site specific profiling information might make sense for this {@link RootNode} * . * * @return true if cloning is allowed else false. */ public boolean isCloningAllowed() { return false; } /** * Reports the execution count of a loop that is a child of this node. The optimization * heuristics can use the loop count to guide compilation and inlining. */ public final void reportLoopCount(int count) { if (getCallTarget() instanceof LoopCountReceiver) { ((LoopCountReceiver) getCallTarget()).reportLoopCount(count); } } /** * Executes this function using the specified frame and returns the result value. * * @param frame the frame of the currently executing guest language method * @return the value of the execution */ public abstract Object execute(VirtualFrame frame); public final RootCallTarget getCallTarget() { return callTarget; } public final FrameDescriptor getFrameDescriptor() { return frameDescriptor; } public final void setCallTarget(RootCallTarget callTarget) { this.callTarget = callTarget; } /** * Returns the {@link ExecutionContext} associated with this RootNode. This allows * the correct ExecutionContext to be determined for a RootNode (and * so also for a {@link RootCallTarget} and a {@link FrameInstance} obtained from the call * stack) without prior knowledge of the language it has come from. * * Used for instance to determine the language of a RootNode: * *
     * 
     * rootNode.getExecutionContext().getLanguageShortName();
     *  
* * Returns null by default. */ public ExecutionContext getExecutionContext() { return null; } /** * Get compiler options specific to this RootNode. */ public CompilerOptions getCompilerOptions() { final ExecutionContext context = getExecutionContext(); if (context == null) { return DefaultCompilerOptions.INSTANCE; } else { return context.getCompilerOptions(); } } /** * Apply all registered instances of {@link ASTProber} to the AST, if any, held by this root * node. This can only be done once the AST is complete, notably once all parent pointers are * correctly assigned. But it also must be done before any AST cloning or execution. *

* If this is not done, then the AST will not be subject to debugging or any other * instrumentation-supported tooling. *

* Implementations should ensure that instrumentation is never applied more than once to an AST, * as this is not guaranteed to be error-free. * * @see Probe#registerASTProber(com.oracle.truffle.api.instrument.ASTProber) */ public void applyInstrumentation() { } } truffle-0.6.orig/com/oracle/truffle/api/nodes/LoopNode.java0000644000000000000000000000364412445312576020630 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import com.oracle.truffle.api.frame.*; /** * Experimental API: may change significantly without notice. */ public abstract class LoopNode extends Node { /* * TODO Unfortunately we cannot yet use interface typed fields as child fields. */ @Child protected Node repeatingNode; public LoopNode(RepeatingNode repeatingNode) { this.repeatingNode = (Node) repeatingNode; } public abstract void executeLoop(VirtualFrame frame); protected final boolean executeRepeatingNode(VirtualFrame frame) { return getRepeatingNode().executeRepeating(frame); } public final RepeatingNode getRepeatingNode() { return (RepeatingNode) repeatingNode; } } truffle-0.6.orig/com/oracle/truffle/api/nodes/Node.java0000644000000000000000000004003412445312576017770 0ustar /* * Copyright (c) 2012, 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.nodes; import java.lang.annotation.*; import java.util.*; import java.util.concurrent.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.utilities.*; /** * Abstract base class for all Truffle nodes. */ public abstract class Node implements NodeInterface, Cloneable { @CompilationFinal private Node parent; @CompilationFinal private SourceSection sourceSection; /** * Marks array fields that are children of this node. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface Children { } /** * Marks fields that represent child nodes of this node. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface Child { } protected Node() { this(null); } protected Node(SourceSection sourceSection) { CompilerAsserts.neverPartOfCompilation(); this.sourceSection = sourceSection; if (TruffleOptions.TraceASTJSON) { JSONHelper.dumpNewNode(this); } } /** * Assigns a link to a guest language source section to this node. * * @param section the object representing a section in guest language source code */ public final void assignSourceSection(SourceSection section) { if (sourceSection != null) { // Patch this test during the transition to constructor-based // source attribution, which would otherwise trigger this // exception. This method will eventually be deprecated. if (getSourceSection() != section) { throw new IllegalStateException("Source section is already assigned. Old: " + getSourceSection() + ", new: " + section); } } this.sourceSection = section; } /** * Returns a rough estimate for the cost of this {@link Node}. This estimate can be used by * runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method * is intended to be overridden by subclasses. The default implementation returns the value of * {@link NodeInfo#cost()} of the {@link NodeInfo} annotation declared at the subclass. If no * {@link NodeInfo} annotation is declared the method returns {@link NodeCost#MONOMORPHIC} as a * default value. */ public NodeCost getCost() { NodeInfo info = getClass().getAnnotation(NodeInfo.class); if (info != null) { return info.cost(); } return NodeCost.MONOMORPHIC; } /** * Clears any previously assigned guest language source code from this node. */ public final void clearSourceSection() { this.sourceSection = null; } /** * Retrieves the guest language source code section that is currently assigned to this node. * * @return the assigned source code section */ public final SourceSection getSourceSection() { return sourceSection; } /** * Retrieves the guest language source code section that is currently assigned to this node. * * @return the assigned source code section */ @ExplodeLoop public final SourceSection getEncapsulatingSourceSection() { Node current = this; while (current != null) { if (current.sourceSection != null) { return current.sourceSection; } current = current.parent; } return null; } /** * Method that updates the link to the parent in the array of specified new child nodes to this * node. * * @param newChildren the array of new children whose parent should be updated * @return the array of new children */ protected final T[] insert(final T[] newChildren) { CompilerDirectives.transferToInterpreterAndInvalidate(); assert newChildren != null; for (Node newChild : newChildren) { adoptHelper(newChild); } return newChildren; } /** * Method that updates the link to the parent in the specified new child node to this node. * * @param newChild the new child whose parent should be updated * @return the new child */ protected final T insert(final T newChild) { CompilerDirectives.transferToInterpreterAndInvalidate(); assert newChild != null; adoptHelper(newChild); return newChild; } public final void adoptChildren() { CompilerDirectives.transferToInterpreterAndInvalidate(); adoptHelper(); } private void adoptHelper(final Node newChild) { assert newChild != null; if (newChild == this) { throw new IllegalStateException("The parent of a node can never be the node itself."); } boolean isInserted = newChild.parent == null; newChild.parent = this; if (TruffleOptions.TraceASTJSON) { JSONHelper.dumpNewChild(this, newChild); } newChild.adoptHelper(); if (isInserted) { newChild.onAdopt(); } } private void adoptHelper() { Iterable children = this.getChildren(); for (Node child : children) { if (child != null && child.getParent() != this) { this.adoptHelper(child); } } } private void adoptUnadoptedHelper(final Node newChild) { assert newChild != null; if (newChild == this) { throw new IllegalStateException("The parent of a node can never be the node itself."); } boolean isInserted = newChild.parent == null; newChild.parent = this; newChild.adoptUnadoptedHelper(); if (isInserted) { newChild.onAdopt(); } } private void adoptUnadoptedHelper() { Iterable children = this.getChildren(); for (Node child : children) { if (child != null && child.getParent() == null) { this.adoptUnadoptedHelper(child); } } } /** * Returns properties of this node interesting for debugging and can be overwritten by * subclasses to add their own custom properties. * * @return the properties as a key/value hash map */ public Map getDebugProperties() { Map properties = new HashMap<>(); return properties; } /** * The current parent node of this node. * * @return the parent node */ public final Node getParent() { return parent; } /** * Replaces this node with another node. If there is a source section (see * {@link #getSourceSection()}) associated with this node, it is transferred to the new node. * * @param newNode the new node that is the replacement * @param reason a description of the reason for the replacement * @return the new node */ public final T replace(final T newNode, final CharSequence reason) { CompilerDirectives.transferToInterpreterAndInvalidate(); atomic(new Runnable() { public void run() { replaceHelper(newNode, reason); } }); return newNode; } /** * Replaces this node with another node. If there is a source section (see * {@link #getSourceSection()}) associated with this node, it is transferred to the new node. * * @param newNode the new node that is the replacement * @return the new node */ public final T replace(T newNode) { return replace(newNode, ""); } private void replaceHelper(Node newNode, CharSequence reason) { CompilerAsserts.neverPartOfCompilation(); if (this.getParent() == null) { throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); } if (sourceSection != null && newNode.getSourceSection() == null) { // Pass on the source section to the new node. newNode.assignSourceSection(sourceSection); } // (aw) need to set parent *before* replace, so that (unsynchronized) getRootNode() // will always find the root node newNode.parent = this.parent; if (NodeUtil.replaceChild(this.parent, this, newNode)) { this.parent.adoptHelper(newNode); } else { this.parent.adoptUnadoptedHelper(newNode); } reportReplace(this, newNode, reason); onReplace(newNode, reason); } /** * Checks if this node is properly adopted by a parent and can be replaced. * * @return {@code true} if it is safe to replace this node. */ public final boolean isReplaceable() { if (getParent() != null) { for (Node sibling : getParent().getChildren()) { if (sibling == this) { return true; } } } return false; } private void reportReplace(Node oldNode, Node newNode, CharSequence reason) { Node node = this; while (node != null) { if (node instanceof ReplaceObserver) { ((ReplaceObserver) node).nodeReplaced(oldNode, newNode, reason); } else if (node instanceof RootNode) { CallTarget target = ((RootNode) node).getCallTarget(); if (target instanceof ReplaceObserver) { ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason); } } node = node.getParent(); } if (TruffleOptions.TraceRewrites) { NodeUtil.traceRewrite(this, newNode, reason); } if (TruffleOptions.TraceASTJSON) { JSONHelper.dumpReplaceChild(this, newNode, reason); } } /** * Intended to be implemented by subclasses of {@link Node} to receive a notification when the * node is rewritten. This method is invoked before the actual replace has happened. * * @param newNode the replacement node * @param reason the reason the replace supplied */ protected void onReplace(Node newNode, CharSequence reason) { // empty default } /** * Subclasses of {@link Node} can implement this method to execute extra functionality when a * node is effectively inserted into the AST. The {@code onAdopt} callback is called after the * node has been effectively inserted, and it is guaranteed to be called only once for any given * node. */ protected void onAdopt() { // empty default } /** * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all * child nodes. * * @param nodeVisitor the visitor */ public final void accept(NodeVisitor nodeVisitor) { if (nodeVisitor.visit(this)) { for (Node child : this.getChildren()) { if (child != null) { child.accept(nodeVisitor); } } } } /** * Iterator over the children of this node. * * @return the iterator */ public final Iterable getChildren() { return new Iterable() { public Iterator iterator() { return NodeUtil.makeIterator(Node.this); } }; } /** * Creates a shallow copy of this node. * * @return the new copy */ public Node copy() { try { return (Node) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } } /** * This method must never be called. It enforces that {@link Object#clone} is not directly * called by subclasses. Use the {@link #copy()} method instead. */ @Override @Deprecated protected final Object clone() throws CloneNotSupportedException { throw new IllegalStateException("This method should never be called, use the copy method instead!"); } /** * Get the root node of the tree a node belongs to. * * @return the {@link RootNode} or {@code null} if there is none. */ public final RootNode getRootNode() { Node rootNode = this; while (rootNode.getParent() != null) { assert !(rootNode instanceof RootNode) : "root node must not have a parent"; rootNode = rootNode.getParent(); } if (rootNode instanceof RootNode) { return (RootNode) rootNode; } return null; } /** * Converts this node to a textual representation useful for debugging. */ @Override public String toString() { StringBuilder sb = new StringBuilder(getClass().getSimpleName()); Map properties = getDebugProperties(); boolean hasProperties = false; for (Map.Entry entry : properties.entrySet()) { sb.append(hasProperties ? "," : "<"); hasProperties = true; sb.append(entry.getKey()).append("=").append(entry.getValue()); } if (hasProperties) { sb.append(">"); } sb.append("@").append(Integer.toHexString(hashCode())); return sb.toString(); } public final void atomic(Runnable closure) { RootNode rootNode = getRootNode(); if (rootNode != null) { synchronized (rootNode) { closure.run(); } } else { closure.run(); } } public final T atomic(Callable closure) { try { RootNode rootNode = getRootNode(); if (rootNode != null) { synchronized (rootNode) { return closure.call(); } } else { return closure.call(); } } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } /** * Returns a user-readable description of the purpose of the Node, or "" if no description is * available. */ public String getDescription() { NodeInfo info = getClass().getAnnotation(NodeInfo.class); if (info != null) { return info.description(); } return ""; } /** * Returns a string representing the language this node has been implemented for. If the * language is unknown, returns "". */ public String getLanguage() { NodeInfo info = getClass().getAnnotation(NodeInfo.class); if (info != null && info.language() != null && info.language().length() > 0) { return info.language(); } if (parent != null) { return parent.getLanguage(); } return ""; } } truffle-0.6.orig/com/oracle/truffle/api/ExactMath.java0000644000000000000000000001131212445312576017646 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; /** * This class contains methods that will be part of java.lang.Math starting with JDK 8. Until JDK 8 * is release, we duplicate them here because they are generally useful for dynamic language * implementations. */ public class ExactMath { public static int addExact(int x, int y) { int r = x + y; // HD 2-12 Overflow iff both arguments have the opposite sign of the result if (((x ^ r) & (y ^ r)) < 0) { throw new ArithmeticException("integer overflow"); } return r; } public static long addExact(long x, long y) { long r = x + y; // HD 2-12 Overflow iff both arguments have the opposite sign of the result if (((x ^ r) & (y ^ r)) < 0) { throw new ArithmeticException("long overflow"); } return r; } public static int subtractExact(int x, int y) { int r = x - y; // HD 2-12 Overflow iff the arguments have different signs and // the sign of the result is different than the sign of x if (((x ^ y) & (x ^ r)) < 0) { throw new ArithmeticException("integer overflow"); } return r; } public static long subtractExact(long x, long y) { long r = x - y; // HD 2-12 Overflow iff the arguments have different signs and // the sign of the result is different than the sign of x if (((x ^ y) & (x ^ r)) < 0) { throw new ArithmeticException("long overflow"); } return r; } public static int multiplyExact(int x, int y) { long r = (long) x * (long) y; if ((int) r != r) { throw new ArithmeticException("long overflow"); } return (int) r; } public static long multiplyExact(long x, long y) { long r = x * y; long ax = Math.abs(x); long ay = Math.abs(y); if (((ax | ay) >>> 31 != 0)) { // Some bits greater than 2^31 that might cause overflow // Check the result using the divide operator // and check for the special case of Long.MIN_VALUE * -1 if (((y != 0) && (r / y != x)) || (x == Long.MIN_VALUE && y == -1)) { throw new ArithmeticException("long overflow"); } } return r; } public static int multiplyHigh(int x, int y) { long r = (long) x * (long) y; return (int) (r >> 32); } public static int multiplyHighUnsigned(int x, int y) { long xl = x & 0xFFFFFFFFL; long yl = y & 0xFFFFFFFFL; long r = xl * yl; return (int) (r >> 32); } public static long multiplyHigh(long x, long y) { // Checkstyle: stop long x0, y0, z0; long x1, y1, z1, z2, t; // Checkstyle: resume x0 = x & 0xFFFFFFFFL; x1 = x >> 32; y0 = y & 0xFFFFFFFFL; y1 = y >> 32; z0 = x0 * y0; t = x1 * y0 + (z0 >>> 32); z1 = t & 0xFFFFFFFFL; z2 = t >> 32; z1 += x0 * y1; return x1 * y1 + z2 + (z1 >> 32); } public static long multiplyHighUnsigned(long x, long y) { // Checkstyle: stop long x0, y0, z0; long x1, y1, z1, z2, t; // Checkstyle: resume x0 = x & 0xFFFFFFFFL; x1 = x >>> 32; y0 = y & 0xFFFFFFFFL; y1 = y >>> 32; z0 = x0 * y0; t = x1 * y0 + (z0 >>> 32); z1 = t & 0xFFFFFFFFL; z2 = t >>> 32; z1 += x0 * y1; return x1 * y1 + z2 + (z1 >>> 32); } } truffle-0.6.orig/com/oracle/truffle/api/CompilerOptions.java0000644000000000000000000000312412445312576021120 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import com.oracle.truffle.api.nodes.*; /** * Allows options to be set to control the compilation of a specific {@link RootNode}, without * creating a dependency on the specific compiler used. Options can be tested for support before * setting. */ public interface CompilerOptions { boolean supportsOption(String name); void setOption(String name, Object value); } truffle-0.6.orig/com/oracle/truffle/api/CompilerDirectives.java0000644000000000000000000007276412445312576021606 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import java.lang.annotation.*; import java.lang.reflect.*; import java.util.concurrent.*; import sun.misc.*; /** * Directives that influence the optimizations of the Truffle compiler. All of the operations have * no effect when executed in the Truffle interpreter. */ public final class CompilerDirectives { public static final double LIKELY_PROBABILITY = 0.75; public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY; public static final double SLOWPATH_PROBABILITY = 0.0001; public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY; private static final Unsafe UNSAFE = getUnsafe(); private static Unsafe getUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException e) { } try { Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class); } catch (Exception e) { throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); } } /** * Directive for the compiler to discontinue compilation at this code position and instead * insert a transfer to the interpreter. */ public static void transferToInterpreter() { if (inInterpreter()) { Truffle.getRuntime().notifyTransferToInterpreter(); } } /** * Directive for the compiler to discontinue compilation at this code position and instead * insert a transfer to the interpreter, invalidating the currently executing machine code. */ public static void transferToInterpreterAndInvalidate() { if (inInterpreter()) { Truffle.getRuntime().notifyTransferToInterpreter(); } } /** * Returns a boolean value indicating whether the method is executed in the interpreter. * * @return {@code true} when executed in the interpreter, {@code false} in compiled code. */ public static boolean inInterpreter() { return true; } /** * Returns a boolean value indicating whether the method is executed in the compiled code. * * @return {@code false} when executed in the interpreter, {@code true} in compiled code. */ public static boolean inCompiledCode() { return false; } /** * Returns a boolean indicating whether or not a given value is seen as constant in optimized * code. If this method is called in the interpreter this method will always return * false. This API may be used in combination with {@link #inCompiledCode()} to * implement compilation constant assertions in the following way: * *

     * 
     * void assertCompilationConstant(Object value) {
     *   if (inCompiledCode()) {
     *     if (!isCompilationConstant(value)) {
     *       throw new AssertionError("Given value is not constant");
     *     }
     *   }
     * }
     * 
     * 
* * Note that optimizations that a compiler will apply to code that is conditional on * isCompilationConstant may be limited. For this reason * isCompilationConstant is not recommended for use to select between alternate * implementations of functionality depending on whether a value is constant. Instead, it is * intended for use as a diagnostic mechanism, such as illustrated above. * * @param value * @return {@code true} when given value is seen as compilation constant, {@code false} if not * compilation constant. */ public static boolean isCompilationConstant(Object value) { return false; } /** * Directive for the compiler that the given runnable should only be executed in the interpreter * and ignored in the compiled code. * * @param runnable the closure that should only be executed in the interpreter */ public static void interpreterOnly(Runnable runnable) { runnable.run(); } /** * Directive for the compiler that the given callable should only be executed in the * interpreter. * * @param callable the closure that should only be executed in the interpreter * @return the result of executing the closure in the interpreter and null in the compiled code * @throws Exception If the closure throws an exception when executed in the interpreter. */ public static T interpreterOnly(Callable callable) throws Exception { return callable.call(); } /** * Injects a probability for the given condition into the probability information of the * immediately succeeding branch instruction for the condition. The probability must be a value * between 0.0 and 1.0 (inclusive). The condition should not be a combined condition. * * Example usage immediately before an if statement (it specifies that the likelihood for a to * be greater than b is 90%): * * * if (injectBranchProbability(0.9, a > b)) { * // ... * } * * * Example usage for a combined condition (it specifies that the likelihood for a to be greater * than b is 90% and under the assumption that this is true, the likelihood for a being 0 is * 10%): * * * if (injectBranchProbability(0.9, a > b) && injectBranchProbability(0.1, a == 0)) { * // ... * } * * * There are predefined constants for commonly used probabilities (see * {@link #LIKELY_PROBABILITY} , {@link #UNLIKELY_PROBABILITY}, {@link #SLOWPATH_PROBABILITY}, * {@link #FASTPATH_PROBABILITY} ). * * @param probability the probability value between 0.0 and 1.0 that should be injected */ public static boolean injectBranchProbability(double probability, boolean condition) { assert probability >= 0.0 && probability <= 1.0; return condition; } /** * Bails out of a compilation (e.g., for guest language features that should never be compiled). * * @param reason the reason for the bailout */ public static void bailout(String reason) { } /** * Marks fields that should be considered final for a Truffle compilation although they are not * final while executing in the interpreter. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface CompilationFinal { } /** * Casts the given value to the value of the given type without any checks. The class must * evaluate to a constant. The condition parameter gives a hint to the compiler under which * circumstances this cast can be moved to an earlier location in the program. * * @param value the value that is known to have the specified type * @param type the specified new type of the value * @param condition the condition that makes this cast safe also at an earlier location of the * program * @return the value to be casted to the new type */ public static T unsafeCast(Object value, Class type, boolean condition) { return unsafeCast(value, type, condition, false); } /** * Casts the given value to the value of the given type without any checks. The class must * evaluate to a constant. The condition parameter gives a hint to the compiler under which * circumstances this cast can be moved to an earlier location in the program. * * @param value the value that is known to have the specified type * @param type the specified new type of the value * @param condition the condition that makes this cast safe also at an earlier location of the * program * @param nonNull whether value is known to never be null * @return the value to be casted to the new type */ @SuppressWarnings("unchecked") public static T unsafeCast(Object value, Class type, boolean condition, boolean nonNull) { return (T) value; } /** * Unsafe access to a boolean value within an object. The condition parameter gives a hint to * the compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getBoolean(receiver, offset); } /** * Unsafe access to a byte value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getByte(receiver, offset); } /** * Unsafe access to a short value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getShort(receiver, offset); } /** * Unsafe access to an int value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getInt(receiver, offset); } /** * Unsafe access to a long value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getLong(receiver, offset); } /** * Unsafe access to a float value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getFloat(receiver, offset); } /** * Unsafe access to a double value within an object. The condition parameter gives a hint to the * compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getDouble(receiver, offset); } /** * Unsafe access to an Object value within an object. The condition parameter gives a hint to * the compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getObject(receiver, offset); } /** * Write a boolean value within an object. The location identity gives a hint to the compiler * for improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { UNSAFE.putBoolean(receiver, offset, value); } /** * Write a byte value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) { UNSAFE.putByte(receiver, offset, value); } /** * Write a short value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) { UNSAFE.putShort(receiver, offset, value); } /** * Write an int value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) { UNSAFE.putInt(receiver, offset, value); } /** * Write a long value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) { UNSAFE.putLong(receiver, offset, value); } /** * Write a float value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) { UNSAFE.putFloat(receiver, offset, value); } /** * Write a double value within an object. The location identity gives a hint to the compiler for * improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) { UNSAFE.putDouble(receiver, offset, value); } /** * Write an Object value within an object. The location identity gives a hint to the compiler * for improved global value numbering. * * @param receiver the object that is written to * @param offset the offset at which to write to the object in bytes * @param value the value to be written * @param locationIdentity the location identity token that can be used for improved global * value numbering or null */ public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) { UNSAFE.putObject(receiver, offset, value); } /** * Unsafe access to a final boolean value within an object. The condition parameter gives a hint * to the compiler under which circumstances this access can be moved to an earlier location in * the program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static boolean unsafeGetFinalBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getBoolean(receiver, offset); } /** * Unsafe access to a final byte value within an object. The condition parameter gives a hint to * the compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static byte unsafeGetFinalByte(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getByte(receiver, offset); } /** * Unsafe access to a final short value within an object. The condition parameter gives a hint * to the compiler under which circumstances this access can be moved to an earlier location in * the program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static short unsafeGetFinalShort(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getShort(receiver, offset); } /** * Unsafe access to a final int value within an object. The condition parameter gives a hint to * the compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static int unsafeGetFinalInt(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getInt(receiver, offset); } /** * Unsafe access to a final long value within an object. The condition parameter gives a hint to * the compiler under which circumstances this access can be moved to an earlier location in the * program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static long unsafeGetFinalLong(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getLong(receiver, offset); } /** * Unsafe access to a final float value within an object. The condition parameter gives a hint * to the compiler under which circumstances this access can be moved to an earlier location in * the program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static float unsafeGetFinalFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getFloat(receiver, offset); } /** * Unsafe access to a final double value within an object. The condition parameter gives a hint * to the compiler under which circumstances this access can be moved to an earlier location in * the program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static double unsafeGetFinalDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getDouble(receiver, offset); } /** * Unsafe access to a final Object value within an object. The condition parameter gives a hint * to the compiler under which circumstances this access can be moved to an earlier location in * the program. The location identity gives a hint to the compiler for improved global value * numbering. * * @param receiver the object that is accessed * @param offset the offset at which to access the object in bytes * @param condition the condition that makes this access safe also at an earlier location in the * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) { return UNSAFE.getObject(receiver, offset); } /** * Marks a method that it is considered as a boundary for Truffle partial evaluation. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface TruffleBoundary { } /** * Marks classes as value types. Reference comparisons (==) between instances of those classes * have undefined semantics and can either return true or false. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface ValueType { } /** * Ensures that the given object is not virtual, i.e., not removed by Escape Analysis at the * point of this call. * * @param obj the object to exclude from Escape Analysis */ public static void materialize(Object obj) { } } truffle-0.6.orig/com/oracle/truffle/api/OptimizationFailedException.java0000644000000000000000000000317412445312576023451 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; public class OptimizationFailedException extends RuntimeException { private final RootCallTarget callTarget; public OptimizationFailedException(Throwable cause, RootCallTarget callTarget) { super(cause); this.callTarget = callTarget; } public RootCallTarget getCallTarget() { return callTarget; } private static final long serialVersionUID = -8797188744430210785L; } truffle-0.6.orig/com/oracle/truffle/api/ExecutionContext.java0000644000000000000000000000505612445312576021310 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.impl.*; /** * Access to information and basic services in the runtime context for a Truffle-implemented guest * language. *

* Disclaimer: this class is under development and will change. */ public abstract class ExecutionContext { private Visualizer visualizer = new DefaultVisualizer(); protected ExecutionContext() { } /** * Access to information visualization services for the specific language. */ public final Visualizer getVisualizer() { return visualizer; } /** * Assign guest language-specific visualization support for tools. This must be assigned outside * the implementation context to avoid build circularities. */ public final void setVisualizer(Visualizer visualizer) { this.visualizer = visualizer; } /** * Gets the name of the language, possibly with version number. in short enough form that it * might be used for an interactive prompt. */ public abstract String getLanguageShortName(); /** * Get compiler options specific to this ExecutionContext. */ public CompilerOptions getCompilerOptions() { return DefaultCompilerOptions.INSTANCE; } } truffle-0.6.orig/com/oracle/truffle/api/instrument/0000755000000000000000000000000012460741021017323 5ustar truffle-0.6.orig/com/oracle/truffle/api/instrument/SyntaxTagged.java0000644000000000000000000000351412445312576022607 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import java.util.*; /** * Information about a guest language program element in a Truffle AST that can be marked as * belonging to 0 or more {@linkplain SyntaxTag tags}. *

* Disclaimer: experimental interface under development. */ public interface SyntaxTagged { /** * Is this node tagged as belonging to a particular human-sensible category of language * constructs? */ boolean isTaggedAs(SyntaxTag tag); /** * In which user-sensible categories has this node been tagged (empty set if none). */ Collection getSyntaxTags(); } truffle-0.6.orig/com/oracle/truffle/api/instrument/Probe.java0000644000000000000000000003643312445312576021262 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import java.lang.ref.*; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.instrument.ProbeNode.Instrumentable; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.utilities.*; //TODO (mlvdv) migrate some of this to external documentation. /** * A binding between a particular location in the Truffle AST representation of a running Guest * Language (GL) program (i.e. a {@link Node}) and a dynamically managed collection of "attached" * {@linkplain Instrument instrumentation} for use by external tools. *

* The effect of a binding is to intercept {@linkplain TruffleEventReceiver execution events} at the * node and notify each attached {@link Instrument} before execution is allowed to resume. *

* A Probe is "inserted" into a GL node via a call to {@link Instrumentable#probe()}; a GL node must * implement {@link Instrumentable} in order to support instrumentation. No more than one Probe can * be inserted at a node. *

* The "probing" of a Truffle AST must be done after it is complete (i.e. with parent pointers * correctly assigned), but before any executions. This is done by creating an instance of * {@link ASTProber} and registering it via {@link #registerASTProber(ASTProber)}, after which it * will be automatically applied to newly created ASTs. *

* Each Probe may also have assigned to it one or more {@link SyntaxTag}s, for example identifying a * node as a {@linkplain StandardSyntaxTag#STATEMENT STATEMENT}. Tags can be queried by tools to * configure behavior relevant to each probed node. *

* Instrumentation is implemented by modifying ASTs, both by inserting nodes into each AST at probed * locations and by attaching additional nodes that implement dynamically attached instruments. * Attached instrumentation code become, in effect, part of the GL program, and is subject to the * same levels of optimization as other GL code. This implementation accounts properly for the fact * that Truffle frequently clones ASTs, along with any attached instrumentation nodes. A * Probe, along with attached Instruments, represents a logical binding with a source code * location, producing event notifications that are (mostly) independent of which AST clone is * executing. * * @see Instrument * @see Instrumentable * @see ASTProber */ public final class Probe implements SyntaxTagged { /** * An observer of events related to {@link Probe}s: creating and tagging. */ public interface ProbeListener { /** * Notifies that all registered {@link ASTProber}s are about to be applied to a newly * constructed AST. * * @param source source code from which the AST was constructed */ void startASTProbing(Source source); /** * Notifies that a {@link Probe} has been newly attached to an AST via * {@link Instrumentable#probe()}. *

* There can be no more than one {@link Probe} at a node; this notification will only be * delivered the first time {@linkplain Instrumentable#probe() probe()} is called at a * particular AST node. There will also be no notification when the AST to which the Probe * is attached is cloned. */ void newProbeInserted(Probe probe); /** * Notifies that a {@link SyntaxTag} has been newly added to the set of tags associated with * a {@link Probe} via {@link Probe#tagAs(SyntaxTag, Object)}. *

* The {@linkplain SyntaxTag tags} at a {@link Probe} are a set; this notification * will only be delivered the first time a particular {@linkplain SyntaxTag tag} is added at * a {@link Probe}. *

* An optional value supplied with {@linkplain Probe#tagAs(SyntaxTag, Object) * tagAs(SyntaxTag, Object)} is reported to all listeners, but not stored. As a consequence, * the optional value will have no effect at all if the tag had already been added. * * @param probe where a tag has been added * @param tag the tag that has been newly added (subsequent additions of the tag are * unreported). * @param tagValue an optional value associated with the tag for the purposes of reporting. */ void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue); /** * Notifies that the application of all registered {@link ASTProber}s to a newly constructed * AST has completed. * * @param source source code from which the AST was constructed */ void endASTProbing(Source source); } private static final List astProbers = new ArrayList<>(); private static final List probeListeners = new ArrayList<>(); /** * All Probes that have been created. */ private static final List> probes = new ArrayList<>(); private static final class FindSourceVisitor implements NodeVisitor { Source source = null; public boolean visit(Node node) { final SourceSection sourceSection = node.getSourceSection(); if (sourceSection != null) { source = sourceSection.getSource(); return false; } return true; } } /** * Walks an AST, looking for the first node with an assigned {@link SourceSection} and returning * the {@link Source}. */ private static Source findSource(Node node) { final FindSourceVisitor visitor = new FindSourceVisitor(); node.accept(visitor); return visitor.source; } /** * The tag trap is a global setting; it only affects {@linkplain Probe probes} with the * {@linkplain SyntaxTag tag} specified . */ private static SyntaxTagTrap globalTagTrap = null; /** * Enables instrumentation at selected nodes in all subsequently constructed ASTs. */ public static void registerASTProber(ASTProber prober) { astProbers.add(prober); } public static void unregisterASTProber(ASTProber prober) { astProbers.remove(prober); } /** * Enables instrumentation in a newly created AST by applying all registered instances of * {@link ASTProber}. */ public static void applyASTProbers(Node node) { final Source source = findSource(node); for (ProbeListener listener : probeListeners) { listener.startASTProbing(source); } for (ASTProber prober : astProbers) { prober.probeAST(node); } for (ProbeListener listener : probeListeners) { listener.endASTProbing(source); } } /** * Adds a {@link ProbeListener} to receive events. */ public static void addProbeListener(ProbeListener listener) { assert listener != null; probeListeners.add(listener); } /** * Removes a {@link ProbeListener}. Ignored if listener not found. */ public static void removeProbeListener(ProbeListener listener) { probeListeners.remove(listener); } /** * Returns all {@link Probe}s holding a particular {@link SyntaxTag}, or the whole collection if * the specified tag is {@code null}. * * @return A collection of probes containing the given tag. */ public static Collection findProbesTaggedAs(SyntaxTag tag) { final List taggedProbes = new ArrayList<>(); for (WeakReference ref : probes) { Probe probe = ref.get(); if (probe != null) { if (tag == null || probe.isTaggedAs(tag)) { taggedProbes.add(ref.get()); } } } return taggedProbes; } /** * Sets the current "tag trap". This causes a callback to be triggered whenever execution * reaches a {@link Probe} (either existing or subsequently created) with the specified tag. * There can only be one tag trap set at a time. * * @param newTagTrap The {@link SyntaxTagTrap} to set. * @throws IllegalStateException if a trap is currently set. */ public static void setTagTrap(SyntaxTagTrap newTagTrap) throws IllegalStateException { assert newTagTrap != null; if (globalTagTrap != null) { throw new IllegalStateException("trap already set"); } globalTagTrap = newTagTrap; final SyntaxTag newTag = newTagTrap.getTag(); for (WeakReference ref : probes) { final Probe probe = ref.get(); if (probe != null && probe.tags.contains(newTag)) { probe.trapActive = true; probe.probeStateUnchanged.invalidate(); } } } /** * Clears the current {@link SyntaxTagTrap}. * * @throws IllegalStateException if no trap is currently set. */ public static void clearTagTrap() { if (globalTagTrap == null) { throw new IllegalStateException("no trap set"); } globalTagTrap = null; for (WeakReference ref : probes) { final Probe probe = ref.get(); if (probe != null && probe.trapActive) { probe.trapActive = false; probe.probeStateUnchanged.invalidate(); } } } private final SourceSection sourceSection; private final ArrayList tags = new ArrayList<>(); private final List> probeNodeClones = new ArrayList<>(); private final CyclicAssumption probeStateUnchanged = new CyclicAssumption("Probe state unchanged"); /** * {@code true} iff the global trap is set and this probe has the matching tag. */ private boolean trapActive = false; /** * @see Instrumentable#probe() */ Probe(ProbeNode probeNode, SourceSection sourceSection) { this.sourceSection = sourceSection; probes.add(new WeakReference<>(this)); registerProbeNodeClone(probeNode); for (ProbeListener listener : probeListeners) { listener.newProbeInserted(this); } } public boolean isTaggedAs(SyntaxTag tag) { assert tag != null; return tags.contains(tag); } public Collection getSyntaxTags() { return Collections.unmodifiableCollection(tags); } /** * Adds a {@linkplain SyntaxTag tag} to the set of tags associated with this {@link Probe}; * {@code no-op} if already in the set. */ public void tagAs(SyntaxTag tag, Object tagValue) { assert tag != null; if (!tags.contains(tag)) { tags.add(tag); for (ProbeListener listener : probeListeners) { listener.probeTaggedAs(this, tag, tagValue); } if (globalTagTrap != null && tag == globalTagTrap.getTag()) { this.trapActive = true; } probeStateUnchanged.invalidate(); } } /** * Adds instrumentation at this Probe. * * @param instrument an instrument not yet attached to a probe * @throws IllegalStateException if the instrument has ever been attached before */ public void attach(Instrument instrument) throws IllegalStateException { if (instrument.isDisposed()) { throw new IllegalStateException("Attempt to attach disposed instrument"); } if (instrument.getProbe() != null) { throw new IllegalStateException("Attampt to attach an already attached instrument"); } instrument.setAttachedTo(this); for (WeakReference ref : probeNodeClones) { final ProbeNode probeNode = ref.get(); if (probeNode != null) { probeNode.addInstrument(instrument); } } probeStateUnchanged.invalidate(); } /** * Gets the {@link SourceSection} associated with the Guest Language AST node being * instrumented, possibly {@code null}. */ public SourceSection getProbedSourceSection() { return sourceSection; } public String getShortDescription() { final String location = sourceSection == null ? "" : sourceSection.getShortDescription(); return "Probe@" + location + getTagsDescription(); } /** * Receives notification that a new clone of the instrument chain associated with this * {@link Probe} has been created as a side-effect of AST cloning. */ void registerProbeNodeClone(ProbeNode probeNode) { probeNodeClones.add(new WeakReference<>(probeNode)); } /** * Gets the currently active {@linkplain SyntaxTagTrap tagTrap}; {@code null} if not set. */ SyntaxTagTrap getTrap() { return trapActive ? globalTagTrap : null; } /** * Gets the {@link Assumption} that the instrumentation-related state of this {@link Probe} has * not changed since this method was last called. */ Assumption getUnchangedAssumption() { return probeStateUnchanged.getAssumption(); } /** * Internal method for removing and rendering inert a specific instrument previously attached at * this Probe. * * @param instrument an instrument already attached * @throws IllegalStateException if instrument not attached at this Probe * @see Instrument#dispose() */ void disposeInstrument(Instrument instrument) throws IllegalStateException { for (WeakReference ref : probeNodeClones) { final ProbeNode probeNode = ref.get(); if (probeNode != null) { probeNode.removeInstrument(instrument); } } probeStateUnchanged.invalidate(); } private String getTagsDescription() { final StringBuilder sb = new StringBuilder(); sb.append("["); String prefix = ""; for (SyntaxTag tag : tags) { sb.append(prefix); prefix = ","; sb.append(tag.toString()); } sb.append("]"); return sb.toString(); } } truffle-0.6.orig/com/oracle/truffle/api/instrument/ProbeNode.java0000644000000000000000000003530012445312576022060 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.Instrument.InstrumentNode; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; /** * Implementation interfaces and classes for attaching {@link Probe}s to {@link WrapperNode}s. */ public abstract class ProbeNode extends Node implements TruffleEventReceiver, InstrumentationNode { /** * Any Truffle node implementing this interface can be "instrumented" by installing a * {@link Probe} that intercepts execution events at the node and routes them to any * {@link Instrument}s that have been attached to the {@link Probe}. Only one {@link Probe} may * be installed at each node; subsequent calls return the one already installed. * * @see Instrument */ public interface Instrumentable { /** * Enables "instrumentation" of a Guest Language Truffle node, where the node is presumed to * be part of a well-formed Truffle AST that is not being executed. The AST may be modified * as a side effect. *

* This interface is not intended to be visible as part of the API for tools * (instrumentation clients). * * @return a (possibly newly created) {@link Probe} associated with this node. */ Probe probe(); /** * Enables a one-time, unchangeable "instrumentation" of a Guest Language Truffle node, * where the node is presumed to be part of a well-formed Truffle AST that is not being * executed. The AST may be modified as a side-effect. Unlike {@link #probe()}, once * {@link #probeLite(TruffleEventReceiver)} is called at a node, no additional probing can * be added and no additional instrumentation can be attached. *

* This interface is not intended to be visible as part of the API for tools * (instrumentation clients). * * @param eventReceiver The {@link TruffleEventReceiver} for the single "instrument" being * attached to this node. */ void probeLite(TruffleEventReceiver eventReceiver); } /** * A node that can be inserted into a Truffle AST, and which enables instrumentation at * a particular Guest Language (GL) node. *

* The implementation must be GL-specific. A wrapper decorates a GL AST node (the * wrapper's child) by acting as a transparent proxy with respect to the GL's * execution semantics. *

* Instrumentation at the wrapped node is implemented by an instance of {@link ProbeNode} * attached as a second child of the {@link WrapperNode}. *

* A wrapper is obliged to notify its attached {@link ProbeNode} when execution events occur at * the wrapped AST node during program execution. *

* When a GL AST is cloned, the {@link WrapperNode}, its {@link ProbeNode} and any * {@linkplain Instrument instrumentation} are also cloned; they are in effect part of the GL * AST. An instance of {@link Probe} represents abstractly the instrumentation at a particular * location in a GL AST; it tracks all the copies of the Wrapper and attached instrumentation, * and acts as a single point of access for tools. *

* This interface is not intended to be visible as part of the API for tools (instrumentation * clients). *

* Implementation guidelines: *

    *
  1. Each GL implementation should include a WrapperNode implementation; usually only one is * needed.
  2. *
  3. The wrapper type should descend from the GL-specific node class.
  4. *
  5. Must have a field: {@code @Child private Node child;}
  6. *
  7. Must have a field: {@code @Child private ProbeNode probeNode;}
  8. *
  9. The wrapper must act as a proxy for its child, which means implementing every * possible execute- method that gets called on guest language AST node types by their * parents, and passing along each call to its child.
  10. *
  11. Method {@code Probe getProbe()} should be implemented as {@code probeNode.getProbe();} *
  12. Method {@code insertProbe(ProbeNode)} should be implemented as * {@code this.probeNode=insert(newProbeNode);}
  13. *
  14. Most importantly, Wrappers must be implemented so that Truffle optimization will reduce * their runtime overhead to zero when there are no attached {@link Instrument}s.
  15. *
*

* Disclaimer: experimental interface under development. * * @see Instrument */ public interface WrapperNode extends InstrumentationNode { /** * Gets the node being "wrapped", i.e. the AST node for which * {@linkplain TruffleEventReceiver execution events} will be reported through the * Instrumentation Framework. */ Node getChild(); /** * Gets the {@link Probe} responsible for installing this wrapper; none if the wrapper * installed via {@linkplain Instrumentable#probeLite(TruffleEventReceiver) "lite-Probing"}. */ Probe getProbe(); /** * Implementation support for completing a newly created wrapper node. */ void insertProbe(ProbeNode probeNode); } /** * Create a new {@link Probe} associated with, and attached to, a Guest Language specific * instance of {@link WrapperNode}. */ public static Probe insertProbe(WrapperNode wrapper) { final SourceSection sourceSection = wrapper.getChild().getSourceSection(); final ProbeFullNode probeFullNode = new ProbeFullNode(); // private constructor final Probe probe = new Probe(probeFullNode, sourceSection); // package private access probeFullNode.setProbe(probe); wrapper.insertProbe(probeFullNode); return probe; } /** * Creates a new {@link ProbeLiteNode} associated with, and attached to, a Guest Language * specific instance of {@link WrapperNode}. */ public static void insertProbeLite(WrapperNode wrapper, TruffleEventReceiver eventReceiver) { final ProbeLiteNode probeLiteNode = new ProbeLiteNode(eventReceiver); wrapper.insertProbe(probeLiteNode); } /** * @return the {@link Probe} permanently associated with this {@link ProbeNode}. * * @throws IllegalStateException if this location was "lite-Probed" */ public abstract Probe getProbe() throws IllegalStateException; /** * Adds an {@link InstrumentNode} to this chain. * * @throws IllegalStateException if at a "lite-Probed" location. */ abstract void addInstrument(Instrument instrument); /** * Removes an instrument from this chain of instruments. * * @throws IllegalStateException if at a "lite-Probed" location. * @throws RuntimeException if no matching instrument is found, */ abstract void removeInstrument(Instrument instrument); /** * Implementation class & interfaces for enabling the attachment of {@linkplain Probe Probes} to * Truffle ASTs. *

* Head of a chain of nodes acting on behalf of {@linkplain Instrument instruments}, attached to * a Guest Language (GL) AST as a child of a GL-specific {@link WrapperNode} node. *

* When Truffle clones an AST, the chain, including all attached {@linkplain Instrument * instruments} will be cloned along with the {@link WrapperNode} to which it is attached. An * instance of {@link Probe} represents abstractly the instrumentation at a particular location * in a GL AST, tracks the clones of the chain, and keeps the instrumentation attached to the * clones consistent. */ @NodeInfo(cost = NodeCost.NONE) private static final class ProbeFullNode extends ProbeNode { /** * First {@link InstrumentNode} node in chain; {@code null} of no instruments in chain. */ @Child protected InstrumentNode firstInstrument; // Never changed once set. @CompilationFinal private Probe probe = null; /** * An assumption that the state of the {@link Probe} with which this chain is associated has * not changed since the last time checking such an assumption failed and a reference to a * new assumption (associated with a new state of the {@link Probe} was retrieved. */ private Assumption probeUnchangedAssumption; private ProbeFullNode() { this.firstInstrument = null; } @Override public Probe getProbe() throws IllegalStateException { return probe; } @Override public Node copy() { Node node = super.copy(); probe.registerProbeNodeClone((ProbeNode) node); return node; } private void setProbe(Probe probe) { this.probe = probe; this.probeUnchangedAssumption = probe.getUnchangedAssumption(); } private void checkProbeUnchangedAssumption() { try { probeUnchangedAssumption.check(); } catch (InvalidAssumptionException ex) { // Failure creates an implicit deoptimization // Get the assumption associated with the new probe state this.probeUnchangedAssumption = probe.getUnchangedAssumption(); } } @Override @TruffleBoundary void addInstrument(Instrument instrument) { assert instrument.getProbe() == probe; // The existing chain of nodes may be empty // Attach the modified chain. firstInstrument = insert(instrument.addToChain(firstInstrument)); } @Override @TruffleBoundary void removeInstrument(Instrument instrument) { assert instrument.getProbe() == probe; final InstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument); if (modifiedChain == null) { firstInstrument = null; } else { firstInstrument = insert(modifiedChain); } } public void enter(Node node, VirtualFrame frame) { final SyntaxTagTrap trap = probe.getTrap(); if (trap != null) { checkProbeUnchangedAssumption(); trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), frame.materialize()); } if (firstInstrument != null) { checkProbeUnchangedAssumption(); firstInstrument.enter(node, frame); } } public void returnVoid(Node node, VirtualFrame frame) { if (firstInstrument != null) { checkProbeUnchangedAssumption(); firstInstrument.returnVoid(node, frame); } } public void returnValue(Node node, VirtualFrame frame, Object result) { if (firstInstrument != null) { checkProbeUnchangedAssumption(); firstInstrument.returnValue(node, frame, result); } } public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { if (firstInstrument != null) { checkProbeUnchangedAssumption(); firstInstrument.returnExceptional(node, frame, exception); } } public String instrumentationInfo() { return "Standard probe"; } } /** * Implementation of a probe that only ever has a single "instrument" associated with it. No * {@link Instrument} is ever created; instead this method simply delegates the various enter * and return events to a {@link TruffleEventReceiver} passed in during construction. */ @NodeInfo(cost = NodeCost.NONE) private static final class ProbeLiteNode extends ProbeNode { private final TruffleEventReceiver eventReceiver; private ProbeLiteNode(TruffleEventReceiver eventReceiver) { this.eventReceiver = eventReceiver; } @Override public Probe getProbe() throws IllegalStateException { throw new IllegalStateException("\"lite-Probed\" nodes have no explicit Probe"); } @Override @TruffleBoundary void addInstrument(Instrument instrument) { throw new IllegalStateException("Instruments may not be added at a \"lite-probed\" location"); } @Override @TruffleBoundary void removeInstrument(Instrument instrument) { throw new IllegalStateException("Instruments may not be removed at a \"lite-probed\" location"); } public void enter(Node node, VirtualFrame frame) { eventReceiver.enter(node, frame); } public void returnVoid(Node node, VirtualFrame frame) { eventReceiver.returnVoid(node, frame); } public void returnValue(Node node, VirtualFrame frame, Object result) { eventReceiver.returnValue(node, frame, result); } public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { eventReceiver.returnExceptional(node, frame, exception); } public String instrumentationInfo() { return "\"Lite\" probe"; } } } truffle-0.6.orig/com/oracle/truffle/api/instrument/ASTPrinter.java0000644000000000000000000000510412445312576022175 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import java.io.*; import com.oracle.truffle.api.nodes.*; /** * Access to AST-based debugging support, which is could be language implementation specific in the * details chosen to be presented. *

* WARNING: this interface is under development and will change substantially. */ public interface ASTPrinter { /** * Prints a textual AST display, one line per node, with nesting. * * @param p * @param node the root node of the display. * @param maxDepth the maximum number of levels to print below the root * @param markNode a node to mark with a textual arrow prefix, if present. */ void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); /** * Creates a textual AST display, one line per node, with nesting. * * @param node the root node of the display. * @param maxDepth the maximum number of levels to print below the root * @param markNode a node to mark with a textual arrow prefix, if present. */ String printTreeToString(Node node, int maxDepth, Node markNode); /** * Creates a textual AST display, one line per node, with nesting. * * @param node the root node of the display. * @param maxDepth the maximum number of levels to print below the root */ String printTreeToString(Node node, int maxDepth); } truffle-0.6.orig/com/oracle/truffle/api/instrument/InstrumentationNode.java0000644000000000000000000000317512445312576024221 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.nodes.*; /** * A marker interface for Truffle {@linkplain Node nodes} that support Instrumentation and * are should not be part of any Guest Language execution semantics. */ public interface InstrumentationNode { /** * A short description of the particular role played by the node, intended to support debugging. */ String instrumentationInfo(); } truffle-0.6.orig/com/oracle/truffle/api/instrument/TruffleEventReceiver.java0000644000000000000000000000427412445312576024307 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * A receiver of Truffle AST runtime execution events that can collect information and possibly * intervene on behalf of an external tool. */ public interface TruffleEventReceiver { /** * Receive notification that an AST node's execute method is about to be called. */ void enter(Node node, VirtualFrame frame); /** * Receive notification that an AST Node's {@code void}-valued execute method has just returned. */ void returnVoid(Node node, VirtualFrame frame); /** * Receive notification that an AST Node'sexecute method has just returned a value (boxed if * primitive). */ void returnValue(Node node, VirtualFrame frame, Object result); /** * Receive notification that an AST Node's execute method has just thrown an exception. */ void returnExceptional(Node node, VirtualFrame frame, Exception exception); } truffle-0.6.orig/com/oracle/truffle/api/instrument/KillException.java0000644000000000000000000000275012445312576022760 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.nodes.*; /** * Controls breaking out of an execution context, such as a shell or eval. */ public final class KillException extends ControlFlowException { private static final long serialVersionUID = 3163641880088766957L; } truffle-0.6.orig/com/oracle/truffle/api/instrument/Instrument.java0000644000000000000000000003272112445312576022357 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.impl.*; import com.oracle.truffle.api.nodes.*; // TODO (mlvdv) migrate some of this to external documentation. /** * A dynamically added/removed binding between a {@link Probe}, which provides notification of * {@linkplain TruffleEventReceiver execution events} taking place at a {@link Node} in a Guest * Language (GL) Truffle AST, and a {@linkplain TruffleEventReceiver receiver}, which consumes * notifications on behalf of an external tool. *

*

Summary: How to "instrument" an AST location:

*
    *
  1. Create an implementation of {@link TruffleEventReceiver} that responds to events on behalf of * a tool.
  2. *
  3. Create an Instrument via factory method {@link Instrument#create(TruffleEventReceiver)}.
  4. *
  5. "Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event * notifications begin to arrive at the receiver.
  6. *
  7. When no longer needed, "detach" the Instrument via {@link Instrument#dispose()}, at which * point event notifications to the receiver cease, and the Instrument becomes unusable.
  8. *
*

*

Options for creating receivers:

*

*

    *
  1. Implement the interface {@link TruffleEventReceiver}. The event handling methods account for * both the entry into an AST node (about to call) and several possible kinds of exit from an AST * node (just returned).
  2. *
  3. Extend {@link DefaultEventReceiver}, which provides a no-op implementation of every * {@link TruffleEventReceiver} method; override the methods of interest.
  4. *
  5. Extend {@link SimpleEventReceiver}, where return values are ignored so only two methods (for * "enter" and "return") will notify all events.
  6. *
*

*

General guidelines for receiver implementation:

*

* When an Instrument is attached to a Probe, the receiver effectively becomes part of the executing * GL program; performance can be affected by the receiver's implementation. *

    *
  • Do not store {@link Frame} or {@link Node} references in fields.
  • *
  • Prefer {@code final} fields and (where performance is important) short methods.
  • *
  • If needed, pass along the {@link VirtualFrame} reference from an event notification as far as * possible through code that is expected to be inlined, since this incurs no runtime overhead. When * access to frame data is needed, substitute a more expensive {@linkplain Frame#materialize() * materialized} representation of the frame.
  • *
  • If a receiver calls back to its tool during event handling, and if performance is an issue, * then this should be through a final "callback" field in the instrument, and the called methods * should be minimal.
  • *
  • On the other hand, implementations should prevent Truffle from inlining beyond a reasonable * point with the method annotation {@link TruffleBoundary}.
  • *
  • The implicit "outer" pointer in a non-static inner class is a useful way to implement * callbacks to owner tools.
  • *
  • Primitive-valued return events are boxed for notification, but Truffle will eliminate the * boxing if they are cast back to their primitive values quickly (in particular before crossing any * {@link TruffleBoundary} annotations). *
*

*

Allowing for AST cloning:

*

* Truffle routinely clones ASTs, which has consequences for receiver implementation. *

    *
  • Even though a {@link Probe} is uniquely associated with a particular location in the * executing Guest Language program, execution events at that location will in general be * implemented by different {@link Node} instances, i.e. clones of the originally probed * node.
  • *
  • Because of cloning the {@link Node} supplied with notifications to a particular * receiver will vary, but because they all represent the same GL program location the events should * be treated as equivalent for most purposes.
  • *
*

*

Access to execution state:

*

*

    *
  • Event notification arguments provide primary access to the GL program's execution states: *
      *
    • {@link Node}: the concrete node (in one of the AST's clones) from which the event originated. *
    • *
    • {@link VirtualFrame}: the current execution frame. *
    *
  • Some global information is available, for example the execution * {@linkplain TruffleRuntime#iterateFrames(FrameInstanceVisitor) stack}.
  • *
  • Additional information needed by a receiver could be stored when created, preferably * {@code final} of course. For example, a reference to the {@link Probe} to which the receiver's * Instrument has been attached would give access to its corresponding * {@linkplain Probe#getProbedSourceSection() source location} or to the collection of * {@linkplain SyntaxTag tags} currently applied to the Probe.
  • *
*

*

Activating and deactivating Instruments:

*

* Instruments are single-use: *

    *
  • An instrument becomes active only when attached to a Probe via * {@link Probe#attach(Instrument)}, and it may only be attached to a single Probe. It is a runtime * error to attempt attaching a previously attached instrument.
  • *
  • Attaching an instrument modifies every existing clone of the AST to which it is being * attached, which can trigger deoptimization.
  • *
  • The method {@link Instrument#dispose()} makes an instrument inactive by removing it from the * Probe to which it was attached and rendering it permanently inert.
  • *
  • Disposal removes the implementation of an instrument from all ASTs to which it was attached, * which can trigger deoptimization.
  • *
*

*

Sharing receivers:

*

* Although an Instrument may only be attached to a single Probe, a receiver can be shared among * multiple Instruments. This can be useful for observing events that might happen at different * locations in a single AST, for example all assignments to a particular variable. In this case a * new Instrument would be created and attached at each assignment node, but all the Instruments * would be created with the same receiver. *

* Disclaimer: experimental; under development. * * @see Probe * @see TruffleEventReceiver */ public final class Instrument { /** * Creates an instrument that will route execution events to a receiver. * * @param receiver a receiver for event generated by the instrument * @param instrumentInfo optional description of the instrument's role * @return a new instrument, ready for attachment at a probe */ public static Instrument create(TruffleEventReceiver receiver, String instrumentInfo) { return new Instrument(receiver, instrumentInfo); } /** * Creates an instrument that will route execution events to a receiver. */ public static Instrument create(TruffleEventReceiver receiver) { return new Instrument(receiver, null); } /** * Tool-supplied receiver of events. */ private final TruffleEventReceiver toolEventreceiver; /** * Optional documentation, mainly for debugging. */ private final String instrumentInfo; /** * Has this instrument been disposed? stays true once set. */ private boolean isDisposed = false; private Probe probe = null; private Instrument(TruffleEventReceiver receiver, String instrumentInfo) { this.toolEventreceiver = receiver; this.instrumentInfo = instrumentInfo; } /** * Removes this instrument (and any clones) from the probe to which it attached and renders the * instrument inert. * * @throws IllegalStateException if this instrument has already been disposed */ public void dispose() throws IllegalStateException { if (isDisposed) { throw new IllegalStateException("Attempt to dispose an already disposed Instrumennt"); } if (probe != null) { // It's attached probe.disposeInstrument(this); } this.isDisposed = true; } Probe getProbe() { return probe; } void setAttachedTo(Probe probe) { this.probe = probe; } /** * Has this instrument been disposed and rendered unusable? */ boolean isDisposed() { return isDisposed; } InstrumentNode addToChain(InstrumentNode nextNode) { return new InstrumentNode(nextNode); } /** * Removes this instrument from an instrument chain. */ InstrumentNode removeFromChain(InstrumentNode instrumentNode) { boolean found = false; if (instrumentNode != null) { if (instrumentNode.getInstrument() == this) { // Found the match at the head of the chain return instrumentNode.nextInstrument; } // Match not at the head of the chain; remove it. found = instrumentNode.removeFromChain(Instrument.this); } if (!found) { throw new IllegalStateException("Couldn't find instrument node to remove: " + this); } return instrumentNode; } @NodeInfo(cost = NodeCost.NONE) final class InstrumentNode extends Node implements TruffleEventReceiver, InstrumentationNode { @Child private InstrumentNode nextInstrument; private InstrumentNode(InstrumentNode nextNode) { this.nextInstrument = nextNode; } /** * Gets the instrument that created this node. */ private Instrument getInstrument() { return Instrument.this; } /** * Removes the node from this chain that was added by a particular instrument, assuming that * the head of the chain is not the one to be replaced. This is awkward, but is required * because {@link Node#replace(Node)} won't take a {@code null} argument. This doesn't work * for the tail of the list, which would be replacing itself with null. So the replacement * must be directed the parent of the node being removed. */ private boolean removeFromChain(Instrument instrument) { assert getInstrument() != instrument; if (nextInstrument == null) { return false; } if (nextInstrument.getInstrument() == instrument) { // Next is the one to remove if (nextInstrument.nextInstrument == null) { // Next is at the tail; just forget nextInstrument = null; } else { // Replace next with its successor nextInstrument.replace(nextInstrument.nextInstrument); } return true; } return nextInstrument.removeFromChain(instrument); } public void enter(Node node, VirtualFrame frame) { Instrument.this.toolEventreceiver.enter(node, frame); if (nextInstrument != null) { nextInstrument.enter(node, frame); } } public void returnVoid(Node node, VirtualFrame frame) { Instrument.this.toolEventreceiver.returnVoid(node, frame); if (nextInstrument != null) { nextInstrument.returnVoid(node, frame); } } public void returnValue(Node node, VirtualFrame frame, Object result) { Instrument.this.toolEventreceiver.returnValue(node, frame, result); if (nextInstrument != null) { nextInstrument.returnValue(node, frame, result); } } public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { Instrument.this.toolEventreceiver.returnExceptional(node, frame, exception); if (nextInstrument != null) { nextInstrument.returnExceptional(node, frame, exception); } } public String instrumentationInfo() { if (Instrument.this.instrumentInfo != null) { return Instrument.this.instrumentInfo; } return toolEventreceiver.getClass().getSimpleName(); } } } truffle-0.6.orig/com/oracle/truffle/api/instrument/QuitException.java0000644000000000000000000000274712445312576023015 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.nodes.*; /** * Controls breaking out of all executions and ending Truffle execution. */ public final class QuitException extends ControlFlowException { private static final long serialVersionUID = -4301115629772778413L; } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/0000755000000000000000000000000012460741021020264 5ustar truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java0000644000000000000000000000530012445312576024603 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; public class DefaultVisualizer implements Visualizer { private final ASTPrinter astPrinter; public DefaultVisualizer() { this.astPrinter = new DefaultASTPrinter(); } public ASTPrinter getASTPrinter() { return astPrinter; } public String displaySourceLocation(Node node) { if (node == null) { return ""; } SourceSection section = node.getSourceSection(); boolean estimated = false; if (section == null) { section = node.getEncapsulatingSourceSection(); estimated = true; } return section.getShortDescription() + (estimated ? "~" : ""); } public String displayMethodName(Node node) { if (node == null) { return null; } RootNode root = node.getRootNode(); if (root == null) { return "unknown"; } return root.getCallTarget().toString(); } public String displayCallTargetName(CallTarget callTarget) { return callTarget.toString(); } public String displayValue(ExecutionContext context, Object value) { return value.toString(); } public String displayIdentifier(FrameSlot slot) { return slot.getIdentifier().toString(); } } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/DefaultEventReceiver.java0000644000000000000000000000354612445312576025226 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; /** * A receiver for AST {@linkplain TruffleEventReceiver execution events} that provides a no-op * implementation of every event. */ public class DefaultEventReceiver implements TruffleEventReceiver { public void enter(Node node, VirtualFrame frame) { } public void returnVoid(Node node, VirtualFrame frame) { } public void returnValue(Node node, VirtualFrame frame, Object result) { } public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { } } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java0000644000000000000000000001451312445312576024447 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import java.io.*; import java.util.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; import com.oracle.truffle.api.nodes.NodeUtil.NodeField; import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; import com.oracle.truffle.api.source.*; /** * A language-agnostic for printing out various pieces of a Truffle AST. */ public class DefaultASTPrinter implements ASTPrinter { public DefaultASTPrinter() { } public void printTree(PrintWriter p, Node node, int maxDepth, Node markNode) { printTree(p, node, maxDepth, markNode, 1); p.println(); p.flush(); } public String printTreeToString(Node node, int maxDepth, Node markNode) { StringWriter out = new StringWriter(); printTree(new PrintWriter(out), node, maxDepth, markNode); return out.toString(); } public String printTreeToString(Node node, int maxDepth) { return printTreeToString(node, maxDepth, null); } protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { if (node == null) { p.print("null"); return; } p.print(nodeName(node)); p.print("("); if (node instanceof InstrumentationNode) { p.print(instrumentInfo((InstrumentationNode) node)); } p.print(sourceInfo(node)); p.print(NodeUtil.printSyntaxTags(node)); ArrayList childFields = new ArrayList<>(); for (NodeField field : NodeClass.get(node.getClass()).getFields()) { if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { childFields.add(field); } else if (field.getKind() == NodeFieldKind.DATA) { // p.print(sep); // sep = ", "; // // final String fieldName = field.getName(); // switch (fieldName) { // // } // p.print(fieldName); // p.print(" = "); // p.print(field.loadValue(node)); } } p.print(")"); if (level <= maxDepth) { if (childFields.size() != 0) { p.print(" {"); for (NodeField field : childFields) { Object value = field.loadValue(node); if (value == null) { printNewLine(p, level); p.print(field.getName()); p.print(" = null "); } else if (field.getKind() == NodeFieldKind.CHILD) { printChild(p, maxDepth, markNode, level, field, value); } else if (field.getKind() == NodeFieldKind.CHILDREN) { printChildren(p, maxDepth, markNode, level, field, value); } else { printNewLine(p, level); p.print(field.getName()); } } printNewLine(p, level - 1); p.print("}"); } } } protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, NodeField field, Object value) { printNewLine(p, level); p.print(field.getName()); Node[] children = (Node[]) value; p.print(" = ["); String sep = ""; for (Node child : children) { p.print(sep); sep = ", "; printTree(p, child, maxDepth, markNode, level + 1); } p.print("]"); } protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, NodeField field, Object value) { final Node valueNode = (Node) value; printNewLine(p, level, valueNode == markNode); p.print(field.getName()); p.print(" = "); printTree(p, valueNode, maxDepth, markNode, level + 1); } protected static void printNewLine(PrintWriter p, int level, boolean mark) { p.println(); for (int i = 0; i < level; i++) { if (mark && i == 0) { p.print(" -->"); } else { p.print(" "); } } } protected static void printNewLine(PrintWriter p, int level) { printNewLine(p, level, false); } protected static String nodeName(Node node) { return node.getClass().getSimpleName(); } protected static String sourceInfo(Node node) { final SourceSection src = node.getSourceSection(); if (src != null) { if (src instanceof NullSourceSection) { final NullSourceSection nullSection = (NullSourceSection) src; return nullSection.getShortDescription(); } else { return src.getSource().getName() + ":" + src.getStartLine(); } } return ""; } protected static String instrumentInfo(InstrumentationNode node) { final String info = node.instrumentationInfo(); return info == null ? "" : info; } } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/LineToProbesMap.java0000644000000000000000000001506112445312576024151 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import java.io.*; import java.util.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.Probe.ProbeListener; import com.oracle.truffle.api.source.*; /** * A mapping from {@link LineLocation} (a line number in a specific piece of {@link Source} code) to * a collection of {@link Probe}s whose associated {@link SourceSection} starts on that line. */ public class LineToProbesMap implements ProbeListener { private static final boolean TRACE = false; private static final PrintStream OUT = System.out; private static void trace(String msg) { OUT.println("LineToProbesMap: " + msg); } /** * Map: Source line ==> probes associated with source sections starting on the line. */ private final Map> lineToProbesMap = new HashMap<>(); public LineToProbesMap() { } public void startASTProbing(Source source) { } public void newProbeInserted(Probe probe) { final SourceSection sourceSection = probe.getProbedSourceSection(); if (sourceSection != null && !(sourceSection instanceof NullSourceSection)) { final LineLocation lineLocation = sourceSection.getLineLocation(); if (TRACE) { trace("ADD " + lineLocation.getShortDescription() + " ==> " + probe.getShortDescription()); } this.addProbeToLine(lineLocation, probe); } } public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { // This map ignores tags } public void endASTProbing(Source source) { } /** * Returns the {@link Probe}, if any, associated with source that starts on a specified line; if * there are more than one, return the one with the first starting character location. */ public Probe findLineProbe(LineLocation lineLocation) { Probe probe = null; final Collection probes = getProbesAtLine(lineLocation); for (Probe probesOnLine : probes) { if (probe == null) { probe = probesOnLine; } else if (probesOnLine.getProbedSourceSection().getCharIndex() < probe.getProbedSourceSection().getCharIndex()) { probe = probesOnLine; } } return probe; } /** * Records creation of a probe whose associated source starts on the given line. *

* If the line already exists in the internal {@link #lineToProbesMap}, this probe will be added * to the existing collection. If no line already exists in the internal map, then a new key is * added along with a new collection containing the probe. *

* This class requires that each added line/probe pair hasn't been previously added. However, * attaching the same probe to a new line location is allowed. * * @param line The {@link LineLocation} to attach the probe to. * @param probe The {@link Probe} to attach for that line location. */ protected void addProbeToLine(LineLocation line, Probe probe) { if (!lineToProbesMap.containsKey(line)) { // Key does not exist, add new probe list final ArrayList newProbeList = new ArrayList<>(2); newProbeList.add(probe); lineToProbesMap.put(line, newProbeList); } else { // Probe list exists, add to existing final Collection existingProbeList = lineToProbesMap.get(line); assert !existingProbeList.contains(probe); existingProbeList.add(probe); } } /** * * Returns a collection of {@link Probe}s whose associated source begins at the given * {@link LineLocation}, an empty list if none. * * @param line The line to check. * @return A collection of probes at the given line. */ public Collection getProbesAtLine(LineLocation line) { Collection probesList = lineToProbesMap.get(line); if (probesList == null) { return Collections.emptyList(); } return probesList; } /** * Convenience method to get probes according to a int line number. Returns a collection of * {@link Probe}s at the given line number, an empty list if none. * * @param lineNumber The line number to check. * @return A collection of probes at the given line. */ public Collection getProbesAtLineNumber(int lineNumber) { final Set keySet = lineToProbesMap.keySet(); if (keySet.size() == 0) { return Collections.emptyList(); } ArrayList probes = new ArrayList<>(); for (LineLocation line : keySet) { if (line.getLineNumber() == lineNumber) { probes.addAll(lineToProbesMap.get(line)); } } return probes; } public void forget(Source source) { final Set mappedLines = lineToProbesMap.keySet(); if (mappedLines.size() > 0) { List forgetLines = new ArrayList<>(); for (LineLocation line : mappedLines) { if (line.getSource().equals(source)) { forgetLines.add(line); } } for (LineLocation line : forgetLines) { lineToProbesMap.remove(line); } } } } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/LineToSourceSectionMap.java0000644000000000000000000001335612445312576025511 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import java.io.*; import java.util.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.Probe.*; import com.oracle.truffle.api.source.*; /** * A mapping from {@link LineLocation} (a line number in a specific piece of {@link Source} code) to * a collection of {@link SourceSection}s that exist on that line. This class assumes that all nodes * are instrumented as it uses the {@link ProbeListener} interface to determine the source sections * that exist in the file. */ public class LineToSourceSectionMap implements ProbeListener { private static final boolean TRACE = false; private static final PrintStream OUT = System.out; private static void trace(String msg) { OUT.println("LineToSourceSectionMap: " + msg); } /** * Map: Source line ==> source sections that exist on the line. */ private final Map> lineToSourceSectionsMap = new HashMap<>(); public LineToSourceSectionMap() { } public void startASTProbing(Source source) { } public void newProbeInserted(Probe probe) { final SourceSection sourceSection = probe.getProbedSourceSection(); if (sourceSection != null && !(sourceSection instanceof NullSourceSection)) { final LineLocation lineLocation = sourceSection.getLineLocation(); if (TRACE) { trace("NEW " + lineLocation.getShortDescription() + " Probe=" + probe); } this.addSourceSectionToLine(lineLocation, sourceSection); } } public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { // This map ignores tags, but this subclasses can override this method to operate on tags. } public void endASTProbing(Source source) { } /** * Adds a source section to the given line. *

* If the line already exists in the internal {@link #lineToSourceSectionsMap}, this source * section will be added to the existing collection. If no line already exists in the internal * map, then a new key is added along with a new collection containing the source section. *

* This class does not check if a source section has already been added to a line. * * @param line The {@link LineLocation} to attach the source section to. * @param sourceSection The {@link SourceSection} to attach for that line location. */ protected void addSourceSectionToLine(LineLocation line, SourceSection sourceSection) { if (!lineToSourceSectionsMap.containsKey(line)) { // Key does not exist, add new source section list final ArrayList newSourceSectionList = new ArrayList<>(2); newSourceSectionList.add(sourceSection); lineToSourceSectionsMap.put(line, newSourceSectionList); } else { // Source section list exists, add to existing final Collection existingSourceSectionList = lineToSourceSectionsMap.get(line); existingSourceSectionList.add(sourceSection); } } /** * Returns a collection of {@link SourceSection}s at the given {@link LineLocation}, an empty * list if none. * * @param line The line to check. * @return the source sections at the given line. */ public Collection getSourceSectionsAtLine(LineLocation line) { Collection sourceSectionList = lineToSourceSectionsMap.get(line); if (sourceSectionList == null) { return Collections.emptyList(); } return sourceSectionList; } /** * Convenience method to get source sections according to a int line number. Returns a * collection of {@link SourceSection}s at the given line number. If there are no source * sections at that line, an empty list is returned. * * @param lineNumber The line number to check. * @return A collection of source sections at the given line. */ public Collection getSourceSectionsAtLineNumber(int lineNumber) { final Set keySet = lineToSourceSectionsMap.keySet(); if (keySet.size() == 0) { return Collections.emptyList(); } final ArrayList sourceSections = new ArrayList<>(); for (LineLocation line : keySet) { if (line.getLineNumber() == lineNumber) { sourceSections.addAll(lineToSourceSectionsMap.get(line)); } } return sourceSections; } } truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/SimpleEventReceiver.java0000644000000000000000000000466412445312576025075 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument.impl; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; /** * An abstract receiver for AST {@linkplain TruffleEventReceiver execution events} that ignores * return values and supports handling all events by overriding only two methods: *

    *
  • {@link #enter(Node, VirtualFrame)}, and
  • *
  • {@link #returnAny(Node, VirtualFrame)}.
  • *
*/ public abstract class SimpleEventReceiver implements TruffleEventReceiver { public void enter(Node node, VirtualFrame frame) { } /** * Receive notification that one of an AST Node's execute methods has just returned by any * means: with or without a return value (ignored) or via exception (ignored). * * @param node * @param frame */ public void returnAny(Node node, VirtualFrame frame) { } public final void returnVoid(Node node, VirtualFrame frame) { returnAny(node, frame); } public final void returnValue(Node node, VirtualFrame frame, Object result) { returnAny(node, frame); } public final void returnExceptional(Node node, VirtualFrame frame, Exception e) { returnAny(node, frame); } } truffle-0.6.orig/com/oracle/truffle/api/instrument/Visualizer.java0000644000000000000000000000504012445312576022336 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * Visualization services for the benefit of instrumentation-based tools, possibly specialized for * each guest language and possibly specialized for relevant information from the underlying Truffle * implementation. *

* Disclaimer: experimental interface under development. */ public interface Visualizer { // TODO (mlvdv) "Visualizer" is misleading: rename. /** * Gets a printer for Truffle ASTs, possibly specialized to be helpful for a specific guest * language implementation. */ ASTPrinter getASTPrinter(); /** * A short description of a source location in terms of source + line number. */ String displaySourceLocation(Node node); /** * Describes the name of the method containing a node. */ String displayMethodName(Node node); /** * The name of the method. */ String displayCallTargetName(CallTarget callTarget); /** * Converts a value in the guest language to a display string. */ String displayValue(ExecutionContext context, Object value); /** * Converts a slot identifier in the guest language to a display string. */ String displayIdentifier(FrameSlot slot); } truffle-0.6.orig/com/oracle/truffle/api/instrument/SyntaxTagTrap.java0000644000000000000000000000344612445312576022762 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * A trap that can be set to interrupt execution at probed nodes carrying a specific tag. */ public abstract class SyntaxTagTrap { private final SyntaxTag tag; protected SyntaxTagTrap(SyntaxTag tag) { this.tag = tag; } public final SyntaxTag getTag() { return tag; } /** * Callback that will be received whenever execution enters a node with the specified tag. */ public abstract void tagTrappedAt(Node node, MaterializedFrame frame); } truffle-0.6.orig/com/oracle/truffle/api/instrument/ASTProber.java0000644000000000000000000000333112445312576022003 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; import com.oracle.truffle.api.nodes.*; /** * Enables instrumentation by attaching {@linkplain Probe Probes} to some nodes in a (newly created, * not yet executed) AST. * * @see Probe * @see Probe#addProbeListener(com.oracle.truffle.api.instrument.Probe.ProbeListener) */ public interface ASTProber { /** * Walk the AST starting at a node and enable instrumentation at selected nodes by attaching * {@linkplain Probe Probes} to them. */ void probeAST(Node node); } truffle-0.6.orig/com/oracle/truffle/api/instrument/SyntaxTag.java0000644000000000000000000000447712445312576022140 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; /** * Program element "tags", presumed to be singletons (best implemented as enums) that define * user-visible behavior for debugging and other simple tools. These categories should correspond to * program structures, for example "statement" and "assignment", that are meaningful * ("human-sensible") to guest language programmers. *

* An untagged Truffle node should be understood as an artifact of the guest language implementation * and should not be visible to guest language programmers. Nodes may also have more than one tag, * for example a variable assignment that is also a statement. Finally, the assignment of tags to * nodes could depending on the use-case of whatever tool is using them. *

* Disclaimer: experimental interface under development. * * @see Probe * @see StandardSyntaxTag */ public interface SyntaxTag { /** * Human-friendly name of guest language program elements belonging to the category, e.g. * "statement". */ String name(); /** * Criteria and example uses for the tag. */ String getDescription(); } truffle-0.6.orig/com/oracle/truffle/api/instrument/StandardSyntaxTag.java0000644000000000000000000000643112445312576023611 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.instrument; /** * A somewhat language-agnostic set of user-sensible syntactic categories, suitable for conventional * imperative languages, and is being developed incrementally. *

* The need for alternative sets of tags is likely to arise, perhaps for other families of languages * (for example for mostly expression-oriented languages) or even for specific languages. *

* Disclaimer: experimental interface under development. * * @see Probe */ public enum StandardSyntaxTag implements SyntaxTag { /** * Marker for a variable assignment. */ ASSIGNMENT("assignment", "a variable assignment"), /** * Marker for a call site. */ CALL("call", "a method/procedure call site"), /** * Marker for a location where a guest language exception is about to be thrown. */ THROW("throw", "creator of an exception"), /** * Marker for a location where ordinary "stepping" should halt. */ STATEMENT("statement", "basic unit of the language, suitable for \"stepping\" in a debugger"), /** * Marker for the start of the body of a method. */ START_METHOD("start-method", "start of the body of a method"), /** * Marker for the start of the body of a loop. */ START_LOOP("start-loop", "start of the body of a loop"), /** * Marker that is attached to some arbitrary locations that appear often-enough in an AST so * that a location with this tag is regularly executed. Could be the start of method and loop * bodies. May be used to implement some kind of safepoint functionality. */ PERIODIC("periodic", "arbitrary locations that appear often-enough in an AST so that a location with this tag is regularly executed"); private final String name; private final String description; private StandardSyntaxTag(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public String getDescription() { return description; } } truffle-0.6.orig/com/oracle/truffle/api/Assumption.java0000644000000000000000000000605612445312576020143 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import com.oracle.truffle.api.nodes.*; /** * An assumption is a global boolean flag that starts with the value true (i.e., the assumption is * valid) and can subsequently be invalidated (using {@link Assumption#invalidate()}). Once * invalidated, an assumption can never get valid again. Assumptions can be created using the * {@link TruffleRuntime#createAssumption()} or the {@link TruffleRuntime#createAssumption(String)} * method. The Truffle compiler has special knowledge of this class in order to produce efficient * machine code for checking an assumption in case the assumption object is a compile time constant. * Therefore, assumptions should be stored in final fields in Truffle nodes. * * All instances of classes implementing {@code Assumption} must be held in {@code final} fields for * compiler optimizations to take effect. */ public interface Assumption { /** * Checks that this assumption is still valid. The method throws an exception, if this is no * longer the case. This method is preferred over the {@link #isValid()} method when writing * guest language interpreter code. The catch block should perform a node rewrite (see * {@link Node#replace(Node)}) with a node that no longer relies on the assumption. * * @throws InvalidAssumptionException If the assumption is no longer valid. */ void check() throws InvalidAssumptionException; /** * Checks whether the assumption is still valid. * * @return a boolean value indicating the validity of the assumption */ boolean isValid(); /** * Invalidates this assumption. Performs no operation, if the assumption is already invalid. */ void invalidate(); /** * A name for the assumption that is used for debug output. * * @return the name of the assumption */ String getName(); } truffle-0.6.orig/com/oracle/truffle/api/script/0000755000000000000000000000000012460741021016417 5ustar truffle-0.6.orig/com/oracle/truffle/api/script/TruffleScriptEngineFactory.java0000644000000000000000000000341512445312576024553 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.script; import javax.script.*; /** * Tool access to the creation of Truffle execution engines. */ public abstract class TruffleScriptEngineFactory implements ScriptEngineFactory { // TODO (mlvdv) first step, based on a suggestion from NetBeans /** * To be called by each concrete factory just after each engine instance is created, presenting * an opportunity for an IDE to interrupt in a language-independent way. * * @param engine a just-created engine */ protected final void engineCreated(ScriptEngine engine) { } } truffle-0.6.orig/com/oracle/truffle/api/TruffleOptions.java0000644000000000000000000001020112445312576020747 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import java.security.*; import com.oracle.truffle.api.nodes.*; /** * Class containing general Truffle options. */ public class TruffleOptions { /** * Enables/disables the rewriting of traces in the Truffle runtime to stdout. *

* Can be set with {@code -Dtruffle.TraceRewrites=true}. */ public static boolean TraceRewrites; /** * Enables the generation of detailed rewrite reasons. Enabling this may introduce some overhead * for rewriting nodes. *

* Can be set with {@code -Dtruffle.DetailedRewriteReasons=true}. */ public static final boolean DetailedRewriteReasons; /** * Filters rewrites that do not contain the given string in the qualified name of the source or * target class hierarchy. *

* Can be set with {@code -Dtruffle.TraceRewritesFilterClass=name}. */ public static String TraceRewritesFilterClass; /** * Filters rewrites which does not contain the {@link NodeCost} in its source {@link NodeInfo}. * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. *

* Can be set with * {@code -Dtruffle.TraceRewritesFilterFromCost=NONE|MONOMORPHIC|POLYMORPHIC|MEGAMORPHIC}. */ public static NodeCost TraceRewritesFilterFromCost; /** * Filters rewrites which does not contain the {@link NodeCost} in its target {@link NodeInfo}. * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. *

* Can be set with * {@code -Dtruffle.TraceRewritesFilterToKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. */ public static NodeCost TraceRewritesFilterToCost; /** * Enables the dumping of Node creations and AST rewrites in JSON format. *

* Can be set with {@code -Dtruffle.TraceASTJSON=true}. */ public static final boolean TraceASTJSON; private static NodeCost parseNodeInfoKind(String kind) { if (kind == null) { return null; } return NodeCost.valueOf(kind); } static { final boolean[] values = {false, false}; AccessController.doPrivileged(new PrivilegedAction() { public Void run() { TraceRewrites = Boolean.getBoolean("truffle.TraceRewrites"); TraceRewritesFilterClass = System.getProperty("truffle.TraceRewritesFilterClass"); TraceRewritesFilterFromCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromCost")); TraceRewritesFilterToCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToCost")); values[0] = Boolean.getBoolean("truffle.DetailedRewriteReasons"); values[1] = Boolean.getBoolean("truffle.TraceASTJSON"); return null; } }); DetailedRewriteReasons = values[0]; TraceASTJSON = values[1]; } } truffle-0.6.orig/com/oracle/truffle/api/object/0000755000000000000000000000000012460741021016361 5ustar truffle-0.6.orig/com/oracle/truffle/api/object/ObjectType.java0000644000000000000000000000476012445312576021317 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; public class ObjectType { /** * Delegate method for {@link DynamicObject#equals(Object)}. */ public boolean equals(DynamicObject object, Object other) { return object == other; } /** * Delegate method for {@link DynamicObject#hashCode()}. */ public int hashCode(DynamicObject object) { return System.identityHashCode(object); } /** * Delegate method for {@link DynamicObject#toString()}. */ @TruffleBoundary public String toString(DynamicObject object) { return "DynamicObject<" + this.toString() + ">@" + Integer.toHexString(hashCode(object)); } /** * Creates a data object to be associated with a newly created shape. * * @param shape the shape for which to create the data object */ public Object createShapeData(Shape shape) { return null; } /** * Called when a new property is added to a shape. * * @param property the added property * @param shapeBefore shape before the property was added * @param shapeAfter shape after the property was added */ public void onPropertyAdded(Property property, Shape shapeBefore, Shape shapeAfter) { } } truffle-0.6.orig/com/oracle/truffle/api/object/Location.java0000644000000000000000000001110412445312576021005 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import com.oracle.truffle.api.*; /** * Property location. * * @see Shape * @see Property * @see DynamicObject */ public abstract class Location implements BaseLocation { protected static IncompatibleLocationException incompatibleLocation() throws IncompatibleLocationException { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new IncompatibleLocationException(); } protected static FinalLocationException finalLocation() throws FinalLocationException { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new FinalLocationException(); } public final Object get(DynamicObject store, Shape shape) { return get(store, checkShape(store, shape)); } public Object get(DynamicObject store, boolean condition) { return getInternal(store); } public void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { setInternal(store, value); } public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { if (canStore(value)) { store.setShapeAndGrow(oldShape, newShape); try { setInternal(store, value); } catch (IncompatibleLocationException ex) { throw new IllegalStateException(); } } else { throw incompatibleLocation(); } } public final void set(DynamicObject store, Object value) throws IncompatibleLocationException, FinalLocationException { set(store, value, null); } protected abstract Object getInternal(DynamicObject store); /** * Like {@link #set(DynamicObject, Object, Shape)}, but does not invalidate final locations. For * internal use only and subject to change, use {@link DynamicObjectFactory} to create objects * with predefined properties. * * @throws IncompatibleLocationException if value is of non-assignable type */ protected abstract void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException; /** * Returns {@code true} if the location can be set to the value. * * @param store the receiver object * @param value the value in question */ public boolean canSet(DynamicObject store, Object value) { return canStore(value); } /** * Returns {@code true} if the location is compatible with the value. * * The value may still be rejected if {@link #canSet(DynamicObject, Object)} returns false. * * @param value the value in question */ public boolean canStore(Object value) { return true; } /** * Returns {@code true} if this is a final location, i.e. readonly once set. */ public boolean isFinal() { return false; } /** * Returns {@code true} if this is an immutable constant location. */ public boolean isConstant() { return false; } /* * Abstract to force overriding. */ @Override public abstract int hashCode(); /* * Abstract to force overriding. */ @Override public abstract boolean equals(Object obj); protected static boolean checkShape(DynamicObject store, Shape shape) { return store.getShape() == shape; } } truffle-0.6.orig/com/oracle/truffle/api/object/LayoutFactory.java0000644000000000000000000000263512445312576022053 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface LayoutFactory { Layout createLayout(LayoutBuilder layoutBuilder); Property createProperty(Object id, Location location, int flags); int getPriority(); } truffle-0.6.orig/com/oracle/truffle/api/object/BaseLocation.java0000644000000000000000000000565012445312576021611 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface BaseLocation { /** * Get object value as object at this location in store. * * @param shape the current shape of the object, which must contain this location */ Object get(DynamicObject store, Shape shape); /** * Get object value as object at this location in store. For internal use only and subject to * change, use {@link #get(DynamicObject, Shape)} instead. * * @param condition the result of a shape check or {@code false} * @see #get(DynamicObject, Shape) */ Object get(DynamicObject store, boolean condition); /** * Set object value at this location in store. * * @throws IncompatibleLocationException for storage type invalidations * @throws FinalLocationException for effectively final fields */ void set(DynamicObject store, Object value) throws IncompatibleLocationException, FinalLocationException; /** * Set object value at this location in store. * * @param shape the current shape of the storage object * @throws IncompatibleLocationException for storage type invalidations * @throws FinalLocationException for effectively final fields */ void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException; /** * Set object value at this location in store and update shape. * * @param oldShape the shape before the transition * @param newShape new shape after the transition * @throws IncompatibleLocationException if value is of non-assignable type */ void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException; } truffle-0.6.orig/com/oracle/truffle/api/object/LocationModifier.java0000644000000000000000000000243612445312576022474 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public enum LocationModifier { Final, NonNull, } truffle-0.6.orig/com/oracle/truffle/api/object/DoubleLocation.java0000644000000000000000000000376212445312576022153 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface DoubleLocation extends TypedLocation { /** * @see #get(DynamicObject, Shape) */ double getDouble(DynamicObject store, Shape shape); /** * @see #get(DynamicObject, boolean) */ double getDouble(DynamicObject store, boolean condition); /** * @see #set(DynamicObject, Object) */ void setDouble(DynamicObject store, double value) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape) */ void setDouble(DynamicObject store, double value, Shape shape) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape, Shape) */ void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape); Class getType(); } truffle-0.6.orig/com/oracle/truffle/api/object/DynamicObject.java0000644000000000000000000001035512445312576021757 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import com.oracle.truffle.api.*; public interface DynamicObject extends TypedObject { /** * Get the object's current shape. */ Shape getShape(); /** * Get property value. * * @param key property identifier * @param defaultValue return value if property is not found * @return property value or defaultValue if object has no such property */ Object get(Object key, Object defaultValue); /** * Set value of existing property. * * @param key property identifier * @param value value to be set * @return {@code true} if successful or {@code false} if property not found */ boolean set(Object key, Object value); /** * Define new property or redefine existing property. * * @param key property identifier * @param value value to be set * @param flags flags to be set */ void define(Object key, Object value, int flags); /** * Define new property with a static location or change existing property. * * @param key property identifier * @param value value to be set * @param flags flags to be set * @param locationFactory factory function that creates a location for a given shape and value */ void define(Object key, Object value, int flags, LocationFactory locationFactory); /** * Change property flags. * * @param key property identifier * @param newFlags flags to be set * @return {@code true} if successful or {@code false} if property not found */ boolean changeFlags(Object key, int newFlags); /** * Change property flags. * * @param key property identifier * @param flagsUpdateFunction function updating old flags to new flags * @return {@code true} if successful or {@code false} if property not found */ boolean changeFlags(Object key, FlagsFunction flagsUpdateFunction); /** * Delete property. * * @param key property identifier * @return {@code true} if successful or {@code false} if property not found */ boolean delete(Object key); /** * Returns the number of properties in this object. */ int size(); /** * Returns {@code true} if this object contains no properties. */ boolean isEmpty(); /** * Set object shape and grow storage if necessary. * * @param oldShape the object's current shape (must equal {@link #getShape()}) * @param newShape the new shape to be set */ void setShapeAndGrow(Shape oldShape, Shape newShape); /** * Set object shape and resize storage if necessary. * * @param oldShape the object's current shape (must equal {@link #getShape()}) * @param newShape the new shape to be set */ void setShapeAndResize(Shape oldShape, Shape newShape); /** * Ensure object shape is up-to-date. * * @return {@code true} if shape has changed */ boolean updateShape(); public interface FlagsFunction { int apply(int t); } } truffle-0.6.orig/com/oracle/truffle/api/object/LocationFactory.java0000644000000000000000000000250212445312576022337 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface LocationFactory { Location createLocation(Shape shape, Object value); } truffle-0.6.orig/com/oracle/truffle/api/object/Layout.java0000644000000000000000000001070712445312576020522 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import java.util.*; import com.oracle.truffle.api.nodes.NodeUtil.FieldOffsetProvider; import com.oracle.truffle.api.object.Shape.*; public abstract class Layout { public static final EnumSet NONE = EnumSet.noneOf(ImplicitCast.class); public static final EnumSet INT_TO_DOUBLE = EnumSet.of(ImplicitCast.IntToDouble); public static final EnumSet INT_TO_LONG = EnumSet.of(ImplicitCast.IntToLong); public static final String OPTION_PREFIX = "truffle.object."; private static final LayoutFactory LAYOUT_FACTORY = loadLayoutFactory(); public enum ImplicitCast { IntToDouble, IntToLong, } public static Layout createLayout() { return createLayout(NONE); } public static Layout createLayout(EnumSet allowedImplicitCasts) { return new LayoutBuilder().setAllowedImplicitCasts(allowedImplicitCasts).build(); } public static Layout createLayout(EnumSet allowedImplicitCasts, FieldOffsetProvider fieldOffsetProvider) { return new LayoutBuilder().setAllowedImplicitCasts(allowedImplicitCasts).setFieldOffsetProvider(fieldOffsetProvider).build(); } public abstract DynamicObject newInstance(Shape shape); public abstract Class getType(); public abstract Shape createShape(ObjectType operations); public abstract Shape createShape(ObjectType operations, Object sharedData); public abstract Shape createShape(ObjectType operations, Object sharedData, int id); /** * Create an allocator for static property creation. Reserves all array extension slots. */ public abstract Allocator createAllocator(); protected static LayoutFactory getFactory() { return LAYOUT_FACTORY; } private static LayoutFactory loadLayoutFactory() { LayoutFactory bestLayoutFactory = null; String layoutFactoryImplClassName = System.getProperty(OPTION_PREFIX + "LayoutFactory"); if (layoutFactoryImplClassName != null) { Class clazz; try { clazz = Class.forName(layoutFactoryImplClassName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } try { bestLayoutFactory = (LayoutFactory) clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new AssertionError(e); } } else { ServiceLoader serviceLoader = ServiceLoader.load(LayoutFactory.class, Layout.class.getClassLoader()); for (LayoutFactory currentLayoutFactory : serviceLoader) { if (bestLayoutFactory == null) { bestLayoutFactory = currentLayoutFactory; } else if (currentLayoutFactory.getPriority() >= bestLayoutFactory.getPriority()) { assert currentLayoutFactory.getPriority() != bestLayoutFactory.getPriority(); bestLayoutFactory = currentLayoutFactory; } } } if (bestLayoutFactory == null) { throw new AssertionError("LayoutFactory not found"); } return bestLayoutFactory; } } truffle-0.6.orig/com/oracle/truffle/api/object/ShapeVisitor.java0000644000000000000000000000245112445312576021662 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface ShapeVisitor { R visitShape(Shape shape); } truffle-0.6.orig/com/oracle/truffle/api/object/DynamicObjectFactory.java0000644000000000000000000000253612445312576023311 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface DynamicObjectFactory { DynamicObject newInstance(Object... initialValues); Shape getShape(); } truffle-0.6.orig/com/oracle/truffle/api/object/DebugCounter.java0000644000000000000000000000423712445312576021634 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import java.io.*; import java.util.*; import java.util.concurrent.atomic.*; public final class DebugCounter { private static final ArrayList allCounters = new ArrayList<>(); private final String name; private final AtomicLong value; private DebugCounter(String name) { this.name = name; this.value = new AtomicLong(); allCounters.add(this); } public static DebugCounter create(String name) { return new DebugCounter(name); } public long get() { return value.get(); } public void inc() { value.incrementAndGet(); } @Override public String toString() { return name + ": " + value; } public static void dumpCounters() { dumpCounters(System.out); } public static void dumpCounters(PrintStream out) { for (DebugCounter counter : allCounters) { out.println(counter); } } } truffle-0.6.orig/com/oracle/truffle/api/object/HiddenKey.java0000644000000000000000000000275512445312576021115 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public final class HiddenKey { private final String name; public HiddenKey(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return name; } } truffle-0.6.orig/com/oracle/truffle/api/object/IntLocation.java0000644000000000000000000000372212445312576021467 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface IntLocation extends TypedLocation { /** * @see #get(DynamicObject, Shape) */ int getInt(DynamicObject store, Shape shape); /** * @see #get(DynamicObject, boolean) */ int getInt(DynamicObject store, boolean condition); /** * @see #set(DynamicObject, Object) */ void setInt(DynamicObject store, int value) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape) */ void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape, Shape) */ void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape); Class getType(); } truffle-0.6.orig/com/oracle/truffle/api/object/Property.java0000644000000000000000000001551512445312576021073 0ustar /* * Copyright (c) 2012, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; /** * Property objects represent the mapping between low-level stores and high-level data. The simplest * Property could be nothing more than a map of one index to one property's value, but abstracting * the interface allows for getter/setter methods, type-checked properties, and other such * specialized and language-specific behavior. ECMAScript[8.6.1] */ public abstract class Property { protected Property() { } public static Property create(Object key, Location location, int flags) { return Layout.getFactory().createProperty(key, location, flags); } /** * Get property identifier. */ public abstract Object getKey(); /** * Get property flags. */ public abstract int getFlags(); /** * Change the property's location. * * @return a Property with the new location (or {@code this} if the location is unchanged). */ public abstract Property relocate(Location newLocation); /** * Gets the value of this property of the object. * * @param store the store that this property resides in * @param shape the current shape of the object, which must contain this location * @see DynamicObject#get(Object, Object) */ public abstract Object get(DynamicObject store, Shape shape); /** * Gets the value of this property of the object. * * @param store the store that this property resides in * @param condition the result of a shape check or {@code false} * @see DynamicObject#get(Object, Object) * @see #get(DynamicObject, Shape) */ public abstract Object get(DynamicObject store, boolean condition); /** * Assigns value to this property of the object. * * Throws an exception if the value cannot be assigned to the property's current location. * * @param store the store that this property resides in * @param value the value to assign * @param shape the current shape of the object or {@code null} * @throws IncompatibleLocationException if the value is incompatible with the property location * @throws FinalLocationException if the location is final and values differ * @see DynamicObject#set(Object, Object) */ public abstract void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException; /** * Assigns value to this property of the object. * * Automatically relocates the property if the value cannot be assigned to its current location. * * @param shape the current shape of the object or {@code null} */ public abstract void setGeneric(DynamicObject store, Object value, Shape shape); /** * Like {@link #set(DynamicObject, Object, Shape)}, but throws an {@link IllegalStateException} * instead. */ public abstract void setSafe(DynamicObject store, Object value, Shape shape); /** * Like {@link #setSafe}, but ignores the finalness of the property. For internal use only. * * @param store the store that this property resides in * @param value the value to assign */ public abstract void setInternal(DynamicObject store, Object value); /** * Assigns value to this property of the object, changing the object's shape. * * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and * {@link #set(DynamicObject, Object, Shape)} to an atomic operation. * * @param store the store that this property resides in * @param value the value to assign * @param oldShape the shape before the transition * @param newShape the shape after the transition * @throws IncompatibleLocationException if the value is incompatible with the property location */ public abstract void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException; /** * Assigns value to this property of the object, changing the object's shape. * * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and * {@link #setGeneric(DynamicObject, Object, Shape)} to an atomic operation. * * @param store the store that this property resides in * @param value the value to assign * @param oldShape the shape before the transition * @param newShape the shape after the transition */ public abstract void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape); /** * Assigns value to this property of the object, changing the object's shape. * * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and * {@link #setSafe(DynamicObject, Object, Shape)} to an atomic operation. * * @param store the store that this property resides in * @param value the value to assign * @param oldShape the shape before the transition * @param newShape the shape after the transition */ public abstract void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape); /** * Returns {@code true} if this property and some other property have the same key and flags. */ public abstract boolean isSame(Property other); /** * Get the property location. */ public abstract Location getLocation(); /** * Is this property hidden from iteration. * * @see HiddenKey */ public abstract boolean isHidden(); public abstract boolean isShadow(); /** * Create a copy of the property with the given flags. */ public abstract Property copyWithFlags(int newFlags); public abstract Property copyWithRelocatable(boolean newRelocatable); } truffle-0.6.orig/com/oracle/truffle/api/object/ObjectLocation.java0000644000000000000000000000267312445312576022147 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface ObjectLocation extends TypedLocation { Class getType(); /** * If {@code true}, this location does not accept {@code null} values. */ boolean isNonNull(); } truffle-0.6.orig/com/oracle/truffle/api/object/LayoutBuilder.java0000644000000000000000000000436012445312576022027 0ustar /* * Copyright (c) 2014, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import java.util.*; import com.oracle.truffle.api.nodes.NodeUtil.*; import com.oracle.truffle.api.object.Layout.*; public class LayoutBuilder { private EnumSet allowedImplicitCasts; private FieldOffsetProvider fieldOffsetProvider; public LayoutBuilder() { this.allowedImplicitCasts = Layout.NONE; this.fieldOffsetProvider = null; } public Layout build() { return Layout.getFactory().createLayout(this); } public LayoutBuilder setAllowedImplicitCasts(EnumSet allowedImplicitCasts) { this.allowedImplicitCasts = allowedImplicitCasts; return this; } public LayoutBuilder setFieldOffsetProvider(FieldOffsetProvider fieldOffsetProvider) { this.fieldOffsetProvider = fieldOffsetProvider; return this; } public EnumSet getAllowedImplicitCasts() { return allowedImplicitCasts; } public FieldOffsetProvider getFieldOffsetProvider() { return fieldOffsetProvider; } } truffle-0.6.orig/com/oracle/truffle/api/object/IncompatibleLocationException.java0000644000000000000000000000264412445312576025224 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import com.oracle.truffle.api.nodes.*; public final class IncompatibleLocationException extends SlowPathException { private static final long serialVersionUID = -7734865392357341789L; } truffle-0.6.orig/com/oracle/truffle/api/object/FinalLocationException.java0000644000000000000000000000263312445312576023645 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import com.oracle.truffle.api.nodes.*; public final class FinalLocationException extends SlowPathException { private static final long serialVersionUID = -30188494510914293L; } truffle-0.6.orig/com/oracle/truffle/api/object/Shape.java0000644000000000000000000002221212445312576020277 0ustar /* * Copyright (c) 2012, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; import java.util.*; import com.oracle.truffle.api.*; /** * Shape objects create a mapping of Property objects to Locations. Shapes are immutable; adding or * deleting a property yields a new Shape which links to the old one. This allows inline caching to * simply check the identity of an object's Shape to determine if the cache is valid. There is one * exception to this immutability, the transition map, but that is used simply to assure that an * identical series of property additions and deletions will yield the same Shape object. * * @see DynamicObject * @see Property * @see Location */ public abstract class Shape { /** * Get a property entry by key. * * @param key the identifier to look up * @return a Property object, or null if not found */ public abstract Property getProperty(Object key); /** * Add a new property in the map, yielding a new or cached Shape object. * * @param property the property to add * @return the new Shape */ public abstract Shape addProperty(Property property); /** * An {@link Iterable} over the shape's properties in insertion order. */ public abstract Iterable getProperties(); /** * Get a list of properties that this Shape stores. * * @return list of properties */ public abstract List getPropertyList(Pred filter); /** * Get a list of all properties that this Shape stores. * * @return list of properties */ public abstract List getPropertyList(); /** * Returns all (also hidden) property objects in this shape. * * @param ascending desired order ({@code true} for insertion order, {@code false} for reverse * insertion order) */ public abstract List getPropertyListInternal(boolean ascending); /** * Get a filtered list of property keys in insertion order. */ public abstract List getKeyList(Pred filter); /** * Get a list of all property keys in insertion order. */ public abstract List getKeyList(); /** * Get all property keys in insertion order. */ public abstract Iterable getKeys(); /** * Get an assumption that the shape is valid. */ public abstract Assumption getValidAssumption(); /** * Check whether this shape is valid. */ public abstract boolean isValid(); /** * Get an assumption that the shape is a leaf. */ public abstract Assumption getLeafAssumption(); /** * Check whether this shape is a leaf in the transition graph, i.e. transitionless. */ public abstract boolean isLeaf(); /** * @return the parent shape or {@code null} if none. */ public abstract Shape getParent(); /** * Check whether the shape has a property with the given key. */ public abstract boolean hasProperty(Object key); /** * Remove the given property from the shape. */ public abstract Shape removeProperty(Property property); /** * Replace a property in the shape. */ public abstract Shape replaceProperty(Property oldProperty, Property newProperty); /** * Get the last added property. */ public abstract Property getLastProperty(); public abstract int getId(); /** * Append the property, relocating it to the next allocated location. */ public abstract Shape append(Property oldProperty); /** * Obtain an {@link Allocator} instance for the purpose of allocating locations. */ public abstract Allocator allocator(); /** * For copying over properties after exchanging the prototype of an object. */ public abstract Shape copyOverPropertiesInternal(Shape destination); /** * Get number of properties in this shape. */ public abstract int getPropertyCount(); /** * Get the shape's operations. */ public abstract ObjectType getObjectType(); /** * Get the root shape. */ public abstract Shape getRoot(); /** * Check whether this shape is identical to the given shape. */ public abstract boolean check(DynamicObject subject); /** * Get the shape's layout. */ public abstract Layout getLayout(); /** * Get the shape's custom data. */ public abstract Object getData(); /** * Get the shape's shared data. */ public abstract Object getSharedData(); /** * Query whether the shape has a transition with the given key. */ public abstract boolean hasTransitionWithKey(Object key); /** * Clone off a separate shape with new shared data. */ public abstract Shape createSeparateShape(Object sharedData); /** * Change the shape's type, yielding a new shape. */ public abstract Shape changeType(ObjectType newOps); /** * Reserve the primitive extension array field. */ public abstract Shape reservePrimitiveExtensionArray(); /** * Create a new {@link DynamicObject} instance with this shape. */ public abstract DynamicObject newInstance(); /** * Create a {@link DynamicObjectFactory} for creating instances of this shape. */ public abstract DynamicObjectFactory createFactory(); /** * Get mutex object shared by related shapes, i.e. shapes with a common root. */ public abstract Object getMutex(); public abstract int getObjectArraySize(); public abstract int getObjectFieldSize(); public abstract int getPrimitiveArraySize(); public abstract int getPrimitiveFieldSize(); public abstract int getObjectArrayCapacity(); public abstract int getPrimitiveArrayCapacity(); public abstract boolean hasPrimitiveArray(); /** * Are these two shapes related, i.e. do they have the same root? * * @param other Shape to compare to * @return true if one shape is an upcast of the other, or the Shapes are equal */ public abstract boolean isRelated(Shape other); public abstract Shape tryMerge(Shape other); public R accept(ShapeVisitor visitor) { return visitor.visitShape(this); } public abstract static class Allocator { protected abstract Location locationForValue(Object value, boolean useFinal, boolean nonNull); public final Location locationForValue(Object value) { return locationForValue(value, false, value != null); } public final Location locationForValue(Object value, EnumSet modifiers) { assert value != null || !modifiers.contains(LocationModifier.NonNull); return locationForValue(value, modifiers.contains(LocationModifier.Final), modifiers.contains(LocationModifier.NonNull)); } protected abstract Location locationForType(Class type, boolean useFinal, boolean nonNull); public final Location locationForType(Class type) { return locationForType(type, false, false); } public final Location locationForType(Class type, EnumSet modifiers) { return locationForType(type, modifiers.contains(LocationModifier.Final), modifiers.contains(LocationModifier.NonNull)); } public abstract Location constantLocation(Object value); public abstract Location declaredLocation(Object value); public abstract Allocator addLocation(Location location); } /** * Represents a predicate (boolean-valued function) of one argument. For Java 7 compatibility. * * @param the type of the input to the predicate */ public interface Pred { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, otherwise {@code false} */ boolean test(T t); } } truffle-0.6.orig/com/oracle/truffle/api/object/LongLocation.java0000644000000000000000000000373212445312576021635 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface LongLocation extends TypedLocation { /** * @see #get(DynamicObject, Shape) */ long getLong(DynamicObject store, Shape shape); /** * @see #get(DynamicObject, boolean) */ long getLong(DynamicObject store, boolean condition); /** * @see #set(DynamicObject, Object) */ void setLong(DynamicObject store, long value) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape) */ void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape, Shape) */ void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape); Class getType(); } truffle-0.6.orig/com/oracle/truffle/api/object/TypedLocation.java0000644000000000000000000000254712445312576022026 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface TypedLocation extends BaseLocation { /** * The type of this location. */ Class getType(); } truffle-0.6.orig/com/oracle/truffle/api/object/BooleanLocation.java0000644000000000000000000000377612445312576022325 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.object; public interface BooleanLocation extends TypedLocation { /** * @see #get(DynamicObject, Shape) */ boolean getBoolean(DynamicObject store, Shape shape); /** * @see #get(DynamicObject, boolean) */ boolean getBoolean(DynamicObject store, boolean condition); /** * @see #set(DynamicObject, Object) */ void setBoolean(DynamicObject store, boolean value) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape) */ void setBoolean(DynamicObject store, boolean value, Shape shape) throws FinalLocationException; /** * @see #set(DynamicObject, Object, Shape, Shape) */ void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape); Class getType(); } truffle-0.6.orig/com/oracle/truffle/api/frame/0000755000000000000000000000000012460741021016205 5ustar truffle-0.6.orig/com/oracle/truffle/api/frame/VirtualFrame.java0000644000000000000000000000312712445312576021470 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; /** * Represents a frame containing values of local variables of the guest language. Instances of this * type must not be stored in a field or cast to {@link java.lang.Object}. If this is necessary, the * frame must be explicitly converted into a materialized frame using the * {@link VirtualFrame#materialize()} method. */ public interface VirtualFrame extends Frame { } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameSlotKind.java0000644000000000000000000000252612445312576021573 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; public enum FrameSlotKind { Object, Illegal, Long, Int, Double, Float, Boolean, Byte; } truffle-0.6.orig/com/oracle/truffle/api/frame/MaterializedFrame.java0000644000000000000000000000333012445312576022450 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; /** * Represents a materialized frame containing values of local variables of the guest language. It * can be created using the {@link VirtualFrame#materialize()} method. Instances of this type are * the only frame instances that may be stored in fields or cast to {@link java.lang.Object}. In * contrast to a {@link VirtualFrame}, a {@link MaterializedFrame} can no longer be packed and it * also does not provide access to the caller frame. */ public interface MaterializedFrame extends Frame { } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameInstance.java0000644000000000000000000000312312445312576021602 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; public interface FrameInstance { public static enum FrameAccess { NONE, READ_ONLY, READ_WRITE, MATERIALIZE } Frame getFrame(FrameAccess access, boolean slowPath); boolean isVirtualFrame(); Node getCallNode(); CallTarget getCallTarget(); } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameSlotTypeException.java0000644000000000000000000000302612445312576023502 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; import com.oracle.truffle.api.nodes.*; /** * Exception thrown if the frame slot type does not match the access type. */ public final class FrameSlotTypeException extends SlowPathException { private static final long serialVersionUID = 6972120475215757452L; public FrameSlotTypeException() { } } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameUtil.java0000644000000000000000000001210712445312576020755 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; public final class FrameUtil { /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getObject(FrameSlot) */ public static Object getObjectSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getObject(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getByte(FrameSlot) */ public static byte getByteSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getByte(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getBoolean(FrameSlot) */ public static boolean getBooleanSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getBoolean(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getInt(FrameSlot) */ public static int getIntSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getInt(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getLong(FrameSlot) */ public static long getLongSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getLong(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getDouble(FrameSlot) */ public static double getDoubleSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getDouble(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getFloat(FrameSlot) */ public static float getFloatSafe(Frame frame, FrameSlot frameSlot) { try { return frame.getFloat(frameSlot); } catch (FrameSlotTypeException e) { throw new IllegalStateException(); } } } truffle-0.6.orig/com/oracle/truffle/api/frame/Frame.java0000644000000000000000000001475612445312576020133 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; /** * Represents a frame containing values of local variables of the guest language. Instances of this * type must not be stored in a field or cast to {@link java.lang.Object}. */ public interface Frame { /** * @return the object describing the layout of this frame */ FrameDescriptor getFrameDescriptor(); /** * Retrieves the arguments object from this frame. The runtime assumes that the arguments object * is never null. * * @return the arguments used when calling this method */ Object[] getArguments(); /** * Read access to a local variable of type {@link Object}. * * @param slot the slot of the local variable * @return the current value of the local variable */ Object getObject(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type {@link Object}. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setObject(FrameSlot slot, Object value); /** * Read access to a local variable of type byte. * * @param slot the slot of the local variable * @return the current value of the local variable * @throws FrameSlotTypeException */ byte getByte(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type byte. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setByte(FrameSlot slot, byte value); /** * Read access to a local variable of type boolean. * * @param slot the slot of the local variable * @return the current value of the local variable */ boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type boolean. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setBoolean(FrameSlot slot, boolean value); /** * Read access to a local variable of type int. * * @param slot the slot of the local variable * @return the current value of the local variable */ int getInt(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type int. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setInt(FrameSlot slot, int value); /** * Read access to a local variable of type long. * * @param slot the slot of the local variable * @return the current value of the local variable */ long getLong(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type long. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setLong(FrameSlot slot, long value); /** * Read access to a local variable of type float. * * @param slot the slot of the local variable * @return the current value of the local variable */ float getFloat(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type float. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setFloat(FrameSlot slot, float value); /** * Read access to a local variable of type double. * * @param slot the slot of the local variable * @return the current value of the local variable */ double getDouble(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type double. * * @param slot the slot of the local variable * @param value the new value of the local variable */ void setDouble(FrameSlot slot, double value); /** * Read access to a local variable of any type. * * @param slot the slot of the local variable * @return the current value of the local variable or defaultValue if unset */ Object getValue(FrameSlot slot); /** * Materializes this frame, which allows it to be stored in a field or cast to * {@link java.lang.Object}. The frame however looses the ability to be packed or to access the * caller frame. * * @return the new materialized frame */ MaterializedFrame materialize(); /** * Check whether the given {@link FrameSlot} is of type object. */ boolean isObject(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type byte. */ boolean isByte(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type boolean. */ boolean isBoolean(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type int. */ boolean isInt(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type long. */ boolean isLong(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type float. */ boolean isFloat(FrameSlot slot); /** * Check whether the given {@link FrameSlot} is of type double. */ boolean isDouble(FrameSlot slot); } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameDescriptor.java0000644000000000000000000001551212445312576022161 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; import java.util.*; import com.oracle.truffle.api.*; /** * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such * descriptor. */ public final class FrameDescriptor implements Cloneable { private final Object defaultValue; private final ArrayList slots; private final HashMap identifierToSlotMap; private Assumption version; private HashMap identifierToNotInFrameAssumptionMap; public FrameDescriptor() { this(null); } public FrameDescriptor(Object defaultValue) { this.defaultValue = defaultValue; slots = new ArrayList<>(); identifierToSlotMap = new HashMap<>(); version = createVersion(); } public static FrameDescriptor create() { return new FrameDescriptor(); } public static FrameDescriptor create(Object defaultValue) { return new FrameDescriptor(defaultValue); } public FrameSlot addFrameSlot(Object identifier) { return addFrameSlot(identifier, null, FrameSlotKind.Illegal); } public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) { return addFrameSlot(identifier, null, kind); } public FrameSlot addFrameSlot(Object identifier, Object info, FrameSlotKind kind) { CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations."); assert !identifierToSlotMap.containsKey(identifier); FrameSlot slot = new FrameSlot(this, identifier, info, slots.size(), kind); slots.add(slot); identifierToSlotMap.put(identifier, slot); updateVersion(); invalidateNotInFrameAssumption(identifier); return slot; } public FrameSlot findFrameSlot(Object identifier) { return identifierToSlotMap.get(identifier); } public FrameSlot findOrAddFrameSlot(Object identifier) { FrameSlot result = findFrameSlot(identifier); if (result != null) { return result; } return addFrameSlot(identifier); } public FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind) { FrameSlot result = findFrameSlot(identifier); if (result != null) { return result; } return addFrameSlot(identifier, kind); } public FrameSlot findOrAddFrameSlot(Object identifier, Object info, FrameSlotKind kind) { FrameSlot result = findFrameSlot(identifier); if (result != null) { return result; } return addFrameSlot(identifier, info, kind); } public void removeFrameSlot(Object identifier) { CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations."); assert identifierToSlotMap.containsKey(identifier); slots.remove(identifierToSlotMap.get(identifier)); identifierToSlotMap.remove(identifier); updateVersion(); getNotInFrameAssumption(identifier); } public int getSize() { return slots.size(); } public List getSlots() { return Collections.unmodifiableList(slots); } /** * Retrieve the list of all the identifiers associated with this frame descriptor. * * @return the list of all the identifiers in this frame descriptor */ public Set getIdentifiers() { return Collections.unmodifiableSet(identifierToSlotMap.keySet()); } public FrameDescriptor copy() { FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue); for (int i = 0; i < this.getSlots().size(); i++) { Object identifier = this.getSlots().get(i).getIdentifier(); clonedFrameDescriptor.addFrameSlot(identifier); } return clonedFrameDescriptor; } public FrameDescriptor shallowCopy() { FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue); clonedFrameDescriptor.slots.addAll(slots); clonedFrameDescriptor.identifierToSlotMap.putAll(identifierToSlotMap); return clonedFrameDescriptor; } void updateVersion() { version.invalidate(); version = createVersion(); } public Assumption getVersion() { return version; } private static Assumption createVersion() { return Truffle.getRuntime().createAssumption("frame version"); } public Object getDefaultValue() { return defaultValue; } public Assumption getNotInFrameAssumption(Object identifier) { if (identifierToSlotMap.containsKey(identifier)) { throw new IllegalArgumentException("Cannot get not-in-frame assumption for existing frame slot!"); } if (identifierToNotInFrameAssumptionMap == null) { identifierToNotInFrameAssumptionMap = new HashMap<>(); } else { Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier); if (assumption != null) { return assumption; } } Assumption assumption = Truffle.getRuntime().createAssumption("not in frame: " + identifier); identifierToNotInFrameAssumptionMap.put(identifier, assumption); return assumption; } private void invalidateNotInFrameAssumption(Object identifier) { if (identifierToNotInFrameAssumptionMap != null) { Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier); if (assumption != null) { assumption.invalidate(); identifierToNotInFrameAssumptionMap.remove(identifier); } } } } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameInstanceVisitor.java0000644000000000000000000000321312445312576023162 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; import com.oracle.truffle.api.*; /** * Callback interface for {@link TruffleRuntime#iterateFrames}. Implementations of * {@link #visitFrame} return null to indicate that frame iteration should continue and the next * caller frame should be visited; and return any non-null value to indicate that frame iteration * should stop. */ public interface FrameInstanceVisitor { T visitFrame(FrameInstance frameInstance); } truffle-0.6.orig/com/oracle/truffle/api/frame/FrameSlot.java0000644000000000000000000000510712445312576020763 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.frame; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** * A slot in a frame that can store a value of a given type. */ public final class FrameSlot implements Cloneable { private final FrameDescriptor descriptor; private final Object identifier; private final Object info; private final int index; @CompilationFinal private FrameSlotKind kind; public FrameSlot(FrameDescriptor descriptor, Object identifier, Object info, int index, FrameSlotKind kind) { this.descriptor = descriptor; this.identifier = identifier; this.info = info; this.index = index; this.kind = kind; } public Object getIdentifier() { return identifier; } public Object getInfo() { return info; } public int getIndex() { return index; } public FrameSlotKind getKind() { return kind; } public void setKind(final FrameSlotKind kind) { if (this.kind != kind) { CompilerDirectives.transferToInterpreter(); this.kind = kind; this.descriptor.updateVersion(); } } @Override public String toString() { return "[" + index + "," + identifier + "," + kind + "]"; } public FrameDescriptor getFrameDescriptor() { return this.descriptor; } } truffle-0.6.orig/com/oracle/truffle/api/RootCallTarget.java0000644000000000000000000000303112445312576020655 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import com.oracle.truffle.api.nodes.*; /** * Represents the target of a call to a {@link RootNode}, i.e., to another tree of nodes. Instances * of this class can be created using {@link TruffleRuntime#createCallTarget(RootNode)}. */ public interface RootCallTarget extends CallTarget { RootNode getRootNode(); } truffle-0.6.orig/com/oracle/truffle/api/ReplaceObserver.java0000644000000000000000000000267112445312576021063 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import com.oracle.truffle.api.nodes.*; /** * An observer that is notified whenever a child node is replaced. */ public interface ReplaceObserver { void nodeReplaced(Node oldNode, Node newNode, CharSequence reason); } truffle-0.6.orig/com/oracle/truffle/api/CompilerAsserts.java0000644000000000000000000001161612445312576021116 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; /** * Assertions about the code produced by the Truffle compiler. All operations have no effect when * either executed in the interpreter or in the compiled code. The assertions are checked during * code generation and the Truffle compiler produces for failing assertions a stack trace that * identifies the code position of the assertion in the context of the current compilation. * */ public class CompilerAsserts { /** * Assertion that this code position should never be reached during compilation. It can be used * for exceptional code paths or rare code paths that should never be included in a compilation * unit. See {@link CompilerDirectives#transferToInterpreter()} for the corresponding compiler * directive. */ public static void neverPartOfCompilation() { } public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) { } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static boolean compilationConstant(boolean value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static byte compilationConstant(byte value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static char compilationConstant(char value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static short compilationConstant(short value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static int compilationConstant(int value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static long compilationConstant(long value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static float compilationConstant(float value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static double compilationConstant(double value) { return value; } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation * @return the value given as parameter */ public static Object compilationConstant(Object value) { return value; } } truffle-0.6.orig/com/oracle/truffle/api/impl/0000755000000000000000000000000012460741021016054 5ustar truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java0000644000000000000000000001261312445312576023216 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * Default implementation of the Truffle runtime if the virtual machine does not provide a better * performing alternative. *

* This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link Truffle#getRuntime()} to retrieve the current {@link TruffleRuntime}. */ public final class DefaultTruffleRuntime implements TruffleRuntime { private ThreadLocal> stackTraces = new ThreadLocal<>(); private ThreadLocal currentFrames = new ThreadLocal<>(); private final Map callTargets = Collections.synchronizedMap(new WeakHashMap()); public DefaultTruffleRuntime() { if (Truffle.getRuntime() != null) { throw new IllegalArgumentException("Cannot instantiate DefaultTruffleRuntime. Use Truffle.getRuntime() instead."); } } @Override public String getName() { return "Default Truffle Runtime"; } @Override public RootCallTarget createCallTarget(RootNode rootNode) { DefaultCallTarget target = new DefaultCallTarget(rootNode); callTargets.put(target, null); return target; } public DirectCallNode createDirectCallNode(CallTarget target) { return new DefaultDirectCallNode(target); } public IndirectCallNode createIndirectCallNode() { return new DefaultIndirectCallNode(); } @Override public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) { return new DefaultVirtualFrame(frameDescriptor, arguments); } @Override public MaterializedFrame createMaterializedFrame(Object[] arguments) { return createMaterializedFrame(arguments, new FrameDescriptor()); } @Override public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) { return new DefaultMaterializedFrame(new DefaultVirtualFrame(frameDescriptor, arguments)); } @Override public CompilerOptions createCompilerOptions() { return new DefaultCompilerOptions(); } @Override public Assumption createAssumption() { return createAssumption(null); } @Override public Assumption createAssumption(String name) { return new DefaultAssumption(name); } private LinkedList getThreadLocalStackTrace() { LinkedList result = stackTraces.get(); if (result == null) { result = new LinkedList<>(); stackTraces.set(result); } return result; } public FrameInstance setCurrentFrame(FrameInstance newValue) { FrameInstance oldValue = currentFrames.get(); currentFrames.set(newValue); return oldValue; } public void pushFrame(FrameInstance frame) { getThreadLocalStackTrace().addFirst(frame); } public void popFrame() { getThreadLocalStackTrace().removeFirst(); } @Override public T iterateFrames(FrameInstanceVisitor visitor) { T result = null; for (FrameInstance frameInstance : getThreadLocalStackTrace()) { result = visitor.visitFrame(frameInstance); if (result != null) { return result; } } return result; } @Override public FrameInstance getCallerFrame() { return getThreadLocalStackTrace().peekFirst(); } @Override public Collection getCallTargets() { return Collections.unmodifiableSet(callTargets.keySet()); } @Override public FrameInstance getCurrentFrame() { return currentFrames.get(); } public T getCapability(Class capability) { return null; } public void notifyTransferToInterpreter() { } public LoopNode createLoopNode(RepeatingNode repeating) { if (!(repeating instanceof Node)) { throw new IllegalArgumentException("Repeating node must be of type Node."); } return new DefaultLoopNode(repeating); } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultDirectCallNode.java0000644000000000000000000000614212445312576023057 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * This is runtime specific API. Do not use in a guest language. */ public final class DefaultDirectCallNode extends DirectCallNode { private boolean inliningForced; public DefaultDirectCallNode(CallTarget target) { super(target); } @Override public Object call(final VirtualFrame frame, Object[] arguments) { final CallTarget currentCallTarget = defaultTruffleRuntime().getCurrentFrame().getCallTarget(); FrameInstance frameInstance = new FrameInstance() { public Frame getFrame(FrameAccess access, boolean slowPath) { return frame; } public boolean isVirtualFrame() { return false; } public Node getCallNode() { return DefaultDirectCallNode.this; } public CallTarget getCallTarget() { return currentCallTarget; } }; defaultTruffleRuntime().pushFrame(frameInstance); try { return getCurrentCallTarget().call(arguments); } finally { defaultTruffleRuntime().popFrame(); } } @Override public void forceInlining() { inliningForced = true; } @Override public boolean isInliningForced() { return inliningForced; } @Override public CallTarget getClonedCallTarget() { return null; } @Override public boolean cloneCallTarget() { return false; } @Override public boolean isCallTargetCloningAllowed() { return false; } @Override public boolean isInlinable() { return false; } private static DefaultTruffleRuntime defaultTruffleRuntime() { return (DefaultTruffleRuntime) Truffle.getRuntime(); } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultCallTarget.java0000644000000000000000000000567212445312576022274 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link TruffleRuntime#createCallTarget(RootNode)} to create a {@link RootCallTarget}. */ public class DefaultCallTarget implements RootCallTarget { private final RootNode rootNode; public DefaultCallTarget(RootNode function) { this.rootNode = function; this.rootNode.adoptChildren(); this.rootNode.applyInstrumentation(); this.rootNode.setCallTarget(this); } @Override public String toString() { return rootNode.toString(); } public final RootNode getRootNode() { return rootNode; } @Override public Object call(Object... args) { final VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); FrameInstance oldCurrentFrame = defaultTruffleRuntime().setCurrentFrame(new FrameInstance() { public Frame getFrame(FrameAccess access, boolean slowPath) { return frame; } public boolean isVirtualFrame() { return false; } public Node getCallNode() { return null; } public CallTarget getCallTarget() { return DefaultCallTarget.this; } }); try { return getRootNode().execute(frame); } finally { defaultTruffleRuntime().setCurrentFrame(oldCurrentFrame); } } private static DefaultTruffleRuntime defaultTruffleRuntime() { return (DefaultTruffleRuntime) Truffle.getRuntime(); } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultIndirectCallNode.java0000644000000000000000000000464312445312576023412 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * This is runtime specific API. Do not use in a guest language. */ final class DefaultIndirectCallNode extends IndirectCallNode { @Override public Object call(final VirtualFrame frame, final CallTarget target, Object[] arguments) { DefaultTruffleRuntime truffleRuntime = (DefaultTruffleRuntime) Truffle.getRuntime(); final CallTarget currentCallTarget = truffleRuntime.getCurrentFrame().getCallTarget(); FrameInstance frameInstance = new FrameInstance() { public Frame getFrame(FrameAccess access, boolean slowPath) { return frame; } public boolean isVirtualFrame() { return false; } public Node getCallNode() { return DefaultIndirectCallNode.this; } public CallTarget getCallTarget() { return currentCallTarget; } }; truffleRuntime.pushFrame(frameInstance); try { return target.call(arguments); } finally { truffleRuntime.popFrame(); } } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultLoopNode.java0000644000000000000000000000312112445312576021754 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; public final class DefaultLoopNode extends LoopNode { public DefaultLoopNode(RepeatingNode repeatNode) { super(repeatNode); } @Override public void executeLoop(VirtualFrame frame) { while (executeRepeatingNode(frame)) { // Empty } } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java0000644000000000000000000001104712445312576023630 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; /** * This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link TruffleRuntime#createMaterializedFrame(Object[])} or {@link Frame#materialize()} to create * a {@link MaterializedFrame}. */ final class DefaultMaterializedFrame implements MaterializedFrame { private final DefaultVirtualFrame wrapped; DefaultMaterializedFrame(DefaultVirtualFrame wrapped) { this.wrapped = wrapped; } @Override public Object[] getArguments() { return wrapped.getArguments(); } @Override public Object getObject(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getObject(slot); } @Override public void setObject(FrameSlot slot, Object value) { wrapped.setObject(slot, value); } @Override public byte getByte(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getByte(slot); } @Override public void setByte(FrameSlot slot, byte value) { wrapped.setByte(slot, value); } @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getBoolean(slot); } @Override public void setBoolean(FrameSlot slot, boolean value) { wrapped.setBoolean(slot, value); } @Override public int getInt(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getInt(slot); } @Override public void setInt(FrameSlot slot, int value) { wrapped.setInt(slot, value); } @Override public long getLong(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getLong(slot); } @Override public void setLong(FrameSlot slot, long value) { wrapped.setLong(slot, value); } @Override public float getFloat(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getFloat(slot); } @Override public void setFloat(FrameSlot slot, float value) { wrapped.setFloat(slot, value); } @Override public double getDouble(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getDouble(slot); } @Override public void setDouble(FrameSlot slot, double value) { wrapped.setDouble(slot, value); } @Override public Object getValue(FrameSlot slot) { return wrapped.getValue(slot); } @Override public MaterializedFrame materialize() { return this; } @Override public FrameDescriptor getFrameDescriptor() { return wrapped.getFrameDescriptor(); } @Override public boolean isObject(FrameSlot slot) { return wrapped.isObject(slot); } @Override public boolean isByte(FrameSlot slot) { return wrapped.isByte(slot); } @Override public boolean isBoolean(FrameSlot slot) { return wrapped.isBoolean(slot); } @Override public boolean isInt(FrameSlot slot) { return wrapped.isInt(slot); } @Override public boolean isLong(FrameSlot slot) { return wrapped.isLong(slot); } @Override public boolean isFloat(FrameSlot slot) { return wrapped.isFloat(slot); } @Override public boolean isDouble(FrameSlot slot) { return wrapped.isDouble(slot); } } truffle-0.6.orig/com/oracle/truffle/api/impl/AbstractAssumption.java0000644000000000000000000000325212445312576022563 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; public abstract class AbstractAssumption implements Assumption { protected final String name; protected boolean isValid; protected AbstractAssumption(String name) { this.name = name; this.isValid = true; } @Override public String getName() { return name; } @Override public String toString() { return "Assumption(valid=" + isValid + "): " + name; } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultCompilerOptions.java0000644000000000000000000000322612445312576023371 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; public class DefaultCompilerOptions implements CompilerOptions { public static DefaultCompilerOptions INSTANCE = new DefaultCompilerOptions(); public boolean supportsOption(String name) { return false; } public void setOption(String name, Object value) { throw new UnsupportedOperationException(String.format("Option %s is not supported by this runtime", name)); } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultVirtualFrame.java0000644000000000000000000001716412445312576022652 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; /** * This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link TruffleRuntime#createVirtualFrame(Object[], FrameDescriptor)} to create a * {@link VirtualFrame}. */ final class DefaultVirtualFrame implements VirtualFrame { private final FrameDescriptor descriptor; private final Object[] arguments; private Object[] locals; private byte[] tags; DefaultVirtualFrame(FrameDescriptor descriptor, Object[] arguments) { this.descriptor = descriptor; this.arguments = arguments; this.locals = new Object[descriptor.getSize()]; Arrays.fill(locals, descriptor.getDefaultValue()); this.tags = new byte[descriptor.getSize()]; } @Override public Object[] getArguments() { return arguments; } @Override public MaterializedFrame materialize() { return new DefaultMaterializedFrame(this); } @Override public Object getObject(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Object); return locals[slot.getIndex()]; } @Override public void setObject(FrameSlot slot, Object value) { verifySet(slot, FrameSlotKind.Object); locals[slot.getIndex()] = value; } @Override public byte getByte(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Byte); return (byte) locals[slot.getIndex()]; } @Override public void setByte(FrameSlot slot, byte value) { verifySet(slot, FrameSlotKind.Byte); locals[slot.getIndex()] = value; } @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Boolean); return (boolean) locals[slot.getIndex()]; } @Override public void setBoolean(FrameSlot slot, boolean value) { verifySet(slot, FrameSlotKind.Boolean); locals[slot.getIndex()] = value; } @Override public int getInt(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Int); return (int) locals[slot.getIndex()]; } @Override public void setInt(FrameSlot slot, int value) { verifySet(slot, FrameSlotKind.Int); locals[slot.getIndex()] = value; } @Override public long getLong(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Long); return (long) locals[slot.getIndex()]; } @Override public void setLong(FrameSlot slot, long value) { verifySet(slot, FrameSlotKind.Long); locals[slot.getIndex()] = value; } @Override public float getFloat(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Float); return (float) locals[slot.getIndex()]; } @Override public void setFloat(FrameSlot slot, float value) { verifySet(slot, FrameSlotKind.Float); locals[slot.getIndex()] = value; } @Override public double getDouble(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Double); return (double) locals[slot.getIndex()]; } @Override public void setDouble(FrameSlot slot, double value) { verifySet(slot, FrameSlotKind.Double); locals[slot.getIndex()] = value; } @Override public FrameDescriptor getFrameDescriptor() { return this.descriptor; } @Override public Object getValue(FrameSlot slot) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { if (!resize()) { throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); } } return locals[slotIndex]; } private void verifySet(FrameSlot slot, FrameSlotKind accessKind) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { if (!resize()) { throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); } } tags[slotIndex] = (byte) accessKind.ordinal(); } private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { if (!resize()) { throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); } } byte tag = tags[slotIndex]; if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) { throw new FrameSlotTypeException(); } } private boolean resize() { int oldSize = tags.length; int newSize = descriptor.getSize(); if (newSize > oldSize) { locals = Arrays.copyOf(locals, newSize); Arrays.fill(locals, oldSize, newSize, descriptor.getDefaultValue()); tags = Arrays.copyOf(tags, newSize); return true; } return false; } private byte getTag(FrameSlot slot) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { if (!resize()) { throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); } } return tags[slotIndex]; } @Override public boolean isObject(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Object.ordinal(); } @Override public boolean isByte(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Byte.ordinal(); } @Override public boolean isBoolean(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Boolean.ordinal(); } @Override public boolean isInt(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Int.ordinal(); } @Override public boolean isLong(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Long.ordinal(); } @Override public boolean isFloat(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Float.ordinal(); } @Override public boolean isDouble(FrameSlot slot) { return getTag(slot) == FrameSlotKind.Double.ordinal(); } } truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultAssumption.java0000644000000000000000000000362212445312576022405 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.impl; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; /** * This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link TruffleRuntime#createAssumption()} to create an {@link Assumption}. */ final class DefaultAssumption extends AbstractAssumption { DefaultAssumption(String name) { super(name); } @Override public void check() throws InvalidAssumptionException { if (!isValid) { throw new InvalidAssumptionException(); } } @Override public void invalidate() { isValid = false; } @Override public boolean isValid() { return isValid; } } truffle-0.6.orig/com/oracle/truffle/api/utilities/0000755000000000000000000000000012460741021017126 5ustar truffle-0.6.orig/com/oracle/truffle/api/utilities/ExactClassValueProfile.java0000644000000000000000000000502012445312576024352 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** * Represents a {@link ValueProfile} that speculates on the exact class of a value. */ public final class ExactClassValueProfile extends ValueProfile { @CompilationFinal protected Class cachedClass; ExactClassValueProfile() { } @SuppressWarnings("unchecked") @Override public T profile(T value) { if (cachedClass != null && cachedClass.isInstance(value)) { return (T) cachedClass.cast(value); } else { CompilerDirectives.transferToInterpreterAndInvalidate(); if (cachedClass == null && value != null) { cachedClass = value.getClass(); } else { cachedClass = Object.class; } } return value; } public boolean isGeneric() { return cachedClass == Object.class; } public boolean isUninitialized() { return cachedClass == null; } public Class getCachedClass() { return cachedClass; } @Override public String toString() { return String.format("%s(%s)@%x", getClass().getSimpleName(), isUninitialized() ? "uninitialized" : (isGeneric() ? "generic" : cachedClass.getName()), hashCode()); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/ConditionProfile.java0000644000000000000000000000612712445312576023262 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; /** * Abstract utility class to speculate on conditions. Condition profiles are intended to be used as * part of if conditions. * * Example usage: * *

 * private final ConditionProfile zero = ConditionProfile.createBinaryProfile();
 * 
 * int value = ...;
 * if (zero.profile(value == 0)) {
 *   return 0;
 * } else {
 *   return value;
 * }
 *
 * 
* * All instances of {@code ConditionProfile} (and subclasses) must be held in {@code final} fields * for compiler optimizations to take effect. * * @see #createCountingProfile() * @see #createBinaryProfile() */ public abstract class ConditionProfile extends NodeCloneable { public abstract boolean profile(boolean value); /** * Returns a {@link ConditionProfile} that speculates on conditions to be never * true or to be never false. Additionally to a binary profile this * method returns a condition profile that also counts the number of times the condition was * true and false. This information is reported to the underlying optimization system using * {@link CompilerDirectives#injectBranchProbability(double, boolean)}. Condition profiles are * intended to be used as part of if conditions. * * @see ConditionProfile * @see #createBinaryProfile() */ public static ConditionProfile createCountingProfile() { return new CountingConditionProfile(); } /** * Returns a {@link ConditionProfile} that speculates on conditions to be never true or to be * never false. Condition profiles are intended to be used as part of if conditions. * * @see ConditionProfile * @see ConditionProfile#createCountingProfile() */ public static ConditionProfile createBinaryProfile() { return new BinaryConditionProfile(); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/CyclicAssumption.java0000644000000000000000000000422312445312576023277 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; /** * Holds an {@link Assumption}, and knows how to recreate it with the same properties on * invalidation. Used so that mutability is isolated in this class, and all other classes that need * an assumption that may be recreated can have a final reference to an object of this class. Note * that you should be careful that repeated invalidations do not cause a deoptimization loop in that * same way that you would with any other assumption. */ public class CyclicAssumption { private final String name; private Assumption assumption; public CyclicAssumption(String name) { this.name = name; invalidate(); } public void invalidate() { if (assumption != null) { assumption.invalidate(); } assumption = Truffle.getRuntime().createAssumption(name); } public Assumption getAssumption() { return assumption; } } truffle-0.6.orig/com/oracle/truffle/api/utilities/BranchProfile.java0000644000000000000000000000465512445312576022535 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.nodes.*; /** * Utility class to speculate on branches to be never visited. If the {@link #enter()} method is * invoked first the optimized code is invalidated and the branch where {@link #enter()} is invoked * is enabled for compilation. Otherwise if the {@link #enter()} method was never invoked the branch * will not get compiled. * * All {@code BranchProfile} instances must be held in {@code final} fields for compiler * optimizations to take effect. */ public final class BranchProfile extends NodeCloneable { @CompilationFinal private boolean visited; private BranchProfile() { } public void enter() { if (!visited) { CompilerDirectives.transferToInterpreterAndInvalidate(); visited = true; } } public boolean isVisited() { return visited; } public static BranchProfile create() { return new BranchProfile(); } @Override public String toString() { return String.format("%s(%s)@%x", getClass().getSimpleName(), visited ? "visited" : "not-visited", hashCode()); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/UnionAssumption.java0000644000000000000000000000440112445312576023157 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; /** * An assumption that combines two other assumptions. A check on this assumption checks both of the * child assumptions. */ public class UnionAssumption implements Assumption { private final String name; private final Assumption first; private final Assumption second; public UnionAssumption(String name, Assumption first, Assumption second) { this.name = name; this.first = first; this.second = second; } public UnionAssumption(Assumption first, Assumption second) { this(null, first, second); } @Override public void check() throws InvalidAssumptionException { first.check(); second.check(); } @Override public void invalidate() { first.invalidate(); second.invalidate(); } @Override public String getName() { return name; } @Override public boolean isValid() { return first.isValid() && second.isValid(); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/BinaryConditionProfile.java0000644000000000000000000000477712445312576024440 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.*; /** * Utility class to speculate on conditions to be never true or to be never false. Condition * profiles are intended to be used as part of if conditions. * * @see ConditionProfile#createBinaryProfile() */ public final class BinaryConditionProfile extends ConditionProfile { @CompilationFinal private boolean wasTrue; @CompilationFinal private boolean wasFalse; BinaryConditionProfile() { /* package protected constructor */ } @Override public boolean profile(boolean value) { if (value) { if (!wasTrue) { CompilerDirectives.transferToInterpreterAndInvalidate(); wasTrue = true; } return true; } else { if (!wasFalse) { CompilerDirectives.transferToInterpreterAndInvalidate(); wasFalse = true; } return false; } } public boolean wasTrue() { return wasTrue; } public boolean wasFalse() { return wasFalse; } @Override public String toString() { return String.format("%s(wasTrue=%s, wasFalse=%s)@%x", getClass().getSimpleName(), wasTrue, wasFalse, hashCode()); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java0000644000000000000000000002004112445312576024270 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** * Represents a {@link ValueProfile} that speculates on the primitive equality or object identity of * values. *

* Note that for {code float} and {@code double} values we compare primitive equality via * {@link Float#floatToRawIntBits} and {@link Double#doubleToRawLongBits}, so that for example * {@code -0.0} is not considered the same as {@code 0.0}, even though primitive equality would * normally say that it was. */ public class PrimitiveValueProfile extends ValueProfile { private static final Object UNINITIALIZED = new Object(); private static final Object GENERIC = new Object(); @CompilationFinal private Object cachedValue = UNINITIALIZED; PrimitiveValueProfile() { } @SuppressWarnings("unchecked") @Override public Object profile(Object value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Byte && value instanceof Byte && (byte) cachedValue == (byte) value) { return cachedValue; } else if (cachedValue instanceof Short && value instanceof Short && (short) cachedValue == (short) value) { return cachedValue; } else if (cachedValue instanceof Integer && value instanceof Integer && (int) cachedValue == (int) value) { return cachedValue; } else if (cachedValue instanceof Long && value instanceof Long && (long) cachedValue == (long) value) { return cachedValue; } else if (cachedValue instanceof Float && value instanceof Float && exactCompare((float) cachedValue, (float) value)) { return cachedValue; } else if (cachedValue instanceof Double && value instanceof Double && exactCompare((double) cachedValue, (double) value)) { return cachedValue; } else if (cachedValue instanceof Boolean && value instanceof Boolean && (boolean) cachedValue == (boolean) value) { return cachedValue; } else if (cachedValue instanceof Character && value instanceof Character && (char) cachedValue == (char) value) { return cachedValue; } else if (cachedValue == value) { return cachedValue; } else { cacheMiss(value); } } return value; } public byte profile(byte value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Byte && (byte) cachedValue == value) { return (byte) cachedValue; } else { cacheMiss(value); } } return value; } public short profile(short value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Short && (short) cachedValue == value) { return (short) cachedValue; } else { cacheMiss(value); } } return value; } public int profile(int value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Integer && (int) cachedValue == value) { return (int) cachedValue; } else { cacheMiss(value); } } return value; } public long profile(long value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Long && (long) cachedValue == value) { return (long) cachedValue; } else { cacheMiss(value); } } return value; } public float profile(float value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Float && exactCompare((float) cachedValue, value)) { return (float) cachedValue; } else { cacheMiss(value); } } return value; } public double profile(double value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Double && exactCompare((double) cachedValue, value)) { return (double) cachedValue; } else { cacheMiss(value); } } return value; } public boolean profile(boolean value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Boolean && (boolean) cachedValue == value) { return (boolean) cachedValue; } else { cacheMiss(value); } } return value; } public char profile(char value) { if (cachedValue != GENERIC) { if (cachedValue instanceof Character && (char) cachedValue == value) { return (char) cachedValue; } else { cacheMiss(value); } } return value; } public boolean isGeneric() { return getCachedValue() == GENERIC; } public boolean isUninitialized() { return getCachedValue() == UNINITIALIZED; } public Object getCachedValue() { return cachedValue; } @Override public String toString() { return String.format("%s(%s)@%x", getClass().getSimpleName(), formatValue(), hashCode()); } private void cacheMiss(Object value) { CompilerDirectives.transferToInterpreterAndInvalidate(); if (cachedValue == UNINITIALIZED) { cachedValue = value; } else { cachedValue = GENERIC; } } public static boolean exactCompare(float a, float b) { /* * -0.0 == 0.0, but you can tell the difference through other means, so we need to * differentiate. */ return Float.floatToRawIntBits(a) == Float.floatToRawIntBits(b); } public static boolean exactCompare(double a, double b) { /* * -0.0 == 0.0, but you can tell the difference through other means, so we need to * differentiate. */ return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b); } private String formatValue() { if (cachedValue == null) { return "null"; } else if (cachedValue == UNINITIALIZED) { return "uninitialized"; } else if (cachedValue == GENERIC) { return "generic"; } else if (cachedValue instanceof Byte || cachedValue instanceof Short || cachedValue instanceof Integer || cachedValue instanceof Long || cachedValue instanceof Float || cachedValue instanceof Double || cachedValue instanceof Boolean || cachedValue instanceof Character) { return String.format("%s=%s", cachedValue.getClass().getSimpleName(), cachedValue); } else { return String.format("%s@%x", cachedValue.getClass().getSimpleName(), Objects.hash(cachedValue)); } } } truffle-0.6.orig/com/oracle/truffle/api/utilities/JSONHelper.java0000644000000000000000000001747412445312576021733 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import java.util.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; /** * Helper function that allows to dump the AST during creation to a JSON format. */ public class JSONHelper { private static StringBuilder AstJsonDumpBuilder = new StringBuilder(); public static void dumpNewChild(Node parentNode, Node childNode) { if (AstJsonDumpBuilder != null) { AstJsonDumpBuilder.append("{ \"action\": \"insertNode\", \"parentId\": \"" + getID(parentNode) + "\", \"newId\": \"" + getID(childNode) + "\" },\n"); } } public static void dumpReplaceChild(Node oldNode, Node newNode, CharSequence reason) { if (AstJsonDumpBuilder != null) { AstJsonDumpBuilder.append("{ \"action\": \"replaceNode\", \"oldId\": \"" + getID(oldNode) + "\", \"newId\": \"" + getID(newNode) + "\", \"reason\": " + quote(reason) + " },\n"); } } public static void dumpNewNode(Node newNode) { if (AstJsonDumpBuilder != null) { AstJsonDumpBuilder.append("{ \"action\": \"createNode\", \"newId\": \"" + getID(newNode) + "\", \"type\": \"" + getType(newNode) + "\", \"description\": \"" + newNode.getDescription() + "\", \"language\": \"" + newNode.getLanguage() + "\"" + getSourceSectionInfo(newNode) + " },\n"); } } private static String getSourceSectionInfo(Node newNode) { SourceSection sourceSection = newNode.getSourceSection(); if (sourceSection != null) { return ", \"identifier\": \"" + sourceSection.getIdentifier() + "\" "; } else { return ""; } } public static String getResult() { return AstJsonDumpBuilder.toString(); } private static String getID(Node newChild) { return String.valueOf(newChild.hashCode()); } private static String getType(Node node) { return node.getClass().getSimpleName(); } private static String quote(CharSequence value) { StringBuilder builder = new StringBuilder(value.length() + 2); builder.append('"'); for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); switch (c) { case '"': builder.append("\\\""); break; case '\\': builder.append("\\\\"); break; case '\b': builder.append("\\b"); break; case '\f': builder.append("\\f"); break; case '\n': builder.append("\\n"); break; case '\r': builder.append("\\r"); break; case '\t': builder.append("\\t"); break; default: { if (c < ' ') { builder.append("\\u00"); builder.append(Character.forDigit((c >> 4) & 0xF, 16)); builder.append(Character.forDigit(c & 0xF, 16)); } else { builder.append(c); } } } } builder.append('"'); return builder.toString(); } public static void restart() { AstJsonDumpBuilder = new StringBuilder(); } public static JSONObjectBuilder object() { return new JSONObjectBuilder(); } public static JSONArrayBuilder array() { return new JSONArrayBuilder(); } public abstract static class JSONStringBuilder { @Override public final String toString() { StringBuilder sb = new StringBuilder(); appendTo(sb); return sb.toString(); } protected abstract void appendTo(StringBuilder sb); protected static void appendValue(StringBuilder sb, Object value) { if (value instanceof JSONStringBuilder) { ((JSONStringBuilder) value).appendTo(sb); } else if (value instanceof Integer || value instanceof Boolean || value == null) { sb.append(value); } else { sb.append(quote(String.valueOf(value))); } } } public static final class JSONObjectBuilder extends JSONStringBuilder { private final Map contents = new LinkedHashMap<>(); private JSONObjectBuilder() { } public JSONObjectBuilder add(String key, String value) { contents.put(key, value); return this; } public JSONObjectBuilder add(String key, Number value) { contents.put(key, value); return this; } public JSONObjectBuilder add(String key, Boolean value) { contents.put(key, value); return this; } public JSONObjectBuilder add(String key, JSONStringBuilder value) { contents.put(key, value); return this; } @Override protected void appendTo(StringBuilder sb) { sb.append("{"); boolean comma = false; for (Map.Entry entry : contents.entrySet()) { if (comma) { sb.append(", "); } sb.append(quote(entry.getKey())); sb.append(": "); appendValue(sb, entry.getValue()); comma = true; } sb.append("}"); } } public static final class JSONArrayBuilder extends JSONStringBuilder { private final List contents = new ArrayList<>(); private JSONArrayBuilder() { } public JSONArrayBuilder add(String value) { contents.add(value); return this; } public JSONArrayBuilder add(Number value) { contents.add(value); return this; } public JSONArrayBuilder add(Boolean value) { contents.add(value); return this; } public JSONArrayBuilder add(JSONStringBuilder value) { contents.add(value); return this; } @Override protected void appendTo(StringBuilder sb) { sb.append("["); boolean comma = false; for (Object value : contents) { if (comma) { sb.append(", "); } appendValue(sb, value); comma = true; } sb.append("]"); } } } truffle-0.6.orig/com/oracle/truffle/api/utilities/ValueProfile.java0000644000000000000000000000470012445312576022403 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; /** * Utility class to speculate on certain properties of values. * * Example usage: * *
 * private final ValueProfile classProfile = ValueProfile.createClassProfile();
 * 
 * return classProfile.profile(value);
 * 
* * All instances of {@code ValueProfile} (and subclasses) must be held in {@code final} fields for * compiler optimizations to take effect. * * @see #createPrimitiveProfile() * @see #createIdentityProfile() * @see #createClassProfile() */ public abstract class ValueProfile { public abstract T profile(T value); /** * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or object * identity of a value. */ public static PrimitiveValueProfile createPrimitiveProfile() { return new PrimitiveValueProfile(); } /** * Returns a {@link ValueProfile} that speculates on the exact class of a value. */ public static ValueProfile createClassProfile() { return new ExactClassValueProfile(); } /** * Returns a {@link ValueProfile} that speculates on the object identity of a value. */ public static ValueProfile createIdentityProfile() { return new IdentityValueProfile(); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/NeverValidAssumption.java0000644000000000000000000000372212445312576024133 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; /** * An assumption that is never valid. Used as a placeholder where an assumption is needed that * should be invalid from the start. */ public final class NeverValidAssumption implements Assumption { public static final NeverValidAssumption INSTANCE = new NeverValidAssumption(); private NeverValidAssumption() { } @Override public void check() throws InvalidAssumptionException { throw new InvalidAssumptionException(); } @Override public void invalidate() { } @Override public String getName() { return getClass().getName(); } @Override public boolean isValid() { return false; } } truffle-0.6.orig/com/oracle/truffle/api/utilities/CountingConditionProfile.java0000644000000000000000000000603412445312576024766 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.*; /** * Utility class to speculate on conditions to be never true or to be never false. Additionally to * {@link BinaryConditionProfile} this implementation of {@link ConditionProfile} also counts the * number of times the condition was true and false. This information is reported to the underlying * optimization system using {@link CompilerDirectives#injectBranchProbability(double, boolean)}. * Condition profiles are intended to be used as part of if conditions. * * @see ConditionProfile#createCountingProfile() */ public final class CountingConditionProfile extends ConditionProfile { @CompilationFinal private int trueCount; @CompilationFinal private int falseCount; CountingConditionProfile() { /* package protected constructor */ } @Override public boolean profile(boolean value) { if (value) { if (trueCount == 0) { CompilerDirectives.transferToInterpreterAndInvalidate(); } if (CompilerDirectives.inInterpreter()) { trueCount++; } } else { if (falseCount == 0) { CompilerDirectives.transferToInterpreterAndInvalidate(); } if (CompilerDirectives.inInterpreter()) { falseCount++; } } return CompilerDirectives.injectBranchProbability((double) trueCount / (double) (trueCount + falseCount), value); } public int getTrueCount() { return trueCount; } public int getFalseCount() { return falseCount; } @Override public String toString() { return String.format("%s(trueCount=%s, falseCount=%s)@%x", getClass().getSimpleName(), trueCount, falseCount, hashCode()); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/AlwaysValidAssumption.java0000644000000000000000000000400112445312576024303 0ustar /* * Copyright (c) 2013, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; /** * An assumption that is always valid. Used as a placeholder where an assumption is needed but never * invalidated. */ public final class AlwaysValidAssumption implements Assumption { public static final AlwaysValidAssumption INSTANCE = new AlwaysValidAssumption(); private AlwaysValidAssumption() { } @Override public void check() throws InvalidAssumptionException { } @Override public void invalidate() { throw new UnsupportedOperationException("Cannot invalidate this assumption - it is always valid"); } @Override public String getName() { return getClass().getName(); } @Override public boolean isValid() { return true; } } truffle-0.6.orig/com/oracle/truffle/api/utilities/IdentityValueProfile.java0000644000000000000000000000534512445312576024123 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** * Represents a {@link ValueProfile} that speculates on the object identity of a value. */ public final class IdentityValueProfile extends ValueProfile { private static final Object UNINITIALIZED = new Object(); private static final Object GENERIC = new Object(); @CompilationFinal protected Object cachedValue = UNINITIALIZED; IdentityValueProfile() { } @Override @SuppressWarnings("unchecked") public T profile(T value) { if (cachedValue != GENERIC) { if (cachedValue == value) { return (T) cachedValue; } else { CompilerDirectives.transferToInterpreterAndInvalidate(); if (cachedValue == UNINITIALIZED) { cachedValue = value; } else { cachedValue = GENERIC; } } } return value; } public boolean isGeneric() { return getCachedValue() == GENERIC; } public boolean isUninitialized() { return getCachedValue() == UNINITIALIZED; } public Object getCachedValue() { return cachedValue; } @Override public String toString() { return String.format("%s(%s)@%x", getClass().getSimpleName(), isUninitialized() ? "uninitialized" : (isGeneric() ? "generic" : String.format("@%x", Objects.hash(cachedValue))), hashCode()); } } truffle-0.6.orig/com/oracle/truffle/api/utilities/AssumedValue.java0000644000000000000000000000602612445312576022407 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.utilities; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.nodes.*; /** * A value that the compiler can assume is constant, but can be changed by invalidation. *

* Compiled code that uses the value will be invalidated each time the value changes, so you should * take care to only change values infrequently, or to monitor the number of times the value has * changed and at some point to replace the value with something more generic so that it does not * have to be changed and code does not have to keep being recompiled. */ public class AssumedValue { private final String name; @CompilationFinal private T value; @CompilationFinal private Assumption assumption; public AssumedValue(T initialValue) { this(null, initialValue); } public AssumedValue(String name, T initialValue) { this.name = name; value = initialValue; assumption = Truffle.getRuntime().createAssumption(name); } /** * Get the current value, updating it if it has been {@link #set}. The compiler may be able to * make this method return a constant value, but still accommodate mutation. */ public T get() { try { assumption.check(); } catch (InvalidAssumptionException e) { // No need to rewrite anything - just pick up the new values } return value; } /** * Set a new value, which will be picked up the next time {@link #get} is called. */ public void set(T newValue) { CompilerDirectives.transferToInterpreter(); value = newValue; final Assumption oldAssumption = assumption; assumption = Truffle.getRuntime().createAssumption(name); oldAssumption.invalidate(); } } truffle-0.6.orig/com/oracle/truffle/api/LoopCountReceiver.java0000644000000000000000000000271512445312576021406 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; /** * Accepts the execution count of a loop that is a child of this node. The optimization heuristics * can use the loop count to guide compilation and inlining. */ public interface LoopCountReceiver { void reportLoopCount(int count); } truffle-0.6.orig/com/oracle/truffle/api/Truffle.java0000644000000000000000000000436112445312576017405 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import java.security.*; import com.oracle.truffle.api.impl.*; /** * Class for obtaining the Truffle runtime singleton object of this virtual machine. */ public class Truffle { private static final TruffleRuntime RUNTIME = initRuntime(); /** * Creates a new {@link TruffleRuntime} instance if the runtime has a specialized * implementation. * * @throws UnsatisfiedLinkError if the runtime does not have a specialized implementation of * {@link TruffleRuntime} */ private static native TruffleRuntime createRuntime(); public static TruffleRuntime getRuntime() { return RUNTIME; } private static TruffleRuntime initRuntime() { try { return AccessController.doPrivileged(new PrivilegedAction() { public TruffleRuntime run() { return createRuntime(); } }); } catch (UnsatisfiedLinkError e) { return new DefaultTruffleRuntime(); } } } truffle-0.6.orig/com/oracle/truffle/api/source/0000755000000000000000000000000012460741021016413 5ustar truffle-0.6.orig/com/oracle/truffle/api/source/BytesDecoder.java0000644000000000000000000000453012445312576021650 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.source; import java.nio.charset.*; import java.util.*; /** * For a language where strings do not map into Java strings, provides utilities to find line * endings and to decode raw bytes into an approximate representation for tools to display. *

* See {@link Source#fromBytes}. */ public interface BytesDecoder { String decode(byte[] bytes, int byteIndex, int length); void decodeLines(byte[] bytes, int byteIndex, int length, LineMarker lineMarker); public interface LineMarker { void markLine(int index); } public static class UTF8BytesDecoder implements BytesDecoder { @Override public String decode(byte[] bytes, int byteIndex, int length) { return new String(Arrays.copyOfRange(bytes, byteIndex, byteIndex + length), StandardCharsets.UTF_8); } @Override public void decodeLines(byte[] bytes, int byteIndex, int length, LineMarker lineMarker) { for (int n = byteIndex; n < byteIndex + length; n++) { if (bytes[n] == '\n') { lineMarker.markLine(n + 1); } } } } } truffle-0.6.orig/com/oracle/truffle/api/source/Source.java0000644000000000000000000011652712445312576020546 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.source; import java.io.*; import java.lang.ref.*; import java.net.*; import java.util.*; /** * Representation of a guest language source code unit and its contents. Sources originate in * several ways: *

    *
  • Literal: A named text string. These are not indexed and should be considered * value objects; equality is defined based on contents.
    * See {@link Source#fromText(CharSequence, String)}
  • *

    *

  • File: Each file is represented as a canonical object, indexed by the * absolute, canonical path name of the file. File contents are read lazily and contents * optionally cached.
    * See {@link Source#fromFileName(String)}
    * See {@link Source#fromFileName(String, boolean)}
  • *

    *

  • URL: Each URL source is represented as a canonical object, indexed by the * URL. Contents are read eagerly and cached.
    * See {@link Source#fromURL(URL, String)}
  • *

    *

  • Reader: Contents are read eagerly and treated as a Literal * .
    * See {@link Source#fromReader(Reader, String)}
  • *

    *

  • Pseudo File: A literal text string that can be retrieved by name as if it * were a file, unlike literal sources; useful for testing.
    * See {@link Source#asPseudoFile(CharSequence, String)}
  • *
*

* File cache: *

    *
  1. File content caching is optional, off by default.
  2. *
  3. The first access to source file contents will result in the contents being read, and (if * enabled) cached.
  4. *
  5. If file contents have been cached, access to contents via {@link Source#getInputStream()} or * {@link Source#getReader()} will be provided from the cache.
  6. *
  7. Any access to file contents via the cache will result in a timestamp check and possible cache * reload.
  8. *
*/ public abstract class Source { // TODO (mlvdv) consider canonicalizing and reusing SourceSection instances // TOOD (mlvdv) connect SourceSections into a spatial tree for fast geometric lookup // Files and pseudo files are indexed. private static final Map> filePathToSource = new Hashtable<>(); private static boolean fileCacheEnabled = true; /** * Gets the canonical representation of a source file, whose contents will be read lazily and * then cached. * * @param fileName name * @param reset forces any existing {@link Source} cache to be cleared, forcing a re-read * @return canonical representation of the file's contents. * @throws IOException if the file can not be read */ public static Source fromFileName(String fileName, boolean reset) throws IOException { final WeakReference nameRef = filePathToSource.get(fileName); Source source = nameRef == null ? null : nameRef.get(); if (source == null) { final File file = new File(fileName); if (!file.canRead()) { throw new IOException("Can't read file " + fileName); } final String path = file.getCanonicalPath(); final WeakReference pathRef = filePathToSource.get(path); source = pathRef == null ? null : pathRef.get(); if (source == null) { source = new FileSource(file, fileName, path); filePathToSource.put(path, new WeakReference<>(source)); } } if (reset) { source.reset(); } return source; } /** * Gets the canonical representation of a source file, whose contents will be read lazily and * then cached. * * @param fileName name * @return canonical representation of the file's contents. * @throws IOException if the file can not be read */ public static Source fromFileName(String fileName) throws IOException { return fromFileName(fileName, false); } /** * Creates a non-canonical source from literal text. If an already created literal source must * be retrievable by name, use {@link #asPseudoFile(CharSequence, String)}. * * @param chars textual source code * @param description a note about the origin, for error messages and debugging * @return a newly created, non-indexed source representation */ public static Source fromText(CharSequence chars, String description) { assert chars != null; return new LiteralSource(description, chars.toString()); } /** * Creates a source whose contents will be read immediately from a URL and cached. * * @param url * @param description identifies the origin, possibly useful for debugging * @return a newly created, non-indexed source representation * @throws IOException if reading fails */ public static Source fromURL(URL url, String description) throws IOException { return URLSource.get(url, description); } /** * Creates a source whose contents will be read immediately and cached. * * @param reader * @param description a note about the origin, possibly useful for debugging * @return a newly created, non-indexed source representation * @throws IOException if reading fails */ public static Source fromReader(Reader reader, String description) throws IOException { return new LiteralSource(description, read(reader)); } /** * Creates a source from raw bytes. This can be used if the encoding of strings in your language * is not compatible with Java strings, or if your parser returns byte indices instead of * character indices. The returned source is then indexed by byte, not by character. * * @param bytes the raw bytes of the source * @param description a note about the origin, possibly useful for debugging * @param decoder how to decode the bytes into Java strings * @return a newly created, non-indexed source representation */ public static Source fromBytes(byte[] bytes, String description, BytesDecoder decoder) { return fromBytes(bytes, 0, bytes.length, description, decoder); } /** * Creates a source from raw bytes. This can be used if the encoding of strings in your language * is not compatible with Java strings, or if your parser returns byte indices instead of * character indices. The returned source is then indexed by byte, not by character. Offsets are * relative to byteIndex. * * @param bytes the raw bytes of the source * @param byteIndex where the string starts in the byte array * @param length the length of the string in the byte array * @param description a note about the origin, possibly useful for debugging * @param decoder how to decode the bytes into Java strings * @return a newly created, non-indexed source representation */ public static Source fromBytes(byte[] bytes, int byteIndex, int length, String description, BytesDecoder decoder) { return new BytesSource(description, bytes, byteIndex, length, decoder); } /** * Creates a source from literal text, but which acts as a file and can be retrieved by name * (unlike other literal sources); intended for testing. * * @param chars textual source code * @param pseudoFileName string to use for indexing/lookup * @return a newly created, source representation, canonical with respect to its name */ public static Source asPseudoFile(CharSequence chars, String pseudoFileName) { final Source source = new LiteralSource(pseudoFileName, chars.toString()); filePathToSource.put(pseudoFileName, new WeakReference<>(source)); return source; } // TODO (mlvdv) enable per-file choice whether to cache? /** * Enables/disables caching of file contents, disabled by default. Caching of sources * created from literal text or readers is always enabled. */ public static void setFileCaching(boolean enabled) { fileCacheEnabled = enabled; } private static String read(Reader reader) throws IOException { final BufferedReader bufferedReader = new BufferedReader(reader); final StringBuilder builder = new StringBuilder(); final char[] buffer = new char[1024]; while (true) { final int n = bufferedReader.read(buffer); if (n == -1) { break; } builder.append(buffer, 0, n); } return builder.toString(); } Source() { } private TextMap textMap = null; protected abstract void reset(); /** * Returns the name of this resource holding a guest language program. An example would be the * name of a guest language source code file. * * @return the name of the guest language program */ public abstract String getName(); /** * Returns a short version of the name of the resource holding a guest language program (as * described in @getName). For example, this could be just the name of the file, rather than a * full path. * * @return the short name of the guest language program */ public abstract String getShortName(); /** * The normalized, canonical name if the source is a file. */ public abstract String getPath(); /** * The URL if the source is retrieved via URL. */ public abstract URL getURL(); /** * Access to the source contents. */ public abstract Reader getReader(); /** * Access to the source contents. */ public final InputStream getInputStream() { return new ByteArrayInputStream(getCode().getBytes()); } /** * Return the complete text of the code. */ public abstract String getCode(); public String getCode(int charIndex, int charLength) { return getCode().substring(charIndex, charIndex + charLength); } /** * Gets the text (not including a possible terminating newline) in a (1-based) numbered line. */ public final String getCode(int lineNumber) { checkTextMap(); final int offset = textMap.lineStartOffset(lineNumber); final int length = textMap.lineLength(lineNumber); return getCode().substring(offset, offset + length); } /** * The number of text lines in the source, including empty lines; characters at the end of the * source without a terminating newline count as a line. */ public final int getLineCount() { return checkTextMap().lineCount(); } /** * Given a 0-based character offset, return the 1-based number of the line that includes the * position. * * @throws IllegalArgumentException if the offset is outside the text contents */ public final int getLineNumber(int offset) throws IllegalArgumentException { return checkTextMap().offsetToLine(offset); } /** * Given a 0-based character offset, return the 1-based number of the column at the position. * * @throws IllegalArgumentException if the offset is outside the text contents */ public final int getColumnNumber(int offset) throws IllegalArgumentException { return checkTextMap().offsetToCol(offset); } /** * Given a 1-based line number, return the 0-based offset of the first character in the line. * * @throws IllegalArgumentException if there is no such line in the text */ public final int getLineStartOffset(int lineNumber) throws IllegalArgumentException { return checkTextMap().lineStartOffset(lineNumber); } /** * The number of characters (not counting a possible terminating newline) in a (1-based) * numbered line. * * @throws IllegalArgumentException if there is no such line in the text */ public final int getLineLength(int lineNumber) throws IllegalArgumentException { return checkTextMap().lineLength(lineNumber); } /** * Creates a representation of a contiguous region of text in the source. *

* This method performs no checks on the validity of the arguments. *

* The resulting representation defines hash/equality around equivalent location, presuming that * {@link Source} representations are canonical. * * @param identifier terse description of the region * @param startLine 1-based line number of the first character in the section * @param startColumn 1-based column number of the first character in the section * @param charIndex the 0-based index of the first character of the section * @param length the number of characters in the section * @return newly created object representing the specified region */ public final SourceSection createSection(String identifier, int startLine, int startColumn, int charIndex, int length) { return new DefaultSourceSection(this, identifier, startLine, startColumn, charIndex, length); } /** * Creates a representation of a contiguous region of text in the source. Computes the * {@code charIndex} value by building a {@linkplain TextMap map} of lines in the source. *

* Checks the position arguments for consistency with the source. *

* The resulting representation defines hash/equality around equivalent location, presuming that * {@link Source} representations are canonical. * * @param identifier terse description of the region * @param startLine 1-based line number of the first character in the section * @param startColumn 1-based column number of the first character in the section * @param length the number of characters in the section * @return newly created object representing the specified region * @throws IllegalArgumentException if arguments are outside the text of the source * @throws IllegalStateException if the source is one of the "null" instances */ public final SourceSection createSection(String identifier, int startLine, int startColumn, int length) { checkTextMap(); final int lineStartOffset = textMap.lineStartOffset(startLine); if (startColumn > textMap.lineLength(startLine)) { throw new IllegalArgumentException("column out of range"); } final int startOffset = lineStartOffset + startColumn - 1; return new DefaultSourceSection(this, identifier, startLine, startColumn, startOffset, length); } /** * Creates a representation of a contiguous region of text in the source. Computes the * {@code (startLine, startColumn)} values by building a {@linkplain TextMap map} of lines in * the source. *

* Checks the position arguments for consistency with the source. *

* The resulting representation defines hash/equality around equivalent location, presuming that * {@link Source} representations are canonical. * * * @param identifier terse description of the region * @param charIndex 0-based position of the first character in the section * @param length the number of characters in the section * @return newly created object representing the specified region * @throws IllegalArgumentException if either of the arguments are outside the text of the * source * @throws IllegalStateException if the source is one of the "null" instances */ public final SourceSection createSection(String identifier, int charIndex, int length) throws IllegalArgumentException { checkRange(charIndex, length); checkTextMap(); final int startLine = getLineNumber(charIndex); final int startColumn = charIndex - getLineStartOffset(startLine) + 1; return new DefaultSourceSection(this, identifier, startLine, startColumn, charIndex, length); } protected void checkRange(int charIndex, int length) { if (!(charIndex >= 0 && length >= 0 && charIndex + length <= getCode().length())) { throw new IllegalArgumentException("text positions out of range"); } } /** * Creates a representation of a line of text in the source identified only by line number, from * which the character information will be computed. * * @param identifier terse description of the line * @param lineNumber 1-based line number of the first character in the section * @return newly created object representing the specified line * @throws IllegalArgumentException if the line does not exist the source * @throws IllegalStateException if the source is one of the "null" instances */ public final SourceSection createSection(String identifier, int lineNumber) { checkTextMap(); final int charIndex = textMap.lineStartOffset(lineNumber); final int length = textMap.lineLength(lineNumber); return createSection(identifier, charIndex, length); } /** * Creates a representation of a line number in this source, suitable for use as a hash table * key with equality defined to mean equivalent location. * * @param lineNumber a 1-based line number in this source * @return a representation of a line in this source */ public final LineLocation createLineLocation(int lineNumber) { return new LineLocationImpl(this, lineNumber); } private TextMap checkTextMap() { if (textMap == null) { textMap = createTextMap(); } return textMap; } protected TextMap createTextMap() { final String code = getCode(); if (code == null) { throw new RuntimeException("can't read file " + getName()); } return TextMap.fromString(code); } private static final class LiteralSource extends Source { private final String name; // Name used originally to describe the source private final String code; public LiteralSource(String name, String code) { this.name = name; this.code = code; } @Override public String getName() { return name; } @Override public String getShortName() { return name; } @Override public String getCode() { return code; } @Override public String getPath() { return name; } @Override public URL getURL() { return null; } @Override public Reader getReader() { return new StringReader(code); } @Override protected void reset() { } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + name.hashCode(); result = prime * result + (code == null ? 0 : code.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof LiteralSource)) { return false; } LiteralSource other = (LiteralSource) obj; return name.equals(other.name) && code.equals(other.code); } } private static final class FileSource extends Source { private final File file; private final String name; // Name used originally to describe the source private final String path; // Normalized path description of an actual file private String code = null; // A cache of the file's contents private long timeStamp; // timestamp of the cache in the file system public FileSource(File file, String name, String path) { this.file = file; this.name = name; this.path = path; } @Override public String getName() { return name; } @Override public String getShortName() { return file.getName(); } @Override public String getCode() { if (fileCacheEnabled) { if (code == null || timeStamp != file.lastModified()) { try { code = read(getReader()); timeStamp = file.lastModified(); } catch (IOException e) { } } return code; } try { return read(new FileReader(file)); } catch (IOException e) { } return null; } @Override public String getPath() { return path; } @Override public URL getURL() { return null; } @Override public Reader getReader() { if (code != null && timeStamp == file.lastModified()) { return new StringReader(code); } try { return new FileReader(file); } catch (FileNotFoundException e) { throw new RuntimeException("Can't find file " + path); } } @Override public int hashCode() { return path.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof FileSource) { FileSource other = (FileSource) obj; return path.equals(other.path); } return false; } @Override protected void reset() { this.code = null; } } private static final class URLSource extends Source { private static final Map> urlToSource = new HashMap<>(); public static URLSource get(URL url, String name) throws IOException { WeakReference sourceRef = urlToSource.get(url); URLSource source = sourceRef == null ? null : sourceRef.get(); if (source == null) { source = new URLSource(url, name); urlToSource.put(url, new WeakReference<>(source)); } return source; } private final URL url; private final String name; private String code = null; // A cache of the source contents public URLSource(URL url, String name) throws IOException { this.url = url; this.name = name; code = read(new InputStreamReader(url.openStream())); } @Override public String getName() { return name; } @Override public String getShortName() { return name; } @Override public String getPath() { return url.getPath(); } @Override public URL getURL() { return url; } @Override public Reader getReader() { return new StringReader(code); } @Override public String getCode() { return code; } @Override protected void reset() { } } private static final class BytesSource extends Source { private final String name; private final byte[] bytes; private final int byteIndex; private final int length; private final BytesDecoder decoder; public BytesSource(String name, byte[] bytes, int byteIndex, int length, BytesDecoder decoder) { this.name = name; this.bytes = bytes; this.byteIndex = byteIndex; this.length = length; this.decoder = decoder; } @Override protected void reset() { } @Override public String getName() { return name; } @Override public String getShortName() { return name; } @Override public String getPath() { return name; } @Override public URL getURL() { return null; } @Override public Reader getReader() { return null; } @Override public String getCode() { return decoder.decode(bytes, byteIndex, length); } @Override public String getCode(int byteOffset, int codeLength) { return decoder.decode(bytes, byteIndex + byteOffset, codeLength); } @Override protected void checkRange(int charIndex, int rangeLength) { if (!(charIndex >= 0 && rangeLength >= 0 && charIndex + rangeLength <= length)) { throw new IllegalArgumentException("text positions out of range"); } } @Override protected TextMap createTextMap() { return TextMap.fromBytes(bytes, byteIndex, length, decoder); } } private static final class DefaultSourceSection implements SourceSection { private final Source source; private final String identifier; private final int startLine; private final int startColumn; private final int charIndex; private final int charLength; /** * Creates a new object representing a contiguous text section within the source code of a * guest language program's text. *

* The starting location of the section is specified using two different coordinate: *

    *
  • (row, column): rows and columns are 1-based, so the first character in a * source file is at position {@code (1,1)}.
  • *
  • character index: 0-based offset of the character from the beginning of the * source, so the first character in a file is at index {@code 0}.
  • *
* The newline that terminates each line counts as a single character for the purpose * of a character index. The (row,column) coordinates of a newline character should never * appear in a text section. *

* * @param source object representing the complete source program that contains this section * @param identifier an identifier used when printing the section * @param startLine the 1-based number of the start line of the section * @param startColumn the 1-based number of the start column of the section * @param charIndex the 0-based index of the first character of the section * @param charLength the length of the section in number of characters */ public DefaultSourceSection(Source source, String identifier, int startLine, int startColumn, int charIndex, int charLength) { this.source = source; this.identifier = identifier; this.startLine = startLine; this.startColumn = startColumn; this.charIndex = charIndex; this.charLength = charLength; } @Override public Source getSource() { return source; } @Override public int getStartLine() { return startLine; } @Override public LineLocation getLineLocation() { return source.createLineLocation(startLine); } @Override public int getStartColumn() { return startColumn; } @Override public int getCharIndex() { return charIndex; } @Override public int getCharLength() { return charLength; } @Override public int getCharEndIndex() { return charIndex + charLength; } @Override public String getIdentifier() { return identifier; } @Override public String getCode() { return getSource().getCode(charIndex, charLength); } @Override public String getShortDescription() { return String.format("%s:%d", source.getShortName(), startLine); } @Override public String toString() { return getCode(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + charIndex; result = prime * result + charLength; result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); result = prime * result + ((source == null) ? 0 : source.hashCode()); result = prime * result + startColumn; result = prime * result + startLine; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof DefaultSourceSection)) { return false; } DefaultSourceSection other = (DefaultSourceSection) obj; if (charIndex != other.charIndex) { return false; } if (charLength != other.charLength) { return false; } if (identifier == null) { if (other.identifier != null) { return false; } } else if (!identifier.equals(other.identifier)) { return false; } if (source == null) { if (other.source != null) { return false; } } else if (!source.equals(other.source)) { return false; } if (startColumn != other.startColumn) { return false; } if (startLine != other.startLine) { return false; } return true; } } private static final class LineLocationImpl implements LineLocation { private final Source source; private final int line; public LineLocationImpl(Source source, int line) { assert source != null; this.source = source; this.line = line; } @Override public Source getSource() { return source; } @Override public int getLineNumber() { return line; } @Override public String getShortDescription() { return source.getShortName() + ":" + line; } @Override public String toString() { return "Line[" + getShortDescription() + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + line; result = prime * result + source.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof LineLocationImpl)) { return false; } LineLocationImpl other = (LineLocationImpl) obj; if (line != other.line) { return false; } return source.equals(other.source); } } /** * A utility for converting between coordinate systems in a string of text interspersed with * newline characters. The coordinate systems are: *

    *
  • 0-based character offset from the beginning of the text, where newline characters count * as a single character and the first character in the text occupies position 0.
  • *
  • 1-based position in the 2D space of lines and columns, in which the first position in the * text is at (1,1).
  • *
*

* This utility is based on positions occupied by characters, not text stream positions as in a * text editor. The distinction shows up in editors where you can put the cursor just past the * last character in a buffer; this is necessary, among other reasons, so that you can put the * edit cursor in a new (empty) buffer. For the purposes of this utility, however, there are no * character positions in an empty text string and there are no lines in an empty text string. *

* A newline character designates the end of a line and occupies a column position. *

* If the text ends with a character other than a newline, then the characters following the * final newline character count as a line, even though not newline-terminated. *

* Limitations: *

    *
  • Does not handle multiple character encodings correctly.
  • *
  • Treats tabs as occupying 1 column.
  • *
  • Does not handle multiple-character line termination sequences correctly.
  • *
*/ private static final class TextMap { // 0-based offsets of newline characters in the text, with sentinel private final int[] nlOffsets; // The number of characters in the text, including newlines (which count as 1). private final int textLength; // Is the final text character a newline? final boolean finalNL; public TextMap(int[] nlOffsets, int textLength, boolean finalNL) { this.nlOffsets = nlOffsets; this.textLength = textLength; this.finalNL = finalNL; } /** * Constructs map permitting translation between 0-based character offsets and 1-based * lines/columns. */ public static TextMap fromString(String text) { final int textLength = text.length(); final ArrayList lines = new ArrayList<>(); lines.add(0); int offset = 0; while (offset < text.length()) { final int nlIndex = text.indexOf('\n', offset); if (nlIndex >= 0) { offset = nlIndex + 1; lines.add(offset); } else { break; } } lines.add(Integer.MAX_VALUE); final int[] nlOffsets = new int[lines.size()]; for (int line = 0; line < lines.size(); line++) { nlOffsets[line] = lines.get(line); } final boolean finalNL = textLength > 0 && (textLength == nlOffsets[nlOffsets.length - 2]); return new TextMap(nlOffsets, textLength, finalNL); } public static TextMap fromBytes(byte[] bytes, int byteIndex, int length, BytesDecoder bytesDecoder) { final ArrayList lines = new ArrayList<>(); lines.add(0); bytesDecoder.decodeLines(bytes, byteIndex, length, new BytesDecoder.LineMarker() { public void markLine(int index) { lines.add(index); } }); lines.add(Integer.MAX_VALUE); final int[] nlOffsets = new int[lines.size()]; for (int line = 0; line < lines.size(); line++) { nlOffsets[line] = lines.get(line); } final boolean finalNL = length > 0 && (length == nlOffsets[nlOffsets.length - 2]); return new TextMap(nlOffsets, length, finalNL); } /** * Converts 0-based character offset to 1-based number of the line containing the character. * * @throws IllegalArgumentException if the offset is outside the string. */ public int offsetToLine(int offset) throws IllegalArgumentException { if (offset < 0 || offset >= textLength) { throw new IllegalArgumentException("offset out of bounds"); } int line = 1; while (offset >= nlOffsets[line]) { line++; } return line; } /** * Converts 0-based character offset to 1-based number of the column occupied by the * character. *

* Tabs are not expanded; they occupy 1 column. * * @throws IllegalArgumentException if the offset is outside the string. */ public int offsetToCol(int offset) throws IllegalArgumentException { return 1 + offset - nlOffsets[offsetToLine(offset) - 1]; } /** * The number of lines in the text; if characters appear after the final newline, then they * also count as a line, even though not newline-terminated. */ public int lineCount() { if (textLength == 0) { return 0; } return finalNL ? nlOffsets.length - 2 : nlOffsets.length - 1; } /** * Converts 1-based line number to the 0-based offset of the line's first character; this * would be the offset of a newline if the line is empty. * * @throws IllegalArgumentException if there is no such line in the text. */ public int lineStartOffset(int line) throws IllegalArgumentException { if (textLength == 0 || lineOutOfRange(line)) { throw new IllegalArgumentException("line out of bounds"); } return nlOffsets[line - 1]; } /** * Gets the number of characters in a line, identified by 1-based line number; * does not include the final newline, if any. * * @throws IllegalArgumentException if there is no such line in the text. */ public int lineLength(int line) throws IllegalArgumentException { if (textLength == 0 || lineOutOfRange(line)) { throw new IllegalArgumentException("line out of bounds"); } if (line == nlOffsets.length - 1 && !finalNL) { return textLength - nlOffsets[line - 1]; } return (nlOffsets[line] - nlOffsets[line - 1]) - 1; } /** * Is the line number out of range. */ private boolean lineOutOfRange(int line) { return line <= 0 || line >= nlOffsets.length || (line == nlOffsets.length - 1 && finalNL); } } } truffle-0.6.orig/com/oracle/truffle/api/source/LineLocation.java0000644000000000000000000000317512445312576021660 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.source; /** * A specification for a location in guest language source, expressed as a line number in a specific * instance of {@link Source}, suitable for hash table keys with equality defined in terms of * content. */ public interface LineLocation { Source getSource(); /** * Gets the 1-based number of a line in the source. */ int getLineNumber(); String getShortDescription(); } truffle-0.6.orig/com/oracle/truffle/api/source/SourceSection.java0000644000000000000000000000705712445312576022070 0ustar /* * Copyright (c) 2013, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.source; /** * Description of contiguous section of text within a {@link Source} of program code; supports * multiple modes of access to the text and its location. A special {@linkplain NullSourceSection * null subtype} should be used for code that is not available from source, e.g language builtins. * * @see Source#createSection(String, int, int, int, int) * @see Source#createSection(String, int, int, int) * @see Source#createSection(String, int, int) * @see Source#createSection(String, int) * @see NullSourceSection */ public interface SourceSection { // TODO support alternate text representations/encodings /** * Representation of the source program that contains this section. * * @return the source object */ Source getSource(); /** * Returns 1-based line number of the first character in this section (inclusive). * * @return the starting line number */ int getStartLine(); /** * Gets a representation of the first line of the section, suitable for a hash key. */ LineLocation getLineLocation(); /** * Returns the 1-based column number of the first character in this section (inclusive). * * @return the starting column number */ int getStartColumn(); /** * Returns the 0-based index of the first character in this section. * * @return the starting character index */ int getCharIndex(); /** * Returns the length of this section in characters. * * @return the number of characters in the section */ int getCharLength(); /** * Returns the index of the text position immediately following the last character in the * section. * * @return the end position of the section */ int getCharEndIndex(); /** * Returns terse text describing this source section, typically used for printing the section. * * @return the identifier of the section */ String getIdentifier(); /** * Returns text described by this section. * * @return the code as a String object */ String getCode(); /** * Returns a short description of the source section, using just the file name, rather than its * full path. * * @return a short description of the source section */ String getShortDescription(); } truffle-0.6.orig/com/oracle/truffle/api/source/NullSourceSection.java0000644000000000000000000000645112445312576022720 0ustar /* * Copyright (c) 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.source; /** * A special subtype of {@link SourceSection} that represents unavailable source, e.g. for language * builtins. */ public class NullSourceSection implements SourceSection { private final String kind; private final String name; private final String asCode; /** * Placeholder for source that is unavailable, e.g. for language builtins. * * @param kind the general category, e.g. "JS builtin" * @param name specific name for this section */ public NullSourceSection(String kind, String name) { this(kind, name, kind); } /** * Placeholder for source that is unavailable, e.g. for language builtins. * * @param kind the general category, e.g. "JS builtin" * @param name specific name for this section * @param asCode string to return when {@link #getCode()} is called */ public NullSourceSection(String kind, String name, String asCode) { this.kind = kind; this.name = name; this.asCode = asCode; } public final Source getSource() { return null; } public final int getStartLine() { throw new UnsupportedOperationException(this.toString()); } public final LineLocation getLineLocation() { throw new UnsupportedOperationException(this.toString()); } public final int getStartColumn() { throw new UnsupportedOperationException(this.toString()); } public final int getCharIndex() { throw new UnsupportedOperationException(this.toString()); } public final int getCharLength() { throw new UnsupportedOperationException(this.toString()); } public final int getCharEndIndex() { throw new UnsupportedOperationException(this.toString()); } public final String getIdentifier() { return name; } public final String getCode() { return asCode; } public final String getShortDescription() { return kind + ": " + name; } @Override public String toString() { return getShortDescription(); } } truffle-0.6.orig/com/oracle/truffle/api/dsl/0000755000000000000000000000000012460741021015675 5ustar truffle-0.6.orig/com/oracle/truffle/api/dsl/TypeSystem.java0000644000000000000000000000735112445312576020710 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** *

* Each {@link Node} has one {@link TypeSystem} at its root to define the types that can be used * throughout the system. Multiple {@link TypeSystem}s are allowed, but they cannot be mixed inside * a single {@link Node} hierarchy. A {@link TypeSystem} defines a list of types as its child * elements, in which every type precedes its super types.The latter condition ensures that the most * concrete type is found first when searching the list sequentially for the type of a given generic * value. *

* *

* Each {@link #value()} is represented as a java type. A type can specify two annotations: * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic * value matches to the current type. The {@link TypeCast} casts a generic type value to the current * type. If the {@link TypeCheck} and {@link TypeCast} annotations are not declared in the * {@link TypeSystem} the a default implementation is provided. The default implementation of * {@link TypeCheck} returns true only on an exact type match and {@link TypeCast} is * only a cast to this type. Specified methods with {@link TypeCheck} and {@link TypeCast} may be * used to extend the definition of a type in the language. In our example, the * isInteger and asInteger methods are defined in a way so that they * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example * points out how we express implicit type conversions. *

* *

* Example: The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent * all values. * *

 *
 * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
 * public abstract class ExampleTypeSystem {
 * 
 *     {@literal @}TypeCheck
 *     public boolean isInteger(Object value) {
 *         return value instanceof Integer || value instanceof Double;
 *     }
 * 
 *     {@literal @}TypeCast
 *     public double asInteger(Object value) {
 *         return ((Number)value).doubleValue();
 *     }
 * }
 * 
* * * @see TypeCast * @see TypeCheck */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface TypeSystem { /** * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type. */ Class[] value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/ImportGuards.java0000644000000000000000000000344712445312576021204 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /** * Imports all public static methods usable as guards for {@link Specialization} annotations to the * current class. Using this annotation common guards can be shared across nodes. Imported guards * are derived from super classes. Guards declared in the node type hierarchy are always preferred * to imported guards. Imported guards for a more concrete type are preferred to guards imported in * the base class. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface ImportGuards { Class[] value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/ExpectError.java0000644000000000000000000000276712445312576021032 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /** * This annotation is internally known by the dsl processor and used to expect errors for testing * purposes. This is not part of public API. */ @Retention(RetentionPolicy.RUNTIME) public @interface ExpectError { String[] value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/Specialization.java0000644000000000000000000000554612445312576021544 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Specialization { /** * @deprecated do not use anymore. Will get removed in the next release. */ @Deprecated int DEFAULT_ORDER = -1; /** * The order has no effect anymore. The declaration order specialization methods is used * instead. * * @deprecated use declaration order instead. Will get removed in the next release. */ @Deprecated int order() default DEFAULT_ORDER; /** * Inserts this and all specializations that are declared after this specialization before a * specialization in the superclass. By default all specializations of the subclass are appended * to the specializations of the superclass. */ String insertBefore() default ""; Class[] rewriteOn() default {}; /** * The contains attribute declares all specializations that are contained by this * specialization. A containing specialization must be strictly generic as the contained * specialization. */ String[] contains() default {}; String[] guards() default {}; /** * Defines the assumptions to check for this specialization. When the specialization method is * invoked it is guaranteed that these assumptions still hold. It is not guaranteed that they * are checked before the {@link #guards()} methods. They may be checked before after or in * between {@link #guards()}. To declare assumptions use the {@link NodeAssumptions} annotation * at class level. */ String[] assumptions() default {}; } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeAssumptions.java0000644000000000000000000000312512445312576021710 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /** * Declares one or multiple assumptions for use inside a source code generation enabled node. * Declared assumptions must be passed to the {@link NodeFactory#createNode(Object...)} method as * parameters. */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeAssumptions { String[] value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/Fallback.java0000644000000000000000000000626412445312576020263 0ustar /* * Copyright (c) 2012, 2014, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** *

* A method annotated with {@link Fallback} is treated as a {@link Specialization} that implicitly * links all the guards of all other declared {@link Specialization} annotated methods of the * operation in a negated form. As a consequence it cannot declare any other guards. The expected * signature of the method must match to the signature of a {@link Specialization} with the * additional limitation that only generically executable argument types are allowed. A generically * executable argument is a an argument hat can be executed from the child {@link Node} using an * execute method without {@link UnsupportedOperationException}. In many cases the generically * executable type is {@link Object}. An operation is limited to just one {@link Fallback} * specialization which is always ordered at the end of the specialization chain. *

* *

* A simple example showing the use of the {@link Fallback} annotation in a DSL operation: *

* *
 * @Specialization int doInt(int a) {..}
 * @Specialization int doDouble(double a) {..}
 * @Fallback int orElse(Object a) {..}
 * 
* *

* The previous example could be redeclared just using {@link Specialization} annotated methods as * follows: *

* *
 * @Specialization int doInt(int a) {..}
 * @Specialization int doDouble(double a) {..}
 * @Specialization(guard={"!isInt(a)", "!isDouble(a)"})
 * int orElse(Object a) {..}
 * 
* *

* Performance note: For operations with a lot of {@link Specialization} annotated methods * the use of {@link Fallback} might generate a guard that is very big. Try to avoid the use of * {@link Fallback} for specializations that are significantly important for peak performance. *

* * @see Specialization * @see NodeChild */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface Fallback { } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeChild.java0000644000000000000000000000454712445312576020417 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** * A {@link NodeChild} element defines an executable child for the enclosing {@link Node}. A * {@link Node} contains multiple {@link NodeChildren} specified in linear execution order. */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeChild { String value() default ""; Class type() default Node.class; /** * The {@link #executeWith()} property allows a node to pass the result of one child's * executable as an input to another child's executable. These referenced children must be * defined before the current node in the execution order. The current node {@link #type()} * attribute must be set to a {@link Node} which supports the evaluated execution with the * number of {@link #executeWith()} arguments that are defined. For example if this child is * executed with one argument, the {@link #type()} attribute must define a node which publicly * declares a method with the signature Object execute*(VirtualFrame, Object). */ String[] executeWith() default {}; } truffle-0.6.orig/com/oracle/truffle/api/dsl/TypeSystemReference.java0000644000000000000000000000326412445312576022526 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy. * * @see TypeSystem * @see Node */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface TypeSystemReference { /** The {@link TypeSystem} java type. */ Class value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/0000755000000000000000000000000012460741021017511 5ustar truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/NodeFactoryBase.java0000644000000000000000000000474512445312576023412 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl.internal; import java.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; /** * This is NOT public API. Do not use directly. This code may change without notice. */ public abstract class NodeFactoryBase implements NodeFactory { private final Class nodeClass; private final Class[][] nodeSignatures; private final Class[] executionSignatures; @SuppressWarnings("unchecked") public NodeFactoryBase(Class nodeClass, Class[] executionSignatures, Class[][] nodeSignatures) { this.nodeClass = nodeClass; this.nodeSignatures = nodeSignatures; this.executionSignatures = (Class[]) executionSignatures; } public abstract T createNode(Object... arguments); public final Class getNodeClass() { return nodeClass; } public final List>> getNodeSignatures() { List>> signatures = new ArrayList<>(); for (int i = 0; i < nodeSignatures.length; i++) { signatures.add(Arrays.asList(nodeSignatures[i])); } return signatures; } public final List> getExecutionSignature() { return Arrays.asList(executionSignatures); } } truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/DSLMetadata.java0000644000000000000000000000507212445312576022457 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl.internal; /** * This is NOT public API. Do not use directly. This code may change without notice. */ public final class DSLMetadata { public static final Class[] EMPTY_CLASS_ARRAY = new Class[]{}; public static final DSLMetadata NONE = new DSLMetadata(null, EMPTY_CLASS_ARRAY, EMPTY_CLASS_ARRAY, EMPTY_CLASS_ARRAY, 0, 0); private final Class specializationClass; private final Class[] includes; private final Class[] excludedBy; private final Class[] specializedTypes; private final int costs; private final int order; public DSLMetadata(Class specializationClass, Class[] includes, Class[] excludes, Class[] specializedTypes, int costs, int order) { this.specializationClass = specializationClass; this.includes = includes; this.excludedBy = excludes; this.specializedTypes = specializedTypes; this.costs = costs; this.order = order; } public Class getSpecializationClass() { return specializationClass; } public Class[] getSpecializedTypes() { return specializedTypes; } Class[] getIncludes() { return includes; } Class[] getExcludedBy() { return excludedBy; } int getCosts() { return costs; } int getOrder() { return order; } } truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/DSLNode.java0000644000000000000000000000304012445312576021615 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl.internal; import com.oracle.truffle.api.nodes.*; /** * This is NOT public API. Do not use directly. This code may change without notice. */ public interface DSLNode { DSLMetadata getMetadata0(); void adoptChildren0(Node other, Node next); void updateTypes0(Class[] types); Node getNext0(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/DSLShare.java0000644000000000000000000002075612445312576022007 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl.internal; import java.util.*; import java.util.concurrent.*; import com.oracle.truffle.api.nodes.*; /** Contains utility classes shared across generated DSLNode implementations. */ public class DSLShare { public static boolean isExcluded(Node currentNode, DSLMetadata otherMetadata) { assert otherMetadata.getExcludedBy().length > 0 : "At least one exclude must be defined for isIncluded."; Node cur = findRoot(currentNode); while (cur != null) { Class curClass = cur.getClass(); if (curClass == otherMetadata.getSpecializationClass()) { return true; } else if (containsClass(otherMetadata.getExcludedBy(), cur)) { return true; } cur = getNext(cur); } return false; } private static boolean includes(Node oldNode, DSLNode newNode) { return containsClass(newNode.getMetadata0().getIncludes(), oldNode); } public static T rewrite(final Node thisNode, final T newNode, final String message) { return thisNode.atomic(new Callable() { public T call() { assert newNode != null; if (getNext(thisNode) != null || getPrevious(thisNode) != null) { // already polymorphic -> append return appendPolymorphic(findUninitialized(thisNode), newNode); } else if (includes(thisNode, newNode)) { // included -> remains monomorphic newNode.adoptChildren0(thisNode, null); return thisNode.replace(newNode, message); } else { // goto polymorphic return null; } } }); } @SuppressWarnings("unchecked") public static T findRoot(T node) { Node prev = node; Node cur; do { cur = prev; prev = getPrevious(cur); } while (prev != null); return (T) cur; } private static Node findUninitialized(Node node) { Node next = node; Node cur; do { cur = next; next = getNext(cur); } while (next != null); return cur; } public static T rewriteUninitialized(final Node uninitialized, final T newNode) { return uninitialized.atomic(new Callable() { public T call() { Node prev = getPrevious(uninitialized); if (prev == null) { newNode.adoptChildren0(uninitialized, null); return uninitialized.replace(newNode, "Uninitialized monomorphic"); } else { return appendPolymorphic(uninitialized, newNode); } } }); } public static T rewriteToPolymorphic(final Node oldNode, final DSLNode uninitializedDSL, final T polymorphic, final DSLNode currentCopy, final DSLNode newNodeDSL, final String message) { return oldNode.atomic(new Callable() { public T call() { assert getNext(oldNode) == null; assert getPrevious(oldNode) == null; assert newNodeDSL != null; Node uninitialized = (Node) uninitializedDSL; Node newNode = (Node) newNodeDSL; polymorphic.adoptChildren0(oldNode, (Node) currentCopy); updateSourceSection(oldNode, uninitialized); // new specialization updateSourceSection(oldNode, newNode); newNodeDSL.adoptChildren0(null, uninitialized); currentCopy.adoptChildren0(null, newNode); oldNode.replace(polymorphic, message); assert polymorphic.getNext0() == currentCopy; assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized; assert uninitializedDSL.getNext0() == null; return polymorphic; } }); } private static void updateSourceSection(Node oldNode, Node newNode) { if (newNode.getSourceSection() == null) { newNode.assignSourceSection(oldNode.getSourceSection()); } } private static Class[] mergeTypes(DSLNode node, Class[] types) { Class[] specializedTypes = node.getMetadata0().getSpecializedTypes(); if (specializedTypes.length == 0) { return null; } else if (types == null) { return Arrays.copyOf(specializedTypes, specializedTypes.length); } else { for (int i = 0; i < specializedTypes.length; i++) { if (specializedTypes[i] != types[i]) { types[i] = Object.class; } } return types; } } private static T appendPolymorphic(Node uninitialized, T newNode) { Class[] includes = newNode.getMetadata0().getIncludes(); Node cur = getPrevious(uninitialized); Node prev = uninitialized; int depth = 0; Class[] types = null; while (cur != null) { if (containsClass(includes, cur)) { cur.replace(prev, "Included in other specialization"); cur = prev; } else { depth++; types = mergeTypes((DSLNode) cur, types); } prev = cur; cur = getPrevious(cur); } assert prev.getCost() == NodeCost.POLYMORPHIC; updateSourceSection(prev, newNode); if (depth <= 1) { newNode.adoptChildren0(prev, null); return prev.replace(newNode, "Polymorphic to monomorphic."); } else { newNode.adoptChildren0(null, uninitialized); ((DSLNode) prev).updateTypes0(mergeTypes(newNode, types)); return uninitialized.replace(newNode, "Appended polymorphic"); } } private static boolean containsClass(Class[] classList, Node node) { Class nodeClass = node.getClass(); for (Class toCheck : classList) { if (nodeClass == toCheck) { if (node.getCost() == NodeCost.UNINITIALIZED) { /* * In case a specialization is excluded by the fallback specialization the * uninitialized class is used as exclusion class. Because the fallback field in * the uninitialized specialization is not accessible we use the costs to check * if the fallback was reached or not. In case the fallback was reached in the * uninitialized version the cost is MONOMORPHIC, otherwise it is UNINITIALIZED. */ continue; } return true; } } return false; } private static Node getNext(Node node) { return ((DSLNode) node).getNext0(); } private static Node getPrevious(Node node) { Node parent = node.getParent(); if (parent instanceof DSLNode && getNext(parent) == node) { return parent; } else { return null; } } } truffle-0.6.orig/com/oracle/truffle/api/dsl/CreateCast.java0000644000000000000000000000300712445312576020572 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** * Specifies a factory method that creates a {@link Node} which is used to cast this child. */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface CreateCast { String[] value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeFactory.java0000644000000000000000000000510212445312576020767 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.util.*; import com.oracle.truffle.api.nodes.*; /** * Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate * generated node classes without using reflection. */ public interface NodeFactory { /** * Instantiates the node using the arguments array. The arguments length and types must suffice * one of the returned signatures in {@link #getNodeSignatures()}. If the arguments array does * not suffice one of the node signatures an {@link IllegalArgumentException} is thrown. * * @param arguments the argument values * @return the instantiated node * @throws IllegalArgumentException */ T createNode(Object... arguments); /** * Returns the node class that will get created by {@link #createNode(Object...)}. The node * class does not match exactly to the instantiated object but they are guaranteed to be * assignable. */ Class getNodeClass(); /** * Returns a list of signatures that can be used to invoke {@link #createNode(Object...)}. */ List>> getNodeSignatures(); /** * Returns a list of children that will be executed by the created node. This is useful for base * nodes that can execute a variable amount of nodes. */ List> getExecutionSignature(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/ShortCircuit.java0000644000000000000000000000257312445312576021205 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface ShortCircuit { String value(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/TypeCast.java0000644000000000000000000000254212445312576020313 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface TypeCast { } truffle-0.6.orig/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java0000644000000000000000000000622412445312576025666 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.util.*; import com.oracle.truffle.api.nodes.*; /** * Thrown by the generated code of Truffle-DSL if no compatible Specialization could be found for * the provided values. */ public final class UnsupportedSpecializationException extends RuntimeException { private static final long serialVersionUID = -2122892028296836269L; private final Node node; private final Node[] suppliedNodes; private final Object[] suppliedValues; public UnsupportedSpecializationException(Node node, Node[] suppliedNodes, Object... suppliedValues) { super("Unexpected values provided for " + node + ": " + Arrays.toString(suppliedValues)); Objects.requireNonNull(suppliedNodes, "The suppliedNodes parameter must not be null."); if (suppliedNodes.length != suppliedValues.length) { throw new IllegalArgumentException("The length of suppliedNodes must match the length of suppliedValues."); } this.node = node; this.suppliedNodes = suppliedNodes; this.suppliedValues = suppliedValues; } /** * Returns the {@link Node} that caused the this {@link UnsupportedSpecializationException}. */ public Node getNode() { return node; } /** * Returns the children of the {@link Node} returned by {@link #getNode()} which produced the * values returned by {@link #getSuppliedValues()}. The array returned by * {@link #getSuppliedNodes()} has the same length as the array returned by * {@link #getSuppliedValues()}. Never returns null. */ public Node[] getSuppliedNodes() { return suppliedNodes; } /** * Returns the dynamic values that were supplied to the node.The array returned by * {@link #getSuppliedNodes()} has the same length as the array returned by * {@link #getSuppliedValues()}. Never returns null. */ public Object[] getSuppliedValues() { return suppliedValues; } } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeField.java0000644000000000000000000000335412445312576020412 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** * A {@link NodeField} element defines a field for the generated {@link Node}. A {@link Node} * contains multiple {@link NodeFields} specified in linear declaration order. The field can be * accessed by declaring an abstract getter named * "get" + firstLetterUpperCase({@link #name()})(). */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeField { String name(); Class type(); } truffle-0.6.orig/com/oracle/truffle/api/dsl/ImplicitCast.java0000644000000000000000000000254612445312576021150 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface ImplicitCast { } truffle-0.6.orig/com/oracle/truffle/api/dsl/GeneratedBy.java0000644000000000000000000000275612445312576020757 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /** * Marks a type as being generated based on another class or method. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface GeneratedBy { Class value(); String methodName() default ""; } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeChildren.java0000644000000000000000000000261112445312576021112 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeChildren { NodeChild[] value() default {}; } truffle-0.6.orig/com/oracle/truffle/api/dsl/NodeFields.java0000644000000000000000000000335212445312576020573 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; import com.oracle.truffle.api.nodes.*; /** * A {@link NodeFields} element defines a field for the generated {@link Node}. A {@link Node} * contains multiple {@link NodeFields} specified in linear declaration order. The field can be * accessed by declaring an abstract getter named * "get" + firstLetterUpperCase({@link #value()})(). */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeFields { NodeField[] value() default {}; } truffle-0.6.orig/com/oracle/truffle/api/dsl/TypeCheck.java0000644000000000000000000000543312445312576020440 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /** *

* Provides a way to define a custom type check for a defined type. The name of the annotated method * must fit to the pattern is${typeName} (eg. isInteger), where ${typeName} must be a valid type * defined in the parent {@link TypeSystem}. The annotated method must have exactly one argument * where the type of the argument is the generic type {@link Object} or a more specific one from the * {@link TypeSystem}. You can define multiple overloaded {@link TypeCheck} methods for the same * type. This can be used to reduce the boxing overhead in type conversions. *

* *

* By default the system generates type checks for all types in the parent {@link TypeSystem} which * look like the follows: * *

 * {@literal @}TypeCheck
 * boolean is${typeName}(Object value) {
 *         return value instanceof ${typeName};
 * }
 * 
* * Example: *

* A type check for BigInteger with one overloaded optimized variant to reduce boxing. *

* *
 *
 *
 * {@literal @}TypeSystem(types = {int.class, BigInteger.class, String.class}, nodeBaseClass = TypedNode.class)
 * public abstract class Types {
 * 
 *     {@literal @}TypeCheck
 *     public boolean isBigInteger(Object value) {
 *         return value instanceof Integer || value instanceof BigInteger;
 *     }
 * 
 *     {@literal @}TypeCheck
 *     public boolean isBigInteger(int value) {
 *         return true;
 *     }
 * 
 * }
 * 
* * */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface TypeCheck { } truffle-0.6.orig/com/oracle/truffle/api/dsl/Implies.java0000644000000000000000000000262412445312576020162 0ustar /* * Copyright (c) 2012, 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api.dsl; import java.lang.annotation.*; /* * Experimental API. */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface Implies { String[] value(); } truffle-0.6.orig/com/oracle/truffle/api/CallTarget.java0000644000000000000000000000276612445312576020027 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; /** * Represents the target of a call. */ public interface CallTarget { /** * Calls this target as a root method. * * @param arguments passed arguments as an object array * @return the return result of the call */ Object call(Object... arguments); } truffle-0.6.orig/com/oracle/truffle/api/TypedObject.java0000644000000000000000000000243312445312576020210 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; public interface TypedObject { Object getTypeIdentifier(); } truffle-0.6.orig/com/oracle/truffle/api/TruffleRuntime.java0000644000000000000000000001362212445312576020751 0ustar /* * Copyright (c) 2012, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.api; import java.util.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** * Interface representing a Truffle runtime object. The runtime is responsible for creating call * targets and performing optimizations for them. */ public interface TruffleRuntime { /** * Name describing this runtime implementation for debugging purposes. * * @return the name as a String */ String getName(); /** * Creates a new call target for a given root node. * * @param rootNode the root node whose * {@link RootNode#execute(com.oracle.truffle.api.frame.VirtualFrame)} method * represents the entry point * @return the new call target object */ RootCallTarget createCallTarget(RootNode rootNode); /** * Creates a new runtime specific version of {@link DirectCallNode}. * * @param target the direct {@link CallTarget} to call * @return the new call node */ DirectCallNode createDirectCallNode(CallTarget target); /** * Experimental API. May change without notice. */ LoopNode createLoopNode(RepeatingNode body); /** * Creates a new runtime specific version of {@link IndirectCallNode}. * * @return the new call node */ IndirectCallNode createIndirectCallNode(); /** * Creates a new assumption object that can be checked and invalidated. * * @return the newly created assumption object */ Assumption createAssumption(); /** * Creates a new assumption object with a given name that can be checked and invalidated. * * @param name the name for the new assumption * @return the newly created assumption object */ Assumption createAssumption(String name); /** * Creates a new virtual frame object that can be used to store values and is potentially * optimizable by the runtime. * * @return the newly created virtual frame object */ VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor); /** * Creates a new materialized frame object that can be used to store values. * * @return the newly created materialized frame object */ MaterializedFrame createMaterializedFrame(Object[] arguments); /** * Creates a new materialized frame object with the given frame descriptor that can be used to * store values. * * @param frameDescriptor the frame descriptor describing this frame's values * @return the newly created materialized frame object */ MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor); /** * Creates an object which allows you to test for support of and set options specific for this * runtime. * * @return the newly created compiler options object */ CompilerOptions createCompilerOptions(); /** * Accesses the current stack, i.e., the contents of the {@link Frame}s and the associated * {@link CallTarget}s. Iteration starts at the caller frame, i.e., it does not include the * current frame. * * Iteration continues as long as {@link FrameInstanceVisitor#visitFrame}, which is invoked for * every {@link FrameInstance}, returns null. Any non-null result of the visitor indicates that * frame iteration should stop. * * @param visitor the visitor that is called for every matching frame. * @return the last result returned by the visitor (which is non-null to indicate that iteration * should stop), or null if the whole stack was iterated. */ T iterateFrames(FrameInstanceVisitor visitor); /** * Accesses the caller frame. This is a convenience method that returns the first frame that is * passed to the visitor of {@link #iterateFrames}. */ FrameInstance getCallerFrame(); /** * Accesses the current frame, i.e., the frame of the closest {@link CallTarget}. It is * important to note that this {@link FrameInstance} supports only slow path access. */ FrameInstance getCurrentFrame(); /** * Requests a capability from the runtime. * * @param capability the type of the interface representing the capability * @return an implementation of the capability or {@code null} if the runtime does not offer it */ T getCapability(Class capability); /** * Returns a list of all still referenced {@link RootCallTarget} instances that were created * using {@link #createCallTarget(RootNode)}. */ Collection getCallTargets(); /** * Internal API method. Do not use. */ void notifyTransferToInterpreter(); } truffle-0.6.orig/com/oracle/truffle/object/0000755000000000000000000000000012460741021015610 5ustar truffle-0.6.orig/com/oracle/truffle/object/PropertyImpl.java0000644000000000000000000002177712445312576021153 0ustar /* * Copyright (c) 2012, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.Locations.*; /** * Property objects represent the mapping between low-level stores and high-level data. The simplest * Property could be nothing more than a map of one index to one property's value, but abstracting * the interface allows for getter/setter methods, type-checked properties, and other such * specialized and language-specific behavior. ECMAScript[8.6.1] */ public class PropertyImpl extends Property { private final Object key; private final Location location; private final int flags; private final boolean shadow; private final boolean relocatable; /** * Generic, usual-case constructor for properties storing at least a name. * * @param key the name of the property */ protected PropertyImpl(Object key, Location location, int flags, boolean shadow, boolean relocatable) { this.key = Objects.requireNonNull(key); this.location = Objects.requireNonNull(location); this.flags = flags; this.shadow = shadow; this.relocatable = relocatable; } public PropertyImpl(Object name, Location location, int flags) { this(name, location, flags, false, true); } @Override public final Object getKey() { return key; } @Override public int getFlags() { return flags; } @Override public Property relocate(Location newLocation) { if ((getLocation() == null || !getLocation().equals(newLocation)) && relocatable) { return construct(getKey(), newLocation, getFlags()); } return this; } @Override public final Object get(DynamicObject store, Shape shape) { return getLocation().get(store, shape); } @Override public final Object get(DynamicObject store, boolean condition) { return getLocation().get(store, condition); } @Override public final void setInternal(DynamicObject store, Object value) { try { ((LocationImpl) getLocation()).setInternal(store, value); } catch (IncompatibleLocationException e) { throw new IllegalStateException(); } } @Override public final void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { assert shape == null || store.getShape() == shape : "wrong shape"; getLocation().set(store, value, shape); } @Override public final void setSafe(DynamicObject store, Object value, Shape shape) { assert shape == null || store.getShape() == shape : "wrong shape"; try { getLocation().set(store, value, shape); } catch (IncompatibleLocationException | FinalLocationException ex) { throw new IllegalStateException(); } } @Override public final void setGeneric(DynamicObject store, Object value, Shape shape) { assert shape == null || store.getShape() == shape : "wrong shape"; try { set(store, value, shape); } catch (IncompatibleLocationException | FinalLocationException ex) { setSlowCase(store, value); } } @Override public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { assert store.getShape() == oldShape : "wrong shape"; assert newShape.isValid(); assert getLocation() != null; getLocation().set(store, value, oldShape, newShape); } @Override public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert store.getShape() == oldShape : "wrong old shape"; assert newShape.isValid(); assert getLocation() != null; try { getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { throw new IllegalStateException(); } } @Override public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert store.getShape() == oldShape : "wrong old shape"; assert newShape.isValid(); assert getLocation() != null; try { getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { setWithShapeSlowCase(store, value, oldShape, newShape); } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } PropertyImpl other = (PropertyImpl) obj; return key.equals(other.key) && ((location == null && other.location == null) || (location != null && location.equals(other.location))) && flags == other.flags && shadow == other.shadow && relocatable == other.relocatable; } @Override public boolean isSame(Property obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } PropertyImpl other = (PropertyImpl) obj; return key.equals(other.key) && flags == other.flags; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getClass().hashCode(); result = prime * result + key.hashCode(); result = prime * result + (location != null ? location.hashCode() : 0); result = prime * result + flags; return result; } @Override public String toString() { return "\"" + key + "\"" + ":" + location; } @Override public final Location getLocation() { return location; } private void setSlowCase(DynamicObject store, Object value) { if (getLocation() instanceof DeclaredLocation) { setDeclaredLocation(store, value); } else { generalize(store, value); } } private void setDeclaredLocation(DynamicObject store, Object value) { store.updateShape(); Shape oldShape = store.getShape(); Shape newShape = oldShape.addProperty(this.relocateShadow(oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)))); store.updateShape(); newShape.getLastProperty().setGeneric(store, value, oldShape, newShape); } private Property generalize(DynamicObject store, Object value) { return ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value); } private void setWithShapeSlowCase(DynamicObject store, Object value, Shape oldShape, Shape newShape) { ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value, oldShape, newShape); } @Override public final boolean isHidden() { return key instanceof HiddenKey; } @Override public final boolean isShadow() { return shadow; } private Property relocateShadow(Location newLocation) { assert !isShadow() && getLocation() instanceof DeclaredLocation && relocatable; return new PropertyImpl(getKey(), newLocation, flags, true, relocatable); } @SuppressWarnings("hiding") protected Property construct(Object name, Location location, int flags) { return new PropertyImpl(name, location, flags, shadow, relocatable); } @Override public Property copyWithFlags(int newFlags) { return construct(key, location, newFlags); } @Override public Property copyWithRelocatable(boolean newRelocatable) { if (this.relocatable != newRelocatable) { return new PropertyImpl(key, location, flags, shadow, newRelocatable); } return this; } } truffle-0.6.orig/com/oracle/truffle/object/LocationImpl.java0000644000000000000000000001115512445312576021064 0ustar /* * Copyright (c) 2013, 2014, 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.object; import com.oracle.truffle.api.object.*; public abstract class LocationImpl extends Location { @Override public void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { setInternal(store, value); } @Override protected final Object getInternal(DynamicObject store) { throw new UnsupportedOperationException(); } @Override protected abstract void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException; @Override public final boolean canSet(DynamicObject store, Object value) { return canStore(value) && canStoreFinal(store, value); } @Override public boolean canStore(Object value) { return true; } @SuppressWarnings("unused") protected boolean canStoreFinal(DynamicObject store, Object value) { return true; } public interface EffectivelyFinalLocation { T toNonFinalLocation(); } public interface TypedObjectLocation extends ObjectLocation { T toUntypedLocation(); } public interface InternalLongLocation extends LongLocation { void setLongInternal(DynamicObject store, long value); } @Override public boolean isFinal() { return false; } @Override public boolean isConstant() { return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (isFinal() ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Location other = (Location) obj; if (isFinal() != other.isFinal()) { return false; } return true; } @Override public String toString() { String finalString = isFinal() ? "f" : ""; String typeString = this instanceof IntLocation ? "i" : (this instanceof DoubleLocation ? "d" : (this instanceof BooleanLocation ? "b" : (this instanceof TypedLocation ? ((TypedLocation) this).getType().getSimpleName() : "o"))); return finalString + typeString + getWhereString(); } protected String getWhereString() { return ""; } /** * Get the number of object array elements this location requires. */ public int objectArrayCount() { return 0; } /** * Get the number of in-object {@link Object} fields this location requires. */ public int objectFieldCount() { return 0; } /** * Get the number of in-object primitive fields this location requires. */ public int primitiveFieldCount() { return 0; } /** * Get the number of primitive array elements this location requires. */ public int primitiveArrayCount() { return 0; } /** * Boxed values need to be compared by value not by reference. * * The first parameter should be the one with the more precise type information. * * For sets to final locations, otherValue.equals(thisValue) seems more beneficial, since we * usually know more about the value to be set. */ public static boolean valueEquals(Object val1, Object val2) { return val1 == val2 || (val1 != null && val1.equals(val2)); } } truffle-0.6.orig/com/oracle/truffle/object/LayoutImpl.java0000644000000000000000000001704612445312576020576 0ustar /* * Copyright (c) 2012, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.api.object.Shape.Allocator; import com.oracle.truffle.object.LocationImpl.EffectivelyFinalLocation; import com.oracle.truffle.object.LocationImpl.TypedObjectLocation; import com.oracle.truffle.object.Locations.ConstantLocation; import com.oracle.truffle.object.Locations.DeclaredLocation; import com.oracle.truffle.object.Locations.DualLocation; import com.oracle.truffle.object.Locations.ValueLocation; import com.oracle.truffle.object.ShapeImpl.BaseAllocator; public abstract class LayoutImpl extends Layout { private static final int INT_TO_DOUBLE_FLAG = 1; private static final int INT_TO_LONG_FLAG = 2; private final LayoutStrategy strategy; private final Class clazz; private final int allowedImplicitCasts; protected LayoutImpl(EnumSet allowedImplicitCasts, Class clazz, LayoutStrategy strategy) { this.strategy = strategy; this.clazz = clazz; this.allowedImplicitCasts = (allowedImplicitCasts.contains(ImplicitCast.IntToDouble) ? INT_TO_DOUBLE_FLAG : 0) | (allowedImplicitCasts.contains(ImplicitCast.IntToLong) ? INT_TO_LONG_FLAG : 0); } @Override public abstract DynamicObject newInstance(Shape shape); @Override public Class getType() { return clazz; } @Override public final Shape createShape(ObjectType operations, Object sharedData) { return createShape(operations, sharedData, 0); } @Override public final Shape createShape(ObjectType operations) { return createShape(operations, null); } public boolean isAllowedIntToDouble() { return (allowedImplicitCasts & INT_TO_DOUBLE_FLAG) != 0; } public boolean isAllowedIntToLong() { return (allowedImplicitCasts & INT_TO_LONG_FLAG) != 0; } protected abstract boolean hasObjectExtensionArray(); protected abstract boolean hasPrimitiveExtensionArray(); protected abstract int getObjectFieldCount(); protected abstract int getPrimitiveFieldCount(); protected abstract Location getObjectArrayLocation(); protected abstract Location getPrimitiveArrayLocation(); protected abstract int objectFieldIndex(Location location); protected boolean isLocationAssignableFrom(Location destination, Location source) { LayoutImpl layout = this; if (destination.isFinal()) { // allowed FinalLocation => FinalLocation // allowed FinalIntLocation => Final{Int,Double}Location // allowed: Final{Int,Double,TypedObject}Location => FinalObjectLocation if (!source.isFinal()) { return false; } } if (destination instanceof IntLocation) { return (source instanceof IntLocation); } else if (destination instanceof DoubleLocation) { return (source instanceof DoubleLocation || (layout.isAllowedIntToDouble() && source instanceof IntLocation)); } else if (destination instanceof LongLocation) { return (source instanceof LongLocation || (layout.isAllowedIntToLong() && source instanceof IntLocation)); } else if (destination instanceof BooleanLocation) { return (source instanceof BooleanLocation); } else if (destination instanceof TypedObjectLocation) { return source instanceof TypedObjectLocation && ((TypedObjectLocation) destination).getType().isAssignableFrom(((TypedObjectLocation) source).getType()); } else if (destination instanceof ValueLocation) { return false; } else { assert destination instanceof ObjectLocation || destination instanceof DualLocation; return true; } } protected Location existingLocationForValue(Object value, Location oldLocation, Shape oldShape) { assert oldShape.getLayout() == this; Location newLocation; if (oldLocation instanceof IntLocation && value instanceof Integer) { newLocation = oldLocation; } else if (oldLocation instanceof DoubleLocation && (value instanceof Double || this.isAllowedIntToDouble() && value instanceof Integer)) { newLocation = oldLocation; } else if (oldLocation instanceof LongLocation && (value instanceof Long || this.isAllowedIntToLong() && value instanceof Long)) { newLocation = oldLocation; } else if (oldLocation instanceof DeclaredLocation) { return oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)); } else if (oldLocation instanceof ConstantLocation) { return LocationImpl.valueEquals(oldLocation.get(null, false), value) ? oldLocation : new Locations.ConstantLocation(value); } else if (oldLocation instanceof TypedObjectLocation && !((TypedObjectLocation) oldLocation).getType().isAssignableFrom(value.getClass())) { newLocation = (((TypedObjectLocation) oldLocation).toUntypedLocation()); } else if (oldLocation instanceof DualLocation) { if (oldLocation.canStore(value)) { newLocation = oldLocation; } else { newLocation = ((BaseAllocator) oldShape.allocator()).locationForValueUpcast(value, oldLocation); } } else if (oldLocation instanceof ObjectLocation) { newLocation = oldLocation; } else { return oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.NonNull)); } if (newLocation instanceof EffectivelyFinalLocation) { newLocation = ((EffectivelyFinalLocation) newLocation).toNonFinalLocation(); } return newLocation; } /** * Is this property an upcast of the other property? * * @param other the property being compared to * @return true if this is a upcast of the other property, false otherwise */ public boolean isPropertyUpcastOf(Property thiz, Property other) { if (thiz.getLocation() != null && other.getLocation() != null && other.getKey().equals(thiz.getKey()) && other.getFlags() == thiz.getFlags()) { if (isLocationAssignableFrom(thiz.getLocation(), other.getLocation())) { return true; } } return false; } @Override public abstract Allocator createAllocator(); public LayoutStrategy getStrategy() { return strategy; } } truffle-0.6.orig/com/oracle/truffle/object/DynamicObjectImpl.java0000644000000000000000000003204012445312576022023 0ustar /* * Copyright (c) 2013, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.Locations.ValueLocation; import com.oracle.truffle.object.debug.*; public abstract class DynamicObjectImpl implements DynamicObject, Cloneable { private ShapeImpl shape; public static final DebugCounter reshapeCount = DebugCounter.create("Reshape count"); public DynamicObjectImpl(Shape shape) { assert shape instanceof ShapeImpl; initialize(shape); setShape(shape); if (ObjectStorageOptions.Profile) { trackObject(this); } } public Object getTypeIdentifier() { return getShape(); } public ShapeImpl getShape() { return shape; } protected void setShape(Shape shape) { assert shape.getLayout().getType().isInstance(this); this.shape = (ShapeImpl) shape; } protected abstract void initialize(Shape initialShape); public final void setShapeAndResize(Shape newShape) { setShapeAndResize(getShape(), newShape); } public final void setShapeAndResize(Shape oldShape, Shape newShape) { assert getShape() == oldShape : "wrong old shape"; if (oldShape != newShape) { setShape(newShape); resizeStore(oldShape, newShape); assert checkExtensionArrayInvariants(newShape); } } /** * Set shape to an immediate child of the current shape, optionally growing the extension array. * Typically this would add a single property. Cannot shrink or grow more than one property at a * time. * * @see #setShapeAndResize(Shape, Shape) */ public final void setShapeAndGrow(Shape oldShape, Shape newShape) { assert getShape() == oldShape : "wrong old shape"; if (oldShape != newShape) { assert checkSetShape(oldShape, newShape); setShape(newShape); growStore(oldShape, newShape); assert checkExtensionArrayInvariants(newShape); } } /** * Simpler version of {@link #resizeStore} when the object is only increasing in size. */ private void growStore(Shape oldShape, Shape newShape) { growObjectStore(oldShape, newShape); if (((ShapeImpl) newShape).hasPrimitiveArray) { growPrimitiveStore(oldShape, newShape); } } protected abstract void growObjectStore(Shape oldShape, Shape newShape); protected abstract void growPrimitiveStore(Shape oldShape, Shape newShape); private void resizeStore(Shape oldShape, Shape newShape) { resizeObjectStore(oldShape, newShape); if (((ShapeImpl) newShape).hasPrimitiveArray) { resizePrimitiveStore(oldShape, newShape); } } protected abstract void resizePrimitiveStore(Shape oldShape, Shape newShape); protected abstract void resizeObjectStore(Shape oldShape, Shape newShape); /** * Check whether fast transition is valid. * * @see #setShapeAndGrow */ private boolean checkSetShape(Shape oldShape, Shape newShape) { Shape currentShape = getShape(); assert oldShape != newShape : "Wrong old shape assumption?"; assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; // assert oldShape == currentShape || (oldShape.getLastProperty() == ((EnterpriseLayout) // oldShape.getLayout()).getPrimitiveArrayProperty() && oldShape.getParent() == // currentShape) : "Out-of-order shape change?" + "\nparentShape=" + currentShape + // "\noldShape=" + oldShape + "\nnewShape=" + newShape; return true; } /** * Check whether the extension arrays are in accordance with the description in the shape. */ protected abstract boolean checkExtensionArrayInvariants(Shape newShape); @Override protected final DynamicObject clone() { try { return (DynamicObject) super.clone(); } catch (CloneNotSupportedException e) { throw new IllegalStateException(); } } protected abstract DynamicObject cloneWithShape(Shape currentShape); void reshapeAfterDelete(final Shape newShape, final Shape deletedParentShape) { DynamicObject original = this.cloneWithShape(getShape()); setShapeAndResize(newShape); copyProperties(original, deletedParentShape); } public final void copyProperties(DynamicObject fromObject, Shape ancestor) { ShapeImpl fromShape = (ShapeImpl) fromObject.getShape(); ShapeImpl toShape = getShape(); assert toShape.isRelated(ancestor); assert toShape.isValid(); assert ancestor.isValid(); for (; toShape != ancestor; toShape = toShape.getParent()) { Transition transitionFromParent = toShape.getTransitionFromParent(); if (transitionFromParent instanceof Transition.AddPropertyTransition) { Property toProperty = ((Transition.AddPropertyTransition) transitionFromParent).getProperty(); Property fromProperty = fromShape.getProperty(toProperty.getKey()); // copy only if property has a location and it's not the same as the source location if (toProperty.getLocation() != null && !(toProperty.getLocation() instanceof ValueLocation) && !toProperty.getLocation().equals(fromProperty.getLocation())) { toProperty.setInternal(this, fromProperty.get(fromObject, false)); assert toShape.isValid(); } if (fromShape.getTransitionFromParent() instanceof Transition.AddPropertyTransition && ((Transition.AddPropertyTransition) fromShape.getTransitionFromParent()).getProperty() == fromProperty) { // no property is looked up twice, so we can skip over to parent fromShape = fromShape.getParent(); } } } } @TruffleBoundary public boolean changeFlags(Object id, int newFlags) { Shape oldShape = getShape(); Property existing = oldShape.getProperty(id); if (existing != null) { if (existing.getFlags() != newFlags) { Property newProperty = existing.copyWithFlags(newFlags); Shape newShape = oldShape.replaceProperty(existing, newProperty); this.setShape(newShape); } return true; } else { return false; } } @TruffleBoundary public boolean changeFlags(Object id, FlagsFunction updateFunction) { Shape oldShape = getShape(); Property existing = oldShape.getProperty(id); if (existing != null) { Integer newFlags = updateFunction.apply(existing.getFlags()); if (newFlags != null && existing.getFlags() != newFlags.intValue()) { Property newProperty = existing.copyWithFlags(newFlags); Shape newShape = oldShape.replaceProperty(existing, newProperty); this.setShape(newShape); } return true; } else { return false; } } public String debugDump(int level) { return debugDump(0, level); } public String debugDump(int level, int levelStop) { List properties = this.getShape().getPropertyListInternal(true); StringBuilder sb = new StringBuilder(properties.size() * 10); sb.append("{\n"); for (Property property : properties) { indent(sb, level + 1); sb.append(property.getKey()); sb.append('[').append(property.getLocation()).append(']'); Object value = property.get(this, false); if (value instanceof DynamicObjectImpl) { if (level < levelStop) { value = ((DynamicObjectImpl) value).debugDump(level + 1, levelStop); } else { value = value.toString(); } } sb.append(": "); sb.append(value); if (property != properties.get(properties.size() - 1)) { sb.append(","); } sb.append("\n"); } indent(sb, level); sb.append("}"); return sb.toString(); } private static StringBuilder indent(StringBuilder sb, int level) { for (int i = 0; i < level; i++) { sb.append(' '); } return sb; } @Override public String toString() { return getShape().getObjectType().toString(this); } @Override public boolean equals(Object obj) { return getShape().getObjectType().equals(this, obj); } @Override public int hashCode() { return getShape().getObjectType().hashCode(this); } @TruffleBoundary public Object get(Object id, Object defaultValue) { Property existing = getShape().getProperty(id); if (existing != null) { return existing.get(this, false); } else { return defaultValue; } } @TruffleBoundary public boolean set(Object id, Object value) { Property existing = getShape().getProperty(id); if (existing != null) { existing.setGeneric(this, value, null); return true; } else { return false; } } @TruffleBoundary public void define(Object id, Object value, int flags) { ShapeImpl oldShape = getShape(); Property existing = oldShape.getProperty(id); if (existing == null) { updateShape(); oldShape = getShape(); Shape newShape = oldShape.addProperty(Property.create(id, oldShape.allocator().locationForValue(value, true, true), flags)); updateShape(); newShape.getLastProperty().setGeneric(this, value, oldShape, newShape); } else { defineExisting(id, value, flags, existing, oldShape); } } private void defineExisting(Object id, Object value, int flags, Property existing, ShapeImpl oldShape) { if (existing.getFlags() == flags) { existing.setGeneric(this, value, null); } else { Property newProperty = Property.create(id, oldShape.getLayout().existingLocationForValue(value, existing.getLocation(), oldShape), flags); Shape newShape = oldShape.replaceProperty(existing, newProperty); this.setShapeAndResize(newShape); newProperty.setInternal(this, value); } } @TruffleBoundary public void define(Object id, Object value, int flags, LocationFactory locationFactory) { ShapeImpl oldShape = getShape(); Property existing = oldShape.getProperty(id); if (existing == null) { updateShape(); oldShape = getShape(); Shape newShape = oldShape.addProperty(Property.create(id, locationFactory.createLocation(oldShape, value), flags)); updateShape(); newShape.getLastProperty().setGeneric(this, value, oldShape, newShape); } else { defineExisting(id, value, flags, existing, oldShape); } } @TruffleBoundary public boolean delete(Object id) { ShapeImpl oldShape = getShape(); Property existing = oldShape.getProperty(id); if (existing != null) { ShapeImpl newShape = oldShape.removeProperty(existing); this.reshapeAfterDelete(newShape, ShapeImpl.findCommonAncestor(oldShape, newShape)); // TODO ancestor should be the parent of found property's shape return true; } else { return false; } } public int size() { return getShape().getPropertyCount(); } public boolean isEmpty() { return size() == 0; } public final boolean updateShape() { return getShape().getLayout().getStrategy().updateShape(this); } private static void trackObject(DynamicObject obj) { ShapeProfiler.getInstance().track(obj); } } truffle-0.6.orig/com/oracle/truffle/object/basic/0000755000000000000000000000000012460741021016671 5ustar truffle-0.6.orig/com/oracle/truffle/object/basic/ShapeBasic.java0000644000000000000000000000372612445312576021562 0ustar /* * Copyright (c) 2012, 2014, 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.object.basic; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; public final class ShapeBasic extends ShapeImpl { public ShapeBasic(Layout layout, Object sharedData, ObjectType operations, int id) { super(layout, operations, sharedData, id); } public ShapeBasic(Layout layout, Object sharedData, ShapeImpl parent, ObjectType objectType, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { super(layout, parent, objectType, sharedData, propertyMap, transition, allocator, id); } @SuppressWarnings("hiding") @Override protected ShapeImpl createShape(Layout layout, Object sharedData, ShapeImpl parent, ObjectType objectType, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { return new ShapeBasic(layout, sharedData, parent, objectType, propertyMap, transition, allocator, id); } } truffle-0.6.orig/com/oracle/truffle/object/basic/BasicAllocator.java0000644000000000000000000002121312445312576022431 0ustar /* * Copyright (c) 2012, 2014, 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.object.basic; import static com.oracle.truffle.object.basic.BasicLocations.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; import com.oracle.truffle.object.LocationImpl.InternalLongLocation; import com.oracle.truffle.object.Locations.ConstantLocation; import com.oracle.truffle.object.Locations.DeclaredDualLocation; import com.oracle.truffle.object.Locations.DualLocation; import com.oracle.truffle.object.Locations.ValueLocation; import com.oracle.truffle.object.basic.BasicLocations.BooleanLocationDecorator; import com.oracle.truffle.object.basic.BasicLocations.DoubleLocationDecorator; import com.oracle.truffle.object.basic.BasicLocations.IntLocationDecorator; import com.oracle.truffle.object.basic.BasicLocations.LongArrayLocation; import com.oracle.truffle.object.basic.BasicLocations.LongFieldLocation; import com.oracle.truffle.object.basic.BasicLocations.ObjectArrayLocation; public abstract class BasicAllocator extends ShapeImpl.BaseAllocator { public BasicAllocator(LayoutImpl layout) { super(layout); advance(((BasicLayout) layout).getPrimitiveArrayLocation()); } public BasicAllocator(ShapeImpl shape) { super(shape); } private BasicLayout getLayout() { return (BasicLayout) layout; } @Override protected Location moveLocation(Location oldLocation) { if (oldLocation instanceof DeclaredDualLocation) { return advance(newDeclaredDualLocation(((DeclaredDualLocation) oldLocation).get(null, false))); } else if (oldLocation instanceof DualLocation) { return advance(newDualLocation(((DualLocation) oldLocation).getType())); } else if (oldLocation instanceof LongLocation) { return newLongLocation(oldLocation.isFinal()); } else if (oldLocation instanceof IntLocation) { return newIntLocation(oldLocation.isFinal()); } else if (oldLocation instanceof DoubleLocation) { return newDoubleLocation(oldLocation.isFinal()); } else if (oldLocation instanceof BooleanLocation) { return newBooleanLocation(oldLocation.isFinal()); } else if (oldLocation instanceof ObjectLocation) { return newObjectLocation(oldLocation.isFinal(), ((ObjectLocation) oldLocation).isNonNull()); } else { assert oldLocation instanceof ValueLocation; return advance(oldLocation); } } @Override public Location newObjectLocation(boolean useFinal, boolean nonNull) { if (ObjectStorageOptions.InObjectFields) { int insertPos = objectFieldSize; while (insertPos + OBJECT_SIZE <= getLayout().getObjectFieldCount()) { return advance((Location) getLayout().getObjectFieldLocation(insertPos)); } } return newObjectArrayLocation(useFinal, nonNull); } @SuppressWarnings("unused") private Location newObjectArrayLocation(boolean useFinal, boolean nonNull) { return advance(new ObjectArrayLocation(objectArraySize, getLayout().getObjectArrayLocation())); } @Override public Location newTypedObjectLocation(boolean useFinal, Class type, boolean nonNull) { return newObjectLocation(useFinal, nonNull); } @Override public Location newIntLocation(boolean useFinal) { if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.IntegerLocations) { if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { return advance(new IntLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize))); } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { return advance(new IntLocationDecorator(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation()))); } } return newObjectLocation(useFinal, true); } @Override public Location newDoubleLocation(boolean useFinal) { if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.DoubleLocations) { if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { return advance(new DoubleLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize), getLayout().isAllowedIntToDouble())); } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { return advance(new DoubleLocationDecorator(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation()), getLayout().isAllowedIntToDouble())); } } return newObjectLocation(useFinal, true); } @Override public Location newLongLocation(boolean useFinal) { if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.LongLocations) { if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { return advance((Location) LongFieldLocation.create(getLayout().getPrimitiveFieldLocation(primitiveFieldSize), getLayout().isAllowedIntToLong())); } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { return advance(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation(), getLayout().isAllowedIntToLong())); } } return newObjectLocation(useFinal, true); } @Override public Location newBooleanLocation(boolean useFinal) { if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.BooleanLocations) { if (primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { return advance(new BooleanLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize))); } } return newObjectLocation(useFinal, true); } private boolean isPrimitiveExtensionArrayAvailable() { return hasPrimitiveArray; } @Override protected Location locationForValueUpcast(Object value, Location oldLocation) { assert !(value instanceof Class); if (oldLocation instanceof DualLocation) { DualLocation dualLocation = (DualLocation) oldLocation; if (dualLocation.getType() == null) { if (value instanceof Integer) { return dualLocation.changeType(int.class); } else if (value instanceof Double) { return dualLocation.changeType(double.class); } else if (value instanceof Long) { return dualLocation.changeType(long.class); } else if (value instanceof Boolean) { return dualLocation.changeType(boolean.class); } else { return dualLocation.changeType(Object.class); } } else if (dualLocation.getType().isPrimitive()) { return dualLocation.changeType(Object.class); } else { throw new UnsupportedOperationException(); } } else if (oldLocation instanceof ConstantLocation) { return constantLocation(value); } else { throw new UnsupportedOperationException(); } } @Override protected DeclaredDualLocation newDeclaredDualLocation(Object value) { return new DeclaredDualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), value, layout); } } truffle-0.6.orig/com/oracle/truffle/object/basic/DynamicObjectBasic.java0000644000000000000000000003316012445312576023230 0ustar /* * Copyright (c) 2014, 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.object.basic; import java.lang.annotation.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; import com.oracle.truffle.object.basic.BasicLocations.*; public class DynamicObjectBasic extends DynamicObjectImpl { @Retention(RetentionPolicy.RUNTIME) protected @interface DynamicField { } @DynamicField private long primitive1; @DynamicField private long primitive2; @DynamicField private long primitive3; @DynamicField private Object object1; @DynamicField private Object object2; @DynamicField private Object object3; @DynamicField private Object object4; private Object[] objext; private long[] primext; public DynamicObjectBasic(Shape shape) { super(shape); } @Override protected final void initialize(Shape shape) { assert getObjectStore(shape) == null; int capacity = ((ShapeImpl) shape).getObjectArrayCapacity(); if (capacity != 0) { this.setObjectStore(new Object[capacity], shape); } if (((ShapeImpl) shape).getPrimitiveArrayCapacity() != 0) { this.setPrimitiveStore(new long[((ShapeImpl) shape).getPrimitiveArrayCapacity()], shape); } } /** * Simpler version of {@link #resizeObjectStore} when the object is only increasing in size. */ @Override protected final void growObjectStore(Shape oldShape, Shape newShape) { int oldObjectArrayCapacity = ((ShapeImpl) oldShape).getObjectArrayCapacity(); int newObjectArrayCapacity = ((ShapeImpl) newShape).getObjectArrayCapacity(); if (oldObjectArrayCapacity != newObjectArrayCapacity) { growObjectStoreIntl(oldObjectArrayCapacity, newObjectArrayCapacity, oldShape); } } private void growObjectStoreIntl(int oldObjectArrayCapacity, int newObjectArrayCapacity, Shape newShape) { Object[] newObjectStore = new Object[newObjectArrayCapacity]; if (oldObjectArrayCapacity != 0) { // monotonic growth assumption assert oldObjectArrayCapacity < newObjectArrayCapacity; Object[] oldObjectStore = this.getObjectStore(newShape); for (int i = 0; i < oldObjectArrayCapacity; ++i) { newObjectStore[i] = oldObjectStore[i]; } } this.setObjectStore(newObjectStore, newShape); } /** * Simpler version of {@link #resizePrimitiveStore} when the object is only increasing in size. */ @Override protected final void growPrimitiveStore(Shape oldShape, Shape newShape) { assert ((ShapeImpl) newShape).hasPrimitiveArray(); int oldPrimitiveCapacity = oldShape.getPrimitiveArrayCapacity(); int newPrimitiveCapacity = newShape.getPrimitiveArrayCapacity(); if (newPrimitiveCapacity == 0) { // due to obsolescence, we might have to reserve an empty primitive array slot this.setPrimitiveStore(null, newShape); } else if (oldPrimitiveCapacity != newPrimitiveCapacity) { growPrimitiveStoreIntl(oldPrimitiveCapacity, newPrimitiveCapacity, oldShape); } } private void growPrimitiveStoreIntl(int oldPrimitiveCapacity, int newPrimitiveCapacity, Shape newShape) { long[] newPrimitiveArray = new long[newPrimitiveCapacity]; if (oldPrimitiveCapacity != 0) { // primitive array can shrink due to type changes long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); for (int i = 0; i < Math.min(oldPrimitiveCapacity, newPrimitiveCapacity); ++i) { newPrimitiveArray[i] = oldPrimitiveArray[i]; } } this.setPrimitiveStore(newPrimitiveArray, newShape); } @Override protected final void resizeObjectStore(Shape oldShape, Shape newShape) { Object[] newObjectStore = null; int destinationCapacity = newShape.getObjectArrayCapacity(); if (destinationCapacity != 0) { newObjectStore = new Object[destinationCapacity]; int sourceCapacity = oldShape.getObjectArrayCapacity(); if (sourceCapacity != 0) { Object[] oldObjectStore = getObjectStore(newShape); for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { newObjectStore[i] = oldObjectStore[i]; } } } this.setObjectStore(newObjectStore, newShape); } private Object[] getObjectStore(@SuppressWarnings("unused") Shape currentShape) { return objext; } private void setObjectStore(Object[] newArray, @SuppressWarnings("unused") Shape currentShape) { objext = newArray; } private long[] getPrimitiveStore(@SuppressWarnings("unused") Shape currentShape) { return primext; } private void setPrimitiveStore(long[] newArray, @SuppressWarnings("unused") Shape currentShape) { primext = newArray; } @Override protected final void resizePrimitiveStore(Shape oldShape, Shape newShape) { assert newShape.hasPrimitiveArray(); long[] newPrimitiveArray = null; int destinationCapacity = newShape.getPrimitiveArrayCapacity(); if (destinationCapacity != 0) { newPrimitiveArray = new long[destinationCapacity]; int sourceCapacity = oldShape.getPrimitiveArrayCapacity(); if (sourceCapacity != 0) { long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { newPrimitiveArray[i] = oldPrimitiveArray[i]; } } } this.setPrimitiveStore(newPrimitiveArray, newShape); } /** * Check whether fast transition is valid. * * @see #setShapeAndGrow */ @SuppressWarnings("unused") private boolean checkSetShape(Shape oldShape, Shape newShape) { Shape currentShape = getShape(); assert oldShape != newShape : "Wrong old shape assumption?"; assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; assert oldShape == currentShape || oldShape.getParent() == currentShape : "Out-of-order shape change?" + "\nparentShape=" + currentShape + "\noldShape=" + oldShape + "\nnewShape=" + newShape; return true; } /** * Check whether the extension arrays are in accordance with the description in the shape. */ @Override protected final boolean checkExtensionArrayInvariants(Shape newShape) { assert getShape() == newShape; assert (getObjectStore(newShape) == null && newShape.getObjectArrayCapacity() == 0) || (getObjectStore(newShape) != null && getObjectStore(newShape).length == newShape.getObjectArrayCapacity()); if (newShape.hasPrimitiveArray()) { assert (getPrimitiveStore(newShape) == null && newShape.getPrimitiveArrayCapacity() == 0) || (getPrimitiveStore(newShape) != null && getPrimitiveStore(newShape).length == newShape.getPrimitiveArrayCapacity()); } return true; } @Override protected final DynamicObject cloneWithShape(Shape currentShape) { assert this.getShape() == currentShape; final DynamicObjectBasic clone = (DynamicObjectBasic) super.clone(); if (this.getObjectStore(currentShape) != null) { clone.setObjectStore(this.getObjectStore(currentShape).clone(), currentShape); } if (currentShape.hasPrimitiveArray() && this.getPrimitiveStore(currentShape) != null) { clone.setPrimitiveStore(this.getPrimitiveStore(currentShape).clone(), currentShape); } return clone; } protected final void reshape(ShapeImpl newShape) { reshapeCount.inc(); ShapeImpl oldShape = getShape(); ShapeImpl commonAncestor = ShapeImpl.findCommonAncestor(oldShape, newShape); if (ObjectStorageOptions.TraceReshape) { int limit = 150; System.out.printf("RESHAPE\nOLD %s\nNEW %s\nLCA %s\nDIFF %s\n---\n", oldShape.toStringLimit(limit), newShape.toStringLimit(limit), commonAncestor.toStringLimit(limit), ShapeImpl.diff(oldShape, newShape)); } DynamicObject original = this.cloneWithShape(oldShape); setShapeAndGrow(oldShape, newShape); assert !((newShape.hasPrimitiveArray() && newShape.getPrimitiveArrayCapacity() == 0)) || getPrimitiveStore(newShape) == null; copyProperties(original, commonAncestor); assert checkExtensionArrayInvariants(newShape); } static final SimpleObjectFieldLocation[] OBJECT_FIELD_LOCATIONS; static final SimpleLongFieldLocation[] PRIMITIVE_FIELD_LOCATIONS; static final SimpleObjectFieldLocation OBJECT_ARRAY_LOCATION; static final SimpleObjectFieldLocation PRIMITIVE_ARRAY_LOCATION; static { int index; index = 0; PRIMITIVE_FIELD_LOCATIONS = new SimpleLongFieldLocation[]{new SimpleLongFieldLocation(index++) { @Override public long getLong(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).primitive1; } @Override public void setLongInternal(DynamicObject store, long value) { ((DynamicObjectBasic) store).primitive1 = value; } }, new SimpleLongFieldLocation(index++) { @Override public long getLong(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).primitive2; } @Override public void setLongInternal(DynamicObject store, long value) { ((DynamicObjectBasic) store).primitive2 = value; } }, new SimpleLongFieldLocation(index++) { @Override public long getLong(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).primitive3; } @Override public void setLongInternal(DynamicObject store, long value) { ((DynamicObjectBasic) store).primitive3 = value; } }}; index = 0; OBJECT_FIELD_LOCATIONS = new SimpleObjectFieldLocation[]{new SimpleObjectFieldLocation(index++) { @Override public Object get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).object1; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).object1 = value; } }, new SimpleObjectFieldLocation(index++) { @Override public Object get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).object2; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).object2 = value; } }, new SimpleObjectFieldLocation(index++) { @Override public Object get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).object3; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).object3 = value; } }, new SimpleObjectFieldLocation(index++) { @Override public Object get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).object4; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).object4 = value; } }}; OBJECT_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { @Override public Object[] get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).objext; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).objext = (Object[]) value; } }; PRIMITIVE_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { @Override public long[] get(DynamicObject store, boolean condition) { return ((DynamicObjectBasic) store).primext; } @Override public void setInternal(DynamicObject store, Object value) { ((DynamicObjectBasic) store).primext = (long[]) value; } }; } } truffle-0.6.orig/com/oracle/truffle/object/basic/BasicLocations.java0000644000000000000000000005257512445312576022463 0ustar /* * Copyright (c) 2013, 2014, 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.object.basic; import java.lang.invoke.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; import com.oracle.truffle.object.LocationImpl.InternalLongLocation; /** * Property location. * * @see Shape * @see Property * @see DynamicObject */ public abstract class BasicLocations { static final int LONG_SIZE = 1; static final int OBJECT_SIZE = 1; public abstract static class ArrayLocation extends LocationImpl { protected final int index; protected final Location arrayLocation; public ArrayLocation(int index, Location arrayLocation) { this.index = index; this.arrayLocation = arrayLocation; } protected final Object getArray(DynamicObject store, boolean condition) { // non-null cast return arrayLocation.get(store, condition); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + index; return result; } @Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } ArrayLocation other = (ArrayLocation) obj; if (index != other.index) { return false; } return true; } public final int getIndex() { return index; } @Override protected String getWhereString() { return "[" + index + "]"; } } public abstract static class FieldLocation extends LocationImpl { private final int index; public FieldLocation(int index) { this.index = index; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + index; return result; } @Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } FieldLocation other = (FieldLocation) obj; if (index != other.index) { return false; } return true; } public final int getIndex() { return index; } @Override protected String getWhereString() { return "@" + index; } } public abstract static class MethodHandleFieldLocation extends FieldLocation { protected final MethodHandle getter; protected final MethodHandle setter; public MethodHandleFieldLocation(int index, MethodHandle getter, MethodHandle setter) { super(index); this.getter = getter; this.setter = setter; } } public static class ObjectArrayLocation extends ArrayLocation implements ObjectLocation { public ObjectArrayLocation(int index, Location arrayLocation) { super(index, arrayLocation); } @Override public Object get(DynamicObject store, boolean condition) { return ((Object[]) getArray(store, condition))[index]; } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { ((Object[]) getArray(store, false))[index] = value; } @Override public boolean canStore(Object value) { return true; } public Class getType() { return Object.class; } public final boolean isNonNull() { return false; } @Override public int objectArrayCount() { return OBJECT_SIZE; } } public static class ObjectFieldLocation extends MethodHandleFieldLocation implements ObjectLocation { public ObjectFieldLocation(int index, MethodHandle getter, MethodHandle setter) { super(index, getter, setter); } @Override public Object get(DynamicObject store, boolean condition) { try { return getter.invokeExact(store); } catch (Throwable e) { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException(e); } } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { try { setter.invokeExact(store, value); } catch (Throwable e) { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException(e); } } @Override public boolean canStore(Object value) { return true; } public Class getType() { return Object.class; } public boolean isNonNull() { return false; } @Override public int objectFieldCount() { return OBJECT_SIZE; } } public abstract static class SimpleObjectFieldLocation extends FieldLocation implements ObjectLocation { public SimpleObjectFieldLocation(int index) { super(index); } @Override public abstract Object get(DynamicObject store, boolean condition); @Override public abstract void setInternal(DynamicObject store, Object value); @Override public boolean canStore(Object value) { return true; } public Class getType() { return Object.class; } public boolean isNonNull() { return false; } @Override public int objectFieldCount() { return OBJECT_SIZE; } } public static class LongArrayLocation extends ArrayLocation implements InternalLongLocation { protected final boolean allowInt; public LongArrayLocation(int index, Location arrayLocation, boolean allowInt) { super(index, arrayLocation); this.allowInt = allowInt; } public LongArrayLocation(int index, Location arrayLocation) { this(index, arrayLocation, false); } @Override public final Object get(DynamicObject store, boolean condition) { return getLong(store, condition); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setLongInternal(store, ((Number) value).longValue()); } else { throw incompatibleLocation(); } } @Override public long getLong(DynamicObject store, boolean condition) { return ((long[]) getArray(store, condition))[index]; } public final void setLongInternal(DynamicObject store, long value) { ((long[]) getArray(store, false))[index] = value; } @Override public void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException { setLongInternal(store, value); } @Override public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setLongInternal(store, value); } @Override public final void setLong(DynamicObject store, long value) throws FinalLocationException { setLong(store, value, null); } public final long getLong(DynamicObject store, Shape shape) { return getLong(store, checkShape(store, shape)); } @Override public final boolean canStore(Object value) { return value instanceof Long || (allowInt && value instanceof Integer); } public Class getType() { return long.class; } @Override public int primitiveArrayCount() { return LONG_SIZE; } } public static class LongFieldLocation extends MethodHandleFieldLocation implements InternalLongLocation { public LongFieldLocation(int index, MethodHandle getter, MethodHandle setter) { super(index, getter, setter); } public static LongLocation create(InternalLongLocation longLocation, boolean allowInt) { if ((!allowInt && (longLocation instanceof LongLocationDecorator)) || (longLocation instanceof LongLocationDecorator && ((LongLocationDecorator) longLocation).allowInt == allowInt)) { return longLocation; } else { return new LongLocationDecorator(longLocation, allowInt); } } @Override public final Object get(DynamicObject store, boolean condition) { return getLong(store, condition); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setLongInternal(store, (long) value); } else { throw incompatibleLocation(); } } @Override public final boolean canStore(Object value) { return value instanceof Long; } @Override public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setLongInternal(store, value); } public long getLong(DynamicObject store, boolean condition) { try { return (long) getter.invokeExact(store); } catch (Throwable e) { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException(e); } } public void setLong(DynamicObject store, long value, Shape shape) { setLongInternal(store, value); } public final void setLong(DynamicObject store, long value) throws FinalLocationException { setLong(store, value, null); } public final void setLongInternal(DynamicObject store, long value) { try { setter.invokeExact(store, value); } catch (Throwable e) { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException(e); } } public final long getLong(DynamicObject store, Shape shape) { return getLong(store, checkShape(store, shape)); } @Override public final int primitiveFieldCount() { return LONG_SIZE; } public Class getType() { return long.class; } } public static class LongLocationDecorator extends PrimitiveLocationDecorator implements InternalLongLocation { protected final boolean allowInt; public LongLocationDecorator(InternalLongLocation longLocation, boolean allowInt) { super(longLocation); this.allowInt = allowInt; } @Override public final Object get(DynamicObject store, boolean condition) { return getLong(store, condition); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setLongInternal(store, ((Number) value).longValue()); } else { throw incompatibleLocation(); } } @Override public final boolean canStore(Object value) { return value instanceof Long || (allowInt && value instanceof Integer); } @Override public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setLongInternal(store, value); } public Class getType() { return long.class; } } public abstract static class SimpleLongFieldLocation extends FieldLocation implements InternalLongLocation { public SimpleLongFieldLocation(int index) { super(index); } @Override public final Object get(DynamicObject store, boolean condition) { return getLong(store, condition); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setLongInternal(store, ((Number) value).longValue()); } else { throw incompatibleLocation(); } } @Override public final boolean canStore(Object value) { return value instanceof Long; } @Override public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setLongInternal(store, value); } public abstract long getLong(DynamicObject store, boolean condition); public final long getLong(DynamicObject store, Shape shape) { return getLong(store, checkShape(store, shape)); } public final void setLong(DynamicObject store, long value) { setLong(store, value, null); } public void setLong(DynamicObject store, long value, Shape shape) { setLongInternal(store, value); } public abstract void setLongInternal(DynamicObject store, long value); @Override public final int primitiveFieldCount() { return LONG_SIZE; } public Class getType() { return long.class; } } public abstract static class PrimitiveLocationDecorator extends LocationImpl { private final InternalLongLocation longLocation; public PrimitiveLocationDecorator(InternalLongLocation longLocation) { this.longLocation = longLocation; } public final long getLong(DynamicObject store, Shape shape) { return longLocation.getLong(store, shape); } public final long getLong(DynamicObject store, boolean condition) { return longLocation.getLong(store, condition); } public final void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException { longLocation.setLong(store, value, shape); } public final void setLong(DynamicObject store, long value) throws FinalLocationException { longLocation.setLong(store, value); } public final void setLongInternal(DynamicObject store, long value) { longLocation.setLongInternal(store, value); } @Override public final int primitiveFieldCount() { return ((LocationImpl) longLocation).primitiveFieldCount(); } @Override public final int primitiveArrayCount() { return ((LocationImpl) longLocation).primitiveArrayCount(); } } public static class IntLocationDecorator extends PrimitiveLocationDecorator implements IntLocation { public IntLocationDecorator(InternalLongLocation longLocation) { super(longLocation); } @Override public final Object get(DynamicObject store, boolean condition) { return getInt(store, condition); } public int getInt(DynamicObject store, boolean condition) { return (int) getLong(store, condition); } public void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException { setLong(store, value, shape); } @Override public final void setInt(DynamicObject store, int value) throws FinalLocationException { setInt(store, value, null); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setLongInternal(store, (int) value); } else { throw incompatibleLocation(); } } public final int getInt(DynamicObject store, Shape shape) { return getInt(store, checkShape(store, shape)); } @Override public final boolean canStore(Object value) { return value instanceof Integer; } @Override public final void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setLongInternal(store, value); } public Class getType() { return int.class; } } public static class DoubleLocationDecorator extends PrimitiveLocationDecorator implements DoubleLocation { private final boolean allowInt; public DoubleLocationDecorator(InternalLongLocation longLocation, boolean allowInt) { super(longLocation); this.allowInt = allowInt; } @Override public final Object get(DynamicObject store, boolean condition) { return getDouble(store, condition); } public double getDouble(DynamicObject store, boolean condition) { return Double.longBitsToDouble(getLong(store, condition)); } public void setDouble(DynamicObject store, double value, Shape shape) { setLongInternal(store, Double.doubleToRawLongBits(value)); } public void setDouble(DynamicObject store, double value) { setDouble(store, value, null); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setDouble(store, ((Number) value).doubleValue(), null); } else { throw incompatibleLocation(); } } public final double getDouble(DynamicObject store, Shape shape) { return getDouble(store, checkShape(store, shape)); } @Override public final boolean canStore(Object value) { return value instanceof Double || (allowInt && value instanceof Integer); } @Override public final void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setDouble(store, value, newShape); } public Class getType() { return double.class; } } public static class BooleanLocationDecorator extends PrimitiveLocationDecorator implements BooleanLocation { public BooleanLocationDecorator(InternalLongLocation longLocation) { super(longLocation); } @Override public final Object get(DynamicObject store, boolean condition) { return getBoolean(store, condition); } public boolean getBoolean(DynamicObject store, boolean condition) { return getLong(store, condition) != 0; } public void setBoolean(DynamicObject store, boolean value, Shape shape) { setLongInternal(store, value ? 1 : 0); } public void setBoolean(DynamicObject store, boolean value) { setBoolean(store, value, null); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (canStore(value)) { setBoolean(store, (boolean) value, null); } else { throw incompatibleLocation(); } } public final boolean getBoolean(DynamicObject store, Shape shape) { return getBoolean(store, checkShape(store, shape)); } @Override public final boolean canStore(Object value) { return value instanceof Boolean; } @Override public final void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape) { store.setShapeAndGrow(oldShape, newShape); setBoolean(store, value, newShape); } public Class getType() { return boolean.class; } } } truffle-0.6.orig/com/oracle/truffle/object/basic/DefaultLayoutFactory.java0000644000000000000000000000311412445312576023661 0ustar /* * Copyright (c) 2014, 2014, 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.object.basic; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; public class DefaultLayoutFactory implements LayoutFactory { public Layout createLayout(LayoutBuilder layoutBuilder) { return BasicLayout.createLayoutImpl(layoutBuilder.getAllowedImplicitCasts(), new DefaultStrategy()); } public Property createProperty(Object id, Location location, int flags) { return new PropertyImpl(id, location, flags); } public int getPriority() { return 10; } } truffle-0.6.orig/com/oracle/truffle/object/basic/BasicLayout.java0000644000000000000000000001030312445312576021764 0ustar /* * Copyright (c) 2012, 2014, 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.object.basic; import java.util.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.api.object.Shape.Allocator; import com.oracle.truffle.object.*; import com.oracle.truffle.object.LocationImpl.InternalLongLocation; import com.oracle.truffle.object.Locations.DualLocation; import com.oracle.truffle.object.basic.BasicLocations.ObjectFieldLocation; import com.oracle.truffle.object.basic.BasicLocations.SimpleObjectFieldLocation; public class BasicLayout extends LayoutImpl { private final ObjectLocation[] objectFields; private final InternalLongLocation[] primitiveFields; private final Location objectArrayLocation; private final Location primitiveArrayLocation; BasicLayout(EnumSet allowedImplicitCasts, LayoutStrategy strategy) { super(allowedImplicitCasts, DynamicObjectBasic.class, strategy); this.objectFields = DynamicObjectBasic.OBJECT_FIELD_LOCATIONS; this.primitiveFields = DynamicObjectBasic.PRIMITIVE_FIELD_LOCATIONS; this.primitiveArrayLocation = DynamicObjectBasic.PRIMITIVE_ARRAY_LOCATION; this.objectArrayLocation = DynamicObjectBasic.OBJECT_ARRAY_LOCATION; } static LayoutImpl createLayoutImpl(EnumSet allowedImplicitCasts, LayoutStrategy strategy) { return new BasicLayout(allowedImplicitCasts, strategy); } @Override public DynamicObject newInstance(Shape shape) { return new DynamicObjectBasic(shape); } @Override public Shape createShape(ObjectType operations, Object sharedData, int id) { return new ShapeBasic(this, sharedData, operations, id); } @Override protected boolean hasObjectExtensionArray() { return true; } @Override protected boolean hasPrimitiveExtensionArray() { return true; } @Override protected int getObjectFieldCount() { return objectFields.length; } @Override protected int getPrimitiveFieldCount() { return primitiveFields.length; } @Override protected Location getObjectArrayLocation() { return objectArrayLocation; } @Override protected Location getPrimitiveArrayLocation() { return primitiveArrayLocation; } protected ObjectLocation getObjectFieldLocation(int index) { return objectFields[index]; } protected InternalLongLocation getPrimitiveFieldLocation(int index) { return primitiveFields[index]; } @Override public Allocator createAllocator() { LayoutImpl layout = this; Allocator allocator = getStrategy().createAllocator(layout); return allocator; } @Override protected int objectFieldIndex(Location location) { if (location instanceof DualLocation) { return objectFieldIndex((Location) ((DualLocation) location).getObjectLocation()); } else if (location instanceof ObjectFieldLocation) { return ((ObjectFieldLocation) location).getIndex(); } else if (location instanceof SimpleObjectFieldLocation) { return ((SimpleObjectFieldLocation) location).getIndex(); } else { return 0; } } } truffle-0.6.orig/com/oracle/truffle/object/basic/DefaultStrategy.java0000644000000000000000000001014512445312576022660 0ustar /* * Copyright (c) 2014, 2014, 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.object.basic; import java.util.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; import com.oracle.truffle.object.ShapeImpl.BaseAllocator; class DefaultStrategy implements LayoutStrategy { public boolean updateShape(DynamicObject object) { assert object.getShape().isValid(); return false; } public Shape returnCached(Shape newShape) { assert newShape.isValid(); return newShape; } private static boolean assertLocationInRange(Shape shape, Location location) { BasicLayout layout = (BasicLayout) shape.getLayout(); assert (shape.getPrimitiveFieldSize() + ((LocationImpl) location).primitiveFieldCount() <= layout.getPrimitiveFieldCount()); assert (shape.getObjectFieldSize() + ((LocationImpl) location).objectFieldCount() <= layout.getObjectFieldCount()); return true; } public Shape ensureSpace(Shape shape, Location location) { Objects.requireNonNull(location); assert assertLocationInRange(shape, location); return shape; } public boolean isAutoExtArray() { return false; } public Property generalizeProperty(DynamicObject object, Property oldProperty, Object value) { Shape oldShape = object.getShape(); Location oldLocation = oldProperty.getLocation(); Location newLocation = ((BasicAllocator) oldShape.allocator()).locationForValueUpcast(value, oldLocation); Property newProperty = oldProperty.relocate(newLocation); Shape newShape = oldShape.replaceProperty(oldProperty, newProperty); newProperty.setSafe(object, value, oldShape, newShape); return newProperty; } public Property generalizeProperty(DynamicObject object, Property oldProperty, Object value, Shape currentShape, Shape oldNewShape) { Location oldLocation = oldProperty.getLocation(); Location newLocation = ((BasicAllocator) currentShape.allocator()).locationForValueUpcast(value, oldLocation); Property newProperty = oldProperty.relocate(newLocation); Shape newShape = oldNewShape.replaceProperty(oldProperty, newProperty); newProperty.setSafe(object, value, currentShape, newShape); return newProperty; } public BaseAllocator createAllocator(Shape shape) { return new DefaultAllocatorImpl((ShapeImpl) shape); } public BaseAllocator createAllocator(Layout layout) { return new DefaultAllocatorImpl((LayoutImpl) layout); } public static class DefaultAllocatorImpl extends BasicAllocator { protected DefaultAllocatorImpl(LayoutImpl layout) { super(layout); } protected DefaultAllocatorImpl(ShapeImpl shape) { super(shape); } @Override public Location locationForValue(Object value, boolean useFinal, boolean nonNull) { return super.newDualLocationForValue(value); } @Override public Location declaredLocation(Object value) { return super.newDeclaredDualLocation(value); } } } truffle-0.6.orig/com/oracle/truffle/object/debug/0000755000000000000000000000000012460741021016676 5ustar truffle-0.6.orig/com/oracle/truffle/object/debug/GraphvizShapeVisitor.java0000644000000000000000000000553012445312576023713 0ustar /* * Copyright (c) 2014, 2014, 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.object.debug; import java.util.*; import java.util.Map.Entry; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; public class GraphvizShapeVisitor extends DebugShapeVisitor { private final Set drawn; private final StringBuilder sb = new StringBuilder(); public GraphvizShapeVisitor() { this.drawn = new HashSet<>(); } @Override public GraphvizShapeVisitor visitShape(Shape shape, Map transitions) { if (!drawn.add(shape)) { return null; } String prefix = "s"; sb.append(prefix).append(getId(shape)); sb.append(" [label=\""); if (shape.getLastProperty() != null) { sb.append(escapeString(shape.getLastProperty().toString())); } else { sb.append("ROOT"); } sb.append("\""); sb.append(", shape=\"rectangle\""); if (!shape.isValid()) { sb.append(", color=\"red\", style=dotted"); } sb.append("];"); for (Entry entry : transitions.entrySet()) { Shape dst = entry.getValue(); dst.accept(this); assert drawn.contains(dst); sb.append(prefix).append(getId(shape)).append("->").append(prefix).append(getId(dst)); sb.append(" [label=\"").append(escapeString(entry.getKey().getShortName())).append("\"]"); sb.append(";"); } return this; } private static String escapeString(String str) { return str.replaceAll("\\\\", "\\\\").replaceAll("\"", "\\\\\""); } @Override public String toString() { return new StringBuilder("digraph{").append(sb).append("}").toString(); } } truffle-0.6.orig/com/oracle/truffle/object/debug/ShapeProfiler.java0000644000000000000000000001756112445312576022332 0ustar /* * Copyright (c) 2014, 2014, 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.object.debug; import java.io.*; import java.text.*; import java.util.*; import java.util.concurrent.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; public class ShapeProfiler { private static final String LINE_SEPARATOR = "***********************************************"; private static final String BULLET = "* "; private static final String TOKEN_SEPARATOR = "\t"; private final ConcurrentLinkedQueue queue; public ShapeProfiler() { queue = new ConcurrentLinkedQueue<>(); } public void track(DynamicObject obj) { queue.add(obj); } public void dump(PrintWriter out) { ShapeStats globalStats = new ShapeStats("Cumulative results for all shapes"); for (DynamicObject obj : queue) { Shape shape = obj.getShape(); globalStats.profile(shape); } globalStats.dump(out); } public void dump(PrintWriter out, int topResults) { if (topResults > 0) { IdentityHashMap shapeMap = new IdentityHashMap<>(); for (DynamicObject obj : queue) { Shape shape = obj.getShape(); ShapeStats stats = shapeMap.get(shape); if (stats == null) { shapeMap.put(shape, stats = new ShapeStats(createLabel(shape))); } stats.profile(shape); } List allStats = new ArrayList<>(shapeMap.values()); Collections.sort(allStats, new Comparator() { public int compare(ShapeStats a, ShapeStats b) { return Long.compare(b.jsObjects, a.jsObjects); } }); ShapeStats avgStats = new ShapeStats("Cumulative results for top " + topResults + " shapes"); for (int i = 0; i < topResults; i++) { ShapeStats stats = allStats.get(i); stats.setLabel("Shape " + (i + 1) + ": " + stats.getLabel()); stats.dump(out); avgStats.add(stats); } avgStats.dump(out); } // Dump also cumulative results. dump(out); } private static String createLabel(Shape shape) { String label = shape.toString(); return label.substring(label.indexOf('{') + 1, label.lastIndexOf('}')); } private static class ShapeStats { private String label; private long jsObjects; private long oac; private long oas; private long ofs; private long pac; private long pas; private long pfs; public ShapeStats(String label) { this.label = label; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public void profile(Shape shape) { jsObjects++; oac += shape.getObjectArrayCapacity(); oas += shape.getObjectArraySize(); ofs += shape.getObjectFieldSize(); pac += shape.getPrimitiveArrayCapacity(); pas += shape.getPrimitiveArraySize(); pfs += shape.getPrimitiveFieldSize(); } public void add(ShapeStats stats) { jsObjects += stats.jsObjects; oac += stats.oac; oas += stats.oas; ofs += stats.ofs; oac += stats.oac; oas += stats.oas; ofs += stats.ofs; } public void dump(PrintWriter out) { DecimalFormat format = new DecimalFormat("###.####"); out.println(LINE_SEPARATOR); out.println(BULLET + label); out.println(LINE_SEPARATOR); out.println(BULLET + "Allocated objects:\t" + jsObjects); out.println(BULLET + "Total object array capacity:\t" + oac); out.println(BULLET + "Total object array size:\t" + oas); out.println(BULLET + "Total object field size:\t" + ofs); out.println(BULLET + "Average object array capacity:\t" + avgOAC(format)); out.println(BULLET + "Average object array size:\t" + avgOAS(format)); out.println(BULLET + "Average object field size:\t" + avgOFS(format)); out.println(LINE_SEPARATOR); out.println(BULLET + "Total primitive array capacity:\t" + pac); out.println(BULLET + "Total primitive array size:\t" + pas); out.println(BULLET + "Total primitive field size:\t" + pfs); out.println(BULLET + "Average primitive array capacity:\t" + avgPAC(format)); out.println(BULLET + "Average primitive array size:\t" + avgPAS(format)); out.println(BULLET + "Average primitive field size:\t" + avgPFS(format)); out.println(LINE_SEPARATOR); out.println(BULLET + toString()); out.println(LINE_SEPARATOR + "\n"); out.flush(); } @Override public String toString() { DecimalFormat format = new DecimalFormat("###.####"); // @formatter:off return "{" + label + "}" + TOKEN_SEPARATOR + jsObjects + TOKEN_SEPARATOR + avgOAC(format) + TOKEN_SEPARATOR + avgOAS(format) + TOKEN_SEPARATOR + avgOFS(format) + TOKEN_SEPARATOR + avgPAC(format) + TOKEN_SEPARATOR + avgPAS(format) + TOKEN_SEPARATOR + avgPFS(format); // @formatter:on } private String avgOAC(DecimalFormat format) { return format.format((double) oac / jsObjects); } private String avgOAS(DecimalFormat format) { return format.format((double) oas / jsObjects); } private String avgOFS(DecimalFormat format) { return format.format((double) ofs / jsObjects); } private String avgPAC(DecimalFormat format) { return format.format((double) pac / jsObjects); } private String avgPAS(DecimalFormat format) { return format.format((double) pas / jsObjects); } private String avgPFS(DecimalFormat format) { return format.format((double) pfs / jsObjects); } } public static ShapeProfiler getInstance() { return shapeProf; } private static final ShapeProfiler shapeProf; static { if (ObjectStorageOptions.Profile) { shapeProf = new ShapeProfiler(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { getInstance().dump(new PrintWriter(System.out), ObjectStorageOptions.ProfileTopResults); } }); } else { shapeProf = null; } } } truffle-0.6.orig/com/oracle/truffle/object/debug/JSONShapeVisitor.java0000644000000000000000000000734712445312576022702 0ustar /* * Copyright (c) 2014, 2014, 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.object.debug; import java.util.*; import java.util.Map.Entry; import com.oracle.truffle.api.object.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.api.utilities.JSONHelper.JSONArrayBuilder; import com.oracle.truffle.api.utilities.JSONHelper.JSONObjectBuilder; import com.oracle.truffle.object.*; import com.oracle.truffle.object.Transition.*; public class JSONShapeVisitor extends DebugShapeVisitor { @Override public JSONObjectBuilder visitShape(Shape shape, Map transitions) { JSONObjectBuilder sb = JSONHelper.object(); JSONArrayBuilder transitionarray = JSONHelper.array(); for (Entry entry : transitions.entrySet()) { transitionarray.add(JSONHelper.object().add("transition", dumpTransition(entry.getKey())).add("successor", getId(entry.getValue()))); } JSONArrayBuilder propertiesarray = JSONHelper.array(); for (Property p : shape.getPropertyList()) { propertiesarray.add(dumpProperty(p)); } sb.add("id", getId(shape)); sb.add("properties", propertiesarray); sb.add("transitions", transitionarray); sb.add("predecessor", shape.getParent() != null ? getId(shape.getParent()) : null); sb.add("valid", shape.isValid()); return sb; } public JSONObjectBuilder dumpProperty(Property property) { return JSONHelper.object().add("id", property.getKey().toString()).add("location", dumpLocation(property.getLocation())).add("flags", property.getFlags()); } public JSONObjectBuilder dumpTransition(Transition transition) { JSONObjectBuilder sb = JSONHelper.object().add("type", transition.getShortName()); if (transition instanceof PropertyTransition) { sb.add("property", dumpProperty(((PropertyTransition) transition).getProperty())); } return sb; } public JSONObjectBuilder dumpLocation(Location location) { JSONObjectBuilder obj = JSONHelper.object(); obj.add("type", (location instanceof TypedLocation ? ((TypedLocation) location).getType() : Object.class).getName()); // if (location instanceof Locations.FieldLocation) { // obj.add("offset", ((Locations.FieldLocation) location).getOffset()); // } // if (location instanceof Locations.ArrayLocation) { // obj.add("index", ((Locations.ArrayLocation) location).getIndex()); // } if (location instanceof Locations.ValueLocation) { obj.add("value", String.valueOf(((Locations.ValueLocation) location).get(null, false))); } return obj; } } truffle-0.6.orig/com/oracle/truffle/object/Locations.java0000644000000000000000000002543212445312576020430 0ustar /* * Copyright (c) 2013, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.object.*; /** * Property location. * * @see Location * @see Shape * @see Property * @see DynamicObject */ public abstract class Locations { public abstract static class ValueLocation extends LocationImpl { private final Object value; public ValueLocation(Object value) { assert !(value instanceof Location); this.value = value; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((value == null) ? 0 : 0 /* value.hashCode() */); return result; } @Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } ValueLocation other = (ValueLocation) obj; if (value == null) { if (other.value != null) { return false; } } else if (!value.equals(other.value)) { return false; } return true; } @Override public final Object get(DynamicObject store, boolean condition) { return value; } @Override public final void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { if (!canStoreFinal(store, value)) { throw finalLocation(); } } @Override protected boolean canStoreFinal(DynamicObject store, Object val) { return valueEquals(this.value, val); } @Override public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (!canStoreFinal(store, value)) { CompilerDirectives.transferToInterpreter(); throw new UnsupportedOperationException(); } } @Override public String toString() { return "=" + String.valueOf(value); } } public static final class ConstantLocation extends ValueLocation { public ConstantLocation(Object value) { super(value); } @Override public boolean isConstant() { return true; } } public static final class DeclaredLocation extends ValueLocation { public DeclaredLocation(Object value) { super(value); } } public static class DualLocation extends LocationImpl implements TypedLocation { protected final InternalLongLocation primitiveLocation; protected final ObjectLocation objectLocation; protected final LayoutImpl layout; private final Class type; public DualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, LayoutImpl layout) { this(primitiveLocation, objectLocation, layout, null); } public DualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, LayoutImpl layout, Class type) { this.primitiveLocation = primitiveLocation; this.objectLocation = objectLocation; this.layout = layout; this.type = type; } @Override public Object get(DynamicObject store, boolean condition) { if (type == Object.class) { return objectLocation.get(store, condition); } else { long rawValue = primitiveLocation.getLong(store, condition); if (type == int.class) { return (int) rawValue; } else if (type == long.class) { return rawValue; } else if (type == double.class) { return Double.longBitsToDouble(rawValue); } else if (type == boolean.class) { return rawValue != 0; } else { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException(); } } } @Override public void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (type == Object.class) { ((LocationImpl) objectLocation).setInternal(store, value); } else { long rawValue; if (type == int.class && value instanceof Integer) { rawValue = (int) value; } else if (type == long.class && value instanceof Long) { rawValue = (long) value; } else if (type == long.class && layout.isAllowedIntToLong() && value instanceof Integer) { rawValue = (int) value; } else if (type == double.class && value instanceof Double) { rawValue = Double.doubleToRawLongBits((double) value); } else if (type == double.class && layout.isAllowedIntToDouble() && value instanceof Integer) { rawValue = Double.doubleToRawLongBits((int) value); } else if (type == boolean.class && value instanceof Boolean) { rawValue = (boolean) value ? 1 : 0; } else { throw incompatibleLocation(); } primitiveLocation.setLongInternal(store, rawValue); } } @Override public int primitiveFieldCount() { return ((LocationImpl) primitiveLocation).primitiveFieldCount(); } @Override public int primitiveArrayCount() { return ((LocationImpl) primitiveLocation).primitiveArrayCount(); } @Override public int objectFieldCount() { return ((LocationImpl) objectLocation).objectFieldCount(); } @Override public int objectArrayCount() { return ((LocationImpl) objectLocation).objectArrayCount(); } @Override public String toString() { return objectLocation.toString() + "," + primitiveLocation.toString() + "," + type; } @Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } DualLocation other = (DualLocation) obj; return getObjectLocation().equals(other.getObjectLocation()) && primitiveLocation.equals(other.primitiveLocation) && layout.equals(other.layout) && Objects.equals(type, other.type); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (getObjectLocation() == null ? 0 : getObjectLocation().hashCode()); result = prime * result + (primitiveLocation == null ? 0 : primitiveLocation.hashCode()); result = prime * result + (type == null ? 0 : type.hashCode()); return result; } public ObjectLocation getObjectLocation() { return objectLocation; } public DualLocation changeType(Class newType) { return new DualLocation(primitiveLocation, objectLocation, layout, newType); } public Class getType() { return type; } public boolean isNonNull() { return false; } @Override public boolean canStore(Object value) { if (type == null) { return false; } else if (type == int.class) { return value instanceof Integer; } else if (type == long.class) { return value instanceof Long || (layout.isAllowedIntToLong() && value instanceof Integer); } else if (type == double.class) { return value instanceof Double || (layout.isAllowedIntToDouble() && value instanceof Integer); } else if (type == boolean.class) { return value instanceof Boolean; } else if (type == Object.class) { return true; } else { throw new IllegalStateException(); } } } public static class DeclaredDualLocation extends DualLocation { private final Object defaultValue; public DeclaredDualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, Object defaultValue, LayoutImpl layout) { super(primitiveLocation, objectLocation, layout); this.defaultValue = defaultValue; } @Override public Object get(DynamicObject store, boolean condition) { return defaultValue; } @Override public void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (valueEquals(defaultValue, value)) { return; } else { throw incompatibleLocation(); } } @Override public boolean equals(Object obj) { return super.equals(obj) && Objects.equals(defaultValue, ((DeclaredDualLocation) obj).defaultValue); } @Override public int hashCode() { return super.hashCode(); } @Override public DualLocation changeType(Class newType) { return new DualLocation(primitiveLocation, objectLocation, layout, newType); } @Override public boolean canStore(Object value) { return valueEquals(defaultValue, value); } @Override public String toString() { return objectLocation.toString() + "," + primitiveLocation.toString() + ",unset"; } } } truffle-0.6.orig/com/oracle/truffle/object/DebugShapeVisitor.java0000644000000000000000000000307312445312576022061 0ustar /* * Copyright (c) 2014, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.object.*; public abstract class DebugShapeVisitor implements ShapeVisitor { public R visitShape(Shape shape) { return visitShape(shape, Collections.unmodifiableMap(((ShapeImpl) shape).getTransitionMapForRead())); } public abstract R visitShape(Shape shape, Map transitions); public static String getId(Shape shape) { return Integer.toHexString(shape.hashCode()); } } truffle-0.6.orig/com/oracle/truffle/object/Transition.java0000644000000000000000000001137112445312576020624 0ustar /* * Copyright (c) 2013, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.object.*; public abstract class Transition { @Override public int hashCode() { int result = 1; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } return true; } public abstract boolean isDirect(); public abstract static class PropertyTransition extends Transition { private final Property property; public PropertyTransition(Property property) { this.property = property; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((property == null) ? 0 : property.hashCode()); return result; } @Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } PropertyTransition other = (PropertyTransition) obj; if (!Objects.equals(property, other.property)) { return false; } return true; } public Property getProperty() { return property; } } public static final class AddPropertyTransition extends PropertyTransition { public AddPropertyTransition(Property property) { super(property); } @Override public boolean isDirect() { return true; } } public static final class RemovePropertyTransition extends PropertyTransition { public RemovePropertyTransition(Property property) { super(property); } @Override public boolean isDirect() { return false; } } public static final class ObjectTypeTransition extends Transition { private final ObjectType objectType; public ObjectTypeTransition(ObjectType objectType) { this.objectType = objectType; } public ObjectType getObjectType() { return objectType; } @Override public boolean equals(Object other) { return super.equals(other) && Objects.equals(objectType, ((ObjectTypeTransition) other).objectType); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((objectType == null) ? 0 : objectType.hashCode()); return result; } @Override public boolean isDirect() { return true; } } public static final class ReplacePropertyTransition extends PropertyTransition { private final Property after; public ReplacePropertyTransition(Property before, Property after) { super(before); this.after = after; } public Property getPropertyBefore() { return this.getProperty(); } public Property getPropertyAfter() { return after; } @Override public boolean isDirect() { return false; } } public static final class ReservePrimitiveArrayTransition extends Transition { public ReservePrimitiveArrayTransition() { } @Override public boolean isDirect() { return true; } } public String getShortName() { return this.getClass().getSimpleName().replaceFirst("Transition$", "").toLowerCase(); } } truffle-0.6.orig/com/oracle/truffle/object/Debug.java0000644000000000000000000000474512445312576017527 0ustar /* * Copyright (c) 2014, 2014, 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.object; import java.io.*; import java.util.*; import java.util.concurrent.*; import com.oracle.truffle.object.debug.*; class Debug { private static Collection allShapes; static void registerShape(ShapeImpl newShape) { allShapes.add(newShape); } static { if (ObjectStorageOptions.DumpShapes) { allShapes = new ConcurrentLinkedQueue<>(); } if (ObjectStorageOptions.DumpShapes) { Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { try (PrintWriter out = new PrintWriter("shapes.json", "UTF-8")) { out.println("{\"shapes\": ["); boolean first = true; for (ShapeImpl shape : allShapes) { if (!first) { out.println(","); } first = false; out.print(shape.accept(new JSONShapeVisitor())); } if (!first) { out.println(); } out.println("]}"); } catch (FileNotFoundException | UnsupportedEncodingException e) { throw new RuntimeException(e); } } })); } } } truffle-0.6.orig/com/oracle/truffle/object/ObjectStorageOptions.java0000644000000000000000000000514312445312576022601 0ustar /* * Copyright (c) 2012, 2014, 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.object; import static com.oracle.truffle.api.object.Layout.*; public class ObjectStorageOptions { // Shape configuration /** Primitive location switch. */ public static boolean PrimitiveLocations = booleanOption(OPTION_PREFIX + "PrimitiveLocations", true); public static boolean IntegerLocations = booleanOption(OPTION_PREFIX + "IntegerLocations", true); public static boolean DoubleLocations = booleanOption(OPTION_PREFIX + "DoubleLocations", true); public static boolean LongLocations = booleanOption(OPTION_PREFIX + "LongLocations", true); public static boolean BooleanLocations = booleanOption(OPTION_PREFIX + "BooleanLocations", true); public static boolean TypedObjectLocations = booleanOption(OPTION_PREFIX + "TypedObjectLocations", true); /** Allocation of in-object fields. */ public static boolean InObjectFields = booleanOption(OPTION_PREFIX + "InObjectFields", true); // Debug options (should be final) public static final boolean TraceReshape = booleanOption(OPTION_PREFIX + "TraceReshape", false); public static final boolean DumpShapes = booleanOption(OPTION_PREFIX + "DumpShapes", false); public static final boolean Profile = booleanOption(OPTION_PREFIX + "Profile", false); public static final int ProfileTopResults = Integer.getInteger(OPTION_PREFIX + "ProfileTopResults", -1); public static boolean booleanOption(String name, boolean defaultValue) { String value = System.getProperty(name); return value == null ? defaultValue : value.equalsIgnoreCase("true"); } } truffle-0.6.orig/com/oracle/truffle/object/PropertyMap.java0000644000000000000000000002600612445312576020755 0ustar /* * Copyright (c) 2014, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.object.*; public final class PropertyMap implements Map { private final PropertyMap car; private final Property cdr; private final int size; private static final PropertyMap EMPTY = new PropertyMap(); private PropertyMap() { this.car = null; this.cdr = null; this.size = 0; } private PropertyMap(PropertyMap parent, Property added) { this.car = Objects.requireNonNull(parent); this.cdr = added; this.size = parent.size + 1; } public static PropertyMap empty() { return EMPTY; } public int size() { return size; } public boolean isEmpty() { return size() == 0; } public boolean containsKey(Object key) { for (Map.Entry entry : reverseOrderEntrySet()) { if (entry.getKey().equals(key)) { return true; } } return false; } public boolean containsValue(Object value) { for (Map.Entry entry : reverseOrderEntrySet()) { if (entry.getValue().equals(value)) { return true; } } return false; } public Property get(Object key) { for (Map.Entry entry : reverseOrderEntrySet()) { if (entry.getKey().equals(key)) { return entry.getValue(); } } return null; } public Property put(Object key, Property value) { throw unmodifiableException(); } public Property remove(Object key) { throw unmodifiableException(); } public void putAll(Map m) { throw unmodifiableException(); } public void clear() { throw unmodifiableException(); } public Set keySet() { return new AbstractSet() { @Override public Iterator iterator() { Object[] keys = new Object[size()]; Iterator> iterator = reverseOrderEntrySet().iterator(); for (int pos = size() - 1; pos >= 0; pos--) { keys[pos] = iterator.next().getKey(); } return Arrays.asList(keys).iterator(); } @Override public int size() { return PropertyMap.this.size(); } }; } public Collection values() { return new AbstractSet() { @Override public Iterator iterator() { Property[] values = new Property[size()]; Iterator> iterator = reverseOrderEntrySet().iterator(); for (int pos = size() - 1; pos >= 0; pos--) { values[pos] = iterator.next().getValue(); } return Arrays.asList(values).iterator(); } @Override public int size() { return PropertyMap.this.size(); } }; } public Set> entrySet() { return new AbstractSet>() { @Override public Iterator> iterator() { @SuppressWarnings("unchecked") Map.Entry[] entries = (Map.Entry[]) new Map.Entry[size()]; Iterator> iterator = reverseOrderEntrySet().iterator(); for (int pos = size() - 1; pos >= 0; pos--) { entries[pos] = iterator.next(); } return Arrays.asList(entries).iterator(); } @Override public int size() { return PropertyMap.this.size(); } }; } public Set> reverseOrderEntrySet() { return new AbstractSet>() { @Override public Iterator> iterator() { return new Iterator>() { PropertyMap current = PropertyMap.this; public Entry next() { if (hasNext()) { try { return new MapEntryImpl(current.cdr); } finally { current = current.car; } } else { throw new NoSuchElementException(); } } public boolean hasNext() { return current != empty(); } public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int size() { return PropertyMap.this.size(); } }; } public Set reverseOrderKeys() { return new AbstractSet() { @Override public Iterator iterator() { return new Iterator() { PropertyMap current = PropertyMap.this; public Object next() { if (hasNext()) { try { return current.cdr.getKey(); } finally { current = current.car; } } else { throw new NoSuchElementException(); } } public boolean hasNext() { return current != empty(); } public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int size() { return PropertyMap.this.size(); } }; } public Set reverseOrderValues() { return new AbstractSet() { @Override public Iterator iterator() { return new Iterator() { PropertyMap current = PropertyMap.this; public Property next() { if (hasNext()) { try { return current.cdr; } finally { current = current.car; } } else { throw new NoSuchElementException(); } } public boolean hasNext() { return current != empty(); } public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int size() { return PropertyMap.this.size(); } }; } private static final class MapEntryImpl implements Map.Entry { private final Property backingProperty; public MapEntryImpl(Property backingProperty) { this.backingProperty = backingProperty; } public Object getKey() { return backingProperty.getKey(); } public Property getValue() { return backingProperty; } public Property setValue(Property value) { throw unmodifiableException(); } } private static UnsupportedOperationException unmodifiableException() { throw new UnsupportedOperationException("unmodifiable"); } public PropertyMap putCopy(Property value) { assert !this.containsValue(value); return new PropertyMap(this, value); } public PropertyMap removeCopy(Property value) { LinkedList shelve = new LinkedList<>(); PropertyMap current = this; while (!current.isEmpty()) { if (current.getLastProperty().equals(value)) { PropertyMap newMap = current.getParentMap(); for (Property property : shelve) { newMap = newMap.putCopy(property); } return newMap; } else { shelve.push(current.getLastProperty()); current = current.getParentMap(); } } return this; } public PropertyMap replaceCopy(Property oldValue, Property newValue) { LinkedList shelve = new LinkedList<>(); PropertyMap current = this; while (!current.isEmpty()) { if (current.getLastProperty().equals(oldValue)) { PropertyMap newMap = current.getParentMap(); newMap = newMap.putCopy(newValue); for (Property property : shelve) { newMap = newMap.putCopy(property); } return newMap; } else { shelve.push(current.getLastProperty()); current = current.getParentMap(); } } return this; } public PropertyMap getOwningMap(Property value) { PropertyMap current = this; while (!current.isEmpty()) { if (current.getLastProperty().equals(value)) { return current; } current = current.getParentMap(); } return null; } PropertyMap getParentMap() { return car; } public Property getLastProperty() { return cdr; } } truffle-0.6.orig/com/oracle/truffle/object/ShapeImpl.java0000644000000000000000000011662312445312576020362 0ustar /* * Copyright (c) 2012, 2014, 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.object; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.object.LocationImpl.InternalLongLocation; import com.oracle.truffle.object.Locations.ConstantLocation; import com.oracle.truffle.object.Locations.DeclaredDualLocation; import com.oracle.truffle.object.Locations.DeclaredLocation; import com.oracle.truffle.object.Locations.DualLocation; import com.oracle.truffle.object.Locations.ValueLocation; import com.oracle.truffle.object.Transition.AddPropertyTransition; import com.oracle.truffle.object.Transition.ObjectTypeTransition; import com.oracle.truffle.object.Transition.PropertyTransition; import com.oracle.truffle.object.Transition.RemovePropertyTransition; import com.oracle.truffle.object.Transition.ReservePrimitiveArrayTransition; /** * Shape objects create a mapping of Property objects to indexes. The mapping of those indexes to an * actual store is not part of Shape's role, but JSObject's. Shapes are immutable; adding or * deleting a property yields a new Shape which links to the old one. This allows inline caching to * simply check the identity of an object's Shape to determine if the cache is valid. There is one * exception to this immutability, the transition map, but that is used simply to assure that an * identical series of property additions and deletions will yield the same Shape object. * * @see DynamicObject * @see Property * @see Locations */ public abstract class ShapeImpl extends Shape { private final int id; protected final LayoutImpl layout; protected final ObjectType objectType; protected final ShapeImpl parent; protected final PropertyMap propertyMap; private final Object extraData; private final Object sharedData; private final ShapeImpl root; protected final int objectArraySize; protected final int objectArrayCapacity; protected final int objectFieldSize; protected final int primitiveFieldSize; protected final int primitiveArraySize; protected final int primitiveArrayCapacity; protected final boolean hasPrimitiveArray; protected final int depth; protected final int propertyCount; protected Property[] propertyArray; protected final Assumption validAssumption; @CompilationFinal protected volatile Assumption leafAssumption; /** * Shape transition map; lazily initialized. * * @see #getTransitionMapForRead() * @see #getTransitionMapForWrite() */ private HashMap transitionMap; private final Transition transitionFromParent; /** * Private constructor. * * @param parent predecessor shape * @param transitionFromParent direct transition from parent shape * @see #ShapeImpl(Layout, ShapeImpl, ObjectType, Object, PropertyMap, Transition, * BaseAllocator, int) */ private ShapeImpl(Layout layout, ShapeImpl parent, ObjectType objectType, Object sharedData, PropertyMap propertyMap, Transition transitionFromParent, int objectArraySize, int objectFieldSize, int primitiveFieldSize, int primitiveArraySize, boolean hasPrimitiveArray, int id) { this.layout = (LayoutImpl) layout; this.objectType = Objects.requireNonNull(objectType); this.propertyMap = Objects.requireNonNull(propertyMap); this.root = parent != null ? parent.getRoot() : this; this.parent = parent; this.transitionFromParent = transitionFromParent; this.objectArraySize = objectArraySize; this.objectArrayCapacity = capacityFromSize(objectArraySize); this.objectFieldSize = objectFieldSize; this.primitiveFieldSize = primitiveFieldSize; this.primitiveArraySize = primitiveArraySize; this.primitiveArrayCapacity = capacityFromSize(primitiveArraySize); this.hasPrimitiveArray = hasPrimitiveArray; if (parent != null) { this.propertyCount = makePropertyCount(parent, propertyMap); this.propertyArray = makePropertiesList(parent, propertyMap); this.depth = parent.depth + 1; } else { this.propertyCount = 0; this.propertyArray = null; this.depth = 0; } this.validAssumption = createValidAssumption(); this.id = id; shapeCount.inc(); this.sharedData = sharedData; this.extraData = objectType.createShapeData(this); debugRegisterShape(this); } protected ShapeImpl(Layout layout, ShapeImpl parent, ObjectType operations, Object sharedData, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { this(layout, parent, operations, sharedData, propertyMap, transition, ((BaseAllocator) allocator).objectArraySize, ((BaseAllocator) allocator).objectFieldSize, ((BaseAllocator) allocator).primitiveFieldSize, ((BaseAllocator) allocator).primitiveArraySize, ((BaseAllocator) allocator).hasPrimitiveArray, id); } @SuppressWarnings("hiding") protected abstract ShapeImpl createShape(Layout layout, Object sharedData, ShapeImpl parent, ObjectType operations, PropertyMap propertyMap, Transition transition, Allocator allocator, int id); protected ShapeImpl(Layout layout, ObjectType operations, Object sharedData, int id) { this(layout, null, operations, sharedData, PropertyMap.empty(), null, layout.createAllocator(), id); } private static int makePropertyCount(ShapeImpl parent, PropertyMap propertyMap) { return parent.propertyCount + ((propertyMap.size() > parent.propertyMap.size() && !propertyMap.getLastProperty().isHidden() && !propertyMap.getLastProperty().isShadow()) ? 1 : 0); } private static Property[] makePropertiesList(ShapeImpl parent, PropertyMap propertyMap) { Property[] properties = parent.propertyArray; if (properties != null && propertyMap.size() != parent.propertyMap.size()) { Property lastProperty = propertyMap.getLastProperty(); if (lastProperty != null && !lastProperty.isHidden()) { propertyListAllocCount.inc(); if (!lastProperty.isShadow()) { properties = Arrays.copyOf(properties, properties.length + 1); properties[properties.length - 1] = lastProperty; } else { properties = Arrays.copyOf(properties, properties.length); for (int i = 0; i < properties.length; i++) { if (properties[i].isSame(lastProperty)) { properties[i] = lastProperty; } } } } else { propertyListShareCount.inc(); } } return properties; } @Override public final Property getLastProperty() { return propertyMap.getLastProperty(); } @Override public final int getId() { return this.id; } /** * Calculate array size for the given number of elements. */ private static int capacityFromSize(int size) { if (size == 0) { return 0; } else if (size < 4) { return 4; } else if (size < 32) { return ((size + 7) / 8) * 8; } else { return ((size + 15) / 16) * 16; } } @Override public final int getObjectArraySize() { return objectArraySize; } @Override public final int getObjectFieldSize() { return objectFieldSize; } @Override public final int getPrimitiveFieldSize() { return primitiveFieldSize; } @Override public final int getObjectArrayCapacity() { return objectArrayCapacity; } @Override public final int getPrimitiveArrayCapacity() { return primitiveArrayCapacity; } @Override public final int getPrimitiveArraySize() { return primitiveArraySize; } @Override public final boolean hasPrimitiveArray() { return hasPrimitiveArray; } /** * Get the (parent) shape that holds the given property. */ public final ShapeImpl getShapeFromProperty(Object propertyName) { ShapeImpl current = this; while (current != getRoot()) { if (current.getTransitionFromParent() instanceof AddPropertyTransition && ((AddPropertyTransition) current.getTransitionFromParent()).getProperty().getKey().equals(propertyName)) { return current; } current = current.getParent(); } return null; } /** * Get the (parent) shape that holds the given property. */ public final ShapeImpl getShapeFromProperty(Property prop) { ShapeImpl current = this; while (current != getRoot()) { if (current.getTransitionFromParent() instanceof AddPropertyTransition && ((AddPropertyTransition) current.getTransitionFromParent()).getProperty().equals(prop)) { return current; } current = current.parent; } return null; } /** * Get a property entry by string name. * * @param key the name to look up * @return a Property object, or null if not found */ @Override @TruffleBoundary public final Property getProperty(Object key) { // return this.propertyMap.get(propertyName); PropertyMap current = this.propertyMap; while (current.getLastProperty() != null) { if (current.getLastProperty().getKey().equals(key)) { return current.getLastProperty(); } current = current.getParentMap(); } return null; } protected final void addDirectTransition(Transition transition, ShapeImpl next) { assert next.getParent() == this && transition.isDirect(); addTransitionInternal(transition, next); } public final void addIndirectTransition(Transition transition, ShapeImpl next) { assert next.getParent() != this && !transition.isDirect(); addTransitionInternal(transition, next); } private void addTransitionInternal(Transition transition, ShapeImpl next) { getTransitionMapForWrite().put(transition, next); } public final Map getTransitionMapForRead() { return transitionMap != null ? transitionMap : Collections. emptyMap(); } private Map getTransitionMapForWrite() { if (transitionMap != null) { return transitionMap; } else { invalidateLeafAssumption(); return transitionMap = new HashMap<>(); } } public final PropertyMap getPropertyMap() { return propertyMap; } private ShapeImpl queryTransition(Transition transition) { ShapeImpl cachedShape = this.getTransitionMapForRead().get(transition); if (cachedShape != null) { // Shape already exists? shapeCacheHitCount.inc(); return (ShapeImpl) layout.getStrategy().returnCached(cachedShape); } shapeCacheMissCount.inc(); return null; } /** * Add a new property in the map, yielding a new or cached Shape object. * * @param property the property to add * @return the new Shape */ @TruffleBoundary @Override public ShapeImpl addProperty(Property property) { assert isValid(); ShapeImpl nextShape = addPropertyInternal(property); objectType.onPropertyAdded(property, this, nextShape); return nextShape; } /** * Add a new property in the map, yielding a new or cached Shape object. * * In contrast to {@link ShapeImpl#addProperty(Property)}, this method does not care about * obsolete shapes. * * @see #addProperty(Property) */ private ShapeImpl addPropertyInternal(Property prop) { CompilerAsserts.neverPartOfCompilation(); assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property"; assert !getPropertyListInternal(false).contains(prop); // invalidatePropertyAssumption(prop.getName()); AddPropertyTransition addTransition = new AddPropertyTransition(prop); ShapeImpl cachedShape = queryTransition(addTransition); if (cachedShape != null) { return cachedShape; } ShapeImpl oldShape = (ShapeImpl) layout.getStrategy().ensureSpace(this, prop.getLocation()); ShapeImpl newShape = makeShapeWithAddedProperty(oldShape, addTransition); oldShape.addDirectTransition(addTransition, newShape); return newShape; } protected ShapeImpl cloneRoot(ShapeImpl from, Object newSharedData) { return createShape(from.layout, newSharedData, null, from.objectType, from.propertyMap, null, from.allocator(), from.id); } /** * Create a separate clone of a shape. * * @param newParent the cloned parent shape */ protected final ShapeImpl cloneOnto(ShapeImpl newParent) { ShapeImpl from = this; ShapeImpl newShape = createShape(newParent.layout, newParent.sharedData, newParent, from.objectType, from.propertyMap, from.transitionFromParent, from.allocator(), newParent.id); shapeCloneCount.inc(); // (aw) need to have this transition for obsolescence newParent.addDirectTransition(from.transitionFromParent, newShape); return newShape; } public final Transition getTransitionFromParent() { return transitionFromParent; } /** * Create a new shape that adds a property to the parent shape. */ private static ShapeImpl makeShapeWithAddedProperty(ShapeImpl parent, AddPropertyTransition addTransition) { Property addend = addTransition.getProperty(); BaseAllocator allocator = parent.allocator().addLocation(addend.getLocation()); PropertyMap newPropertyMap = parent.propertyMap.putCopy(addend); ShapeImpl newShape = parent.createShape(parent.layout, parent.sharedData, parent, parent.objectType, newPropertyMap, addTransition, allocator, parent.id); assert ((LocationImpl) addend.getLocation()).primitiveArrayCount() == 0 || newShape.hasPrimitiveArray; assert newShape.depth == allocator.depth; return newShape; } /** * Create a new shape that reserves the primitive extension array field. */ private static ShapeImpl makeShapeWithPrimitiveExtensionArray(ShapeImpl parent, Transition transition) { assert parent.getLayout().hasPrimitiveExtensionArray(); assert !parent.hasPrimitiveArray(); BaseAllocator allocator = parent.allocator().addLocation(parent.getLayout().getPrimitiveArrayLocation()); ShapeImpl newShape = parent.createShape(parent.layout, parent.sharedData, parent, parent.objectType, parent.propertyMap, transition, allocator, parent.id); assert newShape.hasPrimitiveArray(); assert newShape.depth == allocator.depth; return newShape; } private ShapeImpl addPrimitiveExtensionArray() { assert layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray(); Transition transition = new ReservePrimitiveArrayTransition(); ShapeImpl cachedShape = queryTransition(transition); if (cachedShape != null) { return cachedShape; } ShapeImpl oldShape = (ShapeImpl) layout.getStrategy().ensureSpace(this, layout.getPrimitiveArrayLocation()); ShapeImpl newShape = makeShapeWithPrimitiveExtensionArray(oldShape, transition); oldShape.addDirectTransition(transition, newShape); return newShape; } /** * Are these two shapes related, i.e. do they have the same root? * * @param other Shape to compare to * @return true if one shape is an upcast of the other, or the Shapes are equal */ @Override public boolean isRelated(Shape other) { if (this == other) { return true; } if (this.getRoot() == getRoot()) { return true; } return false; } /** * Get a list of all properties that this Shape stores. * * @return list of properties */ @TruffleBoundary @Override public final List getPropertyList(Pred filter) { LinkedList props = new LinkedList<>(); next: for (Property currentProperty : this.propertyMap.reverseOrderValues()) { if (!currentProperty.isHidden() && filter.test(currentProperty)) { if (currentProperty.getLocation() instanceof DeclaredLocation) { for (Iterator iter = props.iterator(); iter.hasNext();) { Property other = iter.next(); if (other.isShadow() && other.getKey().equals(currentProperty.getKey())) { iter.remove(); props.addFirst(other); continue next; } } } props.addFirst(currentProperty); } } return props; } @Override public final List getPropertyList() { return getPropertyList(ALL); } /** * Returns all (also hidden) Property objects in this shape. * * @param ascending desired order */ @TruffleBoundary @Override public final List getPropertyListInternal(boolean ascending) { LinkedList props = new LinkedList<>(); for (Property current : this.propertyMap.reverseOrderValues()) { if (ascending) { props.addFirst(current); } else { props.add(current); } } return props; } /** * Get a list of all (visible) property names in insertion order. * * @return list of property names */ @TruffleBoundary @Override public final List getKeyList(Pred filter) { LinkedList keys = new LinkedList<>(); for (Property currentProperty : this.propertyMap.reverseOrderValues()) { if (!currentProperty.isHidden() && filter.test(currentProperty) && !currentProperty.isShadow()) { keys.addFirst(currentProperty.getKey()); } } return keys; } @Override public final List getKeyList() { return getKeyList(ALL); } @Override public Iterable getKeys() { return getKeyList(); } @Override public final boolean isValid() { return getValidAssumption().isValid(); } @Override public final Assumption getValidAssumption() { return validAssumption; } private static Assumption createValidAssumption() { return Truffle.getRuntime().createAssumption("valid shape"); } public final void invalidateValidAssumption() { getValidAssumption().invalidate(); } @Override public final boolean isLeaf() { return leafAssumption == null || leafAssumption.isValid(); } @Override public final Assumption getLeafAssumption() { if (leafAssumption == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); synchronized (getMutex()) { if (leafAssumption == null) { leafAssumption = isLeafHelper() ? createLeafAssumption() : NeverValidAssumption.INSTANCE; } } } return leafAssumption; } private boolean isLeafHelper() { return getTransitionMapForRead().isEmpty(); } private static Assumption createLeafAssumption() { return Truffle.getRuntime().createAssumption("leaf shape"); } private void invalidateLeafAssumption() { Assumption assumption = leafAssumption; if (assumption != null) { assumption.invalidate(); } else { leafAssumption = NeverValidAssumption.INSTANCE; } } @Override public String toString() { return toStringLimit(Integer.MAX_VALUE); } @TruffleBoundary public String toStringLimit(int limit) { StringBuilder sb = new StringBuilder(); sb.append('@'); sb.append(Integer.toHexString(hashCode())); if (!isValid()) { sb.append('!'); } sb.append("{"); for (Iterator iterator = propertyMap.reverseOrderValues().iterator(); iterator.hasNext();) { Property p = iterator.next(); sb.append(p); if (iterator.hasNext()) { sb.append(", "); } if (sb.length() >= limit) { sb.append("..."); break; } sb.append("\n"); } sb.append("}"); return sb.toString(); } @Override public final ShapeImpl getParent() { return parent; } public final int getDepth() { return depth; } @Override public final boolean hasProperty(Object name) { return getProperty(name) != null; } @TruffleBoundary @Override public final ShapeImpl removeProperty(Property prop) { RemovePropertyTransition transition = new RemovePropertyTransition(prop); ShapeImpl cachedShape = queryTransition(transition); if (cachedShape != null) { return cachedShape; } ShapeImpl shape = getShapeFromProperty(prop); if (shape != null) { List transitionList = new ArrayList<>(); ShapeImpl current = this; while (current != shape) { transitionList.add(current.getTransitionFromParent()); current = current.parent; } ShapeImpl newShape = shape.parent; for (ListIterator iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { Transition previous = iterator.previous(); newShape = newShape.applyTransition(previous, true); } getTransitionMapForWrite().put(transition, newShape); return newShape; } else { return null; } } @TruffleBoundary @Override public final ShapeImpl append(Property oldProperty) { return addProperty(oldProperty.relocate(allocator().moveLocation(oldProperty.getLocation()))); } public final ShapeImpl applyTransition(Transition transition, boolean append) { if (transition instanceof AddPropertyTransition) { return append ? append(((AddPropertyTransition) transition).getProperty()) : addProperty(((AddPropertyTransition) transition).getProperty()); } else if (transition instanceof ObjectTypeTransition) { return changeType(((ObjectTypeTransition) transition).getObjectType()); } else if (transition instanceof ReservePrimitiveArrayTransition) { return reservePrimitiveExtensionArray(); } else { throw new UnsupportedOperationException(); } } @Override public final BaseAllocator allocator() { return layout.getStrategy().createAllocator(this); } /** * Duplicate shape exchanging existing property with new property. */ @Override public final ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { Transition replacePropertyTransition = new Transition.ReplacePropertyTransition(oldProperty, newProperty); ShapeImpl cachedShape = queryTransition(replacePropertyTransition); if (cachedShape != null) { return cachedShape; } ShapeImpl top = this; List transitionList = new ArrayList<>(); boolean found = false; while (top != getRoot() && !found) { Transition transition = top.getTransitionFromParent(); transitionList.add(transition); if (transition instanceof AddPropertyTransition && ((AddPropertyTransition) transition).getProperty().getKey().equals(newProperty.getKey())) { found = true; } top = top.parent; } ShapeImpl newShape = top; for (ListIterator iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { Transition transition = iterator.previous(); if (transition instanceof AddPropertyTransition && ((AddPropertyTransition) transition).getProperty().getKey().equals(newProperty.getKey())) { newShape = newShape.addProperty(newProperty); } else { newShape = newShape.applyTransition(transition, false); } } addIndirectTransition(replacePropertyTransition, newShape); return newShape; } /** * Find lowest common ancestor of two related shapes. */ public static ShapeImpl findCommonAncestor(ShapeImpl left, ShapeImpl right) { if (!left.isRelated(right)) { throw new IllegalArgumentException("shapes must have the same root"); } else if (left == right) { return left; } int leftLength = left.depth; int rightLength = right.depth; ShapeImpl leftPtr = left; ShapeImpl rightPtr = right; while (leftLength > rightLength) { leftPtr = leftPtr.parent; leftLength--; } while (rightLength > leftLength) { rightPtr = rightPtr.parent; rightLength--; } while (leftPtr != rightPtr) { leftPtr = leftPtr.parent; rightPtr = rightPtr.parent; } return leftPtr; } /** * For copying over properties after exchanging the prototype of an object. */ @TruffleBoundary @Override public final ShapeImpl copyOverPropertiesInternal(Shape destination) { assert ((ShapeImpl) destination).getDepth() == 0; List properties = this.getPropertyListInternal(true); ShapeImpl newShape = ((ShapeImpl) destination).addPropertiesInternal(properties); return newShape; } private ShapeImpl addPropertiesInternal(List properties) { ShapeImpl newShape = this; for (Property p : properties) { newShape = newShape.addPropertyInternal(p); } return newShape; } @Override public final int getPropertyCount() { return propertyCount; } /** * Find difference between two shapes. * * @see ObjectStorageOptions#TraceReshape */ public static List diff(Shape oldShape, Shape newShape) { List oldList = oldShape.getPropertyListInternal(false); List newList = newShape.getPropertyListInternal(false); List diff = new ArrayList<>(oldList); diff.addAll(newList); List intersection = new ArrayList<>(oldList); intersection.retainAll(newList); diff.removeAll(intersection); return diff; } @Override public ObjectType getObjectType() { return objectType; } @Override public ShapeImpl getRoot() { return root; } @Override public final boolean check(DynamicObject subject) { return subject.getShape() == this; } @Override public final LayoutImpl getLayout() { return layout; } @Override public final Object getData() { return extraData; } @Override public final Object getSharedData() { return sharedData; } @TruffleBoundary @Override public final boolean hasTransitionWithKey(Object key) { for (Transition transition : getTransitionMapForRead().keySet()) { if (transition instanceof PropertyTransition) { if (((PropertyTransition) transition).getProperty().getKey().equals(key)) { return true; } } } return false; } /** * Clone off a separate shape with new shared data. */ @TruffleBoundary @Override public final ShapeImpl createSeparateShape(Object newSharedData) { if (parent == null) { return cloneRoot(this, newSharedData); } else { return this.cloneOnto(parent.createSeparateShape(newSharedData)); } } @Override @TruffleBoundary public final ShapeImpl changeType(ObjectType newOps) { ObjectTypeTransition transition = new ObjectTypeTransition(newOps); ShapeImpl cachedShape = queryTransition(transition); if (cachedShape != null) { return cachedShape; } ShapeImpl newShape = createShape(layout, sharedData, this, newOps, propertyMap, transition, allocator(), id); addDirectTransition(transition, newShape); return newShape; } @Override public final ShapeImpl reservePrimitiveExtensionArray() { if (layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray()) { return addPrimitiveExtensionArray(); } return this; } @Override public final Iterable getProperties() { if (getPropertyCount() != 0 && propertyArray == null) { CompilerDirectives.transferToInterpreter(); propertyArray = createPropertiesArray(); } return new Iterable() { public Iterator iterator() { return new Iterator() { private int cursor; public boolean hasNext() { return cursor < getPropertyCount(); } public Property next() { if (hasNext()) { return propertyArray[cursor++]; } throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }; } }; } private Property[] createPropertiesArray() { propertyListAllocCount.inc(); Property[] propertiesArray = new Property[getPropertyCount()]; List ownProperties = getPropertyList(ALL); assert ownProperties.size() == getPropertyCount(); for (int i = 0; i < getPropertyCount(); i++) { propertiesArray[i] = ownProperties.get(i); } return propertiesArray; } @Override public final DynamicObject newInstance() { return layout.newInstance(this); } @Override public final DynamicObjectFactory createFactory() { final List properties = getPropertyListInternal(true); for (Iterator iterator = properties.iterator(); iterator.hasNext();) { Property property = iterator.next(); // skip non-instance fields assert property.getLocation() != layout.getPrimitiveArrayLocation(); if (property.getLocation() instanceof ValueLocation) { iterator.remove(); } } return new DynamicObjectFactory() { @CompilationFinal private final PropertyImpl[] instanceFields = properties.toArray(new PropertyImpl[properties.size()]); @ExplodeLoop public DynamicObject newInstance(Object... initialValues) { DynamicObject store = ShapeImpl.this.newInstance(); for (int i = 0; i < instanceFields.length; i++) { instanceFields[i].setInternal(store, initialValues[i]); } return store; } public Shape getShape() { return ShapeImpl.this; } }; } @Override public Object getMutex() { return getRoot(); } @Override public Shape tryMerge(Shape other) { return null; } public abstract static class BaseAllocator extends Allocator { protected final LayoutImpl layout; protected int objectArraySize; protected int objectFieldSize; protected int primitiveFieldSize; protected int primitiveArraySize; protected boolean hasPrimitiveArray; protected int depth; protected BaseAllocator(LayoutImpl layout) { this.layout = layout; } protected BaseAllocator(ShapeImpl shape) { this(shape.getLayout()); this.objectArraySize = shape.objectArraySize; this.objectFieldSize = shape.objectFieldSize; this.primitiveFieldSize = shape.primitiveFieldSize; this.primitiveArraySize = shape.primitiveArraySize; this.hasPrimitiveArray = shape.hasPrimitiveArray; this.depth = shape.depth; } protected abstract Location moveLocation(Location oldLocation); protected abstract Location newObjectLocation(boolean useFinal, boolean nonNull); protected abstract Location newTypedObjectLocation(boolean useFinal, Class type, boolean nonNull); protected abstract Location newIntLocation(boolean useFinal); protected abstract Location newDoubleLocation(boolean useFinal); protected abstract Location newLongLocation(boolean useFinal); protected abstract Location newBooleanLocation(boolean useFinal); @Override public final Location constantLocation(Object value) { return new ConstantLocation(value); } @Override protected Location locationForValue(Object value, boolean useFinal, boolean nonNull) { if (value instanceof Integer) { return newIntLocation(useFinal); } else if (value instanceof Double) { return newDoubleLocation(useFinal); } else if (value instanceof Long) { return newLongLocation(useFinal); } else if (value instanceof Boolean) { return newBooleanLocation(useFinal); } else if (ObjectStorageOptions.TypedObjectLocations && value != null) { return newTypedObjectLocation(useFinal, value.getClass(), nonNull); } return newObjectLocation(useFinal, nonNull && value != null); } protected abstract Location locationForValueUpcast(Object value, Location oldLocation); @Override protected Location locationForType(Class type, boolean useFinal, boolean nonNull) { if (type == int.class) { return newIntLocation(useFinal); } else if (type == double.class) { return newDoubleLocation(useFinal); } else if (type == long.class) { return newLongLocation(useFinal); } else if (type == boolean.class) { return newBooleanLocation(useFinal); } else if (ObjectStorageOptions.TypedObjectLocations && type != null && type != Object.class) { assert !type.isPrimitive() : "unsupported primitive type"; return newTypedObjectLocation(useFinal, type, nonNull); } return newObjectLocation(useFinal, nonNull); } protected Location newDualLocation(Class type) { return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, type); } protected DualLocation newDualLocationForValue(Object value) { Class initialType = null; if (value instanceof Integer) { initialType = int.class; } else if (value instanceof Double) { initialType = double.class; } else if (value instanceof Boolean) { initialType = boolean.class; } else { initialType = Object.class; } return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, initialType); } protected Location newDeclaredDualLocation(Object value) { return new DeclaredDualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), value, layout); } protected T advance(T location0) { if (location0 instanceof LocationImpl) { LocationImpl location = (LocationImpl) location0; objectArraySize += location.objectArrayCount(); primitiveArraySize += location.primitiveArrayCount(); primitiveFieldSize += location.primitiveFieldCount(); if (layout.hasPrimitiveExtensionArray()) { hasPrimitiveArray |= location == layout.getPrimitiveArrayLocation() || location.primitiveArrayCount() != 0; objectFieldSize = location == layout.getPrimitiveArrayLocation() ? objectFieldSize : Math.max(objectFieldSize, layout.objectFieldIndex(location) + location.objectFieldCount()); } else { assert !hasPrimitiveArray && location.primitiveArrayCount() == 0; objectFieldSize += location.objectFieldCount(); } } depth++; return location0; } @Override public BaseAllocator addLocation(Location location) { advance(location); return this; } } private static void debugRegisterShape(ShapeImpl newShape) { if (ObjectStorageOptions.DumpShapes) { Debug.registerShape(newShape); } } /** * Match all filter. */ public static final Pred ALL = new Pred() { public boolean test(Property t) { return true; } }; private static final DebugCounter shapeCount = DebugCounter.create("Shapes allocated total"); private static final DebugCounter shapeCloneCount = DebugCounter.create("Shapes allocated cloned"); private static final DebugCounter shapeCacheHitCount = DebugCounter.create("Shape cache hits"); private static final DebugCounter shapeCacheMissCount = DebugCounter.create("Shape cache misses"); protected static final DebugCounter propertyListAllocCount = DebugCounter.create("Property lists allocated"); protected static final DebugCounter propertyListShareCount = DebugCounter.create("Property lists shared"); } truffle-0.6.orig/com/oracle/truffle/object/LayoutStrategy.java0000644000000000000000000000325212445312576021471 0ustar /* * Copyright (c) 2014, 2014, 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.object; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.ShapeImpl.*; public interface LayoutStrategy { boolean updateShape(DynamicObject object); Shape returnCached(Shape newShape); Shape ensureSpace(Shape shape, Location location); boolean isAutoExtArray(); Property generalizeProperty(DynamicObject object, Property oldProperty, Object value); Property generalizeProperty(DynamicObject object, Property oldProperty, Object value, Shape oldShape, Shape newShape); BaseAllocator createAllocator(Layout shape); BaseAllocator createAllocator(Shape shape); }