truffle-0.6.orig/ 0000755 0000000 0000000 00000000000 12460741021 010650 5 ustar truffle-0.6.orig/com/ 0000755 0000000 0000000 00000000000 12460741021 011426 5 ustar truffle-0.6.orig/com/oracle/ 0000755 0000000 0000000 00000000000 12460741021 012673 5 ustar truffle-0.6.orig/com/oracle/nfi/ 0000755 0000000 0000000 00000000000 12460741021 013447 5 ustar truffle-0.6.orig/com/oracle/nfi/NativeFunctionInterfaceRuntime.java 0000644 0000000 0000000 00000004067 12445312576 022456 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 014220 5 ustar truffle-0.6.orig/com/oracle/nfi/api/NativeFunctionInterface.java 0000644 0000000 0000000 00000013570 12445312576 021662 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003206 12445312576 021375 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003170 12445312576 020767 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003330 12445312576 021146 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 014342 5 ustar truffle-0.6.orig/com/oracle/truffle/api/ 0000755 0000000 0000000 00000000000 12460741021 015113 5 ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/ 0000755 0000000 0000000 00000000000 12460741021 016223 5 ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/NodeCost.java 0000644 0000000 0000000 00000005211 12445312576 020617 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002651 12445312576 021632 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004741 12445312576 020611 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002722 12445312576 021337 0 ustar /*
* 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.java 0000644 0000000 0000000 00000016344 12445312576 021726 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003144 12445312576 024434 0 ustar /*
* 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.java 0000644 0000000 0000000 00000110544 12445312576 020632 0 ustar /*
* 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 extends Node>) 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 extends Node> clazz;
public static NodeClass get(Class extends Node> clazz) {
return nodeClasses.get(clazz);
}
public NodeClass(Class extends Node> 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 extends Object> 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:
*
* "[{@linkplain StandardSyntaxTag#STATEMENT STATEMENT},
* {@linkplain StandardSyntaxTag#ASSIGNMENT ASSIGNMENT}]" if tags have been applied;
* "[]" if the node supports tags, but none are present; and
* "" if the node does not support tags.
*
*/
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 extends Node> from = oldNode.getClass();
Class extends Node> 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 extends Node> 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.java 0000644 0000000 0000000 00000005104 12445312576 022522 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004320 12445312576 022244 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003224 12445312576 021350 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002517 12445312576 021615 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004174 12445312576 024272 0 ustar /*
* 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.java 0000644 0000000 0000000 00000035747 12445312576 022560 0 ustar /*
* 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 extends GraphPrintHandler> 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 extends GraphPrintHandler> 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.java 0000644 0000000 0000000 00000004240 12445312576 023231 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003122 12445312576 021572 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 017502 5 ustar truffle-0.6.orig/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java 0000644 0000000 0000000 00000006671 12445312576 025067 0 ustar /*
* 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.java 0000644 0000000 0000000 00000020713 12445312576 024337 0 ustar /*
* 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 extends Node> 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.java 0000644 0000000 0000000 00000034074 12445312576 024655 0 ustar /*
* 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 extends Node> 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.java 0000644 0000000 0000000 00000003451 12445312576 030001 0 ustar /*
* 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.java 0000644 0000000 0000000 00000014216 12445312576 025042 0 ustar /*
* 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.java 0000644 0000000 0000000 00000013512 12445312576 020635 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003644 12445312576 020630 0 ustar /*
* 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.java 0000644 0000000 0000000 00000040034 12445312576 017770 0 ustar /*
* 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.java 0000644 0000000 0000000 00000011312 12445312576 017646 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003124 12445312576 021120 0 ustar /*
* 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.java 0000644 0000000 0000000 00000072764 12445312576 021606 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003174 12445312576 023451 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005056 12445312576 021310 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 017323 5 ustar truffle-0.6.orig/com/oracle/truffle/api/instrument/SyntaxTagged.java 0000644 0000000 0000000 00000003514 12445312576 022607 0 ustar /*
* 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.java 0000644 0000000 0000000 00000036433 12445312576 021262 0 ustar /*
* 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.java 0000644 0000000 0000000 00000035300 12445312576 022060 0 ustar /*
* 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:
*
* Each GL implementation should include a WrapperNode implementation; usually only one is
* needed.
* The wrapper type should descend from the GL-specific node class .
* Must have a field: {@code @Child private Node child;}
* Must have a field: {@code @Child private ProbeNode probeNode;}
* 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.
* Method {@code Probe getProbe()} should be implemented as {@code probeNode.getProbe();}
* Method {@code insertProbe(ProbeNode)} should be implemented as
* {@code this.probeNode=insert(newProbeNode);}
* 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.
*
*
* 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.java 0000644 0000000 0000000 00000005104 12445312576 022175 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003175 12445312576 024221 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004274 12445312576 024307 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002750 12445312576 022760 0 ustar /*
* 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.java 0000644 0000000 0000000 00000032721 12445312576 022357 0 ustar /*
* 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:
*
* Create an implementation of {@link TruffleEventReceiver} that responds to events on behalf of
* a tool.
* Create an Instrument via factory method {@link Instrument#create(TruffleEventReceiver)}.
* "Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event
* notifications begin to arrive at the receiver.
* 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.
*
*
*
Options for creating receivers:
*
*
* 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).
* Extend {@link DefaultEventReceiver}, which provides a no-op implementation of every
* {@link TruffleEventReceiver} method; override the methods of interest.
* Extend {@link SimpleEventReceiver}, where return values are ignored so only two methods (for
* "enter" and "return") will notify all events.
*
*
*
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.java 0000644 0000000 0000000 00000002747 12445312576 023015 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 020264 5 ustar truffle-0.6.orig/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java 0000644 0000000 0000000 00000005300 12445312576 024603 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003546 12445312576 025226 0 ustar /*
* 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.java 0000644 0000000 0000000 00000014513 12445312576 024447 0 ustar /*
* 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.java 0000644 0000000 0000000 00000015061 12445312576 024151 0 ustar /*
* 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.java 0000644 0000000 0000000 00000013356 12445312576 025511 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004664 12445312576 025075 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005040 12445312576 022336 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003446 12445312576 022762 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003331 12445312576 022003 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004477 12445312576 022140 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006431 12445312576 023611 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006056 12445312576 020143 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016417 5 ustar truffle-0.6.orig/com/oracle/truffle/api/script/TruffleScriptEngineFactory.java 0000644 0000000 0000000 00000003415 12445312576 024553 0 ustar /*
* 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.java 0000644 0000000 0000000 00000010201 12445312576 020747 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016361 5 ustar truffle-0.6.orig/com/oracle/truffle/api/object/ObjectType.java 0000644 0000000 0000000 00000004760 12445312576 021317 0 ustar /*
* 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.java 0000644 0000000 0000000 00000011104 12445312576 021005 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002635 12445312576 022053 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005650 12445312576 021611 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002436 12445312576 022474 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003762 12445312576 022153 0 ustar /*
* 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.java 0000644 0000000 0000000 00000010355 12445312576 021757 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002502 12445312576 022337 0 ustar /*
* 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.java 0000644 0000000 0000000 00000010707 12445312576 020522 0 ustar /*
* 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 extends DynamicObject> 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.java 0000644 0000000 0000000 00000002451 12445312576 021662 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002536 12445312576 023311 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004237 12445312576 021634 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002755 12445312576 021115 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003722 12445312576 021467 0 ustar /*
* 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.java 0000644 0000000 0000000 00000015515 12445312576 021073 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002673 12445312576 022147 0 ustar /*
* 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 extends Object> getType();
/**
* If {@code true}, this location does not accept {@code null} values.
*/
boolean isNonNull();
}
truffle-0.6.orig/com/oracle/truffle/api/object/LayoutBuilder.java 0000644 0000000 0000000 00000004360 12445312576 022027 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002644 12445312576 025224 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002633 12445312576 023645 0 ustar /*
* 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.java 0000644 0000000 0000000 00000022212 12445312576 020277 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003732 12445312576 021635 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002547 12445312576 022026 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003776 12445312576 022325 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016205 5 ustar truffle-0.6.orig/com/oracle/truffle/api/frame/VirtualFrame.java 0000644 0000000 0000000 00000003127 12445312576 021470 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002526 12445312576 021573 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003330 12445312576 022450 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003123 12445312576 021602 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003026 12445312576 023502 0 ustar /*
* 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.java 0000644 0000000 0000000 00000012107 12445312576 020755 0 ustar /*
* 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.java 0000644 0000000 0000000 00000014756 12445312576 020133 0 ustar /*
* 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.java 0000644 0000000 0000000 00000015512 12445312576 022161 0 ustar /*
* 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 extends FrameSlot> 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.java 0000644 0000000 0000000 00000003213 12445312576 023162 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005107 12445312576 020763 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003031 12445312576 020655 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002671 12445312576 021063 0 ustar /*
* 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.java 0000644 0000000 0000000 00000011616 12445312576 021116 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016054 5 ustar truffle-0.6.orig/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java 0000644 0000000 0000000 00000012613 12445312576 023216 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006142 12445312576 023057 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005672 12445312576 022274 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004643 12445312576 023412 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003121 12445312576 021754 0 ustar /*
* 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.java 0000644 0000000 0000000 00000011047 12445312576 023630 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003252 12445312576 022563 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003226 12445312576 023371 0 ustar /*
* 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.java 0000644 0000000 0000000 00000017164 12445312576 022652 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003622 12445312576 022405 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 017126 5 ustar truffle-0.6.orig/com/oracle/truffle/api/utilities/ExactClassValueProfile.java 0000644 0000000 0000000 00000005020 12445312576 024352 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006127 12445312576 023262 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004223 12445312576 023277 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004655 12445312576 022535 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004401 12445312576 023157 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004777 12445312576 024440 0 ustar /*
* 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.java 0000644 0000000 0000000 00000020041 12445312576 024270 0 ustar /*
* 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.java 0000644 0000000 0000000 00000017474 12445312576 021733 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004700 12445312576 022403 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003722 12445312576 024133 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006034 12445312576 024766 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004001 12445312576 024303 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005345 12445312576 024123 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006026 12445312576 022407 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002715 12445312576 021406 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004361 12445312576 017405 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016413 5 ustar truffle-0.6.orig/com/oracle/truffle/api/source/BytesDecoder.java 0000644 0000000 0000000 00000004530 12445312576 021650 0 ustar /*
* 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.java 0000644 0000000 0000000 00000116527 12445312576 020546 0 ustar /*
* 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:
*
* File content caching is optional, off by default.
* The first access to source file contents will result in the contents being read, and (if
* enabled) cached.
* If file contents have been cached, access to contents via {@link Source#getInputStream()} or
* {@link Source#getReader()} will be provided from the cache.
* Any access to file contents via the cache will result in a timestamp check and possible cache
* reload.
*
*/
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.java 0000644 0000000 0000000 00000003175 12445312576 021660 0 ustar /*
* 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.java 0000644 0000000 0000000 00000007057 12445312576 022070 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006451 12445312576 022720 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 015675 5 ustar truffle-0.6.orig/com/oracle/truffle/api/dsl/TypeSystem.java 0000644 0000000 0000000 00000007351 12445312576 020710 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003447 12445312576 021204 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002767 12445312576 021032 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005546 12445312576 021544 0 ustar /*
* 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 extends Throwable>[] 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.java 0000644 0000000 0000000 00000003125 12445312576 021710 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006264 12445312576 020263 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004547 12445312576 020417 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003264 12445312576 022526 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 017511 5 ustar truffle-0.6.orig/com/oracle/truffle/api/dsl/internal/NodeFactoryBase.java 0000644 0000000 0000000 00000004745 12445312576 023412 0 ustar /*
* 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 extends Node>[] executionSignatures;
@SuppressWarnings("unchecked")
public NodeFactoryBase(Class nodeClass, Class>[] executionSignatures, Class>[][] nodeSignatures) {
this.nodeClass = nodeClass;
this.nodeSignatures = nodeSignatures;
this.executionSignatures = (Class extends Node>[]) 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.java 0000644 0000000 0000000 00000005072 12445312576 022457 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003040 12445312576 021615 0 ustar /*
* 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.java 0000644 0000000 0000000 00000020756 12445312576 022007 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003007 12445312576 020572 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005102 12445312576 020767 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002573 12445312576 021205 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002542 12445312576 020313 0 ustar /*
* 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.java 0000644 0000000 0000000 00000006224 12445312576 025666 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003354 12445312576 020412 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002546 12445312576 021150 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002756 12445312576 020757 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002611 12445312576 021112 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003352 12445312576 020573 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005433 12445312576 020440 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002624 12445312576 020162 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002766 12445312576 020027 0 ustar /*
* 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.java 0000644 0000000 0000000 00000002433 12445312576 020210 0 ustar /*
* 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.java 0000644 0000000 0000000 00000013622 12445312576 020751 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 015610 5 ustar truffle-0.6.orig/com/oracle/truffle/object/PropertyImpl.java 0000644 0000000 0000000 00000021777 12445312576 021153 0 ustar /*
* 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.java 0000644 0000000 0000000 00000011155 12445312576 021064 0 ustar /*
* 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.java 0000644 0000000 0000000 00000017046 12445312576 020576 0 ustar /*
* 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 extends DynamicObject> clazz;
private final int allowedImplicitCasts;
protected LayoutImpl(EnumSet allowedImplicitCasts, Class extends DynamicObjectImpl> 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 extends DynamicObject> 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.java 0000644 0000000 0000000 00000032040 12445312576 022023 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016671 5 ustar truffle-0.6.orig/com/oracle/truffle/object/basic/ShapeBasic.java 0000644 0000000 0000000 00000003726 12445312576 021562 0 ustar /*
* 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.java 0000644 0000000 0000000 00000021213 12445312576 022431 0 ustar /*
* 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.java 0000644 0000000 0000000 00000033160 12445312576 023230 0 ustar /*
* 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.java 0000644 0000000 0000000 00000052575 12445312576 022463 0 ustar /*
* 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 extends Object> 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 extends Object> 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 extends Object> 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.java 0000644 0000000 0000000 00000003114 12445312576 023661 0 ustar /*
* 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.java 0000644 0000000 0000000 00000010303 12445312576 021764 0 ustar /*
* 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.java 0000644 0000000 0000000 00000010145 12445312576 022660 0 ustar /*
* 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/ 0000755 0000000 0000000 00000000000 12460741021 016676 5 ustar truffle-0.6.orig/com/oracle/truffle/object/debug/GraphvizShapeVisitor.java 0000644 0000000 0000000 00000005530 12445312576 023713 0 ustar /*
* 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 extends Transition, ? extends Shape> 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 extends Transition, ? extends Shape> 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.java 0000644 0000000 0000000 00000017561 12445312576 022332 0 ustar /*
* 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.java 0000644 0000000 0000000 00000007347 12445312576 022702 0 ustar /*
* 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 extends Transition, ? extends Shape> transitions) {
JSONObjectBuilder sb = JSONHelper.object();
JSONArrayBuilder transitionarray = JSONHelper.array();
for (Entry extends Transition, ? extends Shape> 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.java 0000644 0000000 0000000 00000025432 12445312576 020430 0 ustar /*
* 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.java 0000644 0000000 0000000 00000003073 12445312576 022061 0 ustar /*
* 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 extends Transition, ? extends Shape> transitions);
public static String getId(Shape shape) {
return Integer.toHexString(shape.hashCode());
}
}
truffle-0.6.orig/com/oracle/truffle/object/Transition.java 0000644 0000000 0000000 00000011371 12445312576 020624 0 ustar /*
* 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.java 0000644 0000000 0000000 00000004745 12445312576 017527 0 ustar /*
* 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.java 0000644 0000000 0000000 00000005143 12445312576 022601 0 ustar /*
* 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.java 0000644 0000000 0000000 00000026006 12445312576 020755 0 ustar /*
* 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 extends Object, ? extends Property> 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