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 }