Mercurial > hg > graal-compiler
comparison graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/TypeCheckHints.java @ 21556:48c1ebd24120
renamed com.oracle.graal.api[meta|code] modules to com.oracle.jvmci.[meta|code] (JBS:GRAAL-53)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 27 May 2015 00:36:16 +0200 |
parents | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java@deab43a789ad |
children |
comparison
equal
deleted
inserted
replaced
21555:d12eaef9af72 | 21556:48c1ebd24120 |
---|---|
1 /* | |
2 * Copyright (c) 2012, 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 com.oracle.jvmci.code; | |
24 | |
25 import com.oracle.jvmci.meta.JavaTypeProfile; | |
26 import com.oracle.jvmci.meta.ResolvedJavaType; | |
27 import com.oracle.jvmci.meta.Assumptions; | |
28 import java.util.*; | |
29 | |
30 import com.oracle.jvmci.meta.Assumptions.AssumptionResult; | |
31 import com.oracle.jvmci.meta.JavaTypeProfile.ProfiledType; | |
32 | |
33 /** | |
34 * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof) based | |
35 * on the target type of the check and any profiling information available for the instruction. | |
36 */ | |
37 public class TypeCheckHints { | |
38 | |
39 /** | |
40 * A receiver type profiled in a type check instruction. | |
41 */ | |
42 public static class Hint { | |
43 | |
44 /** | |
45 * A type seen while profiling a type check instruction. | |
46 */ | |
47 public final ResolvedJavaType type; | |
48 | |
49 /** | |
50 * Specifies if {@link #type} is a sub-type of the checked type. | |
51 */ | |
52 public final boolean positive; | |
53 | |
54 Hint(ResolvedJavaType type, boolean positive) { | |
55 this.type = type; | |
56 this.positive = positive; | |
57 } | |
58 } | |
59 | |
60 private static final Hint[] NO_HINTS = {}; | |
61 | |
62 /** | |
63 * If non-null, then this is the only type that could pass the type check because the target of | |
64 * the type check is a final class or has been speculated to be a final class and this value is | |
65 * the only concrete subclass of the target type. | |
66 */ | |
67 public final ResolvedJavaType exact; | |
68 | |
69 /** | |
70 * The most likely types that the type check instruction will see. | |
71 */ | |
72 public final Hint[] hints; | |
73 | |
74 /** | |
75 * The profile from which this information was derived. | |
76 */ | |
77 public final JavaTypeProfile profile; | |
78 | |
79 /** | |
80 * The total probability that the type check will hit one of the types in {@link #hints}. | |
81 */ | |
82 public final double hintHitProbability; | |
83 | |
84 /** | |
85 * Derives hint information for use when generating the code for a type check instruction. | |
86 * | |
87 * @param targetType the target type of the type check | |
88 * @param profile the profiling information available for the instruction (if any) | |
89 * @param assumptions the object in which speculations are recorded. This is null if | |
90 * speculations are not supported. | |
91 * @param minHintHitProbability if the probability that the type check will hit one of the | |
92 * profiled types (up to {@code maxHints}) is below this value, then {@link #hints} | |
93 * will be null | |
94 * @param maxHints the maximum length of {@link #hints} | |
95 */ | |
96 public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { | |
97 this.profile = profile; | |
98 if (targetType != null && !canHaveSubtype(targetType)) { | |
99 exact = targetType; | |
100 } else { | |
101 if (assumptions != null) { | |
102 AssumptionResult<ResolvedJavaType> leafConcreteSubtype = targetType == null ? null : targetType.findLeafConcreteSubtype(); | |
103 if (leafConcreteSubtype != null) { | |
104 assumptions.record(leafConcreteSubtype); | |
105 exact = leafConcreteSubtype.getResult(); | |
106 } else { | |
107 exact = null; | |
108 } | |
109 } else { | |
110 exact = null; | |
111 } | |
112 } | |
113 Double[] hitProbability = {null}; | |
114 this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability); | |
115 this.hintHitProbability = hitProbability[0]; | |
116 } | |
117 | |
118 private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) { | |
119 double hitProb = 0.0d; | |
120 Hint[] hintsBuf = NO_HINTS; | |
121 if (profile != null) { | |
122 double notRecordedTypes = profile.getNotRecordedProbability(); | |
123 ProfiledType[] ptypes = profile.getTypes(); | |
124 if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { | |
125 hintsBuf = new Hint[ptypes.length]; | |
126 int hintCount = 0; | |
127 for (ProfiledType ptype : ptypes) { | |
128 if (targetType != null) { | |
129 ResolvedJavaType hintType = ptype.getType(); | |
130 hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); | |
131 hitProb += ptype.getProbability(); | |
132 } | |
133 if (hintCount == maxHints) { | |
134 break; | |
135 } | |
136 } | |
137 if (hitProb >= minHintHitProbability) { | |
138 if (hintsBuf.length != hintCount || hintCount > maxHints) { | |
139 hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); | |
140 } | |
141 } else { | |
142 hintsBuf = NO_HINTS; | |
143 hitProb = 0.0d; | |
144 } | |
145 } | |
146 } | |
147 hitProbability[0] = hitProb; | |
148 return hintsBuf; | |
149 } | |
150 | |
151 /** | |
152 * Determines if a given type can have subtypes other than itself. This analysis is purely | |
153 * static; no assumptions are made. | |
154 * | |
155 * @return true if {@code type} can have subtypes | |
156 */ | |
157 public static boolean canHaveSubtype(ResolvedJavaType type) { | |
158 return !type.getElementalType().isFinal(); | |
159 } | |
160 } |