annotate src/share/vm/code/dependencies.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1206
diff changeset
2 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1206
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1206
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1206
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_dependencies.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
30 static bool must_be_in_vm() {
a61af66fc99e Initial load
duke
parents:
diff changeset
31 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
32 if (thread->is_Java_thread())
a61af66fc99e Initial load
duke
parents:
diff changeset
33 return ((JavaThread*)thread)->thread_state() == _thread_in_vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 else
a61af66fc99e Initial load
duke
parents:
diff changeset
35 return true; //something like this: thread->is_VM_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 void Dependencies::initialize(ciEnv* env) {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 Arena* arena = env->arena();
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _oop_recorder = env->oop_recorder();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _log = env->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
44 DEBUG_ONLY(_deps[end_marker] = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _deps[i] = new(arena) GrowableArray<ciObject*>(arena, 10, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _content_bytes = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _size_in_bytes = (size_t)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51 assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 void Dependencies::assert_evol_method(ciMethod* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 assert_common_1(evol_method, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 void Dependencies::assert_leaf_type(ciKlass* ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 if (ctxk->is_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // As a special case, support this assertion on an array type,
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // which reduces to an assertion on its element type.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Note that this cannot be done with assertions that
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // relate to concreteness or abstractness.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 ciType* elemt = ctxk->as_array_klass()->base_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
65 if (!elemt->is_instance_klass()) return; // Ex: int[][]
a61af66fc99e Initial load
duke
parents:
diff changeset
66 ctxk = elemt->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 //if (ctxk->is_final()) return; // Ex: String[][]
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 check_ctxk(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 assert_common_1(leaf_type, ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 void Dependencies::assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 check_ctxk_abstract(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 assert_common_2(abstract_with_unique_concrete_subtype, ctxk, conck);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 void Dependencies::assert_abstract_with_no_concrete_subtype(ciKlass* ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 check_ctxk_abstract(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 assert_common_1(abstract_with_no_concrete_subtype, ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 void Dependencies::assert_concrete_with_no_concrete_subtype(ciKlass* ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 check_ctxk_concrete(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
85 assert_common_1(concrete_with_no_concrete_subtype, ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 check_ctxk(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
90 assert_common_2(unique_concrete_method, ctxk, uniqm);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 void Dependencies::assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 check_ctxk(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 assert_common_3(abstract_with_exclusive_concrete_subtypes_2, ctxk, k1, k2);
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 void Dependencies::assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 check_ctxk(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert_common_3(exclusive_concrete_methods_2, ctxk, m1, m2);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 check_ctxk(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 assert_common_1(no_finalizable_subclasses, ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Helper function. If we are adding a new dep. under ctxk2,
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // try to find an old dep. under a broader* ctxk1. If there is
a61af66fc99e Initial load
duke
parents:
diff changeset
110 //
a61af66fc99e Initial load
duke
parents:
diff changeset
111 bool Dependencies::maybe_merge_ctxk(GrowableArray<ciObject*>* deps,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 int ctxk_i, ciKlass* ctxk2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 ciKlass* ctxk1 = deps->at(ctxk_i)->as_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (ctxk2->is_subtype_of(ctxk1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return true; // success, and no need to change
a61af66fc99e Initial load
duke
parents:
diff changeset
116 } else if (ctxk1->is_subtype_of(ctxk2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // new context class fully subsumes previous one
a61af66fc99e Initial load
duke
parents:
diff changeset
118 deps->at_put(ctxk_i, ctxk2);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 void Dependencies::assert_common_1(Dependencies::DepType dept, ciObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 assert(dep_args(dept) == 1, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
127 log_dependency(dept, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // see if the same (or a similar) dep is already recorded
a61af66fc99e Initial load
duke
parents:
diff changeset
131 if (note_dep_seen(dept, x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 assert(deps->find(x) >= 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
133 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 deps->append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 void Dependencies::assert_common_2(Dependencies::DepType dept,
a61af66fc99e Initial load
duke
parents:
diff changeset
139 ciKlass* ctxk, ciObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert(dep_context_arg(dept) == 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 assert(dep_args(dept) == 2, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 log_dependency(dept, ctxk, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // see if the same (or a similar) dep is already recorded
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (note_dep_seen(dept, x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // look in this bucket for redundant assertions
a61af66fc99e Initial load
duke
parents:
diff changeset
148 const int stride = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 for (int i = deps->length(); (i -= stride) >= 0; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 ciObject* x1 = deps->at(i+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 if (x == x1) { // same subject; check the context
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if (maybe_merge_ctxk(deps, i+0, ctxk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // append the assertion in the correct bucket:
a61af66fc99e Initial load
duke
parents:
diff changeset
160 deps->append(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 deps->append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 void Dependencies::assert_common_3(Dependencies::DepType dept,
a61af66fc99e Initial load
duke
parents:
diff changeset
165 ciKlass* ctxk, ciObject* x, ciObject* x2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 assert(dep_context_arg(dept) == 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
167 assert(dep_args(dept) == 3, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
168 log_dependency(dept, ctxk, x, x2);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // try to normalize an unordered pair:
a61af66fc99e Initial load
duke
parents:
diff changeset
172 bool swap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 switch (dept) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 case abstract_with_exclusive_concrete_subtypes_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
175 swap = (x->ident() > x2->ident() && x != ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 case exclusive_concrete_methods_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
178 swap = (x->ident() > x2->ident() && x->as_method()->holder() != ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (swap) { ciObject* t = x; x = x2; x2 = t; }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // see if the same (or a similar) dep is already recorded
a61af66fc99e Initial load
duke
parents:
diff changeset
184 if (note_dep_seen(dept, x) && note_dep_seen(dept, x2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // look in this bucket for redundant assertions
a61af66fc99e Initial load
duke
parents:
diff changeset
186 const int stride = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 for (int i = deps->length(); (i -= stride) >= 0; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 ciObject* y = deps->at(i+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 ciObject* y2 = deps->at(i+2);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (x == y && x2 == y2) { // same subjects; check the context
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (maybe_merge_ctxk(deps, i+0, ctxk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // append the assertion in the correct bucket:
a61af66fc99e Initial load
duke
parents:
diff changeset
198 deps->append(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 deps->append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 deps->append(x2);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 /// Support for encoding dependencies into an nmethod:
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 void Dependencies::copy_to(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 address beg = nm->dependencies_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 address end = nm->dependencies_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
208 guarantee(end - beg >= (ptrdiff_t) size_in_bytes(), "bad sizing");
a61af66fc99e Initial load
duke
parents:
diff changeset
209 Copy::disjoint_words((HeapWord*) content_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
210 (HeapWord*) beg,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 size_in_bytes() / sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(size_in_bytes() % sizeof(HeapWord) == 0, "copy by words");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 static int sort_dep(ciObject** p1, ciObject** p2, int narg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 for (int i = 0; i < narg; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 int diff = p1[i]->ident() - p2[i]->ident();
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (diff != 0) return diff;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 static int sort_dep_arg_1(ciObject** p1, ciObject** p2)
a61af66fc99e Initial load
duke
parents:
diff changeset
223 { return sort_dep(p1, p2, 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 static int sort_dep_arg_2(ciObject** p1, ciObject** p2)
a61af66fc99e Initial load
duke
parents:
diff changeset
225 { return sort_dep(p1, p2, 2); }
a61af66fc99e Initial load
duke
parents:
diff changeset
226 static int sort_dep_arg_3(ciObject** p1, ciObject** p2)
a61af66fc99e Initial load
duke
parents:
diff changeset
227 { return sort_dep(p1, p2, 3); }
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 void Dependencies::sort_all_deps() {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 DepType dept = (DepType)deptv;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (deps->length() <= 1) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 switch (dep_args(dept)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 case 1: deps->sort(sort_dep_arg_1, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 case 2: deps->sort(sort_dep_arg_2, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 case 3: deps->sort(sort_dep_arg_3, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 size_t Dependencies::estimate_size_in_bytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 size_t est_size = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 DepType dept = (DepType)deptv;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
248 est_size += deps->length()*2; // tags and argument(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 return est_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 ciKlass* Dependencies::ctxk_encoded_as_null(DepType dept, ciObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 switch (dept) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 case abstract_with_exclusive_concrete_subtypes_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return x->as_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 case unique_concrete_method:
a61af66fc99e Initial load
duke
parents:
diff changeset
258 case exclusive_concrete_methods_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
259 return x->as_method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 return NULL; // let NULL be NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 klassOop Dependencies::ctxk_encoded_as_null(DepType dept, oop x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
266 switch (dept) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 case abstract_with_exclusive_concrete_subtypes_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
268 assert(x->is_klass(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
269 return (klassOop) x;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 case unique_concrete_method:
a61af66fc99e Initial load
duke
parents:
diff changeset
271 case exclusive_concrete_methods_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
272 assert(x->is_method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 return ((methodOop)x)->method_holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 return NULL; // let NULL be NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 void Dependencies::encode_content_bytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 sort_all_deps();
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // cast is safe, no deps can overflow INT_MAX
a61af66fc99e Initial load
duke
parents:
diff changeset
282 CompressedWriteStream bytes((int)estimate_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 DepType dept = (DepType)deptv;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (deps->length() == 0) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 int stride = dep_args(dept);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 int ctxkj = dep_context_arg(dept); // -1 if no context arg
a61af66fc99e Initial load
duke
parents:
diff changeset
290 assert(stride > 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
291 for (int i = 0; i < deps->length(); i += stride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 jbyte code_byte = (jbyte)dept;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 int skipj = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 if (ctxkj >= 0 && ctxkj+1 < stride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 ciKlass* ctxk = deps->at(i+ctxkj+0)->as_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
296 ciObject* x = deps->at(i+ctxkj+1); // following argument
a61af66fc99e Initial load
duke
parents:
diff changeset
297 if (ctxk == ctxk_encoded_as_null(dept, x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 skipj = ctxkj; // we win: maybe one less oop to keep track of
a61af66fc99e Initial load
duke
parents:
diff changeset
299 code_byte |= default_context_type_bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 bytes.write_byte(code_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 for (int j = 0; j < stride; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (j == skipj) continue;
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 196
diff changeset
305 bytes.write_int(_oop_recorder->find_index(deps->at(i+j)->constant_encoding()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // write a sentinel byte to mark the end
a61af66fc99e Initial load
duke
parents:
diff changeset
311 bytes.write_byte(end_marker);
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // round it out to a word boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
314 while (bytes.position() % sizeof(HeapWord) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 bytes.write_byte(end_marker);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // check whether the dept byte encoding really works
a61af66fc99e Initial load
duke
parents:
diff changeset
319 assert((jbyte)default_context_type_bit != 0, "byte overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 _content_bytes = bytes.buffer();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 _size_in_bytes = bytes.position();
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 const char* Dependencies::_dep_name[TYPE_LIMIT] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 "end_marker",
a61af66fc99e Initial load
duke
parents:
diff changeset
328 "evol_method",
a61af66fc99e Initial load
duke
parents:
diff changeset
329 "leaf_type",
a61af66fc99e Initial load
duke
parents:
diff changeset
330 "abstract_with_unique_concrete_subtype",
a61af66fc99e Initial load
duke
parents:
diff changeset
331 "abstract_with_no_concrete_subtype",
a61af66fc99e Initial load
duke
parents:
diff changeset
332 "concrete_with_no_concrete_subtype",
a61af66fc99e Initial load
duke
parents:
diff changeset
333 "unique_concrete_method",
a61af66fc99e Initial load
duke
parents:
diff changeset
334 "abstract_with_exclusive_concrete_subtypes_2",
a61af66fc99e Initial load
duke
parents:
diff changeset
335 "exclusive_concrete_methods_2",
a61af66fc99e Initial load
duke
parents:
diff changeset
336 "no_finalizable_subclasses"
a61af66fc99e Initial load
duke
parents:
diff changeset
337 };
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 int Dependencies::_dep_args[TYPE_LIMIT] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 -1,// end_marker
a61af66fc99e Initial load
duke
parents:
diff changeset
341 1, // evol_method m
a61af66fc99e Initial load
duke
parents:
diff changeset
342 1, // leaf_type ctxk
a61af66fc99e Initial load
duke
parents:
diff changeset
343 2, // abstract_with_unique_concrete_subtype ctxk, k
a61af66fc99e Initial load
duke
parents:
diff changeset
344 1, // abstract_with_no_concrete_subtype ctxk
a61af66fc99e Initial load
duke
parents:
diff changeset
345 1, // concrete_with_no_concrete_subtype ctxk
a61af66fc99e Initial load
duke
parents:
diff changeset
346 2, // unique_concrete_method ctxk, m
a61af66fc99e Initial load
duke
parents:
diff changeset
347 3, // unique_concrete_subtypes_2 ctxk, k1, k2
a61af66fc99e Initial load
duke
parents:
diff changeset
348 3, // unique_concrete_methods_2 ctxk, m1, m2
a61af66fc99e Initial load
duke
parents:
diff changeset
349 1 // no_finalizable_subclasses ctxk
a61af66fc99e Initial load
duke
parents:
diff changeset
350 };
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 const char* Dependencies::dep_name(Dependencies::DepType dept) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 if (!dept_in_mask(dept, all_types)) return "?bad-dep?";
a61af66fc99e Initial load
duke
parents:
diff changeset
354 return _dep_name[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 int Dependencies::dep_args(Dependencies::DepType dept) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if (!dept_in_mask(dept, all_types)) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 return _dep_args[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // for the sake of the compiler log, print out current dependencies:
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void Dependencies::log_all_dependencies() {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if (log() == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 ciObject* args[max_arg_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
366 for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 DepType dept = (DepType)deptv;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 GrowableArray<ciObject*>* deps = _deps[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (deps->length() == 0) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 int stride = dep_args(dept);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 for (int i = 0; i < deps->length(); i += stride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 for (int j = 0; j < stride; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // flush out the identities before printing
a61af66fc99e Initial load
duke
parents:
diff changeset
374 args[j] = deps->at(i+j);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 write_dependency_to(log(), dept, stride, args);
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 void Dependencies::write_dependency_to(CompileLog* log,
a61af66fc99e Initial load
duke
parents:
diff changeset
382 DepType dept,
a61af66fc99e Initial load
duke
parents:
diff changeset
383 int nargs, oop args[],
a61af66fc99e Initial load
duke
parents:
diff changeset
384 klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 if (log == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 ciEnv* env = ciEnv::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
389 ciObject* ciargs[max_arg_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
390 assert(nargs <= max_arg_count, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
391 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 ciargs[j] = env->get_object(args[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 Dependencies::write_dependency_to(log, dept, nargs, ciargs, witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 void Dependencies::write_dependency_to(CompileLog* log,
a61af66fc99e Initial load
duke
parents:
diff changeset
398 DepType dept,
a61af66fc99e Initial load
duke
parents:
diff changeset
399 int nargs, ciObject* args[],
a61af66fc99e Initial load
duke
parents:
diff changeset
400 klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (log == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 assert(nargs <= max_arg_count, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
403 int argids[max_arg_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
404 int ctxkj = dep_context_arg(dept); // -1 if no context arg
a61af66fc99e Initial load
duke
parents:
diff changeset
405 int j;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 for (j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 argids[j] = log->identify(args[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 log->begin_elem("dependency_failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
411 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 log->begin_elem("dependency");
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414 log->print(" type='%s'", dep_name(dept));
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (ctxkj >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 log->print(" ctxk='%d'", argids[ctxkj]);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // write remaining arguments, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 for (j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (j == ctxkj) continue; // already logged
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (j == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 log->print( " x='%d'", argids[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 log->print(" x%d='%d'", j, argids[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 log->object("witness", witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 log->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 log->end_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 void Dependencies::write_dependency_to(xmlStream* xtty,
a61af66fc99e Initial load
duke
parents:
diff changeset
435 DepType dept,
a61af66fc99e Initial load
duke
parents:
diff changeset
436 int nargs, oop args[],
a61af66fc99e Initial load
duke
parents:
diff changeset
437 klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if (xtty == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
439 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 int ctxkj = dep_context_arg(dept); // -1 if no context arg
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 xtty->begin_elem("dependency_failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
443 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 xtty->begin_elem("dependency");
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 xtty->print(" type='%s'", dep_name(dept));
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if (ctxkj >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 xtty->object("ctxk", args[ctxkj]);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // write remaining arguments, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
451 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 if (j == ctxkj) continue; // already logged
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if (j == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 xtty->object("x", args[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 char xn[10]; sprintf(xn, "x%d", j);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 xtty->object(xn, args[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 xtty->object("witness", witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 xtty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 xtty->end_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 void Dependencies::print_dependency(DepType dept, int nargs, oop args[],
a61af66fc99e Initial load
duke
parents:
diff changeset
468 klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 ttyLocker ttyl; // keep the following output all in one block
a61af66fc99e Initial load
duke
parents:
diff changeset
471 tty->print_cr("%s of type %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
472 (witness == NULL)? "Dependency": "Failed dependency",
a61af66fc99e Initial load
duke
parents:
diff changeset
473 dep_name(dept));
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // print arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
475 int ctxkj = dep_context_arg(dept); // -1 if no context arg
a61af66fc99e Initial load
duke
parents:
diff changeset
476 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 oop arg = args[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
478 bool put_star = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (arg == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 const char* what;
a61af66fc99e Initial load
duke
parents:
diff changeset
481 if (j == ctxkj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 what = "context";
a61af66fc99e Initial load
duke
parents:
diff changeset
483 put_star = !Dependencies::is_concrete_klass((klassOop)arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 } else if (arg->is_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 what = "method ";
a61af66fc99e Initial load
duke
parents:
diff changeset
486 put_star = !Dependencies::is_concrete_method((methodOop)arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 } else if (arg->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 what = "class ";
a61af66fc99e Initial load
duke
parents:
diff changeset
489 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 what = "object ";
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 tty->print(" %s = %s", what, (put_star? "*": ""));
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if (arg->is_klass())
a61af66fc99e Initial load
duke
parents:
diff changeset
494 tty->print("%s", Klass::cast((klassOop)arg)->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
495 else
a61af66fc99e Initial load
duke
parents:
diff changeset
496 arg->print_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
497 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 bool put_star = !Dependencies::is_concrete_klass(witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 tty->print_cr(" witness = %s%s",
a61af66fc99e Initial load
duke
parents:
diff changeset
502 (put_star? "*": ""),
a61af66fc99e Initial load
duke
parents:
diff changeset
503 Klass::cast(witness)->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 void Dependencies::DepStream::log_dependency(klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (_deps == NULL && xtty == NULL) return; // fast cutout for runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
509 int nargs = argument_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
510 oop args[max_arg_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
511 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
512 args[j] = argument(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (_deps != NULL && _deps->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 Dependencies::write_dependency_to(_deps->log(),
a61af66fc99e Initial load
duke
parents:
diff changeset
516 type(), nargs, args, witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
518 Dependencies::write_dependency_to(xtty,
a61af66fc99e Initial load
duke
parents:
diff changeset
519 type(), nargs, args, witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 void Dependencies::DepStream::print_dependency(klassOop witness, bool verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 int nargs = argument_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 oop args[max_arg_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
526 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 args[j] = argument(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529 Dependencies::print_dependency(type(), nargs, args, witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (_code != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 tty->print(" code: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
533 _code->print_value_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 /// Dependency stream support (decodes dependencies from an nmethod):
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
543 void Dependencies::DepStream::initial_asserts(size_t byte_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
545 _byte_limit = byte_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 _type = (DepType)(end_marker-1); // defeat "already at end" assert
a61af66fc99e Initial load
duke
parents:
diff changeset
547 assert((_code!=NULL) + (_deps!=NULL) == 1, "one or t'other");
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 bool Dependencies::DepStream::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 assert(_type != end_marker, "already at end");
a61af66fc99e Initial load
duke
parents:
diff changeset
553 if (_bytes.position() == 0 && _code != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
554 && _code->dependencies_size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // Method has no dependencies at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
556 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558 int code_byte = (_bytes.read_byte() & 0xFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 if (code_byte == end_marker) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 DEBUG_ONLY(_type = end_marker);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
562 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 int ctxk_bit = (code_byte & Dependencies::default_context_type_bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 code_byte -= ctxk_bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 DepType dept = (DepType)code_byte;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 _type = dept;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 guarantee((dept - FIRST_TYPE) < (TYPE_LIMIT - FIRST_TYPE),
a61af66fc99e Initial load
duke
parents:
diff changeset
568 "bad dependency type tag");
a61af66fc99e Initial load
duke
parents:
diff changeset
569 int stride = _dep_args[dept];
a61af66fc99e Initial load
duke
parents:
diff changeset
570 assert(stride == dep_args(dept), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
571 int skipj = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (ctxk_bit != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 skipj = 0; // currently the only context argument is at zero
a61af66fc99e Initial load
duke
parents:
diff changeset
574 assert(skipj == dep_context_arg(dept), "zero arg always ctxk");
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576 for (int j = 0; j < stride; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 _xi[j] = (j == skipj)? 0: _bytes.read_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 DEBUG_ONLY(_xi[stride] = -1); // help detect overruns
a61af66fc99e Initial load
duke
parents:
diff changeset
580 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 inline oop Dependencies::DepStream::recorded_oop_at(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 return (_code != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
586 ? _code->oop_at(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
587 : JNIHandles::resolve(_deps->oop_recorder()->handle_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 oop Dependencies::DepStream::argument(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 return recorded_oop_at(argument_index(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 klassOop Dependencies::DepStream::context_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
596 int ctxkj = dep_context_arg(_type); // -1 if no context arg
a61af66fc99e Initial load
duke
parents:
diff changeset
597 if (ctxkj < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 return NULL; // for example, evol_method
a61af66fc99e Initial load
duke
parents:
diff changeset
599 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 oop k = recorded_oop_at(_xi[ctxkj]);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (k != NULL) { // context type was not compressed away
a61af66fc99e Initial load
duke
parents:
diff changeset
602 assert(k->is_klass(), "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
603 return (klassOop) k;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 } else { // recompute "default" context type
a61af66fc99e Initial load
duke
parents:
diff changeset
605 return ctxk_encoded_as_null(_type, recorded_oop_at(_xi[ctxkj+1]));
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 /// Checking dependencies:
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // This hierarchy walker inspects subtypes of a given type,
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // trying to find a "bad" class which breaks a dependency.
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // Such a class is called a "witness" to the broken dependency.
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // While searching around, we ignore "participants", which
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // are already known to the dependency.
a61af66fc99e Initial load
duke
parents:
diff changeset
617 class ClassHierarchyWalker {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
619 enum { PARTICIPANT_LIMIT = 3 };
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // optional method descriptor to check for:
a61af66fc99e Initial load
duke
parents:
diff changeset
623 symbolOop _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
624 symbolOop _signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // special classes which are not allowed to be witnesses:
a61af66fc99e Initial load
duke
parents:
diff changeset
627 klassOop _participants[PARTICIPANT_LIMIT+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
628 int _num_participants;
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // cache of method lookups
a61af66fc99e Initial load
duke
parents:
diff changeset
631 methodOop _found_methods[PARTICIPANT_LIMIT+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // if non-zero, tells how many witnesses to convert to participants
a61af66fc99e Initial load
duke
parents:
diff changeset
634 int _record_witnesses;
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 void initialize(klassOop participant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 _record_witnesses = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 _participants[0] = participant;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 _found_methods[0] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
640 _num_participants = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 if (participant != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Terminating NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
643 _participants[1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 _found_methods[1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _num_participants = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 void initialize_from_method(methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
650 assert(m != NULL && m->is_method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
651 _name = m->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
652 _signature = m->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654
a61af66fc99e Initial load
duke
parents:
diff changeset
655 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // The walker is initialized to recognize certain methods and/or types
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // as friendly participants.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 ClassHierarchyWalker(klassOop participant, methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 initialize_from_method(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 initialize(participant);
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 ClassHierarchyWalker(methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 initialize_from_method(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 initialize(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 ClassHierarchyWalker(klassOop participant = NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 _name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 _signature = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 initialize(participant);
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // This is common code for two searches: One for concrete subtypes,
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // the other for concrete method implementations and overrides.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 bool doing_subtype_search() {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 return _name == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 int num_participants() { return _num_participants; }
a61af66fc99e Initial load
duke
parents:
diff changeset
679 klassOop participant(int n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 assert((uint)n <= (uint)_num_participants, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
681 return _participants[n];
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Note: If n==num_participants, returns NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
685 methodOop found_method(int n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
686 assert((uint)n <= (uint)_num_participants, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 methodOop fm = _found_methods[n];
a61af66fc99e Initial load
duke
parents:
diff changeset
688 assert(n == _num_participants || fm != NULL, "proper usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
689 assert(fm == NULL || fm->method_holder() == _participants[n], "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
690 return fm;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // Assert that m is inherited into ctxk, without intervening overrides.
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // (May return true even if this is not true, in corner cases where we punt.)
a61af66fc99e Initial load
duke
parents:
diff changeset
696 bool check_method_context(klassOop ctxk, methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 if (m->method_holder() == ctxk)
a61af66fc99e Initial load
duke
parents:
diff changeset
698 return true; // Quick win.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 if (m->is_private())
a61af66fc99e Initial load
duke
parents:
diff changeset
700 return false; // Quick lose. Should not happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
701 if (!(m->is_public() || m->is_protected()))
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // The override story is complex when packages get involved.
a61af66fc99e Initial load
duke
parents:
diff changeset
703 return true; // Must punt the assertion to true.
a61af66fc99e Initial load
duke
parents:
diff changeset
704 Klass* k = Klass::cast(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
705 methodOop lm = k->lookup_method(m->name(), m->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if (lm == NULL && k->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // It might be an abstract interface method, devoid of mirandas.
a61af66fc99e Initial load
duke
parents:
diff changeset
708 lm = ((instanceKlass*)k)->lookup_method_in_all_interfaces(m->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
709 m->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711 if (lm == m)
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // Method m is inherited into ctxk.
a61af66fc99e Initial load
duke
parents:
diff changeset
713 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 if (lm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (!(lm->is_public() || lm->is_protected()))
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // Method is [package-]private, so the override story is complex.
a61af66fc99e Initial load
duke
parents:
diff changeset
717 return true; // Must punt the assertion to true.
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if ( !Dependencies::is_concrete_method(lm)
a61af66fc99e Initial load
duke
parents:
diff changeset
719 && !Dependencies::is_concrete_method(m)
a61af66fc99e Initial load
duke
parents:
diff changeset
720 && Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder()))
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Method m is overridden by lm, but both are non-concrete.
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 tty->print_cr("Dependency method not found in the associated context:");
a61af66fc99e Initial load
duke
parents:
diff changeset
726 tty->print_cr(" context = %s", Klass::cast(ctxk)->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
727 tty->print( " method = "); m->print_short_name(tty); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (lm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 tty->print( " found = "); lm->print_short_name(tty); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 void add_participant(klassOop participant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 assert(_num_participants + _record_witnesses < PARTICIPANT_LIMIT, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
737 int np = _num_participants++;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _participants[np] = participant;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 _participants[np+1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _found_methods[np+1] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 void record_witnesses(int add) {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 if (add > PARTICIPANT_LIMIT) add = PARTICIPANT_LIMIT;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 assert(_num_participants + add < PARTICIPANT_LIMIT, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
746 _record_witnesses = add;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 bool is_witness(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if (doing_subtype_search()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 return Dependencies::is_concrete_klass(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
752 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 methodOop m = instanceKlass::cast(k)->find_method(_name, _signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if (m == NULL || !Dependencies::is_concrete_method(m)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 _found_methods[_num_participants] = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Note: If add_participant(k) is called,
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // the method m will already be memoized for it.
a61af66fc99e Initial load
duke
parents:
diff changeset
758 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 bool is_participant(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if (k == _participants[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
765 } else if (_num_participants <= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
767 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 return in_list(k, &_participants[1]);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 bool ignore_witness(klassOop witness) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 if (_record_witnesses == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
773 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 --_record_witnesses;
a61af66fc99e Initial load
duke
parents:
diff changeset
776 add_participant(witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 static bool in_list(klassOop x, klassOop* list) {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 for (int i = 0; ; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 klassOop y = list[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (y == NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 if (y == x) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 return false; // not in list
a61af66fc99e Initial load
duke
parents:
diff changeset
787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // the actual search method:
a61af66fc99e Initial load
duke
parents:
diff changeset
791 klassOop find_witness_anywhere(klassOop context_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
792 bool participants_hide_witnesses,
a61af66fc99e Initial load
duke
parents:
diff changeset
793 bool top_level_call = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // the spot-checking version:
a61af66fc99e Initial load
duke
parents:
diff changeset
795 klassOop find_witness_in(DepChange& changes,
a61af66fc99e Initial load
duke
parents:
diff changeset
796 klassOop context_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
797 bool participants_hide_witnesses);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
799 klassOop find_witness_subtype(klassOop context_type, DepChange* changes = NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 assert(doing_subtype_search(), "must set up a subtype search");
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // When looking for unexpected concrete types,
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // do not look beneath expected ones.
a61af66fc99e Initial load
duke
parents:
diff changeset
803 const bool participants_hide_witnesses = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // CX > CC > C' is OK, even if C' is new.
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // CX > { CC, C' } is not OK if C' is new, and C' is the witness.
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if (changes != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 return find_witness_in(*changes, context_type, participants_hide_witnesses);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 return find_witness_anywhere(context_type, participants_hide_witnesses);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
812 klassOop find_witness_definer(klassOop context_type, DepChange* changes = NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 assert(!doing_subtype_search(), "must set up a method definer search");
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // When looking for unexpected concrete methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // look beneath expected ones, to see if there are overrides.
a61af66fc99e Initial load
duke
parents:
diff changeset
816 const bool participants_hide_witnesses = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // CX.m > CC.m > C'.m is not OK, if C'.m is new, and C' is the witness.
a61af66fc99e Initial load
duke
parents:
diff changeset
818 if (changes != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
819 return find_witness_in(*changes, context_type, !participants_hide_witnesses);
a61af66fc99e Initial load
duke
parents:
diff changeset
820 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
821 return find_witness_anywhere(context_type, !participants_hide_witnesses);
a61af66fc99e Initial load
duke
parents:
diff changeset
822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
824 };
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
827 static int deps_find_witness_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 static int deps_find_witness_steps = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 static int deps_find_witness_recursions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 static int deps_find_witness_singles = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 static int deps_find_witness_print = 0; // set to -1 to force a final print
a61af66fc99e Initial load
duke
parents:
diff changeset
832 static bool count_find_witness_calls() {
a61af66fc99e Initial load
duke
parents:
diff changeset
833 if (TraceDependencies || LogCompilation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 int pcount = deps_find_witness_print + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 bool final_stats = (pcount == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 bool initial_call = (pcount == 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 bool occasional_print = ((pcount & ((1<<10) - 1)) == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
838 if (pcount < 0) pcount = 1; // crude overflow protection
a61af66fc99e Initial load
duke
parents:
diff changeset
839 deps_find_witness_print = pcount;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (VerifyDependencies && initial_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 tty->print_cr("Warning: TraceDependencies results may be inflated by VerifyDependencies");
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if (occasional_print || final_stats) {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // Every now and then dump a little info about dependency searching.
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (xtty != NULL) {
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1123
diff changeset
846 ttyLocker ttyl;
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1123
diff changeset
847 xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
848 deps_find_witness_calls,
a61af66fc99e Initial load
duke
parents:
diff changeset
849 deps_find_witness_steps,
a61af66fc99e Initial load
duke
parents:
diff changeset
850 deps_find_witness_recursions,
a61af66fc99e Initial load
duke
parents:
diff changeset
851 deps_find_witness_singles);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 if (final_stats || (TraceDependencies && WizardMode)) {
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1123
diff changeset
854 ttyLocker ttyl;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
855 tty->print_cr("Dependency check (find_witness) "
a61af66fc99e Initial load
duke
parents:
diff changeset
856 "calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d",
a61af66fc99e Initial load
duke
parents:
diff changeset
857 deps_find_witness_calls,
a61af66fc99e Initial load
duke
parents:
diff changeset
858 deps_find_witness_steps,
a61af66fc99e Initial load
duke
parents:
diff changeset
859 (double)deps_find_witness_steps / deps_find_witness_calls,
a61af66fc99e Initial load
duke
parents:
diff changeset
860 deps_find_witness_recursions,
a61af66fc99e Initial load
duke
parents:
diff changeset
861 deps_find_witness_singles);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #define count_find_witness_calls() (0)
a61af66fc99e Initial load
duke
parents:
diff changeset
870 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 klassOop ClassHierarchyWalker::find_witness_in(DepChange& changes,
a61af66fc99e Initial load
duke
parents:
diff changeset
874 klassOop context_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
875 bool participants_hide_witnesses) {
a61af66fc99e Initial load
duke
parents:
diff changeset
876 assert(changes.involves_context(context_type), "irrelevant dependency");
a61af66fc99e Initial load
duke
parents:
diff changeset
877 klassOop new_type = changes.new_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 count_find_witness_calls();
a61af66fc99e Initial load
duke
parents:
diff changeset
880 NOT_PRODUCT(deps_find_witness_singles++);
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Current thread must be in VM (not native mode, as in CI):
a61af66fc99e Initial load
duke
parents:
diff changeset
883 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // Must not move the class hierarchy during this check:
a61af66fc99e Initial load
duke
parents:
diff changeset
885 assert_locked_or_safepoint(Compile_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
886
30
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
887 int nof_impls = instanceKlass::cast(context_type)->nof_implementors();
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
888 if (nof_impls > 1) {
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
889 // Avoid this case: *I.m > { A.m, C }; B.m > C
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
890 // %%% Until this is fixed more systematically, bail out.
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
891 // See corresponding comment in find_witness_anywhere.
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
892 return context_type;
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
893 }
65a06b4a51b8 6610906: inexplicable IncompatibleClassChangeError
jrose
parents: 0
diff changeset
894
0
a61af66fc99e Initial load
duke
parents:
diff changeset
895 assert(!is_participant(new_type), "only old classes are participants");
a61af66fc99e Initial load
duke
parents:
diff changeset
896 if (participants_hide_witnesses) {
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // If the new type is a subtype of a participant, we are done.
a61af66fc99e Initial load
duke
parents:
diff changeset
898 for (int i = 0; i < num_participants(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 klassOop part = participant(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 if (part == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 assert(changes.involves_context(part) == Klass::cast(new_type)->is_subtype_of(part),
a61af66fc99e Initial load
duke
parents:
diff changeset
902 "correct marking of participants, b/c new_type is unique");
a61af66fc99e Initial load
duke
parents:
diff changeset
903 if (changes.involves_context(part)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // new guy is protected from this check by previous participant
a61af66fc99e Initial load
duke
parents:
diff changeset
905 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 if (is_witness(new_type) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
911 !ignore_witness(new_type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 return new_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Walk hierarchy under a context type, looking for unexpected types.
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // Do not report participant types, and recursively walk beneath
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // them only if participants_hide_witnesses is false.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // If top_level_call is false, skip testing the context type,
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // because the caller has already considered it.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 klassOop ClassHierarchyWalker::find_witness_anywhere(klassOop context_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
925 bool participants_hide_witnesses,
a61af66fc99e Initial load
duke
parents:
diff changeset
926 bool top_level_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // Current thread must be in VM (not native mode, as in CI):
a61af66fc99e Initial load
duke
parents:
diff changeset
928 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Must not move the class hierarchy during this check:
a61af66fc99e Initial load
duke
parents:
diff changeset
930 assert_locked_or_safepoint(Compile_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 bool do_counts = count_find_witness_calls();
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // Check the root of the sub-hierarchy first.
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (top_level_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (do_counts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 NOT_PRODUCT(deps_find_witness_calls++);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 NOT_PRODUCT(deps_find_witness_steps++);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 if (is_participant(context_type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 if (participants_hide_witnesses) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // else fall through to search loop...
a61af66fc99e Initial load
duke
parents:
diff changeset
943 } else if (is_witness(context_type) && !ignore_witness(context_type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // The context is an abstract class or interface, to start with.
a61af66fc99e Initial load
duke
parents:
diff changeset
945 return context_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // Now we must check each implementor and each subclass.
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Use a short worklist to avoid blowing the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Each worklist entry is a *chain* of subklass siblings to process.
a61af66fc99e Initial load
duke
parents:
diff changeset
952 const int CHAINMAX = 100; // >= 1 + instanceKlass::implementors_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
953 Klass* chains[CHAINMAX];
a61af66fc99e Initial load
duke
parents:
diff changeset
954 int chaini = 0; // index into worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
955 Klass* chain; // scratch variable
a61af66fc99e Initial load
duke
parents:
diff changeset
956 #define ADD_SUBCLASS_CHAIN(k) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
957 assert(chaini < CHAINMAX, "oob"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
958 chain = instanceKlass::cast(k)->subklass(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
959 if (chain != NULL) chains[chaini++] = chain; }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Look for non-abstract subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // (Note: Interfaces do not have subclasses.)
a61af66fc99e Initial load
duke
parents:
diff changeset
963 ADD_SUBCLASS_CHAIN(context_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // If it is an interface, search its direct implementors.
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // (Their subclasses are additional indirect implementors.
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // See instanceKlass::add_implementor.)
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // (Note: nof_implementors is always zero for non-interfaces.)
a61af66fc99e Initial load
duke
parents:
diff changeset
969 int nof_impls = instanceKlass::cast(context_type)->nof_implementors();
a61af66fc99e Initial load
duke
parents:
diff changeset
970 if (nof_impls > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // Avoid this case: *I.m > { A.m, C }; B.m > C
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // Here, I.m has 2 concrete implementations, but m appears unique
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // as A.m, because the search misses B.m when checking C.
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // The inherited method B.m was getting missed by the walker
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // when interface 'I' was the starting point.
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // %%% Until this is fixed more systematically, bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // (Old CHA had the same limitation.)
a61af66fc99e Initial load
duke
parents:
diff changeset
978 return context_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980 for (int i = 0; i < nof_impls; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 klassOop impl = instanceKlass::cast(context_type)->implementor(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if (impl == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // implementors array overflowed => no exact info.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 return context_type; // report an inexact witness to this sad affair
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986 if (do_counts)
a61af66fc99e Initial load
duke
parents:
diff changeset
987 { NOT_PRODUCT(deps_find_witness_steps++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (is_participant(impl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (participants_hide_witnesses) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // else fall through to process this guy's subclasses
a61af66fc99e Initial load
duke
parents:
diff changeset
991 } else if (is_witness(impl) && !ignore_witness(impl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 return impl;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
994 ADD_SUBCLASS_CHAIN(impl);
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // Recursively process each non-trivial sibling chain.
a61af66fc99e Initial load
duke
parents:
diff changeset
998 while (chaini > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
999 Klass* chain = chains[--chaini];
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 for (Klass* subk = chain; subk != NULL; subk = subk->next_sibling()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 klassOop sub = subk->as_klassOop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 if (do_counts) { NOT_PRODUCT(deps_find_witness_steps++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 if (is_participant(sub)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 if (participants_hide_witnesses) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // else fall through to process this guy's subclasses
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 } else if (is_witness(sub) && !ignore_witness(sub)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 return sub;
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if (chaini < (VerifyDependencies? 2: CHAINMAX)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // Fast path. (Partially disabled if VerifyDependencies.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 ADD_SUBCLASS_CHAIN(sub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // Worklist overflow. Do a recursive call. Should be rare.
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // The recursive call will have its own worklist, of course.
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // (Note that sub has already been tested, so that there is
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // no need for the recursive call to re-test. That's handy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // since the recursive call sees sub as the context_type.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 if (do_counts) { NOT_PRODUCT(deps_find_witness_recursions++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 klassOop witness = find_witness_anywhere(sub,
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 participants_hide_witnesses,
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 /*top_level_call=*/ false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 if (witness != NULL) return witness;
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // No witness found. The dependency remains unbroken.
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 #undef ADD_SUBCLASS_CHAIN
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 bool Dependencies::is_concrete_klass(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 if (Klass::cast(k)->is_abstract()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // %%% We could treat classes which are concrete but
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // have not yet been instantiated as virtually abstract.
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // This would require a deoptimization barrier on first instantiation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 //if (k->is_not_instantiated()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 bool Dependencies::is_concrete_method(methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 if (m->is_abstract()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // %%% We could treat unexecuted methods as virtually abstract also.
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // This would require a deoptimization barrier on first execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 return !m->is_abstract();
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 Klass* Dependencies::find_finalizable_subclass(Klass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 if (k->is_interface()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 if (k->has_finalizer()) return k;
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 k = k->subklass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 while (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 Klass* result = find_finalizable_subclass(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 if (result != NULL) return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 k = k->next_sibling();
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 bool Dependencies::is_concrete_klass(ciInstanceKlass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 if (k->is_abstract()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // We could return also false if k does not yet appear to be
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // instantiated, if the VM version supports this distinction also.
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 //if (k->is_not_instantiated()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 bool Dependencies::is_concrete_method(ciMethod* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // Statics are irrelevant to virtual call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 if (m->is_static()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // We could return also false if m does not yet appear to be
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // executed, if the VM version supports this distinction also.
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 return !m->is_abstract();
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 return k->has_finalizable_subclass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // Any use of the contents (bytecodes) of a method must be
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // marked by an "evol_method" dependency, if those contents
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // can change. (Note: A method is always dependent on itself.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 klassOop Dependencies::check_evol_method(methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // Did somebody do a JVMTI RedefineClasses while our backs were turned?
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // Or is there a now a breakpoint?
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // (Assumes compiled code cannot handle bkpts; change if UseFastBreakpoints.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 if (m->is_old()
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 || m->number_of_breakpoints() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 return m->method_holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // This is a strong assertion: It is that the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // has no subtypes whatever. It is most useful for
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // optimizing checks on reflected types or on array types.
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // (Checks on types which are derived from real instances
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // can be optimized more strongly than this, because we
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // know that the checked type comes from a concrete type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // and therefore we can disregard abstract types.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 klassOop Dependencies::check_leaf_type(klassOop ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 assert(must_be_in_vm(), "raw oops here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 assert_locked_or_safepoint(Compile_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 instanceKlass* ctx = instanceKlass::cast(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 Klass* sub = ctx->subklass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if (sub != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 return sub->as_klassOop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 } else if (ctx->nof_implementors() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // if it is an interface, it must be unimplemented
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // (if it is not an interface, nof_implementors is always zero)
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 klassOop impl = ctx->implementor(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 return (impl != NULL)? impl: ctxk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Test the assertion that conck is the only concrete subtype* of ctxk.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // The type conck itself is allowed to have have further concrete subtypes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // This allows the compiler to narrow occurrences of ctxk by conck,
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // when dealing with the types of actual instances.
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 klassOop Dependencies::check_abstract_with_unique_concrete_subtype(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 klassOop conck,
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 ClassHierarchyWalker wf(conck);
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 return wf.find_witness_subtype(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // If a non-concrete class has no concrete subtypes, it is not (yet)
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // instantiatable. This can allow the compiler to make some paths go
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // dead, if they are gated by a test of the type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 klassOop Dependencies::check_abstract_with_no_concrete_subtype(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Find any concrete subtype, with no participants:
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 ClassHierarchyWalker wf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 return wf.find_witness_subtype(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // If a concrete class has no concrete subtypes, it can always be
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // exactly typed. This allows the use of a cheaper type test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 klassOop Dependencies::check_concrete_with_no_concrete_subtype(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // Find any concrete subtype, with only the ctxk as participant:
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 ClassHierarchyWalker wf(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 return wf.find_witness_subtype(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // Find the unique concrete proper subtype of ctxk, or NULL if there
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // is more than one concrete proper subtype. If there are no concrete
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // proper subtypes, return ctxk itself, whether it is concrete or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // The returned subtype is allowed to have have further concrete subtypes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // That is, return CC1 for CX > CC1 > CC2, but NULL for CX > { CC1, CC2 }.
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 klassOop Dependencies::find_unique_concrete_subtype(klassOop ctxk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 ClassHierarchyWalker wf(ctxk); // Ignore ctxk when walking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 wf.record_witnesses(1); // Record one other witness when walking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 klassOop wit = wf.find_witness_subtype(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 if (wit != NULL) return NULL; // Too many witnesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 klassOop conck = wf.participant(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 if (conck == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // Make sure the dependency mechanism will pass this discovery:
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 if (VerifyDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Turn off dependency tracing while actually testing deps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 FlagSetting fs(TraceDependencies, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 if (!Dependencies::is_concrete_klass(ctxk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 guarantee(NULL ==
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 (void *)check_abstract_with_no_concrete_subtype(ctxk),
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 guarantee(NULL ==
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 (void *)check_concrete_with_no_concrete_subtype(ctxk),
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 return ctxk; // Return ctxk as a flag for "no subtypes".
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // Make sure the dependency mechanism will pass this discovery:
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 if (VerifyDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // Turn off dependency tracing while actually testing deps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 FlagSetting fs(TraceDependencies, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 if (!Dependencies::is_concrete_klass(ctxk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 guarantee(NULL == (void *)
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 check_abstract_with_unique_concrete_subtype(ctxk, conck),
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 return conck;
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1203
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // Test the assertion that the k[12] are the only concrete subtypes of ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // except possibly for further subtypes of k[12] themselves.
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // The context type must be abstract. The types k1 and k2 are themselves
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // allowed to have further concrete subtypes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 klassOop Dependencies::check_abstract_with_exclusive_concrete_subtypes(
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 klassOop k1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 klassOop k2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 ClassHierarchyWalker wf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 wf.add_participant(k1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 wf.add_participant(k2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 return wf.find_witness_subtype(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Search ctxk for concrete implementations. If there are klen or fewer,
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // pack them into the given array and return the number.
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // Otherwise, return -1, meaning the given array would overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // (Note that a return of 0 means there are exactly no concrete subtypes.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // In this search, if ctxk is concrete, it will be reported alone.
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // For any type CC reported, no proper subtypes of CC will be reported.
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 int Dependencies::find_exclusive_concrete_subtypes(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 int klen,
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 klassOop karray[]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 ClassHierarchyWalker wf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 wf.record_witnesses(klen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 klassOop wit = wf.find_witness_subtype(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (wit != NULL) return -1; // Too many witnesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 int num = wf.num_participants();
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 assert(num <= klen, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // Pack the result array with the good news.
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 for (int i = 0; i < num; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 karray[i] = wf.participant(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // Make sure the dependency mechanism will pass this discovery:
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 if (VerifyDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // Turn off dependency tracing while actually testing deps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 FlagSetting fs(TraceDependencies, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 switch (Dependencies::is_concrete_klass(ctxk)? -1: num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 case -1: // ctxk was itself concrete
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 guarantee(num == 1 && karray[0] == ctxk, "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 case 0:
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 guarantee(NULL == (void *)check_abstract_with_no_concrete_subtype(ctxk),
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 case 1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 guarantee(NULL == (void *)
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 check_abstract_with_unique_concrete_subtype(ctxk, karray[0]),
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 case 2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 guarantee(NULL == (void *)
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 check_abstract_with_exclusive_concrete_subtypes(ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 karray[0],
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 karray[1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 ShouldNotReachHere(); // klen > 2 yet supported
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 return num;
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // If a class (or interface) has a unique concrete method uniqm, return NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // Otherwise, return a class that contains an interfering method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Here is a missing optimization: If uniqm->is_final(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // we don't really need to search beneath it for overrides.
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // This is probably not important, since we don't use dependencies
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // to track final methods. (They can't be "definalized".)
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 ClassHierarchyWalker wf(uniqm->method_holder(), uniqm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 return wf.find_witness_definer(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1281
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // Find the set of all non-abstract methods under ctxk that match m.
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // (The method m must be defined or inherited in ctxk.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // Include m itself in the set, unless it is abstract.
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // If this set has exactly one element, return that element.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 methodOop Dependencies::find_unique_concrete_method(klassOop ctxk, methodOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 ClassHierarchyWalker wf(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 assert(wf.check_method_context(ctxk, m), "proper context");
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 wf.record_witnesses(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 klassOop wit = wf.find_witness_definer(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 if (wit != NULL) return NULL; // Too many witnesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 methodOop fm = wf.found_method(0); // Will be NULL if num_parts == 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 if (Dependencies::is_concrete_method(m)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 if (fm == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // It turns out that m was always the only implementation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 fm = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 } else if (fm != m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // Two conflicting implementations after all.
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // (This can happen if m is inherited into ctxk and fm overrides it.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // Make sure the dependency mechanism will pass this discovery:
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if (VerifyDependencies && fm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 guarantee(NULL == (void *)check_unique_concrete_method(ctxk, fm),
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 return fm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 klassOop Dependencies::check_exclusive_concrete_methods(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 methodOop m1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 methodOop m2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 ClassHierarchyWalker wf(m1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 wf.add_participant(m1->method_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 wf.add_participant(m2->method_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 return wf.find_witness_definer(ctxk, changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // Find the set of all non-abstract methods under ctxk that match m[0].
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // (The method m[0] must be defined or inherited in ctxk.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // Include m itself in the set, unless it is abstract.
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // Fill the given array m[0..(mlen-1)] with this set, and return the length.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // (The length may be zero if no concrete methods are found anywhere.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // If there are too many concrete methods to fit in marray, return -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 int Dependencies::find_exclusive_concrete_methods(klassOop ctxk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 int mlen,
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 methodOop marray[]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 methodOop m0 = marray[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 ClassHierarchyWalker wf(m0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 assert(wf.check_method_context(ctxk, m0), "proper context");
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 wf.record_witnesses(mlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 bool participants_hide_witnesses = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 klassOop wit = wf.find_witness_definer(ctxk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if (wit != NULL) return -1; // Too many witnesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 int num = wf.num_participants();
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 assert(num <= mlen, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // Keep track of whether m is also part of the result set.
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 int mfill = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 assert(marray[mfill] == m0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 if (Dependencies::is_concrete_method(m0))
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 mfill++; // keep m0 as marray[0], the first result
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 for (int i = 0; i < num; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 methodOop fm = wf.found_method(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 if (fm == m0) continue; // Already put this guy in the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 if (mfill == mlen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 return -1; // Oops. Too many methods after all!
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 marray[mfill++] = fm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // Make sure the dependency mechanism will pass this discovery:
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 if (VerifyDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // Turn off dependency tracing while actually testing deps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 FlagSetting fs(TraceDependencies, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 switch (mfill) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 case 1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 case 2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 guarantee(NULL == (void *)
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 check_exclusive_concrete_methods(ctxk, marray[0], marray[1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 "verify dep.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 ShouldNotReachHere(); // mlen > 2 yet supported
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 return mfill;
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk, DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 Klass* search_at = ctxk->klass_part();
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 if (changes != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 search_at = changes->new_type()->klass_part(); // just look at the new bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 Klass* result = find_finalizable_subclass(search_at);
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 return result->as_klassOop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 klassOop Dependencies::DepStream::check_dependency_impl(DepChange* changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 assert_locked_or_safepoint(Compile_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1392
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 klassOop witness = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 switch (type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 case evol_method:
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 witness = check_evol_method(method_argument(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 case leaf_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 witness = check_leaf_type(context_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 case abstract_with_unique_concrete_subtype:
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 witness = check_abstract_with_unique_concrete_subtype(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 type_argument(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 case abstract_with_no_concrete_subtype:
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 witness = check_abstract_with_no_concrete_subtype(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 case concrete_with_no_concrete_subtype:
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 witness = check_concrete_with_no_concrete_subtype(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 case unique_concrete_method:
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 witness = check_unique_concrete_method(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 method_argument(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 case abstract_with_exclusive_concrete_subtypes_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 witness = check_abstract_with_exclusive_concrete_subtypes(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 type_argument(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 type_argument(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 case exclusive_concrete_methods_2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 witness = check_exclusive_concrete_methods(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 method_argument(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 method_argument(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 case no_finalizable_subclasses:
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 witness = check_has_no_finalizable_subclasses(context_type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 witness = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 if (witness != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 if (TraceDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 print_dependency(witness, /*verbose=*/ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // The following is a no-op unless logging is enabled:
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 log_dependency(witness);
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 return witness;
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1449
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 klassOop Dependencies::DepStream::spot_check_dependency_at(DepChange& changes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 if (!changes.involves_context(context_type()))
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // irrelevant dependency; skip it
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 return check_dependency_impl(&changes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 void DepChange::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // entire transaction must be under this lock:
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 assert_lock_strong(Compile_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // Mark all dependee and all its superclasses
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // Mark transitive interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 for (ContextStream str(*this); str.next(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 klassOop d = str.klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
975
83c29a26f67c 6879572: SA fails _is_marked_dependent not found
acorn
parents: 973
diff changeset
1469 instanceKlass::cast(d)->set_is_marked_dependent(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 DepChange::~DepChange() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // Unmark all dependee and all its superclasses
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // Unmark transitive interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 for (ContextStream str(*this); str.next(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 klassOop d = str.klass();
975
83c29a26f67c 6879572: SA fails _is_marked_dependent not found
acorn
parents: 973
diff changeset
1478 instanceKlass::cast(d)->set_is_marked_dependent(false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 bool DepChange::involves_context(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 if (k == NULL || !Klass::cast(k)->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 instanceKlass* ik = instanceKlass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 bool is_contained = ik->is_marked_dependent();
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 assert(is_contained == Klass::cast(new_type())->is_subtype_of(k),
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 "correct marking of potential context types");
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 return is_contained;
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 bool DepChange::ContextStream::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 switch (_change_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 case Start_Klass: // initial state; _klass is the new type
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 _ti_base = instanceKlass::cast(_klass)->transitive_interfaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 _ti_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 _change_type = Change_new_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 case Change_new_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 _change_type = Change_new_sub;
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 case Change_new_sub:
54
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1504 // 6598190: brackets workaround Sun Studio C++ compiler bug 6629277
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1505 {
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1506 _klass = instanceKlass::cast(_klass)->super();
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1507 if (_klass != NULL) {
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1508 return true;
d4a0f561287a 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops
sbohne
parents: 0
diff changeset
1509 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // else set up _ti_limit and fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 _change_type = Change_new_impl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 case Change_new_impl:
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 if (_ti_index < _ti_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 _klass = klassOop( _ti_base->obj_at(_ti_index++) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 // fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 _change_type = NO_CHANGE; // iterator is exhausted
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 case NO_CHANGE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1528
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 void DepChange::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 int nsup = 0, nint = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 for (ContextStream str(*this); str.next(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 klassOop k = str.klass();
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1533 switch (str.change_type()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 case Change_new_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 tty->print_cr(" dependee = %s", instanceKlass::cast(k)->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 case Change_new_sub:
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1538 if (!WizardMode) {
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1539 ++nsup;
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1540 } else {
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1541 tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name());
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1542 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 case Change_new_impl:
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1545 if (!WizardMode) {
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1546 ++nint;
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1547 } else {
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1548 tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name());
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 993
diff changeset
1549 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 if (nsup + nint != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 tty->print_cr(" context supers = %d, interfaces = %d", nsup, nint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 void Dependencies::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 if (deps_find_witness_print != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // Call one final time, to flush out the data.
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 deps_find_witness_print = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 count_find_witness_calls();
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 #endif