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