1 /* 2 * Copyright (c) 2012, 2014, 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.hotspot.replacements; 24 25 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; 26 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.ARRAY_KLASS_COMPONENT_MIRROR; 27 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_ACCESS_FLAGS_LOCATION; 28 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_MODIFIER_FLAGS_LOCATION; 29 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_SUPER_KLASS_LOCATION; 30 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassComponentMirrorOffset; 31 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassAccessFlagsOffset; 32 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassIsArray; 33 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassModifierFlagsOffset; 34 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassSuperKlassOffset; 35 36 import java.lang.reflect.Modifier; 37 38 import org.graalvm.compiler.api.replacements.ClassSubstitution; 39 import org.graalvm.compiler.api.replacements.MethodSubstitution; 40 import org.graalvm.compiler.hotspot.word.KlassPointer; 41 import org.graalvm.compiler.nodes.PiNode; 42 43 // JaCoCo Exclude 44 45 /** 46 * Substitutions for {@link java.lang.Class} methods. 47 */ 48 @ClassSubstitution(Class.class) 49 public class HotSpotClassSubstitutions { 50 51 @MethodSubstitution(isStatic = false) 52 public static int getModifiers(final Class<?> thisObj) { 53 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 54 if (klass.isNull()) { 55 // Class for primitive type 56 return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; 57 } else { 58 return klass.readInt(klassModifierFlagsOffset(INJECTED_VMCONFIG), KLASS_MODIFIER_FLAGS_LOCATION); 59 } 60 } 61 62 @MethodSubstitution(isStatic = false) 63 public static boolean isInterface(final Class<?> thisObj) { 64 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 65 if (klass.isNull()) { 66 // Class for primitive type 67 return false; 68 } else { 69 int accessFlags = klass.readInt(klassAccessFlagsOffset(INJECTED_VMCONFIG), KLASS_ACCESS_FLAGS_LOCATION); 70 return (accessFlags & Modifier.INTERFACE) != 0; 71 } 72 } 73 74 @MethodSubstitution(isStatic = false) 75 public static boolean isArray(final Class<?> thisObj) { 76 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 77 if (klass.isNull()) { 78 // Class for primitive type 79 return false; 80 } else { 81 return klassIsArray(klass); 82 } 83 } 84 85 @MethodSubstitution(isStatic = false) 86 public static boolean isPrimitive(final Class<?> thisObj) { 87 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 88 return klass.isNull(); 89 } 90 91 @MethodSubstitution(isStatic = false) 92 public static Class<?> getSuperclass(final Class<?> thisObj) { 93 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 94 if (!klass.isNull()) { 95 int accessFlags = klass.readInt(klassAccessFlagsOffset(INJECTED_VMCONFIG), KLASS_ACCESS_FLAGS_LOCATION); 96 if ((accessFlags & Modifier.INTERFACE) == 0) { 97 if (klassIsArray(klass)) { 98 return Object.class; 99 } else { 100 KlassPointer superKlass = klass.readKlassPointer(klassSuperKlassOffset(INJECTED_VMCONFIG), KLASS_SUPER_KLASS_LOCATION); 101 if (superKlass.isNull()) { 102 return null; 103 } else { 104 return readJavaMirror(superKlass); 105 } 106 } 107 } 108 } else { 109 // Class for primitive type 110 } 111 return null; 112 } 113 114 public static Class<?> readJavaMirror(KlassPointer klass) { 115 return PiNode.asNonNullClass(HubGetClassNode.readClass(klass)); 116 } 117 118 @MethodSubstitution(isStatic = false) 119 public static Class<?> getComponentType(final Class<?> thisObj) { 120 KlassPointer klass = ClassGetHubNode.readClass(thisObj); 121 if (!klass.isNull()) { 122 if (klassIsArray(klass)) { 123 return PiNode.asNonNullClass(klass.readObject(arrayKlassComponentMirrorOffset(INJECTED_VMCONFIG), ARRAY_KLASS_COMPONENT_MIRROR)); 124 } 125 } else { 126 // Class for primitive type 127 } 128 return null; 129 } 130 }