1 /* 2 * Copyright (c) 2012, 2015, 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 org.graalvm.compiler.word; 24 25 import org.graalvm.compiler.bytecode.BridgeMethodUtils; 26 import org.graalvm.compiler.core.common.type.Stamp; 27 import org.graalvm.compiler.core.common.type.StampFactory; 28 import org.graalvm.compiler.nodes.ValueNode; 29 import org.graalvm.compiler.nodes.type.StampTool; 30 import org.graalvm.compiler.word.Word.Operation; 31 32 import jdk.vm.ci.meta.JavaKind; 33 import jdk.vm.ci.meta.JavaType; 34 import jdk.vm.ci.meta.MetaAccessProvider; 35 import jdk.vm.ci.meta.ResolvedJavaMethod; 36 import jdk.vm.ci.meta.ResolvedJavaType; 37 38 /** 39 * Encapsulates information for Java types representing raw words (as opposed to Objects). 40 */ 41 public class WordTypes { 42 43 /** 44 * Resolved type for {@link WordBase}. 45 */ 46 private final ResolvedJavaType wordBaseType; 47 48 /** 49 * Resolved type for {@link Word}. 50 */ 51 private final ResolvedJavaType wordImplType; 52 53 /** 54 * Resolved type for {@link ObjectAccess}. 55 */ 56 private final ResolvedJavaType objectAccessType; 57 58 /** 59 * Resolved type for {@link BarrieredAccess}. 60 */ 61 private final ResolvedJavaType barrieredAccessType; 62 63 private final JavaKind wordKind; 64 65 public WordTypes(MetaAccessProvider metaAccess, JavaKind wordKind) { 66 this.wordKind = wordKind; 67 this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); 68 this.wordImplType = metaAccess.lookupJavaType(Word.class); 69 this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class); 70 this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class); 71 } 72 73 /** 74 * Determines if a given method denotes a word operation. 75 */ 76 public boolean isWordOperation(ResolvedJavaMethod targetMethod) { 77 final boolean isObjectAccess = objectAccessType.equals(targetMethod.getDeclaringClass()); 78 final boolean isBarrieredAccess = barrieredAccessType.equals(targetMethod.getDeclaringClass()); 79 if (isObjectAccess || isBarrieredAccess) { 80 assert targetMethod.getAnnotation(Operation.class) != null : targetMethod + " should be annotated with @" + Operation.class.getSimpleName(); 81 return true; 82 } 83 return isWord(targetMethod.getDeclaringClass()); 84 } 85 86 /** 87 * Gets the method annotated with {@link Operation} based on a given method that represents a 88 * word operation (but may not necessarily have the annotation). 89 * 90 * @param callingContextType the {@linkplain ResolvedJavaType type} from which 91 * {@code targetMethod} is invoked 92 * @return the {@link Operation} method resolved for {@code targetMethod} if any 93 */ 94 public ResolvedJavaMethod getWordOperation(ResolvedJavaMethod targetMethod, ResolvedJavaType callingContextType) { 95 final boolean isWordBase = wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass()); 96 ResolvedJavaMethod wordMethod = targetMethod; 97 if (isWordBase && !targetMethod.isStatic()) { 98 assert wordImplType.isLinked(); 99 wordMethod = wordImplType.resolveConcreteMethod(targetMethod, callingContextType); 100 } 101 assert wordMethod != null : targetMethod; 102 assert BridgeMethodUtils.getAnnotation(Operation.class, wordMethod) != null; 103 return wordMethod; 104 } 105 106 /** 107 * Determines if a given node has a word type. 108 */ 109 public boolean isWord(ValueNode node) { 110 return isWord(StampTool.typeOrNull(node)); 111 } 112 113 /** 114 * Determines if a given type is a word type. 115 */ 116 public boolean isWord(JavaType type) { 117 return type instanceof ResolvedJavaType && wordBaseType.isAssignableFrom((ResolvedJavaType) type); 118 } 119 120 /** 121 * Gets the kind for a given type, returning the {@linkplain #getWordKind() word kind} if 122 * {@code type} is a {@linkplain #isWord(JavaType) word type}. 123 */ 124 public JavaKind asKind(JavaType type) { 125 if (isWord(type)) { 126 return wordKind; 127 } else { 128 return type.getJavaKind(); 129 } 130 } 131 132 public JavaKind getWordKind() { 133 return wordKind; 134 } 135 136 /** 137 * Gets the stamp for a given {@linkplain #isWord(JavaType) word type}. 138 */ 139 public Stamp getWordStamp(ResolvedJavaType type) { 140 assert isWord(type); 141 return StampFactory.forKind(wordKind); 142 } 143 144 public ResolvedJavaType getWordImplType() { 145 return wordImplType; 146 } 147 }