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