comparison graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TypeCheckHints.java @ 5369:2e9a5365dfb0

moved conversion of type profiles into hints for type check instructions from front end to lowering phase
author Doug Simon <doug.simon@oracle.com>
date Wed, 09 May 2012 22:21:58 +0200
parents
children dc71b06d09f8
comparison
equal deleted inserted replaced
5368:a4218dd1b157 5369:2e9a5365dfb0
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.max.criutils;
24
25 import java.lang.reflect.*;
26 import java.util.*;
27
28 import com.oracle.max.cri.ci.*;
29 import com.oracle.max.cri.ri.*;
30 import com.oracle.max.cri.ri.RiTypeProfile.ProfiledType;
31
32 /**
33 * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof)
34 * based on the target type of the check and any profiling information available for the instruction.
35 */
36 public class TypeCheckHints {
37
38 private static final RiResolvedType[] NO_TYPES = {};
39
40 /**
41 * If true, then {@link #types} contains the only possible type that could pass the type check
42 * because the target of the type check is a final class or has been speculated to be a final class.
43 */
44 public final boolean exact;
45
46 /**
47 * The most likely types that the type check instruction will see.
48 */
49 public final RiResolvedType[] types;
50
51 /**
52 * Derives hint information for use when generating the code for a type check instruction.
53 *
54 * @param type the target type of the type check
55 * @param profile the profiling information available for the instruction (if any)
56 * @param assumptions the object in which speculations are recorded. This is null if speculations are not supported.
57 * @param minHintHitProbability if the probability that the type check will hit one the profiled types (up to
58 * {@code maxHints}) is below this value, then {@link #types} will be null
59 * @param maxHints the maximum length of {@link #types}
60 */
61 public TypeCheckHints(RiResolvedType type, RiTypeProfile profile, CiAssumptions assumptions, double minHintHitProbability, int maxHints) {
62 if (type != null && isFinalClass(type)) {
63 types = new RiResolvedType[] {type};
64 exact = true;
65 } else {
66 RiResolvedType uniqueSubtype = type == null ? null : type.uniqueConcreteSubtype();
67 if (uniqueSubtype != null) {
68 types = new RiResolvedType[] {uniqueSubtype};
69 if (assumptions != null) {
70 assumptions.recordConcreteSubtype(type, uniqueSubtype);
71 exact = true;
72 } else {
73 exact = false;
74 }
75 } else {
76 exact = false;
77 RiResolvedType[] hintTypes = NO_TYPES;
78 RiTypeProfile typeProfile = profile;
79 if (typeProfile != null) {
80 double notRecordedTypes = typeProfile.getNotRecordedProbability();
81 ProfiledType[] ptypes = typeProfile.getTypes();
82 if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) {
83 hintTypes = new RiResolvedType[ptypes.length];
84 int hintCount = 0;
85 double totalHintProbability = 0.0d;
86 for (ProfiledType ptype : ptypes) {
87 RiResolvedType hint = ptype.type;
88 if (type != null && hint.isSubtypeOf(type)) {
89 hintTypes[hintCount++] = hint;
90 totalHintProbability += ptype.probability;
91 }
92 }
93 if (totalHintProbability >= minHintHitProbability) {
94 if (hintTypes.length != hintCount || hintCount > maxHints) {
95 hintTypes = Arrays.copyOf(hintTypes, Math.min(maxHints, hintCount));
96 }
97 } else {
98 hintTypes = NO_TYPES;
99 }
100
101 }
102 }
103 this.types = hintTypes;
104 }
105 }
106 }
107
108 public static boolean isFinalClass(RiResolvedType type) {
109 return Modifier.isFinal(type.accessFlags()) || (type.isArrayClass() && Modifier.isFinal(type.componentType().accessFlags()));
110 }
111 }