DynamicNewInstanceNode.java revision 13190:3c91140c49a7
1/* 2 * Copyright (c) 2013, 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 */ 23package org.graalvm.compiler.nodes.java; 24 25import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 26 27import java.lang.reflect.Modifier; 28 29import org.graalvm.compiler.core.common.type.ObjectStamp; 30import org.graalvm.compiler.core.common.type.StampFactory; 31import org.graalvm.compiler.graph.Node; 32import org.graalvm.compiler.graph.NodeClass; 33import org.graalvm.compiler.graph.spi.Canonicalizable; 34import org.graalvm.compiler.graph.spi.CanonicalizerTool; 35import org.graalvm.compiler.nodeinfo.NodeInfo; 36import org.graalvm.compiler.nodes.FrameState; 37import org.graalvm.compiler.nodes.ValueNode; 38 39import jdk.vm.ci.meta.MetaAccessProvider; 40import jdk.vm.ci.meta.ResolvedJavaType; 41 42@NodeInfo 43public class DynamicNewInstanceNode extends AbstractNewObjectNode implements Canonicalizable { 44 public static final NodeClass<DynamicNewInstanceNode> TYPE = NodeClass.create(DynamicNewInstanceNode.class); 45 46 @Input ValueNode clazz; 47 48 /** 49 * Class pointer to class.class needs to be exposed earlier than this node is lowered so that it 50 * can be replaced by the AOT machinery. If it's not needed for lowering this input can be 51 * ignored. 52 */ 53 @OptionalInput ValueNode classClass; 54 55 public DynamicNewInstanceNode(ValueNode clazz, boolean fillContents) { 56 this(TYPE, clazz, fillContents, null); 57 } 58 59 protected DynamicNewInstanceNode(NodeClass<? extends DynamicNewInstanceNode> c, ValueNode clazz, boolean fillContents, FrameState stateBefore) { 60 super(c, StampFactory.objectNonNull(), fillContents, stateBefore); 61 this.clazz = clazz; 62 assert ((ObjectStamp) clazz.stamp()).nonNull(); 63 } 64 65 public ValueNode getInstanceType() { 66 return clazz; 67 } 68 69 @Override 70 public Node canonical(CanonicalizerTool tool) { 71 if (clazz.isConstant()) { 72 if (GeneratePIC.getValue(tool.getOptions())) { 73 // Can't fold for AOT, because the resulting NewInstanceNode will be missing its 74 // InitializeKlassNode. 75 return this; 76 } 77 ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant()); 78 if (type != null && type.isInitialized() && !throwsInstantiationException(type, tool.getMetaAccess())) { 79 return createNewInstanceNode(type); 80 } 81 } 82 return this; 83 } 84 85 /** Hook for subclasses to instantiate a subclass of {@link NewInstanceNode}. */ 86 protected NewInstanceNode createNewInstanceNode(ResolvedJavaType type) { 87 return new NewInstanceNode(type, fillContents(), stateBefore()); 88 } 89 90 public static boolean throwsInstantiationException(Class<?> type, Class<?> classClass) { 91 return type.isPrimitive() || type.isArray() || type.isInterface() || Modifier.isAbstract(type.getModifiers()) || type == classClass; 92 } 93 94 public static boolean throwsInstantiationException(ResolvedJavaType type, MetaAccessProvider metaAccess) { 95 return type.isPrimitive() || type.isArray() || type.isInterface() || Modifier.isAbstract(type.getModifiers()) || type.equals(metaAccess.lookupJavaType(Class.class)); 96 } 97 98 public ValueNode getClassClass() { 99 return classClass; 100 } 101 102 public void setClassClass(ValueNode newClassClass) { 103 updateUsages(classClass, newClassClass); 104 classClass = newClassClass; 105 } 106} 107