# HG changeset patch # User twisti # Date 1367260289 25200 # Node ID 16c354398d0922e33096ebf65d29e0b9ca275117 # Parent 016523a011b796efcb5df457aa0e5235c1fa186c intrinsify Reflection.getCallerClass diff -r 016523a011b7 -r 16c354398d09 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Apr 29 18:26:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Apr 29 11:31:29 2013 -0700 @@ -54,6 +54,10 @@ private final HotSpotResolvedObjectType holder; private/* final */int codeSize; private/* final */int exceptionHandlerCount; + private boolean callerSensitive; + private boolean forceInline; + private boolean dontInline; + private boolean ignoredBySecurityStackWalk; private HotSpotSignature signature; private Boolean hasBalancedMonitors; private Map compilerStorage; @@ -131,6 +135,43 @@ return graalRuntime().getCompilerToVM().initializeExceptionHandlers(metaspaceMethod, handlers); } + /** + * Returns true if this method has a CallerSensitive annotation. + * + * @return true if CallerSensitive annotation present, false otherwise + */ + public boolean isCallerSensitive() { + return callerSensitive; + } + + /** + * Returns true if this method has a ForceInline annotation. + * + * @return true if ForceInline annotation present, false otherwise + */ + public boolean isForceInline() { + return forceInline; + } + + /** + * Returns true if this method has a DontInline annotation. + * + * @return true if DontInline annotation present, false otherwise + */ + public boolean isDontInline() { + return dontInline; + } + + /** + * Returns true if this method is one of the special methods that is ignored by security stack + * walks. + * + * @return true if special method ignored by security stack walks, false otherwise + */ + public boolean ignoredBySecurityStackWalk() { + return ignoredBySecurityStackWalk; + } + public boolean hasBalancedMonitors() { if (hasBalancedMonitors == null) { hasBalancedMonitors = graalRuntime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod); diff -r 016523a011b7 -r 16c354398d09 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Apr 29 18:26:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Apr 29 11:31:29 2013 -0700 @@ -349,6 +349,9 @@ replacements.registerSubstitutions(AESCryptSubstitutions.class); replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class); } + if (GraalOptions.IntrinsifyReflectionMethods) { + replacements.registerSubstitutions(ReflectionSubstitutions.class); + } checkcastSnippets = new CheckCastSnippets.Templates(this, replacements, graalRuntime.getTarget()); instanceofSnippets = new InstanceOfSnippets.Templates(this, replacements, graalRuntime.getTarget()); diff -r 016523a011b7 -r 16c354398d09 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Apr 29 11:31:29 2013 -0700 @@ -0,0 +1,102 @@ +/* + * 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.graal.hotspot.replacements; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.replacements.nodes.*; + +public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable { + + public ReflectionGetCallerClassNode(Invoke invoke) { + super(invoke); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + ConstantNode callerClassNode = getCallerClassNode(tool.runtime()); + if (callerClassNode != null) { + return callerClassNode; + } + return this; + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + StructuredGraph graph = (StructuredGraph) graph(); + + ConstantNode callerClassNode = getCallerClassNode(tool.getRuntime()); + + if (callerClassNode != null) { + graph.replaceFixedWithFloating(this, callerClassNode); + } else { + graph.replaceFixedWithFixed(this, createInvoke()); + } + } + + /** + * If inlining is deep enough this method returns a {@link ConstantNode} of the caller class by + * walking the the stack. + * + * @param runtime + * @return ConstantNode of the caller class, or null + */ + private ConstantNode getCallerClassNode(MetaAccessProvider runtime) { + if (!GraalOptions.IntrinsifyReflectionMethods) { + return null; + } + + // Walk back up the frame states to find the caller at the required depth. + FrameState state = stateAfter(); + + // Cf. JVM_GetCallerClass + // NOTE: Start the loop at depth 1 because the current frame state does + // not include the Reflection.getCallerClass() frame. + for (int n = 1; state != null; state = state.outerFrameState(), n++) { + HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) state.method(); + switch (n) { + case 0: + throw GraalInternalError.shouldNotReachHere("current frame state does not include the Reflection.getCallerClass frame"); + case 1: + // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). + if (!method.isCallerSensitive()) { + return null; // bail-out; let JVM_GetCallerClass do the work + } + break; + default: + if (!method.ignoredBySecurityStackWalk()) { + // We have reached the desired frame; return the holder class. + HotSpotResolvedObjectType callerClass = (HotSpotResolvedObjectType) method.getDeclaringClass(); + return ConstantNode.forObject(callerClass.mirror(), runtime, graph()); + } + break; + } + } + return null; // bail-out; let JVM_GetCallerClass do the work + } + +} diff -r 016523a011b7 -r 16c354398d09 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionSubstitutions.java Mon Apr 29 11:31:29 2013 -0700 @@ -0,0 +1,37 @@ +/* + * 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.graal.hotspot.replacements; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.spi.MacroSubstitution; + +/** + * Substitutions for {@link sun.reflect.Reflection} methods. + */ +@ClassSubstitution(sun.reflect.Reflection.class) +public class ReflectionSubstitutions { + + @MacroSubstitution(macro = ReflectionGetCallerClassNode.class, optional = true) + public static native Class getCallerClass(); + +} diff -r 016523a011b7 -r 16c354398d09 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Apr 29 18:26:39 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Apr 29 11:31:29 2013 -0700 @@ -222,6 +222,7 @@ public static boolean IntrinsifyUnsafeMethods = true; public static boolean IntrinsifyMathMethods = true; public static boolean IntrinsifyAESMethods = true; + public static boolean IntrinsifyReflectionMethods = true; public static boolean IntrinsifyInstalledCodeMethods = true; public static boolean IntrinsifyCallSiteTarget = true; /** diff -r 016523a011b7 -r 16c354398d09 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 29 18:26:39 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 29 11:31:29 2013 -0700 @@ -276,6 +276,10 @@ HotSpotResolvedJavaMethod::set_name(hotspot_method, name()); HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size()); HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length()); + HotSpotResolvedJavaMethod::set_callerSensitive(hotspot_method, method->caller_sensitive()); + HotSpotResolvedJavaMethod::set_forceInline(hotspot_method, method->force_inline()); + HotSpotResolvedJavaMethod::set_dontInline(hotspot_method, method->dont_inline()); + HotSpotResolvedJavaMethod::set_ignoredBySecurityStackWalk(hotspot_method, method->is_ignored_by_security_stack_walk()); C2V_END C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method)) diff -r 016523a011b7 -r 16c354398d09 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 29 18:26:39 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 29 11:31:29 2013 -0700 @@ -58,6 +58,10 @@ long_field(HotSpotResolvedJavaMethod, metaspaceMethod) \ int_field(HotSpotResolvedJavaMethod, codeSize) \ int_field(HotSpotResolvedJavaMethod, exceptionHandlerCount) \ + boolean_field(HotSpotResolvedJavaMethod, callerSensitive) \ + boolean_field(HotSpotResolvedJavaMethod, forceInline) \ + boolean_field(HotSpotResolvedJavaMethod, dontInline) \ + boolean_field(HotSpotResolvedJavaMethod, ignoredBySecurityStackWalk) \ end_class \ start_class(HotSpotMethodData) \ long_field(HotSpotMethodData, metaspaceMethodData) \