src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
changeset 48861 47f19ff9903c
parent 48190 25cfedf27edc
child 49451 e06f9607f370
equal deleted inserted replaced
48860:5bce1b7e7800 48861:47f19ff9903c
   263 import java.util.Collections;
   263 import java.util.Collections;
   264 import java.util.Comparator;
   264 import java.util.Comparator;
   265 import java.util.Formatter;
   265 import java.util.Formatter;
   266 import java.util.List;
   266 import java.util.List;
   267 
   267 
       
   268 import org.graalvm.collections.EconomicMap;
       
   269 import org.graalvm.collections.Equivalence;
   268 import org.graalvm.compiler.api.replacements.Snippet;
   270 import org.graalvm.compiler.api.replacements.Snippet;
   269 import org.graalvm.compiler.bytecode.Bytecode;
   271 import org.graalvm.compiler.bytecode.Bytecode;
   270 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
   272 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
   271 import org.graalvm.compiler.bytecode.BytecodeLookupSwitch;
   273 import org.graalvm.compiler.bytecode.BytecodeLookupSwitch;
   272 import org.graalvm.compiler.bytecode.BytecodeProvider;
   274 import org.graalvm.compiler.bytecode.BytecodeProvider;
   276 import org.graalvm.compiler.bytecode.Bytecodes;
   278 import org.graalvm.compiler.bytecode.Bytecodes;
   277 import org.graalvm.compiler.bytecode.Bytes;
   279 import org.graalvm.compiler.bytecode.Bytes;
   278 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
   280 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
   279 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
   281 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
   280 import org.graalvm.compiler.core.common.PermanentBailoutException;
   282 import org.graalvm.compiler.core.common.PermanentBailoutException;
       
   283 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
   281 import org.graalvm.compiler.core.common.calc.Condition;
   284 import org.graalvm.compiler.core.common.calc.Condition;
       
   285 import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
   282 import org.graalvm.compiler.core.common.calc.FloatConvert;
   286 import org.graalvm.compiler.core.common.calc.FloatConvert;
   283 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
   287 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
       
   288 import org.graalvm.compiler.core.common.type.IntegerStamp;
   284 import org.graalvm.compiler.core.common.type.ObjectStamp;
   289 import org.graalvm.compiler.core.common.type.ObjectStamp;
   285 import org.graalvm.compiler.core.common.type.Stamp;
   290 import org.graalvm.compiler.core.common.type.Stamp;
   286 import org.graalvm.compiler.core.common.type.StampFactory;
   291 import org.graalvm.compiler.core.common.type.StampFactory;
   287 import org.graalvm.compiler.core.common.type.StampPair;
   292 import org.graalvm.compiler.core.common.type.StampPair;
   288 import org.graalvm.compiler.core.common.type.TypeReference;
   293 import org.graalvm.compiler.core.common.type.TypeReference;
   341 import org.graalvm.compiler.nodes.ValueNode;
   346 import org.graalvm.compiler.nodes.ValueNode;
   342 import org.graalvm.compiler.nodes.calc.AddNode;
   347 import org.graalvm.compiler.nodes.calc.AddNode;
   343 import org.graalvm.compiler.nodes.calc.AndNode;
   348 import org.graalvm.compiler.nodes.calc.AndNode;
   344 import org.graalvm.compiler.nodes.calc.CompareNode;
   349 import org.graalvm.compiler.nodes.calc.CompareNode;
   345 import org.graalvm.compiler.nodes.calc.ConditionalNode;
   350 import org.graalvm.compiler.nodes.calc.ConditionalNode;
       
   351 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
   346 import org.graalvm.compiler.nodes.calc.FloatDivNode;
   352 import org.graalvm.compiler.nodes.calc.FloatDivNode;
   347 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
       
   348 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
   353 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
   349 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
   354 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
   350 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
   355 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
   351 import org.graalvm.compiler.nodes.calc.IsNullNode;
   356 import org.graalvm.compiler.nodes.calc.IsNullNode;
   352 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
   357 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
   406 import org.graalvm.compiler.nodes.type.StampTool;
   411 import org.graalvm.compiler.nodes.type.StampTool;
   407 import org.graalvm.compiler.nodes.util.GraphUtil;
   412 import org.graalvm.compiler.nodes.util.GraphUtil;
   408 import org.graalvm.compiler.options.OptionValues;
   413 import org.graalvm.compiler.options.OptionValues;
   409 import org.graalvm.compiler.phases.OptimisticOptimizations;
   414 import org.graalvm.compiler.phases.OptimisticOptimizations;
   410 import org.graalvm.compiler.phases.util.ValueMergeUtil;
   415 import org.graalvm.compiler.phases.util.ValueMergeUtil;
   411 import org.graalvm.util.EconomicMap;
       
   412 import org.graalvm.util.Equivalence;
       
   413 import org.graalvm.word.LocationIdentity;
   416 import org.graalvm.word.LocationIdentity;
   414 
   417 
   415 import jdk.vm.ci.code.BailoutException;
   418 import jdk.vm.ci.code.BailoutException;
   416 import jdk.vm.ci.code.BytecodeFrame;
   419 import jdk.vm.ci.code.BytecodeFrame;
   417 import jdk.vm.ci.code.CodeUtil;
   420 import jdk.vm.ci.code.CodeUtil;
   434 import jdk.vm.ci.meta.ResolvedJavaField;
   437 import jdk.vm.ci.meta.ResolvedJavaField;
   435 import jdk.vm.ci.meta.ResolvedJavaMethod;
   438 import jdk.vm.ci.meta.ResolvedJavaMethod;
   436 import jdk.vm.ci.meta.ResolvedJavaType;
   439 import jdk.vm.ci.meta.ResolvedJavaType;
   437 import jdk.vm.ci.meta.Signature;
   440 import jdk.vm.ci.meta.Signature;
   438 import jdk.vm.ci.meta.TriState;
   441 import jdk.vm.ci.meta.TriState;
   439 import org.graalvm.compiler.core.common.type.IntegerStamp;
       
   440 
   442 
   441 /**
   443 /**
   442  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
   444  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
   443  */
   445  */
   444 public class BytecodeParser implements GraphBuilderContext {
   446 public class BytecodeParser implements GraphBuilderContext {
   575                             // intrinsified indicates an exception was seen. As per JVM
   577                             // intrinsified indicates an exception was seen. As per JVM
   576                             // bytecode semantics, the interpreter expects a single
   578                             // bytecode semantics, the interpreter expects a single
   577                             // value on the stack on entry to an exception handler,
   579                             // value on the stack on entry to an exception handler,
   578                             // namely the exception object.
   580                             // namely the exception object.
   579                             assert frameState.rethrowException();
   581                             assert frameState.rethrowException();
   580                             ExceptionObjectNode exceptionObject = (ExceptionObjectNode) frameState.stackAt(0);
   582                             ValueNode exceptionValue = frameState.stackAt(0);
       
   583                             ExceptionObjectNode exceptionObject = (ExceptionObjectNode) GraphUtil.unproxify(exceptionValue);
   581                             FrameStateBuilder dispatchState = parser.frameState.copy();
   584                             FrameStateBuilder dispatchState = parser.frameState.copy();
   582                             dispatchState.clearStack();
   585                             dispatchState.clearStack();
   583                             dispatchState.push(JavaKind.Object, exceptionObject);
   586                             dispatchState.push(JavaKind.Object, exceptionValue);
   584                             dispatchState.setRethrowException(true);
   587                             dispatchState.setRethrowException(true);
   585                             FrameState newFrameState = dispatchState.create(parser.bci(), exceptionObject);
   588                             FrameState newFrameState = dispatchState.create(parser.bci(), exceptionObject);
   586                             frameState.replaceAndDelete(newFrameState);
   589                             frameState.replaceAndDelete(newFrameState);
   587                             newFrameState.setNodeSourcePosition(frameState.getNodeSourcePosition());
   590                             newFrameState.setNodeSourcePosition(frameState.getNodeSourcePosition());
   588                         } else {
   591                         } else {
   697         this.intrinsicContext = intrinsicContext;
   700         this.intrinsicContext = intrinsicContext;
   698         this.entryBCI = entryBCI;
   701         this.entryBCI = entryBCI;
   699         this.parent = parent;
   702         this.parent = parent;
   700 
   703 
   701         assert code.getCode() != null : "method must contain bytecodes: " + method;
   704         assert code.getCode() != null : "method must contain bytecodes: " + method;
       
   705 
       
   706         if (TraceBytecodeParserLevel.getValue(options) != 0) {
       
   707             if (!Assertions.assertionsEnabled()) {
       
   708                 throw new IllegalArgumentException("A non-zero " + TraceBytecodeParserLevel.getName() + " value requires assertions to be enabled");
       
   709             }
       
   710         }
   702 
   711 
   703         if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
   712         if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
   704             lnt = code.getLineNumberTable();
   713             lnt = code.getLineNumberTable();
   705             previousLineNumber = -1;
   714             previousLineNumber = -1;
   706         }
   715         }
  1891             ValueNode nonNullReceiver = pluginReceiver.get();
  1900             ValueNode nonNullReceiver = pluginReceiver.get();
  1892             Stamp methodStamp = stampProvider.createMethodStamp();
  1901             Stamp methodStamp = stampProvider.createMethodStamp();
  1893             LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
  1902             LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
  1894             LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
  1903             LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
  1895             ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
  1904             ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
  1896             LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
  1905             LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
  1897 
  1906 
  1898             JavaTypeProfile profile = null;
  1907             JavaTypeProfile profile = null;
  1899             if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
  1908             if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
  1900                 profile = profilingInfo.getTypeProfile(bci());
  1909                 profile = profilingInfo.getTypeProfile(bci());
  1901                 if (profile != null) {
  1910                 if (profile != null) {
  2265         }
  2274         }
  2266         throw res;
  2275         throw res;
  2267     }
  2276     }
  2268 
  2277 
  2269     protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
  2278     protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
       
  2279         FixedWithNextNode calleeBeforeUnwindNode = null;
       
  2280         ValueNode calleeUnwindValue = null;
       
  2281 
  2270         try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
  2282         try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
  2271 
       
  2272             BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
  2283             BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
  2273             FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
  2284             FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
  2274             if (!targetMethod.isStatic()) {
  2285             if (!targetMethod.isStatic()) {
  2275                 args[0] = nullCheckedValue(args[0]);
  2286                 args[0] = nullCheckedValue(args[0]);
  2276             }
  2287             }
  2313                 for (StateSplit sideEffect : parser.frameState.sideEffects()) {
  2324                 for (StateSplit sideEffect : parser.frameState.sideEffects()) {
  2314                     frameState.addSideEffect(sideEffect);
  2325                     frameState.addSideEffect(sideEffect);
  2315                 }
  2326                 }
  2316             }
  2327             }
  2317 
  2328 
  2318             FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
  2329             calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
  2319             if (calleeBeforeUnwindNode != null) {
  2330             if (calleeBeforeUnwindNode != null) {
  2320                 ValueNode calleeUnwindValue = parser.getUnwindValue();
  2331                 calleeUnwindValue = parser.getUnwindValue();
  2321                 assert calleeUnwindValue != null;
  2332                 assert calleeUnwindValue != null;
  2322                 calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
  2333             }
  2323             }
  2334         }
       
  2335 
       
  2336         /*
       
  2337          * Method handleException will call createTarget, which wires this exception edge to the
       
  2338          * corresponding exception dispatch block in the caller. In the case where it wires to the
       
  2339          * caller's unwind block, any FrameState created meanwhile, e.g., FrameState for
       
  2340          * LoopExitNode, would be instantiated with AFTER_EXCEPTION_BCI. Such frame states should
       
  2341          * not be fixed by IntrinsicScope.close, as they denote the states of the caller. Thus, the
       
  2342          * following code should be placed outside the IntrinsicScope, so that correctly created
       
  2343          * FrameStates are not replaced.
       
  2344          */
       
  2345         if (calleeBeforeUnwindNode != null) {
       
  2346             calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
  2324         }
  2347         }
  2325     }
  2348     }
  2326 
  2349 
  2327     public MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, JavaTypeProfile profile) {
  2350     public MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, JavaTypeProfile profile) {
  2328         return new MethodCallTargetNode(invokeKind, targetMethod, args, returnStamp, profile);
  2351         return new MethodCallTargetNode(invokeKind, targetMethod, args, returnStamp, profile);
  2771             lastInstr = firstInstruction;
  2794             lastInstr = firstInstruction;
  2772             frameState = getEntryState(block);
  2795             frameState = getEntryState(block);
  2773             setCurrentFrameState(frameState);
  2796             setCurrentFrameState(frameState);
  2774             currentBlock = block;
  2797             currentBlock = block;
  2775 
  2798 
       
  2799             if (block != blockMap.getUnwindBlock() && !(block instanceof ExceptionDispatchBlock)) {
       
  2800                 frameState.setRethrowException(false);
       
  2801             }
       
  2802 
  2776             if (firstInstruction instanceof AbstractMergeNode) {
  2803             if (firstInstruction instanceof AbstractMergeNode) {
  2777                 setMergeStateAfter(block, firstInstruction);
  2804                 setMergeStateAfter(block, firstInstruction);
  2778             }
  2805             }
  2779 
  2806 
  2780             if (block == blockMap.getUnwindBlock()) {
  2807             if (block == blockMap.getUnwindBlock()) {
  2781                 handleUnwindBlock((ExceptionDispatchBlock) block);
  2808                 handleUnwindBlock((ExceptionDispatchBlock) block);
  2782             } else if (block instanceof ExceptionDispatchBlock) {
  2809             } else if (block instanceof ExceptionDispatchBlock) {
  2783                 createExceptionDispatch((ExceptionDispatchBlock) block);
  2810                 createExceptionDispatch((ExceptionDispatchBlock) block);
  2784             } else {
  2811             } else {
  2785                 frameState.setRethrowException(false);
       
  2786                 iterateBytecodesForBlock(block);
  2812                 iterateBytecodesForBlock(block);
  2787             }
  2813             }
  2788         }
  2814         }
  2789     }
  2815     }
  2790 
  2816 
  3053             append(new FullInfopointNode(reason, createFrameState(bci(), null), escapedReturnValue));
  3079             append(new FullInfopointNode(reason, createFrameState(bci(), null), escapedReturnValue));
  3054         }
  3080         }
  3055     }
  3081     }
  3056 
  3082 
  3057     private boolean traceState() {
  3083     private boolean traceState() {
  3058         if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
  3084         if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
  3059             frameState.traceState();
  3085             frameState.traceState();
  3060         }
  3086         }
  3061         return true;
  3087         return true;
  3062     }
  3088     }
  3063 
  3089 
  3073             return;
  3099             return;
  3074         }
  3100         }
  3075 
  3101 
  3076         ValueNode a = x;
  3102         ValueNode a = x;
  3077         ValueNode b = y;
  3103         ValueNode b = y;
       
  3104         BciBlock trueSuccessor = trueBlock;
       
  3105         BciBlock falseSuccessor = falseBlock;
       
  3106 
       
  3107         CanonicalizedCondition canonicalizedCondition = cond.canonicalize();
  3078 
  3108 
  3079         // Check whether the condition needs to mirror the operands.
  3109         // Check whether the condition needs to mirror the operands.
  3080         if (cond.canonicalMirror()) {
  3110         if (canonicalizedCondition.mustMirror()) {
  3081             a = y;
  3111             a = y;
  3082             b = x;
  3112             b = x;
  3083         }
  3113         }
       
  3114         if (canonicalizedCondition.mustNegate()) {
       
  3115             trueSuccessor = falseBlock;
       
  3116             falseSuccessor = trueBlock;
       
  3117         }
  3084 
  3118 
  3085         // Create the logic node for the condition.
  3119         // Create the logic node for the condition.
  3086         LogicNode condition = createLogicNode(cond, a, b);
  3120         LogicNode condition = createLogicNode(canonicalizedCondition.getCanonicalCondition(), a, b);
  3087 
  3121 
  3088         // Check whether the condition needs to negate the result.
  3122         double probability = -1;
  3089         boolean negate = cond.canonicalNegate();
  3123         if (condition instanceof IntegerEqualsNode) {
  3090         genIf(condition, negate, trueBlock, falseBlock);
  3124             probability = extractInjectedProbability((IntegerEqualsNode) condition);
  3091     }
  3125             // the probability coming from here is about the actual condition
  3092 
  3126         }
  3093     protected void genIf(LogicNode conditionInput, boolean negateCondition, BciBlock trueBlockInput, BciBlock falseBlockInput) {
  3127 
       
  3128         if (probability == -1) {
       
  3129             probability = getProfileProbability(canonicalizedCondition.mustNegate());
       
  3130         }
       
  3131 
       
  3132         probability = clampProbability(probability);
       
  3133         genIf(condition, trueSuccessor, falseSuccessor, probability);
       
  3134     }
       
  3135 
       
  3136     private double getProfileProbability(boolean negate) {
       
  3137         double probability;
       
  3138         if (profilingInfo == null) {
       
  3139             probability = 0.5;
       
  3140         } else {
       
  3141             assert assertAtIfBytecode();
       
  3142             probability = profilingInfo.getBranchTakenProbability(bci());
       
  3143             if (probability < 0) {
       
  3144                 assert probability == -1 : "invalid probability";
       
  3145                 debug.log("missing probability in %s at bci %d", code, bci());
       
  3146                 probability = 0.5;
       
  3147             } else {
       
  3148                 if (negate) {
       
  3149                     // the probability coming from profile is about the original condition
       
  3150                     probability = 1 - probability;
       
  3151                 }
       
  3152             }
       
  3153         }
       
  3154         return probability;
       
  3155     }
       
  3156 
       
  3157     private static double extractInjectedProbability(IntegerEqualsNode condition) {
       
  3158         // Propagate injected branch probability if any.
       
  3159         IntegerEqualsNode equalsNode = condition;
       
  3160         BranchProbabilityNode probabilityNode = null;
       
  3161         ValueNode other = null;
       
  3162         if (equalsNode.getX() instanceof BranchProbabilityNode) {
       
  3163             probabilityNode = (BranchProbabilityNode) equalsNode.getX();
       
  3164             other = equalsNode.getY();
       
  3165         } else if (equalsNode.getY() instanceof BranchProbabilityNode) {
       
  3166             probabilityNode = (BranchProbabilityNode) equalsNode.getY();
       
  3167             other = equalsNode.getX();
       
  3168         }
       
  3169 
       
  3170         if (probabilityNode != null && probabilityNode.getProbability().isConstant() && other != null && other.isConstant()) {
       
  3171             double probabilityValue = probabilityNode.getProbability().asJavaConstant().asDouble();
       
  3172             return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
       
  3173         }
       
  3174         return -1;
       
  3175     }
       
  3176 
       
  3177     protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
  3094         BciBlock trueBlock = trueBlockInput;
  3178         BciBlock trueBlock = trueBlockInput;
  3095         BciBlock falseBlock = falseBlockInput;
  3179         BciBlock falseBlock = falseBlockInput;
  3096         LogicNode condition = conditionInput;
  3180         LogicNode condition = conditionInput;
       
  3181         double probability = probabilityInput;
  3097         FrameState stateBefore = null;
  3182         FrameState stateBefore = null;
  3098         ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
  3183         ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
  3099         if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
  3184         if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
  3100             stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
  3185             stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
  3101         }
  3186         }
  3102 
  3187 
  3103         // Remove a logic negation node and fold it into the negate boolean.
  3188         // Remove a logic negation node.
  3104         boolean negate = negateCondition;
       
  3105         if (condition instanceof LogicNegationNode) {
  3189         if (condition instanceof LogicNegationNode) {
  3106             LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
  3190             LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
  3107             negate = !negate;
  3191             BciBlock tmpBlock = trueBlock;
       
  3192             trueBlock = falseBlock;
       
  3193             falseBlock = tmpBlock;
       
  3194             probability = 1 - probability;
  3108             condition = logicNegationNode.getValue();
  3195             condition = logicNegationNode.getValue();
  3109         }
  3196         }
  3110 
  3197 
  3111         if (condition instanceof LogicConstantNode) {
  3198         if (condition instanceof LogicConstantNode) {
  3112             genConstantTargetIf(trueBlock, falseBlock, negate, condition);
  3199             genConstantTargetIf(trueBlock, falseBlock, condition);
  3113         } else {
  3200         } else {
  3114             if (condition.graph() == null) {
  3201             if (condition.graph() == null) {
  3115                 condition = genUnique(condition);
  3202                 condition = genUnique(condition);
  3116             }
       
  3117 
       
  3118             // Need to get probability based on current bci.
       
  3119             double probability = branchProbability(condition);
       
  3120 
       
  3121             if (negate) {
       
  3122                 BciBlock tmpBlock = trueBlock;
       
  3123                 trueBlock = falseBlock;
       
  3124                 falseBlock = tmpBlock;
       
  3125                 probability = 1 - probability;
       
  3126             }
  3203             }
  3127 
  3204 
  3128             if (isNeverExecutedCode(probability)) {
  3205             if (isNeverExecutedCode(probability)) {
  3129                 append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
  3206                 append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
  3130                 if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
  3207                 if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
  3198             appendGoto(trueBlock.getSuccessor(0));
  3275             appendGoto(trueBlock.getSuccessor(0));
  3199             stream.setBCI(oldBci);
  3276             stream.setBCI(oldBci);
  3200         }
  3277         }
  3201     }
  3278     }
  3202 
  3279 
  3203     private LogicNode createLogicNode(Condition cond, ValueNode a, ValueNode b) {
  3280     private LogicNode createLogicNode(CanonicalCondition cond, ValueNode a, ValueNode b) {
  3204         LogicNode condition;
       
  3205         assert !a.getStackKind().isNumericFloat();
  3281         assert !a.getStackKind().isNumericFloat();
  3206         if (cond == Condition.EQ || cond == Condition.NE) {
  3282         switch (cond) {
  3207             if (a.getStackKind() == JavaKind.Object) {
  3283             case EQ:
  3208                 condition = genObjectEquals(a, b);
  3284                 if (a.getStackKind() == JavaKind.Object) {
  3209             } else {
  3285                     return genObjectEquals(a, b);
  3210                 condition = genIntegerEquals(a, b);
  3286                 } else {
  3211             }
  3287                     return genIntegerEquals(a, b);
  3212         } else {
  3288                 }
  3213             assert a.getStackKind() != JavaKind.Object && !cond.isUnsigned();
  3289             case LT:
  3214             condition = genIntegerLessThan(a, b);
  3290                 assert a.getStackKind() != JavaKind.Object;
  3215         }
  3291                 return genIntegerLessThan(a, b);
  3216         return condition;
  3292             default:
  3217     }
  3293                 throw GraalError.shouldNotReachHere("Unexpected condition: " + cond);
  3218 
  3294         }
  3219     private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, boolean negate, LogicNode condition) {
  3295     }
       
  3296 
       
  3297     private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, LogicNode condition) {
  3220         LogicConstantNode constantLogicNode = (LogicConstantNode) condition;
  3298         LogicConstantNode constantLogicNode = (LogicConstantNode) condition;
  3221         boolean value = constantLogicNode.getValue();
  3299         boolean value = constantLogicNode.getValue();
  3222         if (negate) {
       
  3223             value = !value;
       
  3224         }
       
  3225         BciBlock nextBlock = falseBlock;
  3300         BciBlock nextBlock = falseBlock;
  3226         if (value) {
  3301         if (value) {
  3227             nextBlock = trueBlock;
  3302             nextBlock = trueBlock;
  3228         }
  3303         }
  3229         int startBci = nextBlock.startBci;
  3304         int startBci = nextBlock.startBci;
  3773         if (next <= currentBlock.endBci && (value == Bytecodes.IFEQ || value == Bytecodes.IFNE)) {
  3848         if (next <= currentBlock.endBci && (value == Bytecodes.IFEQ || value == Bytecodes.IFNE)) {
  3774             getStream().next();
  3849             getStream().next();
  3775             BciBlock firstSucc = currentBlock.getSuccessor(0);
  3850             BciBlock firstSucc = currentBlock.getSuccessor(0);
  3776             BciBlock secondSucc = currentBlock.getSuccessor(1);
  3851             BciBlock secondSucc = currentBlock.getSuccessor(1);
  3777             if (firstSucc != secondSucc) {
  3852             if (firstSucc != secondSucc) {
  3778                 genIf(instanceOfNode, value != Bytecodes.IFNE, firstSucc, secondSucc);
  3853                 boolean negate = value != Bytecodes.IFNE;
       
  3854                 if (negate) {
       
  3855                     BciBlock tmp = firstSucc;
       
  3856                     firstSucc = secondSucc;
       
  3857                     secondSucc = tmp;
       
  3858                 }
       
  3859                 genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
  3779             } else {
  3860             } else {
  3780                 appendGoto(firstSucc);
  3861                 appendGoto(firstSucc);
  3781             }
  3862             }
  3782         } else {
  3863         } else {
  3783             // Most frequent for value is IRETURN, followed by ISTORE.
  3864             // Most frequent for value is IRETURN, followed by ISTORE.
  4261 
  4342 
  4262     protected boolean isNeverExecutedCode(double probability) {
  4343     protected boolean isNeverExecutedCode(double probability) {
  4263         return probability == 0 && optimisticOpts.removeNeverExecutedCode(getOptions());
  4344         return probability == 0 && optimisticOpts.removeNeverExecutedCode(getOptions());
  4264     }
  4345     }
  4265 
  4346 
  4266     private double rawBranchProbability(LogicNode conditionInput) {
  4347     private double clampProbability(double probability) {
  4267         if (conditionInput instanceof IntegerEqualsNode) {
       
  4268             // Propagate injected branch probability if any.
       
  4269             IntegerEqualsNode condition = (IntegerEqualsNode) conditionInput;
       
  4270             BranchProbabilityNode injectedProbability = null;
       
  4271             ValueNode other = null;
       
  4272             if (condition.getX() instanceof BranchProbabilityNode) {
       
  4273                 injectedProbability = (BranchProbabilityNode) condition.getX();
       
  4274                 other = condition.getY();
       
  4275             } else if (condition.getY() instanceof BranchProbabilityNode) {
       
  4276                 injectedProbability = (BranchProbabilityNode) condition.getY();
       
  4277                 other = condition.getX();
       
  4278             }
       
  4279 
       
  4280             if (injectedProbability != null && injectedProbability.getProbability().isConstant() && other != null && other.isConstant()) {
       
  4281                 double probabilityValue = injectedProbability.getProbability().asJavaConstant().asDouble();
       
  4282                 return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
       
  4283             }
       
  4284         }
       
  4285 
       
  4286         if (profilingInfo == null) {
       
  4287             return 0.5;
       
  4288         }
       
  4289         assert assertAtIfBytecode();
       
  4290 
       
  4291         return profilingInfo.getBranchTakenProbability(bci());
       
  4292     }
       
  4293 
       
  4294     protected double branchProbability(LogicNode conditionInput) {
       
  4295         double probability = rawBranchProbability(conditionInput);
       
  4296         if (probability < 0) {
       
  4297             assert probability == -1 : "invalid probability";
       
  4298             debug.log("missing probability in %s at bci %d", code, bci());
       
  4299             probability = 0.5;
       
  4300         }
       
  4301 
       
  4302         if (!optimisticOpts.removeNeverExecutedCode(getOptions())) {
  4348         if (!optimisticOpts.removeNeverExecutedCode(getOptions())) {
  4303             if (probability == 0) {
  4349             if (probability == 0) {
  4304                 probability = 0.0000001;
  4350                 return 0.0000001;
  4305             } else if (probability == 1) {
  4351             } else if (probability == 1) {
  4306                 probability = 0.999999;
  4352                 return 0.999999;
  4307             }
  4353             }
  4308         }
  4354         }
  4309         return probability;
  4355         return probability;
  4310     }
  4356     }
  4311 
  4357 
  4566     public FrameStateBuilder getFrameStateBuilder() {
  4612     public FrameStateBuilder getFrameStateBuilder() {
  4567         return frameState;
  4613         return frameState;
  4568     }
  4614     }
  4569 
  4615 
  4570     protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
  4616     protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
  4571         if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
  4617         if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
  4572             traceInstructionHelper(bci, opcode, blockStart);
  4618             traceInstructionHelper(bci, opcode, blockStart);
  4573         }
  4619         }
  4574         return true;
  4620         return true;
  4575     }
  4621     }
  4576 
  4622 
  4587             sb.append(' ').append(stream.readUByte(i));
  4633             sb.append(' ').append(stream.readUByte(i));
  4588         }
  4634         }
  4589         if (!currentBlock.getJsrScope().isEmpty()) {
  4635         if (!currentBlock.getJsrScope().isEmpty()) {
  4590             sb.append(' ').append(currentBlock.getJsrScope());
  4636             sb.append(' ').append(currentBlock.getJsrScope());
  4591         }
  4637         }
  4592         debug.log("%s", sb);
  4638         TTY.println("%s", sb);
  4593     }
  4639     }
  4594 
  4640 
  4595     @Override
  4641     @Override
  4596     public boolean parsingIntrinsic() {
  4642     public boolean parsingIntrinsic() {
  4597         return intrinsicContext != null;
  4643         return intrinsicContext != null;