src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractUnsafeCompareAndSwapNode.java
author dlong
Thu, 31 Oct 2019 16:54:16 -0700
changeset 58877 aec7bf35d6f5
parent 52910 583fd71c47d6
permissions -rw-r--r--
8233273: Update Graal Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52578
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     1
/*
58877
aec7bf35d6f5 8233273: Update Graal
dlong
parents: 52910
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
52578
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     4
 *
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     7
 * published by the Free Software Foundation.
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     8
 *
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    13
 * accompanied this code).
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    14
 *
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    18
 *
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    21
 * questions.
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    22
 */
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    23
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    24
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    25
package org.graalvm.compiler.nodes.java;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    26
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    27
import static org.graalvm.compiler.core.common.calc.CanonicalCondition.EQ;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    28
import static org.graalvm.compiler.debug.DebugContext.DETAILED_LEVEL;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    29
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    30
import static org.graalvm.compiler.nodeinfo.InputType.Value;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    31
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    32
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    33
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    34
import org.graalvm.compiler.core.common.type.Stamp;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    35
import org.graalvm.compiler.graph.NodeClass;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    36
import org.graalvm.compiler.nodeinfo.NodeInfo;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    37
import org.graalvm.compiler.nodes.LogicConstantNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    38
import org.graalvm.compiler.nodes.LogicNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    39
import org.graalvm.compiler.nodes.NodeView;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    40
import org.graalvm.compiler.nodes.ValueNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    41
import org.graalvm.compiler.nodes.calc.CompareNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    42
import org.graalvm.compiler.nodes.calc.ConditionalNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    43
import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    44
import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    45
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    46
import org.graalvm.compiler.nodes.spi.Lowerable;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    47
import org.graalvm.compiler.nodes.spi.LoweringTool;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    48
import org.graalvm.compiler.nodes.spi.Virtualizable;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    49
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    50
import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    51
import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    52
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    53
import jdk.internal.vm.compiler.word.LocationIdentity;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    54
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    55
import jdk.vm.ci.meta.JavaKind;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    56
import jdk.vm.ci.meta.ResolvedJavaField;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    57
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    58
@NodeInfo(allowedUsageTypes = {Value, Memory}, cycles = CYCLES_8, size = SIZE_8)
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    59
public abstract class AbstractUnsafeCompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single, Virtualizable {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    60
    public static final NodeClass<AbstractUnsafeCompareAndSwapNode> TYPE = NodeClass.create(AbstractUnsafeCompareAndSwapNode.class);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    61
    @Input ValueNode object;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    62
    @Input ValueNode offset;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    63
    @Input ValueNode expected;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    64
    @Input ValueNode newValue;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    65
    protected final JavaKind valueKind;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    66
    protected final LocationIdentity locationIdentity;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    67
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    68
    public AbstractUnsafeCompareAndSwapNode(NodeClass<? extends AbstractMemoryCheckpoint> c, Stamp stamp, ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue,
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    69
                    JavaKind valueKind, LocationIdentity locationIdentity) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    70
        super(c, stamp);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    71
        this.object = object;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    72
        this.offset = offset;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    73
        this.expected = expected;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    74
        this.newValue = newValue;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    75
        this.valueKind = valueKind;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    76
        this.locationIdentity = locationIdentity;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    77
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    78
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    79
    public ValueNode object() {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    80
        return object;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    81
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    82
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    83
    public ValueNode offset() {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    84
        return offset;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    85
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    86
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    87
    public ValueNode expected() {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    88
        return expected;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    89
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    90
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    91
    public ValueNode newValue() {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    92
        return newValue;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    93
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    94
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    95
    public JavaKind getValueKind() {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    96
        return valueKind;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    97
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    98
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
    99
    @Override
58877
aec7bf35d6f5 8233273: Update Graal
dlong
parents: 52910
diff changeset
   100
    public LocationIdentity getKilledLocationIdentity() {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   101
        return locationIdentity;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   102
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   103
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   104
    @Override
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   105
    public void lower(LoweringTool tool) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   106
        tool.getLowerer().lower(this, tool);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   107
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   108
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   109
    @Override
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   110
    public void virtualize(VirtualizerTool tool) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   111
        ValueNode offsetAlias = tool.getAlias(offset);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   112
        if (!offsetAlias.isJavaConstant()) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   113
            return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   114
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   115
        long constantOffset = offsetAlias.asJavaConstant().asLong();
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   116
        ValueNode objectAlias = tool.getAlias(object);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   117
        int index;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   118
        if (objectAlias instanceof VirtualInstanceNode) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   119
            VirtualInstanceNode obj = (VirtualInstanceNode) objectAlias;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   120
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   121
            ResolvedJavaField field = obj.type().findInstanceFieldWithOffset(constantOffset, expected.getStackKind());
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   122
            if (field == null) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   123
                tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Unknown field", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   124
                return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   125
            }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   126
            index = obj.fieldIndex(field);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   127
        } else if (objectAlias instanceof VirtualArrayNode) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   128
            VirtualArrayNode array = (VirtualArrayNode) objectAlias;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   129
            index = array.entryIndexForOffset(tool.getMetaAccess(), constantOffset, valueKind);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   130
        } else {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   131
            return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   132
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   133
        if (index < 0) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   134
            tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Unknown index", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   135
            return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   136
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   137
        VirtualObjectNode obj = (VirtualObjectNode) objectAlias;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   138
        ValueNode currentValue = tool.getEntry(obj, index);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   139
        ValueNode expectedAlias = tool.getAlias(this.expected);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   140
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   141
        LogicNode equalsNode = null;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   142
        if (valueKind.isObject()) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   143
            equalsNode = ObjectEqualsNode.virtualizeComparison(expectedAlias, currentValue, graph(), tool);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   144
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   145
        if (equalsNode == null && !(expectedAlias instanceof VirtualObjectNode) && !(currentValue instanceof VirtualObjectNode)) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   146
            equalsNode = CompareNode.createCompareNode(EQ, expectedAlias, currentValue, tool.getConstantReflection(), NodeView.DEFAULT);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   147
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   148
        if (equalsNode == null) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   149
            tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Expected and/or current values are virtual and the comparison can not be folded", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   150
            return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   151
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   152
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   153
        ValueNode newValueAlias = tool.getAlias(this.newValue);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   154
        ValueNode fieldValue;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   155
        if (equalsNode instanceof LogicConstantNode) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   156
            fieldValue = ((LogicConstantNode) equalsNode).getValue() ? newValue : currentValue;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   157
        } else {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   158
            if (currentValue instanceof VirtualObjectNode || newValueAlias instanceof VirtualObjectNode) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   159
                tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Unknown outcome and current or new value is virtual", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   160
                return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   161
            }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   162
            fieldValue = ConditionalNode.create(equalsNode, newValueAlias, currentValue, NodeView.DEFAULT);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   163
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   164
        if (!tool.setVirtualEntry(obj, index, fieldValue, valueKind, constantOffset)) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   165
            tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Could not set virtual entry", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   166
            return;
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   167
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   168
        tool.getDebug().log(DETAILED_LEVEL, "%s.virtualize() -> Success: virtualizing", this);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   169
        if (!equalsNode.isAlive()) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   170
            tool.addNode(equalsNode);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   171
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   172
        if (!fieldValue.isAlive() && !(fieldValue instanceof VirtualObjectNode)) {
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   173
            tool.addNode(fieldValue);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   174
        }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   175
        finishVirtualize(tool, equalsNode, currentValue);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   176
    }
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   177
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   178
    protected abstract void finishVirtualize(VirtualizerTool tool, LogicNode equalsNode, ValueNode currentValue);
7dd81e82d083 8210777: Update Graal
dlong
parents:
diff changeset
   179
}