src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54914 9feb4852536f
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     1 /*
     1 /*
     2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    33 import static org.graalvm.compiler.bytecode.Bytecodes.POP;
    33 import static org.graalvm.compiler.bytecode.Bytecodes.POP;
    34 import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
    34 import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
    35 import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
    35 import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
    36 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
    36 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
    37 import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
    37 import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
       
    38 import static org.graalvm.compiler.nodes.util.GraphUtil.originalValue;
    38 
    39 
    39 import java.util.ArrayList;
    40 import java.util.ArrayList;
    40 import java.util.Arrays;
    41 import java.util.Arrays;
    41 import java.util.List;
    42 import java.util.List;
    42 import java.util.function.Function;
    43 import java.util.function.Function;
    43 
    44 
    44 import org.graalvm.compiler.bytecode.Bytecode;
    45 import org.graalvm.compiler.bytecode.Bytecode;
    45 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
    46 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
    46 import org.graalvm.compiler.core.common.GraalOptions;
       
    47 import org.graalvm.compiler.core.common.PermanentBailoutException;
    47 import org.graalvm.compiler.core.common.PermanentBailoutException;
    48 import org.graalvm.compiler.core.common.type.StampFactory;
    48 import org.graalvm.compiler.core.common.type.StampFactory;
    49 import org.graalvm.compiler.core.common.type.StampPair;
    49 import org.graalvm.compiler.core.common.type.StampPair;
    50 import org.graalvm.compiler.debug.DebugContext;
    50 import org.graalvm.compiler.debug.DebugContext;
    51 import org.graalvm.compiler.debug.GraalError;
    51 import org.graalvm.compiler.debug.GraalError;
    69 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
    69 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
    70 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
    70 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
    71 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
    71 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
    72 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
    72 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
    73 import org.graalvm.compiler.nodes.java.MonitorIdNode;
    73 import org.graalvm.compiler.nodes.java.MonitorIdNode;
    74 import org.graalvm.compiler.nodes.util.GraphUtil;
       
    75 
    74 
    76 import jdk.vm.ci.code.BytecodeFrame;
    75 import jdk.vm.ci.code.BytecodeFrame;
    77 import jdk.vm.ci.meta.Assumptions;
    76 import jdk.vm.ci.meta.Assumptions;
    78 import jdk.vm.ci.meta.JavaKind;
    77 import jdk.vm.ci.meta.JavaKind;
    79 import jdk.vm.ci.meta.JavaType;
    78 import jdk.vm.ci.meta.JavaType;
   144 
   143 
   145         assert graph != null;
   144         assert graph != null;
   146 
   145 
   147         this.monitorIds = EMPTY_MONITOR_ARRAY;
   146         this.monitorIds = EMPTY_MONITOR_ARRAY;
   148         this.graph = graph;
   147         this.graph = graph;
   149         this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions()) && !shouldRetainLocalVariables;
   148         this.clearNonLiveLocals = !shouldRetainLocalVariables;
   150         this.canVerifyKind = true;
   149         this.canVerifyKind = true;
   151     }
   150     }
   152 
   151 
   153     public void disableKindVerification() {
   152     public void disableKindVerification() {
   154         canVerifyKind = false;
   153         canVerifyKind = false;
   273         assert other.graph != null;
   272         assert other.graph != null;
   274         graph = other.graph;
   273         graph = other.graph;
   275         clearNonLiveLocals = other.clearNonLiveLocals;
   274         clearNonLiveLocals = other.clearNonLiveLocals;
   276         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
   275         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
   277 
   276 
   278         assert locals.length == code.getMaxLocals();
       
   279         assert stack.length == Math.max(1, code.getMaxStackSize());
       
   280         assert lockedObjects.length == monitorIds.length;
   277         assert lockedObjects.length == monitorIds.length;
   281     }
   278     }
   282 
   279 
   283     private static ValueNode[] allocateArray(int length) {
   280     private static ValueNode[] allocateArray(int length) {
   284         return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
   281         return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
   385 
   382 
   386     public FrameStateBuilder copy() {
   383     public FrameStateBuilder copy() {
   387         return new FrameStateBuilder(this);
   384         return new FrameStateBuilder(this);
   388     }
   385     }
   389 
   386 
   390     public boolean isCompatibleWith(FrameStateBuilder other) {
   387     private String incompatibilityErrorMessage(String reason, FrameStateBuilder other) {
       
   388         return String.format("Frame states being merged are incompatible: %s%n This frame state: %s%nOther frame state: %s%nParser context: %s", reason, this, other, parser);
       
   389     }
       
   390 
       
   391     /**
       
   392      * Checks invariants that must hold when merging {@code other} into this frame state.
       
   393      *
       
   394      * @param other
       
   395      * @throws PermanentBailoutException if the frame states are incompatible with respect to their
       
   396      *             locked objects. This indicates bytecode that has unstructured or unbalanced
       
   397      *             locks.
       
   398      * @throws GraalError if the frame states are incompatible in terms of {@link #rethrowException}
       
   399      *             or stack slots
       
   400      */
       
   401     public void checkCompatibleWith(FrameStateBuilder other) {
   391         assert code.equals(other.code) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method";
   402         assert code.equals(other.code) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method";
   392         assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds";
   403         assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds";
   393 
   404 
   394         if (rethrowException != other.rethrowException) {
   405         if (rethrowException != other.rethrowException) {
   395             return false;
   406             throw new GraalError(incompatibilityErrorMessage("mismatch in rethrowException flag", other));
   396         }
   407         }
   397 
   408 
   398         if (stackSize() != other.stackSize()) {
   409         if (stackSize() != other.stackSize()) {
   399             return false;
   410             throw new GraalError(incompatibilityErrorMessage("mismatch in stack sizes", other));
   400         }
   411         }
   401         for (int i = 0; i < stackSize(); i++) {
   412         for (int i = 0; i < stackSize(); i++) {
   402             ValueNode x = stack[i];
   413             ValueNode x = stack[i];
   403             ValueNode y = other.stack[i];
   414             ValueNode y = other.stack[i];
   404             assert x != null && y != null;
   415             assert x != null && y != null;
   405             if (x != y && (x == TWO_SLOT_MARKER || x.isDeleted() || y == TWO_SLOT_MARKER || y.isDeleted() || x.getStackKind() != y.getStackKind())) {
   416             if (x != y && (x == TWO_SLOT_MARKER || x.isDeleted() || y == TWO_SLOT_MARKER || y.isDeleted() || x.getStackKind() != y.getStackKind())) {
   406                 return false;
   417                 throw new GraalError(incompatibilityErrorMessage("mismatch in stack types", other));
   407             }
   418             }
   408         }
   419         }
   409         if (lockedObjects.length != other.lockedObjects.length) {
   420         if (lockedObjects.length != other.lockedObjects.length) {
   410             return false;
   421             throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
   411         }
   422         }
   412         for (int i = 0; i < lockedObjects.length; i++) {
   423         for (int i = 0; i < lockedObjects.length; i++) {
   413             if (GraphUtil.originalValue(lockedObjects[i]) != GraphUtil.originalValue(other.lockedObjects[i]) || monitorIds[i] != other.monitorIds[i]) {
   424             if (originalValue(lockedObjects[i], false) != originalValue(other.lockedObjects[i], false)) {
   414                 throw new PermanentBailoutException("unbalanced monitors");
   425                 throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
   415             }
   426             }
   416         }
   427             if (monitorIds[i] != other.monitorIds[i]) {
   417         return true;
   428                 throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - monitors do not match", other));
       
   429             }
       
   430         }
   418     }
   431     }
   419 
   432 
   420     public void merge(AbstractMergeNode block, FrameStateBuilder other) {
   433     public void merge(AbstractMergeNode block, FrameStateBuilder other) {
   421         GraalError.guarantee(isCompatibleWith(other), "stacks do not match on merge; bytecodes would not verify:%nexpect: %s%nactual: %s", block, other);
   434         checkCompatibleWith(other);
   422 
   435 
   423         for (int i = 0; i < localsSize(); i++) {
   436         for (int i = 0; i < localsSize(); i++) {
   424             locals[i] = merge(locals[i], other.locals[i], block);
   437             locals[i] = merge(locals[i], other.locals[i], block);
   425         }
   438         }
   426         for (int i = 0; i < stackSize(); i++) {
   439         for (int i = 0; i < stackSize(); i++) {
   789      * @return the instruction on the top of the stack
   802      * @return the instruction on the top of the stack
   790      */
   803      */
   791     public ValueNode pop(JavaKind slotKind) {
   804     public ValueNode pop(JavaKind slotKind) {
   792         if (slotKind.needsTwoSlots()) {
   805         if (slotKind.needsTwoSlots()) {
   793             ValueNode s = xpop();
   806             ValueNode s = xpop();
   794             assert s == TWO_SLOT_MARKER;
   807             assert s == TWO_SLOT_MARKER : s;
   795         }
   808         }
   796         ValueNode x = xpop();
   809         ValueNode x = xpop();
   797         assert verifyKind(slotKind, x);
   810         assert verifyKind(slotKind, x);
   798         return x;
   811         return x;
   799     }
   812     }
   833             ValueNode x = xpop();
   846             ValueNode x = xpop();
   834             if (x == TWO_SLOT_MARKER) {
   847             if (x == TWO_SLOT_MARKER) {
   835                 /* Ignore second slot of two-slot value. */
   848                 /* Ignore second slot of two-slot value. */
   836                 x = xpop();
   849                 x = xpop();
   837             }
   850             }
   838             assert x != null && x != TWO_SLOT_MARKER;
   851             assert x != null && x != TWO_SLOT_MARKER : x;
   839             result[i] = x;
   852             result[i] = x;
   840         }
   853         }
   841         return result;
   854         return result;
   842     }
   855     }
   843 
   856