001/*
002 * Copyright (c) 2011, 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.virtual;
024
025import jdk.internal.jvmci.meta.*;
026
027import com.oracle.graal.graph.*;
028import com.oracle.graal.nodeinfo.*;
029import com.oracle.graal.nodes.*;
030
031@NodeInfo(nameTemplate = "VirtualInstance {p#type/s}")
032public class VirtualInstanceNode extends VirtualObjectNode {
033
034    public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.create(VirtualInstanceNode.class);
035    protected final ResolvedJavaType type;
036    protected final ResolvedJavaField[] fields;
037
038    public VirtualInstanceNode(ResolvedJavaType type, boolean hasIdentity) {
039        this(type, type.getInstanceFields(true), hasIdentity);
040    }
041
042    public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, boolean hasIdentity) {
043        this(TYPE, type, fields, hasIdentity);
044    }
045
046    protected VirtualInstanceNode(NodeClass<? extends VirtualInstanceNode> c, ResolvedJavaType type, boolean hasIdentity) {
047        this(c, type, type.getInstanceFields(true), hasIdentity);
048    }
049
050    protected VirtualInstanceNode(NodeClass<? extends VirtualInstanceNode> c, ResolvedJavaType type, ResolvedJavaField[] fields, boolean hasIdentity) {
051        super(c, type, hasIdentity);
052        this.type = type;
053        this.fields = fields;
054    }
055
056    @Override
057    public ResolvedJavaType type() {
058        return type;
059    }
060
061    @Override
062    public int entryCount() {
063        return fields.length;
064    }
065
066    public ResolvedJavaField field(int index) {
067        return fields[index];
068    }
069
070    public ResolvedJavaField[] getFields() {
071        return fields;
072    }
073
074    @Override
075    public String toString(Verbosity verbosity) {
076        if (verbosity == Verbosity.Name) {
077            return super.toString(Verbosity.Name) + " " + type.toJavaName(false);
078        } else {
079            return super.toString(verbosity);
080        }
081    }
082
083    @Override
084    public String entryName(int index) {
085        return fields[index].getName();
086    }
087
088    public int fieldIndex(ResolvedJavaField field) {
089        // on average fields.length == ~6, so a linear search is fast enough
090        for (int i = 0; i < fields.length; i++) {
091            if (fields[i].equals(field)) {
092                return i;
093            }
094        }
095        return -1;
096    }
097
098    @Override
099    public int entryIndexForOffset(long constantOffset, Kind expectedEntryKind) {
100        return fieldIndex(type.findInstanceFieldWithOffset(constantOffset, expectedEntryKind));
101    }
102
103    @Override
104    public Kind entryKind(int index) {
105        assert index >= 0 && index < fields.length;
106        return fields[index].getKind();
107    }
108
109    @Override
110    public VirtualInstanceNode duplicate() {
111        return new VirtualInstanceNode(type, fields, super.hasIdentity());
112    }
113
114    @Override
115    public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) {
116        return new AllocatedObjectNode(this);
117    }
118}