001/*
002 * Copyright (c) 2009, 2011, 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.nodes.java;
024
025import java.lang.ref.*;
026import java.util.*;
027
028import jdk.internal.jvmci.meta.*;
029
030import com.oracle.graal.compiler.common.type.*;
031import com.oracle.graal.graph.*;
032import com.oracle.graal.nodeinfo.*;
033import com.oracle.graal.nodes.*;
034import com.oracle.graal.nodes.spi.*;
035import com.oracle.graal.nodes.virtual.*;
036
037/**
038 * The {@code NewInstanceNode} represents the allocation of an instance class object.
039 */
040@NodeInfo(nameTemplate = "New {p#instanceClass/s}")
041public class NewInstanceNode extends AbstractNewObjectNode implements VirtualizableAllocation {
042
043    public static final NodeClass<NewInstanceNode> TYPE = NodeClass.create(NewInstanceNode.class);
044    protected final ResolvedJavaType instanceClass;
045
046    public NewInstanceNode(ResolvedJavaType type, boolean fillContents) {
047        this(TYPE, type, fillContents, null);
048    }
049
050    public NewInstanceNode(ResolvedJavaType type, boolean fillContents, FrameState stateBefore) {
051        this(TYPE, type, fillContents, stateBefore);
052    }
053
054    protected NewInstanceNode(NodeClass<? extends NewInstanceNode> c, ResolvedJavaType type, boolean fillContents, FrameState stateBefore) {
055        super(c, StampFactory.exactNonNull(type), fillContents, stateBefore);
056        assert !type.isArray() && !type.isInterface() && !type.isPrimitive();
057        this.instanceClass = type;
058    }
059
060    /**
061     * Gets the instance class being allocated by this node.
062     *
063     * @return the instance class allocated
064     */
065    public ResolvedJavaType instanceClass() {
066        return instanceClass;
067    }
068
069    @Override
070    public void virtualize(VirtualizerTool tool) {
071        /*
072         * Reference objects can escape into their ReferenceQueue at any safepoint, therefore
073         * they're excluded from escape analysis.
074         */
075        if (!tool.getMetaAccessProvider().lookupJavaType(Reference.class).isAssignableFrom(instanceClass)) {
076            VirtualInstanceNode virtualObject = createVirtualInstanceNode(true);
077            ResolvedJavaField[] fields = virtualObject.getFields();
078            ValueNode[] state = new ValueNode[fields.length];
079            for (int i = 0; i < state.length; i++) {
080                state[i] = defaultFieldValue(fields[i]);
081            }
082            tool.createVirtualObject(virtualObject, state, Collections.<MonitorIdNode> emptyList(), false);
083            tool.replaceWithVirtual(virtualObject);
084        }
085    }
086
087    protected VirtualInstanceNode createVirtualInstanceNode(boolean hasIdentity) {
088        return new VirtualInstanceNode(instanceClass(), hasIdentity);
089    }
090
091    /* Factored out in a separate method so that subclasses can override it. */
092    protected ConstantNode defaultFieldValue(ResolvedJavaField field) {
093        return ConstantNode.defaultForKind(field.getType().getKind(), graph());
094    }
095}