Mercurial > hg > truffle
annotate src/share/vm/code/dependencies.hpp @ 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 | c4f1e23c4139 d5b74c583ec1 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
2 * Copyright (c) 2005, 2012, 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:
1123
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1123
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:
1123
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP |
26 #define SHARE_VM_CODE_DEPENDENCIES_HPP | |
27 | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
28 #include "ci/ciCallSite.hpp" |
1972 | 29 #include "ci/ciKlass.hpp" |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
30 #include "ci/ciMethodHandle.hpp" |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
31 #include "classfile/systemDictionary.hpp" |
1972 | 32 #include "code/compressedStream.hpp" |
33 #include "code/nmethod.hpp" | |
34 #include "utilities/growableArray.hpp" | |
35 | |
0 | 36 //** Dependencies represent assertions (approximate invariants) within |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
37 // the runtime system, e.g. class hierarchy changes. An example is an |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
38 // assertion that a given method is not overridden; another example is |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
39 // that a type has only one concrete subtype. Compiled code which |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
40 // relies on such assertions must be discarded if they are overturned |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
41 // by changes in the runtime system. We can think of these assertions |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
42 // as approximate invariants, because we expect them to be overturned |
0 | 43 // very infrequently. We are willing to perform expensive recovery |
44 // operations when they are overturned. The benefit, of course, is | |
45 // performing optimistic optimizations (!) on the object code. | |
46 // | |
47 // Changes in the class hierarchy due to dynamic linking or | |
48 // class evolution can violate dependencies. There is enough | |
49 // indexing between classes and nmethods to make dependency | |
50 // checking reasonably efficient. | |
51 | |
52 class ciEnv; | |
53 class nmethod; | |
54 class OopRecorder; | |
55 class xmlStream; | |
56 class CompileLog; | |
57 class DepChange; | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
58 class KlassDepChange; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
59 class CallSiteDepChange; |
0 | 60 class No_Safepoint_Verifier; |
61 | |
62 class Dependencies: public ResourceObj { | |
63 public: | |
64 // Note: In the comments on dependency types, most uses of the terms | |
65 // subtype and supertype are used in a "non-strict" or "inclusive" | |
66 // sense, and are starred to remind the reader of this fact. | |
67 // Strict uses of the terms use the word "proper". | |
68 // | |
69 // Specifically, every class is its own subtype* and supertype*. | |
70 // (This trick is easier than continually saying things like "Y is a | |
71 // subtype of X or X itself".) | |
72 // | |
73 // Sometimes we write X > Y to mean X is a proper supertype of Y. | |
74 // The notation X > {Y, Z} means X has proper subtypes Y, Z. | |
75 // The notation X.m > Y means that Y inherits m from X, while | |
76 // X.m > Y.m means Y overrides X.m. A star denotes abstractness, | |
77 // as *I > A, meaning (abstract) interface I is a super type of A, | |
78 // or A.*m > B.m, meaning B.m implements abstract method A.m. | |
79 // | |
80 // In this module, the terms "subtype" and "supertype" refer to | |
81 // Java-level reference type conversions, as detected by | |
82 // "instanceof" and performed by "checkcast" operations. The method | |
83 // Klass::is_subtype_of tests these relations. Note that "subtype" | |
84 // is richer than "subclass" (as tested by Klass::is_subclass_of), | |
85 // since it takes account of relations involving interface and array | |
86 // types. | |
87 // | |
88 // To avoid needless complexity, dependencies involving array types | |
89 // are not accepted. If you need to make an assertion about an | |
90 // array type, make the assertion about its corresponding element | |
91 // types. Any assertion that might change about an array type can | |
92 // be converted to an assertion about its element type. | |
93 // | |
94 // Most dependencies are evaluated over a "context type" CX, which | |
95 // stands for the set Subtypes(CX) of every Java type that is a subtype* | |
96 // of CX. When the system loads a new class or interface N, it is | |
97 // responsible for re-evaluating changed dependencies whose context | |
98 // type now includes N, that is, all super types of N. | |
99 // | |
100 enum DepType { | |
101 end_marker = 0, | |
102 | |
103 // An 'evol' dependency simply notes that the contents of the | |
104 // method were used. If it evolves (is replaced), the nmethod | |
105 // must be recompiled. No other dependencies are implied. | |
106 evol_method, | |
107 FIRST_TYPE = evol_method, | |
108 | |
109 // A context type CX is a leaf it if has no proper subtype. | |
110 leaf_type, | |
111 | |
112 // An abstract class CX has exactly one concrete subtype CC. | |
113 abstract_with_unique_concrete_subtype, | |
114 | |
115 // The type CX is purely abstract, with no concrete subtype* at all. | |
116 abstract_with_no_concrete_subtype, | |
117 | |
118 // The concrete CX is free of concrete proper subtypes. | |
119 concrete_with_no_concrete_subtype, | |
120 | |
121 // Given a method M1 and a context class CX, the set MM(CX, M1) of | |
122 // "concrete matching methods" in CX of M1 is the set of every | |
123 // concrete M2 for which it is possible to create an invokevirtual | |
124 // or invokeinterface call site that can reach either M1 or M2. | |
125 // That is, M1 and M2 share a name, signature, and vtable index. | |
126 // We wish to notice when the set MM(CX, M1) is just {M1}, or | |
127 // perhaps a set of two {M1,M2}, and issue dependencies on this. | |
128 | |
129 // The set MM(CX, M1) can be computed by starting with any matching | |
130 // concrete M2 that is inherited into CX, and then walking the | |
131 // subtypes* of CX looking for concrete definitions. | |
132 | |
133 // The parameters to this dependency are the method M1 and the | |
134 // context class CX. M1 must be either inherited in CX or defined | |
135 // in a subtype* of CX. It asserts that MM(CX, M1) is no greater | |
136 // than {M1}. | |
137 unique_concrete_method, // one unique concrete method under CX | |
138 | |
139 // An "exclusive" assertion concerns two methods or subtypes, and | |
140 // declares that there are at most two (or perhaps later N>2) | |
141 // specific items that jointly satisfy the restriction. | |
142 // We list all items explicitly rather than just giving their | |
143 // count, for robustness in the face of complex schema changes. | |
144 | |
145 // A context class CX (which may be either abstract or concrete) | |
146 // has two exclusive concrete subtypes* C1, C2 if every concrete | |
147 // subtype* of CX is either C1 or C2. Note that if neither C1 or C2 | |
148 // are equal to CX, then CX itself must be abstract. But it is | |
149 // also possible (for example) that C1 is CX (a concrete class) | |
150 // and C2 is a proper subtype of C1. | |
151 abstract_with_exclusive_concrete_subtypes_2, | |
152 | |
153 // This dependency asserts that MM(CX, M1) is no greater than {M1,M2}. | |
154 exclusive_concrete_methods_2, | |
155 | |
156 // This dependency asserts that no instances of class or it's | |
157 // subclasses require finalization registration. | |
158 no_finalizable_subclasses, | |
159 | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
160 // This dependency asserts when the CallSite.target value changed. |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
161 call_site_target_value, |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
162 |
0 | 163 TYPE_LIMIT |
164 }; | |
165 enum { | |
166 LG2_TYPE_LIMIT = 4, // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT)) | |
167 | |
168 // handy categorizations of dependency types: | |
3894
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
169 all_types = ((1 << TYPE_LIMIT) - 1) & ((-1) << FIRST_TYPE), |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
170 |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
171 non_klass_types = (1 << call_site_target_value), |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
172 klass_types = all_types & ~non_klass_types, |
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 non_ctxk_types = (1 << evol_method), |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
175 implicit_ctxk_types = (1 << call_site_target_value), |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
176 explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types), |
0 | 177 |
178 max_arg_count = 3, // current maximum number of arguments (incl. ctxk) | |
179 | |
180 // A "context type" is a class or interface that | |
181 // provides context for evaluating a dependency. | |
182 // When present, it is one of the arguments (dep_context_arg). | |
183 // | |
184 // If a dependency does not have a context type, there is a | |
185 // default context, depending on the type of the dependency. | |
186 // This bit signals that a default context has been compressed away. | |
187 default_context_type_bit = (1<<LG2_TYPE_LIMIT) | |
188 }; | |
189 | |
190 static const char* dep_name(DepType dept); | |
191 static int dep_args(DepType dept); | |
3894
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
192 |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
193 static bool is_klass_type( DepType dept) { return dept_in_mask(dept, klass_types ); } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
194 |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
195 static bool has_explicit_context_arg(DepType dept) { return dept_in_mask(dept, explicit_ctxk_types); } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
196 static bool has_implicit_context_arg(DepType dept) { return dept_in_mask(dept, implicit_ctxk_types); } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
197 |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
198 static int dep_context_arg(DepType dept) { return has_explicit_context_arg(dept) ? 0 : -1; } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
199 static int dep_implicit_context_arg(DepType dept) { return has_implicit_context_arg(dept) ? 0 : -1; } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
200 |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
201 static void check_valid_dependency_type(DepType dept); |
0 | 202 |
203 private: | |
204 // State for writing a new set of dependencies: | |
205 GrowableArray<int>* _dep_seen; // (seen[h->ident] & (1<<dept)) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
206 GrowableArray<ciBaseObject*>* _deps[TYPE_LIMIT]; |
0 | 207 |
208 static const char* _dep_name[TYPE_LIMIT]; | |
209 static int _dep_args[TYPE_LIMIT]; | |
210 | |
211 static bool dept_in_mask(DepType dept, int mask) { | |
212 return (int)dept >= 0 && dept < TYPE_LIMIT && ((1<<dept) & mask) != 0; | |
213 } | |
214 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
215 bool note_dep_seen(int dept, ciBaseObject* x) { |
0 | 216 assert(dept < BitsPerInt, "oob"); |
217 int x_id = x->ident(); | |
218 assert(_dep_seen != NULL, "deps must be writable"); | |
219 int seen = _dep_seen->at_grow(x_id, 0); | |
220 _dep_seen->at_put(x_id, seen | (1<<dept)); | |
221 // return true if we've already seen dept/x | |
222 return (seen & (1<<dept)) != 0; | |
223 } | |
224 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
225 bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps, |
0 | 226 int ctxk_i, ciKlass* ctxk); |
227 | |
228 void sort_all_deps(); | |
229 size_t estimate_size_in_bytes(); | |
230 | |
231 // Initialize _deps, etc. | |
232 void initialize(ciEnv* env); | |
233 | |
234 // State for making a new set of dependencies: | |
235 OopRecorder* _oop_recorder; | |
236 | |
237 // Logging support | |
238 CompileLog* _log; | |
239 | |
240 address _content_bytes; // everything but the oop references, encoded | |
241 size_t _size_in_bytes; | |
242 | |
243 public: | |
244 // Make a new empty dependencies set. | |
245 Dependencies(ciEnv* env) { | |
246 initialize(env); | |
247 } | |
248 | |
249 private: | |
250 // Check for a valid context type. | |
251 // Enforce the restriction against array types. | |
252 static void check_ctxk(ciKlass* ctxk) { | |
253 assert(ctxk->is_instance_klass(), "java types only"); | |
254 } | |
255 static void check_ctxk_concrete(ciKlass* ctxk) { | |
256 assert(is_concrete_klass(ctxk->as_instance_klass()), "must be concrete"); | |
257 } | |
258 static void check_ctxk_abstract(ciKlass* ctxk) { | |
259 check_ctxk(ctxk); | |
260 assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract"); | |
261 } | |
262 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
263 void assert_common_1(DepType dept, ciBaseObject* x); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
264 void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
265 void assert_common_3(DepType dept, ciKlass* ctxk, ciBaseObject* x1, ciBaseObject* x2); |
0 | 266 |
267 public: | |
268 // Adding assertions to a new dependency set at compile time: | |
269 void assert_evol_method(ciMethod* m); | |
270 void assert_leaf_type(ciKlass* ctxk); | |
271 void assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck); | |
272 void assert_abstract_with_no_concrete_subtype(ciKlass* ctxk); | |
273 void assert_concrete_with_no_concrete_subtype(ciKlass* ctxk); | |
274 void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); | |
275 void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); | |
276 void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); | |
277 void assert_has_no_finalizable_subclasses(ciKlass* ctxk); | |
3894
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
278 void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); |
0 | 279 |
280 // Define whether a given method or type is concrete. | |
281 // These methods define the term "concrete" as used in this module. | |
282 // For this module, an "abstract" class is one which is non-concrete. | |
283 // | |
284 // Future optimizations may allow some classes to remain | |
285 // non-concrete until their first instantiation, and allow some | |
286 // methods to remain non-concrete until their first invocation. | |
287 // In that case, there would be a middle ground between concrete | |
288 // and abstract (as defined by the Java language and VM). | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
289 static bool is_concrete_klass(Klass* k); // k is instantiable |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
290 static bool is_concrete_method(Method* m); // m is invocable |
0 | 291 static Klass* find_finalizable_subclass(Klass* k); |
292 | |
293 // These versions of the concreteness queries work through the CI. | |
294 // The CI versions are allowed to skew sometimes from the VM | |
295 // (oop-based) versions. The cost of such a difference is a | |
296 // (safely) aborted compilation, or a deoptimization, or a missed | |
297 // optimization opportunity. | |
298 // | |
299 // In order to prevent spurious assertions, query results must | |
300 // remain stable within any single ciEnv instance. (I.e., they must | |
301 // not go back into the VM to get their value; they must cache the | |
302 // bit in the CI, either eagerly or lazily.) | |
303 static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable | |
304 static bool is_concrete_method(ciMethod* m); // m appears invocable | |
305 static bool has_finalizable_subclass(ciInstanceKlass* k); | |
306 | |
307 // As a general rule, it is OK to compile under the assumption that | |
308 // a given type or method is concrete, even if it at some future | |
309 // point becomes abstract. So dependency checking is one-sided, in | |
310 // that it permits supposedly concrete classes or methods to turn up | |
311 // as really abstract. (This shouldn't happen, except during class | |
312 // evolution, but that's the logic of the checking.) However, if a | |
313 // supposedly abstract class or method suddenly becomes concrete, a | |
314 // dependency on it must fail. | |
315 | |
316 // Checking old assertions at run-time (in the VM only): | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
317 static Klass* check_evol_method(Method* m); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
318 static Klass* check_leaf_type(Klass* ctxk); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
319 static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
320 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
321 static Klass* check_abstract_with_no_concrete_subtype(Klass* ctxk, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
322 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
323 static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
324 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
325 static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
326 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
327 static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
328 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
329 static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2, |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
330 KlassDepChange* changes = NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
331 static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
332 static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
333 // A returned Klass* is NULL if the dependency assertion is still |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
334 // valid. A non-NULL Klass* is a 'witness' to the assertion |
0 | 335 // failure, a point in the class hierarchy where the assertion has |
336 // been proven false. For example, if check_leaf_type returns | |
337 // non-NULL, the value is a subtype of the supposed leaf type. This | |
338 // witness value may be useful for logging the dependency failure. | |
339 // Note that, when a dependency fails, there may be several possible | |
340 // witnesses to the failure. The value returned from the check_foo | |
341 // method is chosen arbitrarily. | |
342 | |
343 // The 'changes' value, if non-null, requests a limited spot-check | |
344 // near the indicated recent changes in the class hierarchy. | |
345 // It is used by DepStream::spot_check_dependency_at. | |
346 | |
347 // Detecting possible new assertions: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
348 static Klass* find_unique_concrete_subtype(Klass* ctxk); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
349 static Method* find_unique_concrete_method(Klass* ctxk, Method* m); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
350 static int find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
351 static int find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]); |
0 | 352 |
353 // Create the encoding which will be stored in an nmethod. | |
354 void encode_content_bytes(); | |
355 | |
356 address content_bytes() { | |
357 assert(_content_bytes != NULL, "encode it first"); | |
358 return _content_bytes; | |
359 } | |
360 size_t size_in_bytes() { | |
361 assert(_content_bytes != NULL, "encode it first"); | |
362 return _size_in_bytes; | |
363 } | |
364 | |
365 OopRecorder* oop_recorder() { return _oop_recorder; } | |
366 CompileLog* log() { return _log; } | |
367 | |
368 void copy_to(nmethod* nm); | |
369 | |
370 void log_all_dependencies(); | |
20316
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
371 |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
372 void log_dependency(DepType dept, GrowableArray<ciBaseObject*>* args) { |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
373 ResourceMark rm; |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
374 int argslen = args->length(); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
375 write_dependency_to(log(), dept, args); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
376 guarantee(argslen == args->length(), |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
377 "args array cannot grow inside nested ResoureMark scope"); |
0 | 378 } |
20316
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
379 |
0 | 380 void log_dependency(DepType dept, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
381 ciBaseObject* x0, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
382 ciBaseObject* x1 = NULL, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
383 ciBaseObject* x2 = NULL) { |
20316
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
384 if (log() == NULL) { |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
385 return; |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
386 } |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
387 ResourceMark rm; |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
388 GrowableArray<ciBaseObject*>* ciargs = |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
389 new GrowableArray<ciBaseObject*>(dep_args(dept)); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
390 assert (x0 != NULL, "no log x0"); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
391 ciargs->push(x0); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
392 |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
393 if (x1 != NULL) { |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
394 ciargs->push(x1); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
395 } |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
396 if (x2 != NULL) { |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
397 ciargs->push(x2); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
398 } |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
399 assert(ciargs->length() == dep_args(dept), ""); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
400 log_dependency(dept, ciargs); |
0 | 401 } |
402 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
403 class DepArgument : public ResourceObj { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
404 private: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
405 bool _is_oop; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
406 bool _valid; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
407 void* _value; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
408 public: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
409 DepArgument() : _is_oop(false), _value(NULL), _valid(false) {} |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
410 DepArgument(oop v): _is_oop(true), _value(v), _valid(true) {} |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
411 DepArgument(Metadata* v): _is_oop(false), _value(v), _valid(true) {} |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
412 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
413 bool is_null() const { return _value == NULL; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
414 bool is_oop() const { return _is_oop; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
415 bool is_metadata() const { return !_is_oop; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
416 bool is_klass() const { return is_metadata() && metadata_value()->is_klass(); } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
417 bool is_method() const { return is_metadata() && metadata_value()->is_method(); } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
418 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
419 oop oop_value() const { assert(_is_oop && _valid, "must be"); return (oop) _value; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
420 Metadata* metadata_value() const { assert(!_is_oop && _valid, "must be"); return (Metadata*) _value; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
421 }; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
422 |
0 | 423 static void print_dependency(DepType dept, |
20316
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
424 GrowableArray<DepArgument>* args, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
425 Klass* witness = NULL); |
0 | 426 |
427 private: | |
428 // helper for encoding common context types as zero: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
429 static ciKlass* ctxk_encoded_as_null(DepType dept, ciBaseObject* x); |
0 | 430 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
431 static Klass* ctxk_encoded_as_null(DepType dept, Metadata* x); |
0 | 432 |
20316
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
433 static void write_dependency_to(CompileLog* log, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
434 DepType dept, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
435 GrowableArray<ciBaseObject*>* args, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
436 Klass* witness = NULL); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
437 static void write_dependency_to(CompileLog* log, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
438 DepType dept, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
439 GrowableArray<DepArgument>* args, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
440 Klass* witness = NULL); |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
441 static void write_dependency_to(xmlStream* xtty, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
442 DepType dept, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
443 GrowableArray<DepArgument>* args, |
3c048df3ef8b
8040920: Uninitialised memory in hotspot/src/share/vm/code/dependencies.cpp
morris
parents:
6725
diff
changeset
|
444 Klass* witness = NULL); |
0 | 445 public: |
446 // Use this to iterate over an nmethod's dependency set. | |
447 // Works on new and old dependency sets. | |
448 // Usage: | |
449 // | |
450 // ; | |
451 // Dependencies::DepType dept; | |
452 // for (Dependencies::DepStream deps(nm); deps.next(); ) { | |
453 // ... | |
454 // } | |
455 // | |
456 // The caller must be in the VM, since oops are not wrapped in handles. | |
457 class DepStream { | |
458 private: | |
459 nmethod* _code; // null if in a compiler thread | |
460 Dependencies* _deps; // null if not in a compiler thread | |
461 CompressedReadStream _bytes; | |
462 #ifdef ASSERT | |
463 size_t _byte_limit; | |
464 #endif | |
465 | |
466 // iteration variables: | |
467 DepType _type; | |
468 int _xi[max_arg_count+1]; | |
469 | |
470 void initial_asserts(size_t byte_limit) NOT_DEBUG({}); | |
471 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
472 inline Metadata* recorded_metadata_at(int i); |
0 | 473 inline oop recorded_oop_at(int i); |
474 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
475 Klass* check_klass_dependency(KlassDepChange* changes); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
476 Klass* check_call_site_dependency(CallSiteDepChange* changes); |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
477 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
478 void trace_and_log_witness(Klass* witness); |
0 | 479 |
480 public: | |
481 DepStream(Dependencies* deps) | |
482 : _deps(deps), | |
483 _code(NULL), | |
484 _bytes(deps->content_bytes()) | |
485 { | |
486 initial_asserts(deps->size_in_bytes()); | |
487 } | |
488 DepStream(nmethod* code) | |
489 : _deps(NULL), | |
490 _code(code), | |
491 _bytes(code->dependencies_begin()) | |
492 { | |
493 initial_asserts(code->dependencies_size()); | |
494 } | |
495 | |
496 bool next(); | |
497 | |
498 DepType type() { return _type; } | |
499 int argument_count() { return dep_args(type()); } | |
500 int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob"); | |
501 return _xi[i]; } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
502 Metadata* argument(int i); // => recorded_oop_at(argument_index(i)) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
503 oop argument_oop(int i); // => recorded_oop_at(argument_index(i)) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
504 Klass* context_type(); |
0 | 505 |
3894
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
506 bool is_klass_type() { return Dependencies::is_klass_type(type()); } |
b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
twisti
parents:
3852
diff
changeset
|
507 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
508 Method* method_argument(int i) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
509 Metadata* x = argument(i); |
0 | 510 assert(x->is_method(), "type"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
511 return (Method*) x; |
0 | 512 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
513 Klass* type_argument(int i) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
514 Metadata* x = argument(i); |
0 | 515 assert(x->is_klass(), "type"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
516 return (Klass*) x; |
0 | 517 } |
518 | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
519 // The point of the whole exercise: Is this dep still OK? |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
520 Klass* check_dependency() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
521 Klass* result = check_klass_dependency(NULL); |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
522 if (result != NULL) return result; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
523 return check_call_site_dependency(NULL); |
0 | 524 } |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
525 |
0 | 526 // A lighter version: Checks only around recent changes in a class |
527 // hierarchy. (See Universe::flush_dependents_on.) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
528 Klass* spot_check_dependency_at(DepChange& changes); |
0 | 529 |
530 // Log the current dependency to xtty or compilation log. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
531 void log_dependency(Klass* witness = NULL); |
0 | 532 |
533 // Print the current dependency to tty. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
534 void print_dependency(Klass* witness = NULL, bool verbose = false); |
0 | 535 }; |
536 friend class Dependencies::DepStream; | |
537 | |
538 static void print_statistics() PRODUCT_RETURN; | |
539 }; | |
540 | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
541 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
542 // Every particular DepChange is a sub-class of this class. |
0 | 543 class DepChange : public StackObj { |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
544 public: |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
545 // What kind of DepChange is this? |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
546 virtual bool is_klass_change() const { return false; } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
547 virtual bool is_call_site_change() const { return false; } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
548 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
549 // Subclass casting with assertions. |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
550 KlassDepChange* as_klass_change() { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
551 assert(is_klass_change(), "bad cast"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
552 return (KlassDepChange*) this; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
553 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
554 CallSiteDepChange* as_call_site_change() { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
555 assert(is_call_site_change(), "bad cast"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
556 return (CallSiteDepChange*) this; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
557 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
558 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
559 void print(); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
560 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
561 public: |
0 | 562 enum ChangeType { |
563 NO_CHANGE = 0, // an uninvolved klass | |
564 Change_new_type, // a newly loaded type | |
565 Change_new_sub, // a super with a new subtype | |
566 Change_new_impl, // an interface with a new implementation | |
567 CHANGE_LIMIT, | |
568 Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream | |
569 }; | |
570 | |
571 // Usage: | |
572 // for (DepChange::ContextStream str(changes); str.next(); ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
573 // Klass* k = str.klass(); |
0 | 574 // switch (str.change_type()) { |
575 // ... | |
576 // } | |
577 // } | |
578 class ContextStream : public StackObj { | |
579 private: | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
580 DepChange& _changes; |
0 | 581 friend class DepChange; |
582 | |
583 // iteration variables: | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
584 ChangeType _change_type; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
585 Klass* _klass; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
586 Array<Klass*>* _ti_base; // i.e., transitive_interfaces |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
587 int _ti_index; |
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
588 int _ti_limit; |
0 | 589 |
590 // start at the beginning: | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
591 void start(); |
0 | 592 |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
593 public: |
0 | 594 ContextStream(DepChange& changes) |
595 : _changes(changes) | |
596 { start(); } | |
597 | |
598 ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv) | |
599 : _changes(changes) | |
600 // the nsv argument makes it safe to hold oops like _klass | |
601 { start(); } | |
602 | |
603 bool next(); | |
604 | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
0
diff
changeset
|
605 ChangeType change_type() { return _change_type; } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
606 Klass* klass() { return _klass; } |
0 | 607 }; |
608 friend class DepChange::ContextStream; | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
609 }; |
0 | 610 |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
611 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
612 // A class hierarchy change coming through the VM (under the Compile_lock). |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
613 // The change is structured as a single new type with any number of supers |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
614 // and implemented interface types. Other than the new type, any of the |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
615 // super types can be context types for a relevant dependency, which the |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
616 // new type could invalidate. |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
617 class KlassDepChange : public DepChange { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
618 private: |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
619 // each change set is rooted in exactly one new type (at present): |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
620 KlassHandle _new_type; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
621 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
622 void initialize(); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
623 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
624 public: |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
625 // notes the new type, marks it and all its super-types |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
626 KlassDepChange(KlassHandle new_type) |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
627 : _new_type(new_type) |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
628 { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
629 initialize(); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
630 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
631 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
632 // cleans up the marks |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
633 ~KlassDepChange(); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
634 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
635 // What kind of DepChange is this? |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
636 virtual bool is_klass_change() const { return true; } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
637 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
638 Klass* new_type() { return _new_type(); } |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
639 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
640 // involves_context(k) is true if k is new_type or any of the super types |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3894
diff
changeset
|
641 bool involves_context(Klass* k); |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
642 }; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
643 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
644 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
645 // A CallSite has changed its target. |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
646 class CallSiteDepChange : public DepChange { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
647 private: |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
648 Handle _call_site; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
649 Handle _method_handle; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
650 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
651 public: |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
652 CallSiteDepChange(Handle call_site, Handle method_handle) |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
653 : _call_site(call_site), |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
654 _method_handle(method_handle) |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
655 { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
656 assert(_call_site() ->is_a(SystemDictionary::CallSite_klass()), "must be"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
657 assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
658 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
659 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
660 // What kind of DepChange is this? |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
661 virtual bool is_call_site_change() const { return true; } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
662 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
663 oop call_site() const { return _call_site(); } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
1972
diff
changeset
|
664 oop method_handle() const { return _method_handle(); } |
0 | 665 }; |
1972 | 666 |
667 #endif // SHARE_VM_CODE_DEPENDENCIES_HPP |