001/* 002 * Copyright (c) 2014, 2015, 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.hotspot.replacements; 024 025import jdk.internal.jvmci.hotspot.*; 026import jdk.internal.jvmci.meta.*; 027 028import com.oracle.graal.compiler.common.calc.*; 029import com.oracle.graal.graph.*; 030import com.oracle.graal.graph.spi.*; 031import com.oracle.graal.hotspot.word.*; 032import com.oracle.graal.nodeinfo.*; 033import com.oracle.graal.nodes.*; 034import com.oracle.graal.nodes.calc.*; 035import com.oracle.graal.nodes.extended.*; 036import com.oracle.graal.nodes.memory.*; 037import com.oracle.graal.nodes.memory.address.*; 038import com.oracle.graal.nodes.spi.*; 039 040/** 041 * Read {@code Class::_klass} to get the hub for a {@link java.lang.Class}. This node mostly exists 042 * to replace {@code _klass._java_mirror._klass} with {@code _klass}. The constant folding could be 043 * handled by 044 * {@link ReadNode#canonicalizeRead(ValueNode, AddressNode, LocationIdentity, CanonicalizerTool)}. 045 */ 046@NodeInfo 047public final class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { 048 public static final NodeClass<ClassGetHubNode> TYPE = NodeClass.create(ClassGetHubNode.class); 049 @Input protected ValueNode clazz; 050 StampProvider stampProvider; 051 052 public ClassGetHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode clazz) { 053 this(stampProvider, clazz, null); 054 } 055 056 public ClassGetHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode clazz, ValueNode guard) { 057 super(TYPE, stampProvider.createHubStamp(false), (GuardingNode) guard); 058 this.clazz = clazz; 059 this.stampProvider = stampProvider; 060 } 061 062 @Override 063 public Node canonical(CanonicalizerTool tool) { 064 if (tool.allUsagesAvailable() && hasNoUsages()) { 065 return null; 066 } else { 067 if (clazz.isConstant()) { 068 MetaAccessProvider metaAccess = tool.getMetaAccess(); 069 if (metaAccess != null) { 070 ResolvedJavaType exactType = tool.getConstantReflection().asJavaType(clazz.asJavaConstant()); 071 if (exactType instanceof HotSpotResolvedObjectType) { 072 HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) exactType; 073 ConstantNode cn = ConstantNode.forConstant(stamp(), objectType.getObjectHub(), metaAccess); 074 return cn; 075 } else if (exactType instanceof HotSpotResolvedPrimitiveType) { 076 return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, metaAccess); 077 } 078 } 079 } 080 if (clazz instanceof GetClassNode) { 081 GetClassNode getClass = (GetClassNode) clazz; 082 return new LoadHubNode(stampProvider, getClass.getObject(), null); 083 } 084 if (clazz instanceof HubGetClassNode) { 085 // replace _klass._java_mirror._klass -> _klass 086 return ((HubGetClassNode) clazz).getHub(); 087 } 088 return this; 089 } 090 } 091 092 @Override 093 public void lower(LoweringTool tool) { 094 tool.getLowerer().lower(this, tool); 095 } 096 097 @NodeIntrinsic 098 public static native KlassPointer readClass(Class<?> clazz); 099 100 @NodeIntrinsic 101 public static native KlassPointer readClass(Class<?> clazz, GuardingNode guard); 102 103 public ValueNode getValue() { 104 return clazz; 105 } 106 107 @Override 108 public Constant convert(Constant c, ConstantReflectionProvider constantReflection) { 109 ResolvedJavaType exactType = constantReflection.asJavaType(c); 110 if (exactType instanceof HotSpotResolvedObjectType) { 111 HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) exactType; 112 return objectType.getObjectHub(); 113 } else { 114 assert exactType instanceof HotSpotResolvedPrimitiveType; 115 return JavaConstant.NULL_POINTER; 116 } 117 } 118 119 @Override 120 public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) { 121 assert !c.equals(JavaConstant.NULL_POINTER); 122 ResolvedJavaType objectType = constantReflection.asJavaType(c); 123 return objectType.getJavaClass(); 124 } 125 126 public boolean isLossless() { 127 return false; 128 } 129 130 @Override 131 public boolean preservesOrder(Condition op, Constant value, ConstantReflectionProvider constantReflection) { 132 assert op == Condition.EQ || op == Condition.NE; 133 ResolvedJavaType exactType = constantReflection.asJavaType(value); 134 return exactType instanceof HotSpotResolvedObjectType; 135 } 136 137}