DynamicNewInstanceNode.java revision 12651:6ef01bd40ce2
190075Sobrien/* 290075Sobrien * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 3169689Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 490075Sobrien * 590075Sobrien * This code is free software; you can redistribute it and/or modify it 690075Sobrien * under the terms of the GNU General Public License version 2 only, as 790075Sobrien * published by the Free Software Foundation. 8132718Skan * 990075Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 10132718Skan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11132718Skan * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12132718Skan * version 2 for more details (a copy is included in the LICENSE file that 13132718Skan * accompanied this code). 1490075Sobrien * 15132718Skan * You should have received a copy of the GNU General Public License version 16132718Skan * 2 along with this work; if not, write to the Free Software Foundation, 17132718Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18132718Skan * 1990075Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2090075Sobrien * or visit www.oracle.com if you need additional information or have any 21132718Skan * questions. 22169689Skan */ 23169689Skanpackage org.graalvm.compiler.nodes.java; 2490075Sobrien 2590075Sobrienimport java.lang.reflect.Modifier; 2690075Sobrien 2790075Sobrienimport org.graalvm.compiler.core.common.type.StampFactory; 2890075Sobrienimport org.graalvm.compiler.graph.Node; 2990075Sobrienimport org.graalvm.compiler.graph.NodeClass; 3090075Sobrienimport org.graalvm.compiler.graph.spi.Canonicalizable; 3190075Sobrienimport org.graalvm.compiler.graph.spi.CanonicalizerTool; 3290075Sobrienimport org.graalvm.compiler.nodeinfo.NodeInfo; 33169689Skanimport org.graalvm.compiler.nodes.FrameState; 34169689Skanimport org.graalvm.compiler.nodes.ValueNode; 3590075Sobrien 3690075Sobrienimport jdk.vm.ci.meta.MetaAccessProvider; 3790075Sobrienimport jdk.vm.ci.meta.ResolvedJavaType; 3890075Sobrien 39169689Skan@NodeInfo 40169689Skanpublic class DynamicNewInstanceNode extends AbstractNewObjectNode implements Canonicalizable { 41169689Skan public static final NodeClass<DynamicNewInstanceNode> TYPE = NodeClass.create(DynamicNewInstanceNode.class); 4290075Sobrien 4390075Sobrien @Input ValueNode clazz; 44132718Skan 45132718Skan /** 46132718Skan * Class pointer to class.class needs to be exposed earlier than this node is lowered so that it 47132718Skan * can be replaced by the AOT machinery. If it's not needed for lowering this input can be 48132718Skan * ignored. 49132718Skan */ 50132718Skan @OptionalInput ValueNode classClass; 5190075Sobrien 5290075Sobrien public DynamicNewInstanceNode(ValueNode clazz, boolean fillContents) { 5390075Sobrien this(TYPE, clazz, fillContents, null); 5490075Sobrien } 5590075Sobrien 5690075Sobrien protected DynamicNewInstanceNode(NodeClass<? extends DynamicNewInstanceNode> c, ValueNode clazz, boolean fillContents, FrameState stateBefore) { 5790075Sobrien super(c, StampFactory.objectNonNull(), fillContents, stateBefore); 5890075Sobrien this.clazz = clazz; 5990075Sobrien } 6090075Sobrien 6190075Sobrien public ValueNode getInstanceType() { 6290075Sobrien return clazz; 6390075Sobrien } 6490075Sobrien 6590075Sobrien @Override 6690075Sobrien public Node canonical(CanonicalizerTool tool) { 6790075Sobrien if (clazz.isConstant()) { 6890075Sobrien ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant()); 69117395Skan if (type != null && type.isInitialized() && !throwsInstantiationException(type, tool.getMetaAccess())) { 70117395Skan return createNewInstanceNode(type); 71117395Skan } 72117395Skan } 73117395Skan return this; 7490075Sobrien } 7590075Sobrien 7690075Sobrien /** Hook for subclasses to instantiate a subclass of {@link NewInstanceNode}. */ 7790075Sobrien protected NewInstanceNode createNewInstanceNode(ResolvedJavaType type) { 7890075Sobrien return new NewInstanceNode(type, fillContents(), stateBefore()); 7990075Sobrien } 80117395Skan 81132718Skan public static boolean throwsInstantiationException(Class<?> type, Class<?> classClass) { 82132718Skan return type.isPrimitive() || type.isArray() || type.isInterface() || Modifier.isAbstract(type.getModifiers()) || type == classClass; 83132718Skan } 84132718Skan 85132718Skan public static boolean throwsInstantiationException(ResolvedJavaType type, MetaAccessProvider metaAccess) { 86132718Skan return type.isPrimitive() || type.isArray() || type.isInterface() || Modifier.isAbstract(type.getModifiers()) || type.equals(metaAccess.lookupJavaType(Class.class)); 87132718Skan } 88132718Skan 89132718Skan public ValueNode getClassClass() { 90132718Skan return classClass; 91132718Skan } 92132718Skan 93169689Skan public void setClassClass(ValueNode newClassClass) { 94169689Skan updateUsages(classClass, newClassClass); 95169689Skan classClass = newClassClass; 9690075Sobrien } 9790075Sobrien} 9890075Sobrien