1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package com.oracle.graal.hotspot; 24 25 import java.lang.reflect.*; 26 27 import com.oracle.graal.api.code.*; 28 import com.oracle.graal.api.meta.*; 29 import com.oracle.graal.api.replacements.*; 30 import com.oracle.graal.compiler.common.*; 31 import com.oracle.graal.hotspot.meta.*; 32 import com.oracle.graal.hotspot.replacements.*; 33 import com.oracle.graal.hotspot.word.*; 34 import com.oracle.graal.nodes.*; 35 import com.oracle.graal.phases.util.*; 36 import com.oracle.graal.replacements.*; 37 import com.oracle.graal.replacements.IntegerSubstitutions; 38 import com.oracle.graal.replacements.LongSubstitutions; 39 import com.oracle.graal.word.phases.*; 40 41 /** 42 * Filters certain method substitutions based on whether there is underlying hardware support for 43 * them. 44 */ 45 public class HotSpotReplacementsImpl extends ReplacementsImpl { 46 47 private final HotSpotVMConfig config; 48 49 public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) { 50 super(providers, snippetReflection, assumptions, target); 51 this.config = config; 52 } 53 54 @Override 55 protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Executable originalMethod, Method substituteMethod) { 56 final Class<?> substituteClass = substituteMethod.getDeclaringClass(); 57 if (substituteClass.getDeclaringClass() == BoxingSubstitutions.class) { 58 if (config.useHeapProfiler) { 59 return null; 60 } 61 } else if (substituteClass == IntegerSubstitutions.class || substituteClass == LongSubstitutions.class) { 62 if (substituteMethod.getName().equals("bitCount")) { 63 if (!config.usePopCountInstruction) { 64 return null; 65 } 66 } else if (substituteMethod.getName().equals("numberOfLeadingZeros")) { 67 if (config.useCountLeadingZerosInstruction) { 68 return null; 69 } 70 } else if (substituteMethod.getName().equals("numberOfTrailingZeros")) { 71 if (config.useCountTrailingZerosInstruction) { 72 return null; 73 } 74 } 75 } else if (substituteClass == CRC32Substitutions.class) { 76 if (!config.useCRC32Intrinsics) { 77 return null; 78 } 79 } else if (substituteClass == StringSubstitutions.class) { 80 /* 81 * AMD64's String.equals substitution needs about 8 registers so we better disable the 82 * substitution if there is some register pressure. 83 */ 84 if (GraalOptions.RegisterPressure.getValue() != null) { 85 return null; 86 } 87 } 88 return super.registerMethodSubstitution(cr, originalMethod, substituteMethod); 89 } 90 91 @Override 92 public Class<? extends FixedWithNextNode> getMacroSubstitution(ResolvedJavaMethod method) { 93 HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; 94 int intrinsicId = hsMethod.intrinsicId(); 95 if (intrinsicId != 0) { 96 /* 97 * The methods of MethodHandle that need substitution are signature-polymorphic, i.e., 98 * the VM replicates them for every signature that they are actually used for. 99 * Therefore, we cannot use the usual annotation-driven mechanism to define the 100 */ 101 if (MethodHandleNode.lookupMethodHandleIntrinsic(method, providers.getConstantReflection().getMethodHandleAccess()) != null) { 102 return MethodHandleNode.class; 103 } 104 } 105 return super.getMacroSubstitution(method); 106 } 107 108 @Override 109 protected GraphMaker createGraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original, FrameStateProcessing frameStateProcessing) { 110 return new HotSpotGraphMaker(this, substitute, original, frameStateProcessing); 111 } 112 113 public static class HotSpotGraphMaker extends ReplacementsImpl.GraphMaker { 114 115 public HotSpotGraphMaker(ReplacementsImpl replacements, ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod, FrameStateProcessing frameStateProcessing) { 116 super(replacements, substitute, substitutedMethod, frameStateProcessing); 117 } 118 119 @Override 120 protected void afterParsing(StructuredGraph graph) { 121 MetaAccessProvider metaAccess = replacements.providers.getMetaAccess(); 122 new WordTypeVerificationPhase(metaAccess, replacements.snippetReflection, replacements.providers.getConstantReflection(), replacements.target.wordKind).apply(graph); 123 new HotSpotWordTypeRewriterPhase(metaAccess, replacements.snippetReflection, replacements.providers.getConstantReflection(), replacements.target.wordKind).apply(graph); 124 } 125 } 126 }