001/*
002 * Copyright (c) 2009, 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.nodes.java;
024
025import jdk.internal.jvmci.meta.*;
026
027import com.oracle.graal.compiler.common.type.*;
028import com.oracle.graal.graph.*;
029import com.oracle.graal.nodeinfo.*;
030import com.oracle.graal.nodes.*;
031import com.oracle.graal.nodes.spi.*;
032import com.oracle.graal.nodes.type.*;
033import com.oracle.graal.nodes.virtual.*;
034
035/**
036 * The {@code StoreIndexedNode} represents a write to an array element.
037 */
038@NodeInfo
039public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable, Virtualizable {
040
041    public static final NodeClass<StoreIndexedNode> TYPE = NodeClass.create(StoreIndexedNode.class);
042    @Input ValueNode value;
043    @OptionalInput(InputType.State) FrameState stateAfter;
044
045    public FrameState stateAfter() {
046        return stateAfter;
047    }
048
049    public void setStateAfter(FrameState x) {
050        assert x == null || x.isAlive() : "frame state must be in a graph";
051        updateUsages(stateAfter, x);
052        stateAfter = x;
053    }
054
055    public boolean hasSideEffect() {
056        return true;
057    }
058
059    public ValueNode value() {
060        return value;
061    }
062
063    public StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value) {
064        super(TYPE, StampFactory.forVoid(), array, index, elementKind);
065        this.value = value;
066    }
067
068    @Override
069    public void virtualize(VirtualizerTool tool) {
070        ValueNode alias = tool.getAlias(array());
071        if (alias instanceof VirtualObjectNode) {
072            ValueNode indexValue = tool.getAlias(index());
073            int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
074            VirtualArrayNode virtual = (VirtualArrayNode) alias;
075            if (idx >= 0 && idx < virtual.entryCount()) {
076                ResolvedJavaType componentType = virtual.type().getComponentType();
077                if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
078                                (StampTool.typeOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
079                    tool.setVirtualEntry(virtual, idx, value(), false);
080                    tool.delete();
081                }
082            }
083        }
084    }
085
086    public FrameState getState() {
087        return stateAfter;
088    }
089}