001/* 002 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.word; 024 025import jdk.internal.jvmci.meta.*; 026 027import com.oracle.graal.compiler.common.type.*; 028import com.oracle.graal.nodes.*; 029import com.oracle.graal.nodes.type.*; 030import com.oracle.graal.word.Word.Operation; 031 032/** 033 * Encapsulates information for Java types representing raw words (as opposed to Objects). 034 */ 035public class WordTypes { 036 037 /** 038 * Resolved type for {@link WordBase}. 039 */ 040 private final ResolvedJavaType wordBaseType; 041 042 /** 043 * Resolved type for {@link Word}. 044 */ 045 private final ResolvedJavaType wordImplType; 046 047 /** 048 * Resolved type for {@link ObjectAccess}. 049 */ 050 private final ResolvedJavaType objectAccessType; 051 052 /** 053 * Resolved type for {@link BarrieredAccess}. 054 */ 055 private final ResolvedJavaType barrieredAccessType; 056 057 private final Kind wordKind; 058 059 public WordTypes(MetaAccessProvider metaAccess, Kind wordKind) { 060 this.wordKind = wordKind; 061 this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); 062 this.wordImplType = metaAccess.lookupJavaType(Word.class); 063 this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class); 064 this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class); 065 } 066 067 /** 068 * Determines if a given method denotes a word operation. 069 */ 070 public boolean isWordOperation(ResolvedJavaMethod targetMethod) { 071 final boolean isObjectAccess = objectAccessType.equals(targetMethod.getDeclaringClass()); 072 final boolean isBarrieredAccess = barrieredAccessType.equals(targetMethod.getDeclaringClass()); 073 if (isObjectAccess || isBarrieredAccess) { 074 assert targetMethod.getAnnotation(Operation.class) != null : targetMethod + " should be annotated with @" + Operation.class.getSimpleName(); 075 return true; 076 } 077 return isWord(targetMethod.getDeclaringClass()); 078 } 079 080 /** 081 * Gets the method annotated with {@link Operation} based on a given method that represents a 082 * word operation (but may not necessarily have the annotation). 083 * 084 * @param callingContextType the {@linkplain ResolvedJavaType type} from which 085 * {@code targetMethod} is invoked 086 * @return the {@link Operation} method resolved for {@code targetMethod} if any 087 */ 088 public ResolvedJavaMethod getWordOperation(ResolvedJavaMethod targetMethod, ResolvedJavaType callingContextType) { 089 final boolean isWordBase = wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass()); 090 ResolvedJavaMethod wordMethod = targetMethod; 091 if (isWordBase && !targetMethod.isStatic()) { 092 assert wordImplType.isLinked(); 093 wordMethod = wordImplType.resolveConcreteMethod(targetMethod, callingContextType); 094 } 095 assert wordMethod != null : targetMethod; 096 assert wordMethod.getAnnotation(Operation.class) != null : wordMethod; 097 return wordMethod; 098 } 099 100 /** 101 * Determines if a given node has a word type. 102 */ 103 public boolean isWord(ValueNode node) { 104 return isWord(StampTool.typeOrNull(node)); 105 } 106 107 /** 108 * Determines if a given type is a word type. 109 */ 110 public boolean isWord(ResolvedJavaType type) { 111 return type != null && wordBaseType.isAssignableFrom(type); 112 } 113 114 /** 115 * Gets the kind for a given type, returning the {@linkplain #getWordKind() word kind} if 116 * {@code type} is a {@linkplain #isWord(ResolvedJavaType) word type}. 117 */ 118 public Kind asKind(JavaType type) { 119 if (type instanceof ResolvedJavaType && isWord((ResolvedJavaType) type)) { 120 return wordKind; 121 } else { 122 return type.getKind(); 123 } 124 } 125 126 public Kind getWordKind() { 127 return wordKind; 128 } 129 130 /** 131 * Gets the stamp for a given {@linkplain #isWord(ResolvedJavaType) word type}. 132 */ 133 public Stamp getWordStamp(ResolvedJavaType type) { 134 assert isWord(type); 135 return StampFactory.forKind(wordKind); 136 } 137 138 public ResolvedJavaType getWordImplType() { 139 return wordImplType; 140 } 141}