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