1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 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 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.meta; 24 25 /** 26 * Manages unique deoptimization reasons. Reasons are embedded in compiled code and can be 27 * invalidated at run time. Subsequent compilations then should not speculate again on such 28 * invalidated reasons to avoid repeated deoptimization. 29 * 30 * All methods of this interface are called by the compiler. There is no need for API to register 31 * failed speculations during deoptimization, since every VM has different needs there. 32 */ 33 public interface SpeculationLog { 34 /** 35 * Marker interface for speculation objects that can be added to the speculation log. 36 */ 37 public interface SpeculationReason { 38 } 39 40 /** 41 * Marker class that indicates that a speculation has no reason. 42 */ 43 final class NoSpeculationReason implements SpeculationReason { 44 } 45 46 class Speculation { 47 private SpeculationReason reason; 48 49 public Speculation(SpeculationReason reason) { 50 this.reason = reason; 51 } 52 53 public SpeculationReason getReason() { 54 return reason; 55 } 56 57 @Override 58 public String toString() { 59 return reason.toString(); 60 } 61 62 @Override 63 public boolean equals(Object obj) { 64 if (obj instanceof Speculation) { 65 Speculation other = (Speculation) obj; 66 return reason.equals(other.reason); 67 } 68 return false; 69 } 70 71 @Override 72 public int hashCode() { 73 return getReason().hashCode(); 74 } 75 } 76 77 Speculation NO_SPECULATION = new Speculation(new NoSpeculationReason()); 78 79 /** 80 * Must be called before compilation, i.e., before a compiler calls {@link #maySpeculate}. 81 */ 82 void collectFailedSpeculations(); 83 84 /** 85 * If this method returns true, the compiler is allowed to {@link #speculate} with the given 86 * reason. 87 */ 88 boolean maySpeculate(SpeculationReason reason); 89 90 /** 91 * Registers a speculation performed by the compiler. The compiler must guard every call to this 92 * method for a specific reason with a call to {@link #maySpeculate(SpeculationReason)}. 93 * 94 * This API is subject to a benign race where a during the course of a compilation another 95 * thread might fail a speculation such that {@link #maySpeculate(SpeculationReason)} will 96 * return false but an earlier call returned true. This method will still return a working 97 * {@link Speculation} in that case but the compile will eventually be invalidated and the 98 * compile attempted again without the now invalid speculation. 99 * 100 * @param reason an object representing the reason for the speculation | 1 /* 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. 4 * 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 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.meta; 24 25 import java.util.Map; 26 import java.util.function.Supplier; 27 28 /** 29 * Manages unique {@link SpeculationReason} objects that denote why a deoptimization occurred. 30 * Reasons are embedded in compiled code for a method. If the compiled code deoptimizes at a 31 * position associated with a {@link SpeculationReason}, the reason is added to a set of failed 32 * speculations associated with the method. A subsequent compilation of the method can query the 33 * failed speculations via a {@link SpeculationLog} to avoid making a speculation based on 34 * invalidated reasons. This avoids repeated deoptimizations. 35 */ 36 public interface SpeculationLog { 37 /** 38 * The specific attributes of a speculation that a compiler uses to denote a speculation in a 39 * compiled method. Typical attributes of a speculation are a bytecode position, type 40 * information about a variable being speculated on and an enum denoting the type of operation 41 * to which the speculation applies. A {@link SpeculationReason} is used as a key in a 42 * {@link Map} and so it must implement {@link Object#equals(Object)} and 43 * {@link Object#hashCode()} in terms of its attributes. 44 * 45 * A JVMCI implementation may serialize speculations for storage off heap (e.g. in native memory 46 * associated with an nmethod). For this reason, the attributes of a {@link SpeculationReason} 47 * are restricted to those supported by the {@code add...} methods of 48 * {@link SpeculationReasonEncoding}. 49 */ 50 public interface SpeculationReason { 51 52 /** 53 * Encodes the attributes of this reason using a {@link SpeculationReasonEncoding}. For 54 * efficiency, a {@link SpeculationReason} implementation should cache the returned value 55 * and return it for all subsequent calls to this method. This also underlines the 56 * requirement that the encoding for a specific reason instance should be stable. 57 * 58 * @param encodingSupplier source of a {@link SpeculationReasonEncoding} 59 * @return a {@link SpeculationReasonEncoding} that encodes all the attributes that uniquely 60 * identify this reason 61 */ 62 default SpeculationReasonEncoding encode(Supplier<SpeculationReasonEncoding> encodingSupplier) { 63 return null; 64 } 65 } 66 67 /** 68 * Provides a facility for encoding the attributes of a {@link SpeculationReason}. The encoding 69 * format is determined by the implementation of this interface. 70 */ 71 public interface SpeculationReasonEncoding { 72 void addByte(int value); 73 74 void addShort(int value); 75 76 void addInt(int value); 77 78 void addLong(long value); 79 80 void addMethod(ResolvedJavaMethod method); 81 82 void addType(ResolvedJavaType type); 83 84 void addString(String value); 85 86 default void addField(ResolvedJavaField field) { 87 addType(field.getDeclaringClass()); 88 addInt(field.getModifiers()); 89 addInt(field.getOffset()); 90 } 91 } 92 93 /** 94 * Marker class that indicates that a speculation has no reason. 95 */ 96 final class NoSpeculationReason implements SpeculationReason { 97 } 98 99 class Speculation { 100 private final SpeculationReason reason; 101 102 public Speculation(SpeculationReason reason) { 103 this.reason = reason; 104 } 105 106 public SpeculationReason getReason() { 107 return reason; 108 } 109 110 @Override 111 public String toString() { 112 return reason.toString(); 113 } 114 115 @Override 116 public boolean equals(Object obj) { 117 if (obj instanceof Speculation) { 118 Speculation other = (Speculation) obj; 119 return reason.equals(other.reason); 120 } 121 return false; 122 } 123 124 @Override 125 public int hashCode() { 126 return getReason().hashCode(); 127 } 128 } 129 130 Speculation NO_SPECULATION = new Speculation(new NoSpeculationReason()); 131 132 /** 133 * Updates the set of failed speculations recorded in this log. This must be called before 134 * compilation. 135 */ 136 void collectFailedSpeculations(); 137 138 /** 139 * If this method returns true, the compiler is allowed to {@link #speculate} with the given 140 * reason. 141 */ 142 boolean maySpeculate(SpeculationReason reason); 143 144 /** 145 * Registers a speculation performed by the compiler. The compiler must guard every call to this 146 * method for a specific reason with a call to {@link #maySpeculate(SpeculationReason)}. 147 * 148 * This API is subject to a benign race where a during the course of a compilation another 149 * thread might fail a speculation such that {@link #maySpeculate(SpeculationReason)} will 150 * return false but an earlier call returned true. This method will still return a working 151 * {@link Speculation} in that case but the compile will eventually be invalidated and the 152 * compile attempted again without the now invalid speculation. 153 * 154 * @param reason an object representing the reason for the speculation |