Mercurial > hg > graal-compiler
annotate src/share/vm/classfile/classFileParser.cpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | adc176e95bf2 |
children | 5b6a231e5a86 |
rev | line source |
---|---|
0 | 1 /* |
7579
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
2 * Copyright (c) 1997, 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:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
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:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classFileParser.hpp" | |
27 #include "classfile/classLoader.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
28 #include "classfile/classLoaderData.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
29 #include "classfile/classLoaderData.inline.hpp" |
6934 | 30 #include "classfile/defaultMethods.hpp" |
31 #include "classfile/genericSignatures.hpp" | |
1972 | 32 #include "classfile/javaClasses.hpp" |
33 #include "classfile/symbolTable.hpp" | |
34 #include "classfile/systemDictionary.hpp" | |
35 #include "classfile/verificationType.hpp" | |
36 #include "classfile/verifier.hpp" | |
37 #include "classfile/vmSymbols.hpp" | |
38 #include "memory/allocation.hpp" | |
39 #include "memory/gcLocker.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
40 #include "memory/metadataFactory.hpp" |
1972 | 41 #include "memory/oopFactory.hpp" |
42 #include "memory/universe.inline.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
43 #include "oops/constantPool.hpp" |
3938 | 44 #include "oops/fieldStreams.hpp" |
1972 | 45 #include "oops/instanceKlass.hpp" |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
46 #include "oops/instanceMirrorKlass.hpp" |
1972 | 47 #include "oops/klass.inline.hpp" |
48 #include "oops/klassVtable.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
49 #include "oops/method.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
50 #include "oops/symbol.hpp" |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
51 #include "prims/jvm.h" |
1972 | 52 #include "prims/jvmtiExport.hpp" |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
53 #include "prims/jvmtiThreadState.hpp" |
1972 | 54 #include "runtime/javaCalls.hpp" |
55 #include "runtime/perfData.hpp" | |
56 #include "runtime/reflection.hpp" | |
57 #include "runtime/signature.hpp" | |
58 #include "runtime/timer.hpp" | |
59 #include "services/classLoadingService.hpp" | |
60 #include "services/threadService.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
61 #include "utilities/array.hpp" |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
62 #include "utilities/globalDefinitions.hpp" |
0 | 63 |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
64 // We generally try to create the oops directly when parsing, rather than |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
65 // allocating temporary data structures and copying the bytes twice. A |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
66 // temporary area is only needed when parsing utf8 entries in the constant |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
67 // pool and when parsing line number tables. |
0 | 68 |
69 // We add assert in debug mode when class format is not checked. | |
70 | |
71 #define JAVA_CLASSFILE_MAGIC 0xCAFEBABE | |
72 #define JAVA_MIN_SUPPORTED_VERSION 45 | |
6868 | 73 #define JAVA_MAX_SUPPORTED_VERSION 52 |
0 | 74 #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0 |
75 | |
76 // Used for two backward compatibility reasons: | |
77 // - to check for new additions to the class file format in JDK1.5 | |
78 // - to check for bug fixes in the format checker in JDK1.5 | |
79 #define JAVA_1_5_VERSION 49 | |
80 | |
81 // Used for backward compatibility reasons: | |
82 // - to check for javac bug fixes that happened after 1.5 | |
176
6b648fefb395
6705523: Fix for 6695506 will violate spec when used in JDK6
kamg
parents:
136
diff
changeset
|
83 // - also used as the max version when running in jdk6 |
0 | 84 #define JAVA_6_VERSION 50 |
85 | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
86 // Used for backward compatibility reasons: |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
87 // - to check NameAndType_info signatures more aggressively |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
88 #define JAVA_7_VERSION 51 |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
89 |
6934 | 90 // Extension method support. |
91 #define JAVA_8_VERSION 52 | |
92 | |
0 | 93 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
94 void ClassFileParser::parse_constant_pool_entries(ClassLoaderData* loader_data, constantPoolHandle cp, int length, TRAPS) { |
0 | 95 // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize |
96 // this function (_current can be allocated in a register, with scalar | |
97 // replacement of aggregates). The _current pointer is copied back to | |
98 // stream() when this function returns. DON'T call another method within | |
99 // this method that uses stream(). | |
100 ClassFileStream* cfs0 = stream(); | |
101 ClassFileStream cfs1 = *cfs0; | |
102 ClassFileStream* cfs = &cfs1; | |
103 #ifdef ASSERT | |
1685 | 104 assert(cfs->allocated_on_stack(),"should be local"); |
0 | 105 u1* old_current = cfs0->current(); |
106 #endif | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
107 Handle class_loader(THREAD, loader_data->class_loader()); |
0 | 108 |
109 // Used for batching symbol allocations. | |
110 const char* names[SymbolTable::symbol_alloc_batch_size]; | |
111 int lengths[SymbolTable::symbol_alloc_batch_size]; | |
112 int indices[SymbolTable::symbol_alloc_batch_size]; | |
113 unsigned int hashValues[SymbolTable::symbol_alloc_batch_size]; | |
114 int names_count = 0; | |
115 | |
116 // parsing Index 0 is unused | |
117 for (int index = 1; index < length; index++) { | |
118 // Each of the following case guarantees one more byte in the stream | |
119 // for the following tag or the access_flags following constant pool, | |
120 // so we don't need bounds-check for reading tag. | |
121 u1 tag = cfs->get_u1_fast(); | |
122 switch (tag) { | |
123 case JVM_CONSTANT_Class : | |
124 { | |
125 cfs->guarantee_more(3, CHECK); // name_index, tag/access_flags | |
126 u2 name_index = cfs->get_u2_fast(); | |
127 cp->klass_index_at_put(index, name_index); | |
128 } | |
129 break; | |
130 case JVM_CONSTANT_Fieldref : | |
131 { | |
132 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags | |
133 u2 class_index = cfs->get_u2_fast(); | |
134 u2 name_and_type_index = cfs->get_u2_fast(); | |
135 cp->field_at_put(index, class_index, name_and_type_index); | |
136 } | |
137 break; | |
138 case JVM_CONSTANT_Methodref : | |
139 { | |
140 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags | |
141 u2 class_index = cfs->get_u2_fast(); | |
142 u2 name_and_type_index = cfs->get_u2_fast(); | |
143 cp->method_at_put(index, class_index, name_and_type_index); | |
144 } | |
145 break; | |
146 case JVM_CONSTANT_InterfaceMethodref : | |
147 { | |
148 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags | |
149 u2 class_index = cfs->get_u2_fast(); | |
150 u2 name_and_type_index = cfs->get_u2_fast(); | |
151 cp->interface_method_at_put(index, class_index, name_and_type_index); | |
152 } | |
153 break; | |
154 case JVM_CONSTANT_String : | |
155 { | |
156 cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags | |
157 u2 string_index = cfs->get_u2_fast(); | |
158 cp->string_index_at_put(index, string_index); | |
159 } | |
160 break; | |
1602 | 161 case JVM_CONSTANT_MethodHandle : |
162 case JVM_CONSTANT_MethodType : | |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
163 if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { |
1602 | 164 classfile_parse_error( |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
165 "Class file version does not support constant tag %u in class file %s", |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
166 tag, CHECK); |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
167 } |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
168 if (!EnableInvokeDynamic) { |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
169 classfile_parse_error( |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
170 "This JVM does not support constant tag %u in class file %s", |
1602 | 171 tag, CHECK); |
172 } | |
173 if (tag == JVM_CONSTANT_MethodHandle) { | |
174 cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags | |
175 u1 ref_kind = cfs->get_u1_fast(); | |
176 u2 method_index = cfs->get_u2_fast(); | |
177 cp->method_handle_index_at_put(index, ref_kind, method_index); | |
178 } else if (tag == JVM_CONSTANT_MethodType) { | |
179 cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags | |
180 u2 signature_index = cfs->get_u2_fast(); | |
181 cp->method_type_index_at_put(index, signature_index); | |
182 } else { | |
183 ShouldNotReachHere(); | |
184 } | |
185 break; | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
186 case JVM_CONSTANT_InvokeDynamic : |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
187 { |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
188 if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
189 classfile_parse_error( |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
190 "Class file version does not support constant tag %u in class file %s", |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
191 tag, CHECK); |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
192 } |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
193 if (!EnableInvokeDynamic) { |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
194 classfile_parse_error( |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2334
diff
changeset
|
195 "This JVM does not support constant tag %u in class file %s", |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
196 tag, CHECK); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
197 } |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
198 cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
199 u2 bootstrap_specifier_index = cfs->get_u2_fast(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
200 u2 name_and_type_index = cfs->get_u2_fast(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
201 if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
202 _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
203 cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
204 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
205 break; |
0 | 206 case JVM_CONSTANT_Integer : |
207 { | |
208 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags | |
209 u4 bytes = cfs->get_u4_fast(); | |
210 cp->int_at_put(index, (jint) bytes); | |
211 } | |
212 break; | |
213 case JVM_CONSTANT_Float : | |
214 { | |
215 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags | |
216 u4 bytes = cfs->get_u4_fast(); | |
217 cp->float_at_put(index, *(jfloat*)&bytes); | |
218 } | |
219 break; | |
220 case JVM_CONSTANT_Long : | |
221 // A mangled type might cause you to overrun allocated memory | |
222 guarantee_property(index+1 < length, | |
223 "Invalid constant pool entry %u in class file %s", | |
224 index, CHECK); | |
225 { | |
226 cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags | |
227 u8 bytes = cfs->get_u8_fast(); | |
228 cp->long_at_put(index, bytes); | |
229 } | |
230 index++; // Skip entry following eigth-byte constant, see JVM book p. 98 | |
231 break; | |
232 case JVM_CONSTANT_Double : | |
233 // A mangled type might cause you to overrun allocated memory | |
234 guarantee_property(index+1 < length, | |
235 "Invalid constant pool entry %u in class file %s", | |
236 index, CHECK); | |
237 { | |
238 cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags | |
239 u8 bytes = cfs->get_u8_fast(); | |
240 cp->double_at_put(index, *(jdouble*)&bytes); | |
241 } | |
242 index++; // Skip entry following eigth-byte constant, see JVM book p. 98 | |
243 break; | |
244 case JVM_CONSTANT_NameAndType : | |
245 { | |
246 cfs->guarantee_more(5, CHECK); // name_index, signature_index, tag/access_flags | |
247 u2 name_index = cfs->get_u2_fast(); | |
248 u2 signature_index = cfs->get_u2_fast(); | |
249 cp->name_and_type_at_put(index, name_index, signature_index); | |
250 } | |
251 break; | |
252 case JVM_CONSTANT_Utf8 : | |
253 { | |
254 cfs->guarantee_more(2, CHECK); // utf8_length | |
255 u2 utf8_length = cfs->get_u2_fast(); | |
256 u1* utf8_buffer = cfs->get_u1_buffer(); | |
257 assert(utf8_buffer != NULL, "null utf8 buffer"); | |
258 // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward. | |
259 cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags | |
260 cfs->skip_u1_fast(utf8_length); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
261 |
0 | 262 // Before storing the symbol, make sure it's legal |
263 if (_need_verify) { | |
264 verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK); | |
265 } | |
266 | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
267 if (EnableInvokeDynamic && has_cp_patch_at(index)) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
268 Handle patch = clear_cp_patch_at(index); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
269 guarantee_property(java_lang_String::is_instance(patch()), |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
270 "Illegal utf8 patch at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
271 index, CHECK); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
272 char* str = java_lang_String::as_utf8_string(patch()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
273 // (could use java_lang_String::as_symbol instead, but might as well batch them) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
274 utf8_buffer = (u1*) str; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
275 utf8_length = (int) strlen(str); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
276 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
277 |
0 | 278 unsigned int hash; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
279 Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); |
0 | 280 if (result == NULL) { |
281 names[names_count] = (char*)utf8_buffer; | |
282 lengths[names_count] = utf8_length; | |
283 indices[names_count] = index; | |
284 hashValues[names_count++] = hash; | |
285 if (names_count == SymbolTable::symbol_alloc_batch_size) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
286 SymbolTable::new_symbols(loader_data, cp, names_count, names, lengths, indices, hashValues, CHECK); |
0 | 287 names_count = 0; |
288 } | |
289 } else { | |
290 cp->symbol_at_put(index, result); | |
291 } | |
292 } | |
293 break; | |
294 default: | |
295 classfile_parse_error( | |
296 "Unknown constant tag %u in class file %s", tag, CHECK); | |
297 break; | |
298 } | |
299 } | |
300 | |
301 // Allocate the remaining symbols | |
302 if (names_count > 0) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
303 SymbolTable::new_symbols(loader_data, cp, names_count, names, lengths, indices, hashValues, CHECK); |
0 | 304 } |
305 | |
306 // Copy _current pointer of local copy back to stream(). | |
307 #ifdef ASSERT | |
308 assert(cfs0->current() == old_current, "non-exclusive use of stream()"); | |
309 #endif | |
310 cfs0->set_current(cfs1.current()); | |
311 } | |
312 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
313 // This class unreferences constant pool symbols if an error has occurred |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
314 // while parsing the class before it is assigned into the class. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
315 // If it gets an error after that it is unloaded and the constant pool will |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
316 // be cleaned up then. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
317 class ConstantPoolCleaner : public StackObj { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
318 constantPoolHandle _cphandle; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
319 bool _in_error; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
320 public: |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
321 ConstantPoolCleaner(constantPoolHandle cp) : _cphandle(cp), _in_error(true) {} |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
322 ~ConstantPoolCleaner() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
323 if (_in_error && _cphandle.not_null()) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
324 _cphandle->unreference_symbols(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
325 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
326 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
327 void set_in_error(bool clean) { _in_error = clean; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
328 }; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
329 |
0 | 330 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } |
331 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
332 inline Symbol* check_symbol_at(constantPoolHandle cp, int index) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
333 if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8()) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
334 return cp->symbol_at(index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
335 else |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
336 return NULL; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
337 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
338 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
339 constantPoolHandle ClassFileParser::parse_constant_pool(ClassLoaderData* loader_data, TRAPS) { |
0 | 340 ClassFileStream* cfs = stream(); |
341 constantPoolHandle nullHandle; | |
342 | |
343 cfs->guarantee_more(3, CHECK_(nullHandle)); // length, first cp tag | |
344 u2 length = cfs->get_u2_fast(); | |
345 guarantee_property( | |
346 length >= 1, "Illegal constant pool size %u in class file %s", | |
347 length, CHECK_(nullHandle)); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
348 ConstantPool* constant_pool = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
349 ConstantPool::allocate(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
350 length, |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
474
diff
changeset
|
351 CHECK_(nullHandle)); |
0 | 352 constantPoolHandle cp (THREAD, constant_pool); |
353 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
354 ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up. |
0 | 355 |
356 // parsing constant pool entries | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
357 parse_constant_pool_entries(loader_data, cp, length, CHECK_(nullHandle)); |
0 | 358 |
359 int index = 1; // declared outside of loops for portability | |
360 | |
361 // first verification pass - validate cross references and fixup class and string constants | |
362 for (index = 1; index < length; index++) { // Index 0 is unused | |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
363 jbyte tag = cp->tag_at(index).value(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
364 switch (tag) { |
0 | 365 case JVM_CONSTANT_Class : |
366 ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present | |
367 break; | |
368 case JVM_CONSTANT_Fieldref : | |
369 // fall through | |
370 case JVM_CONSTANT_Methodref : | |
371 // fall through | |
372 case JVM_CONSTANT_InterfaceMethodref : { | |
373 if (!_need_verify) break; | |
374 int klass_ref_index = cp->klass_ref_index_at(index); | |
375 int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); | |
376 check_property(valid_cp_range(klass_ref_index, length) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
377 is_klass_reference(cp, klass_ref_index), |
0 | 378 "Invalid constant pool index %u in class file %s", |
379 klass_ref_index, | |
380 CHECK_(nullHandle)); | |
381 check_property(valid_cp_range(name_and_type_ref_index, length) && | |
382 cp->tag_at(name_and_type_ref_index).is_name_and_type(), | |
383 "Invalid constant pool index %u in class file %s", | |
384 name_and_type_ref_index, | |
385 CHECK_(nullHandle)); | |
386 break; | |
387 } | |
388 case JVM_CONSTANT_String : | |
389 ShouldNotReachHere(); // Only JVM_CONSTANT_StringIndex should be present | |
390 break; | |
391 case JVM_CONSTANT_Integer : | |
392 break; | |
393 case JVM_CONSTANT_Float : | |
394 break; | |
395 case JVM_CONSTANT_Long : | |
396 case JVM_CONSTANT_Double : | |
397 index++; | |
398 check_property( | |
399 (index < length && cp->tag_at(index).is_invalid()), | |
400 "Improper constant pool long/double index %u in class file %s", | |
401 index, CHECK_(nullHandle)); | |
402 break; | |
403 case JVM_CONSTANT_NameAndType : { | |
404 if (!_need_verify) break; | |
405 int name_ref_index = cp->name_ref_index_at(index); | |
406 int signature_ref_index = cp->signature_ref_index_at(index); | |
407 check_property( | |
408 valid_cp_range(name_ref_index, length) && | |
409 cp->tag_at(name_ref_index).is_utf8(), | |
410 "Invalid constant pool index %u in class file %s", | |
411 name_ref_index, CHECK_(nullHandle)); | |
412 check_property( | |
413 valid_cp_range(signature_ref_index, length) && | |
414 cp->tag_at(signature_ref_index).is_utf8(), | |
415 "Invalid constant pool index %u in class file %s", | |
416 signature_ref_index, CHECK_(nullHandle)); | |
417 break; | |
418 } | |
419 case JVM_CONSTANT_Utf8 : | |
420 break; | |
421 case JVM_CONSTANT_UnresolvedClass : // fall-through | |
422 case JVM_CONSTANT_UnresolvedClassInError: | |
423 ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present | |
424 break; | |
425 case JVM_CONSTANT_ClassIndex : | |
426 { | |
427 int class_index = cp->klass_index_at(index); | |
428 check_property( | |
429 valid_cp_range(class_index, length) && | |
430 cp->tag_at(class_index).is_utf8(), | |
431 "Invalid constant pool index %u in class file %s", | |
432 class_index, CHECK_(nullHandle)); | |
433 cp->unresolved_klass_at_put(index, cp->symbol_at(class_index)); | |
434 } | |
435 break; | |
436 case JVM_CONSTANT_StringIndex : | |
437 { | |
438 int string_index = cp->string_index_at(index); | |
439 check_property( | |
440 valid_cp_range(string_index, length) && | |
441 cp->tag_at(string_index).is_utf8(), | |
442 "Invalid constant pool index %u in class file %s", | |
443 string_index, CHECK_(nullHandle)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
444 Symbol* sym = cp->symbol_at(string_index); |
0 | 445 cp->unresolved_string_at_put(index, sym); |
446 } | |
447 break; | |
1602 | 448 case JVM_CONSTANT_MethodHandle : |
449 { | |
450 int ref_index = cp->method_handle_index_at(index); | |
451 check_property( | |
452 valid_cp_range(ref_index, length) && | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
453 EnableInvokeDynamic, |
1602 | 454 "Invalid constant pool index %u in class file %s", |
455 ref_index, CHECK_(nullHandle)); | |
456 constantTag tag = cp->tag_at(ref_index); | |
457 int ref_kind = cp->method_handle_ref_kind_at(index); | |
458 switch (ref_kind) { | |
459 case JVM_REF_getField: | |
460 case JVM_REF_getStatic: | |
461 case JVM_REF_putField: | |
462 case JVM_REF_putStatic: | |
463 check_property( | |
464 tag.is_field(), | |
465 "Invalid constant pool index %u in class file %s (not a field)", | |
466 ref_index, CHECK_(nullHandle)); | |
467 break; | |
468 case JVM_REF_invokeVirtual: | |
469 case JVM_REF_invokeStatic: | |
470 case JVM_REF_invokeSpecial: | |
471 case JVM_REF_newInvokeSpecial: | |
472 check_property( | |
473 tag.is_method(), | |
474 "Invalid constant pool index %u in class file %s (not a method)", | |
475 ref_index, CHECK_(nullHandle)); | |
476 break; | |
477 case JVM_REF_invokeInterface: | |
478 check_property( | |
479 tag.is_interface_method(), | |
480 "Invalid constant pool index %u in class file %s (not an interface method)", | |
481 ref_index, CHECK_(nullHandle)); | |
482 break; | |
483 default: | |
484 classfile_parse_error( | |
485 "Bad method handle kind at constant pool index %u in class file %s", | |
486 index, CHECK_(nullHandle)); | |
487 } | |
488 // Keep the ref_index unchanged. It will be indirected at link-time. | |
489 } | |
490 break; | |
491 case JVM_CONSTANT_MethodType : | |
492 { | |
493 int ref_index = cp->method_type_index_at(index); | |
494 check_property( | |
495 valid_cp_range(ref_index, length) && | |
496 cp->tag_at(ref_index).is_utf8() && | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
497 EnableInvokeDynamic, |
1602 | 498 "Invalid constant pool index %u in class file %s", |
499 ref_index, CHECK_(nullHandle)); | |
500 } | |
501 break; | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
502 case JVM_CONSTANT_InvokeDynamic : |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
503 { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
504 int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
505 check_property(valid_cp_range(name_and_type_ref_index, length) && |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
506 cp->tag_at(name_and_type_ref_index).is_name_and_type(), |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
507 "Invalid constant pool index %u in class file %s", |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
508 name_and_type_ref_index, |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
509 CHECK_(nullHandle)); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
510 // bootstrap specifier index must be checked later, when BootstrapMethods attr is available |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
511 break; |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1608
diff
changeset
|
512 } |
0 | 513 default: |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1366
diff
changeset
|
514 fatal(err_msg("bad constant pool tag value %u", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1366
diff
changeset
|
515 cp->tag_at(index).value())); |
0 | 516 ShouldNotReachHere(); |
517 break; | |
518 } // end of switch | |
519 } // end of for | |
520 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
521 if (_cp_patches != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
522 // need to treat this_class specially... |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
523 assert(EnableInvokeDynamic, ""); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
524 int this_class_index; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
525 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
526 cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
527 u1* mark = cfs->current(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
528 u2 flags = cfs->get_u2_fast(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
529 this_class_index = cfs->get_u2_fast(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
530 cfs->set_current(mark); // revert to mark |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
531 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
532 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
533 for (index = 1; index < length; index++) { // Index 0 is unused |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
534 if (has_cp_patch_at(index)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
535 guarantee_property(index != this_class_index, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
536 "Illegal constant pool patch to self at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
537 index, CHECK_(nullHandle)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
538 patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
539 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
540 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
541 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
542 |
0 | 543 if (!_need_verify) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
544 cp_in_error.set_in_error(false); |
0 | 545 return cp; |
546 } | |
547 | |
548 // second verification pass - checks the strings are of the right format. | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
549 // but not yet to the other entries |
0 | 550 for (index = 1; index < length; index++) { |
551 jbyte tag = cp->tag_at(index).value(); | |
552 switch (tag) { | |
553 case JVM_CONSTANT_UnresolvedClass: { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
554 Symbol* class_name = cp->unresolved_klass_at(index); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
555 // check the name, even if _cp_patches will overwrite it |
0 | 556 verify_legal_class_name(class_name, CHECK_(nullHandle)); |
557 break; | |
558 } | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
559 case JVM_CONSTANT_NameAndType: { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
560 if (_need_verify && _major_version >= JAVA_7_VERSION) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
561 int sig_index = cp->signature_ref_index_at(index); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
562 int name_index = cp->name_ref_index_at(index); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
563 Symbol* name = cp->symbol_at(name_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
564 Symbol* sig = cp->symbol_at(sig_index); |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
565 if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
566 verify_legal_method_signature(name, sig, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
567 } else { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
568 verify_legal_field_signature(name, sig, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
569 } |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
570 } |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
571 break; |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
572 } |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2460
diff
changeset
|
573 case JVM_CONSTANT_InvokeDynamic: |
0 | 574 case JVM_CONSTANT_Fieldref: |
575 case JVM_CONSTANT_Methodref: | |
576 case JVM_CONSTANT_InterfaceMethodref: { | |
577 int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); | |
578 // already verified to be utf8 | |
579 int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); | |
580 // already verified to be utf8 | |
581 int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
582 Symbol* name = cp->symbol_at(name_ref_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
583 Symbol* signature = cp->symbol_at(signature_ref_index); |
0 | 584 if (tag == JVM_CONSTANT_Fieldref) { |
585 verify_legal_field_name(name, CHECK_(nullHandle)); | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
586 if (_need_verify && _major_version >= JAVA_7_VERSION) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
587 // Signature is verified above, when iterating NameAndType_info. |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
588 // Need only to be sure it's the right type. |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
589 if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
590 throwIllegalSignature( |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
591 "Field", name, signature, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
592 } |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
593 } else { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
594 verify_legal_field_signature(name, signature, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
595 } |
0 | 596 } else { |
597 verify_legal_method_name(name, CHECK_(nullHandle)); | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
598 if (_need_verify && _major_version >= JAVA_7_VERSION) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
599 // Signature is verified above, when iterating NameAndType_info. |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
600 // Need only to be sure it's the right type. |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
601 if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
602 throwIllegalSignature( |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
603 "Method", name, signature, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
604 } |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
605 } else { |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
606 verify_legal_method_signature(name, signature, CHECK_(nullHandle)); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
607 } |
0 | 608 if (tag == JVM_CONSTANT_Methodref) { |
609 // 4509014: If a class method name begins with '<', it must be "<init>". | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
610 assert(name != NULL, "method name in constant pool is null"); |
0 | 611 unsigned int name_len = name->utf8_length(); |
612 assert(name_len > 0, "bad method name"); // already verified as legal name | |
613 if (name->byte_at(0) == '<') { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
614 if (name != vmSymbols::object_initializer_name()) { |
0 | 615 classfile_parse_error( |
616 "Bad method name at constant pool index %u in class file %s", | |
617 name_ref_index, CHECK_(nullHandle)); | |
618 } | |
619 } | |
620 } | |
621 } | |
622 break; | |
623 } | |
1602 | 624 case JVM_CONSTANT_MethodHandle: { |
625 int ref_index = cp->method_handle_index_at(index); | |
626 int ref_kind = cp->method_handle_ref_kind_at(index); | |
627 switch (ref_kind) { | |
628 case JVM_REF_invokeVirtual: | |
629 case JVM_REF_invokeStatic: | |
630 case JVM_REF_invokeSpecial: | |
631 case JVM_REF_newInvokeSpecial: | |
632 { | |
633 int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); | |
634 int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
635 Symbol* name = cp->symbol_at(name_ref_index); |
1602 | 636 if (ref_kind == JVM_REF_newInvokeSpecial) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
637 if (name != vmSymbols::object_initializer_name()) { |
1602 | 638 classfile_parse_error( |
639 "Bad constructor name at constant pool index %u in class file %s", | |
640 name_ref_index, CHECK_(nullHandle)); | |
641 } | |
642 } else { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
643 if (name == vmSymbols::object_initializer_name()) { |
1602 | 644 classfile_parse_error( |
645 "Bad method name at constant pool index %u in class file %s", | |
646 name_ref_index, CHECK_(nullHandle)); | |
647 } | |
648 } | |
649 } | |
650 break; | |
651 // Other ref_kinds are already fully checked in previous pass. | |
652 } | |
653 break; | |
654 } | |
655 case JVM_CONSTANT_MethodType: { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
656 Symbol* no_name = vmSymbols::type_name(); // place holder |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
657 Symbol* signature = cp->method_type_signature_at(index); |
1602 | 658 verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); |
659 break; | |
660 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
661 case JVM_CONSTANT_Utf8: { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
662 assert(cp->symbol_at(index)->refcount() != 0, "count corrupted"); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
663 } |
0 | 664 } // end of switch |
665 } // end of for | |
666 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
667 cp_in_error.set_in_error(false); |
0 | 668 return cp; |
669 } | |
670 | |
671 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
672 void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) { |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
673 assert(EnableInvokeDynamic, ""); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
674 BasicType patch_type = T_VOID; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
675 |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
676 switch (cp->tag_at(index).value()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
677 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
678 case JVM_CONSTANT_UnresolvedClass : |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
679 // Patching a class means pre-resolving it. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
680 // The name in the constant pool is ignored. |
1602 | 681 if (java_lang_Class::is_instance(patch())) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
682 guarantee_property(!java_lang_Class::is_primitive(patch()), |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
683 "Illegal class patch at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
684 index, CHECK); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
685 cp->klass_at_put(index, java_lang_Class::as_Klass(patch())); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
686 } else { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
687 guarantee_property(java_lang_String::is_instance(patch()), |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
688 "Illegal class patch at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
689 index, CHECK); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
690 Symbol* name = java_lang_String::as_symbol(patch(), CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
691 cp->unresolved_klass_at_put(index, name); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
692 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
693 break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
694 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
695 case JVM_CONSTANT_String : |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
696 // skip this patch and don't clear it. Needs the oop array for resolved |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
697 // references to be created first. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
698 return; |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
699 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
700 case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
701 case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
702 case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
703 case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
704 patch_prim: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
705 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
706 jvalue value; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
707 BasicType value_type = java_lang_boxing_object::get_value(patch(), &value); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
708 guarantee_property(value_type == patch_type, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
709 "Illegal primitive patch at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
710 index, CHECK); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
711 switch (value_type) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
712 case T_INT: cp->int_at_put(index, value.i); break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
713 case T_FLOAT: cp->float_at_put(index, value.f); break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
714 case T_LONG: cp->long_at_put(index, value.j); break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
715 case T_DOUBLE: cp->double_at_put(index, value.d); break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
716 default: assert(false, ""); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
717 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
718 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
719 break; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
720 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
721 default: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
722 // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
723 guarantee_property(!has_cp_patch_at(index), |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
724 "Illegal unexpected patch at %d in class file %s", |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
725 index, CHECK); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
726 return; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
727 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
728 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
729 // On fall-through, mark the patch as used. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
730 clear_cp_patch_at(index); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
731 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
732 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
733 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
734 |
0 | 735 class NameSigHash: public ResourceObj { |
736 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
737 Symbol* _name; // name |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
738 Symbol* _sig; // signature |
0 | 739 NameSigHash* _next; // Next entry in hash table |
740 }; | |
741 | |
742 | |
743 #define HASH_ROW_SIZE 256 | |
744 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
745 unsigned int hash(Symbol* name, Symbol* sig) { |
0 | 746 unsigned int raw_hash = 0; |
747 raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2); | |
748 raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize; | |
749 | |
750 return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE; | |
751 } | |
752 | |
753 | |
754 void initialize_hashtable(NameSigHash** table) { | |
755 memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE); | |
756 } | |
757 | |
758 // Return false if the name/sig combination is found in table. | |
759 // Return true if no duplicate is found. And name/sig is added as a new entry in table. | |
760 // The old format checker uses heap sort to find duplicates. | |
761 // NOTE: caller should guarantee that GC doesn't happen during the life cycle | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
762 // of table since we don't expect Symbol*'s to move. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
763 bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) { |
0 | 764 assert(name != NULL, "name in constant pool is NULL"); |
765 | |
766 // First lookup for duplicates | |
767 int index = hash(name, sig); | |
768 NameSigHash* entry = table[index]; | |
769 while (entry != NULL) { | |
770 if (entry->_name == name && entry->_sig == sig) { | |
771 return false; | |
772 } | |
773 entry = entry->_next; | |
774 } | |
775 | |
776 // No duplicate is found, allocate a new entry and fill it. | |
777 entry = new NameSigHash(); | |
778 entry->_name = name; | |
779 entry->_sig = sig; | |
780 | |
781 // Insert into hash table | |
782 entry->_next = table[index]; | |
783 table[index] = entry; | |
784 | |
785 return true; | |
786 } | |
787 | |
788 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
789 Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp, |
0 | 790 int length, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
791 ClassLoaderData* loader_data, |
0 | 792 Handle protection_domain, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
793 Symbol* class_name, |
6934 | 794 bool* has_default_methods, |
0 | 795 TRAPS) { |
796 ClassFileStream* cfs = stream(); | |
797 assert(length > 0, "only called for length>0"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
798 // FIXME: Leak at later OOM. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
799 Array<Klass*>* interfaces = MetadataFactory::new_array<Klass*>(loader_data, length, NULL, CHECK_NULL); |
0 | 800 |
801 int index; | |
802 for (index = 0; index < length; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
803 u2 interface_index = cfs->get_u2(CHECK_NULL); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
804 KlassHandle interf; |
0 | 805 check_property( |
806 valid_cp_range(interface_index, cp->length()) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
807 is_klass_reference(cp, interface_index), |
0 | 808 "Interface name has bad constant pool index %u in class file %s", |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
809 interface_index, CHECK_NULL); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
810 if (cp->tag_at(interface_index).is_klass()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
811 interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
812 } else { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
813 Symbol* unresolved_klass = cp->klass_name_at(interface_index); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
814 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
815 // Don't need to check legal name because it's checked when parsing constant pool. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
816 // But need to make sure it's not an array type. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
817 guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
818 "Bad interface name in class file %s", CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
819 Handle class_loader(THREAD, loader_data->class_loader()); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
820 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
821 // Call resolve_super so classcircularity is checked |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
822 Klass* k = SystemDictionary::resolve_super_or_fail(class_name, |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
823 unresolved_klass, class_loader, protection_domain, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
824 false, CHECK_NULL); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
825 interf = KlassHandle(THREAD, k); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
826 } |
0 | 827 |
6983 | 828 if (!interf()->is_interface()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
829 THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL); |
0 | 830 } |
6934 | 831 if (InstanceKlass::cast(interf())->has_default_methods()) { |
832 *has_default_methods = true; | |
833 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
834 interfaces->at_put(index, interf()); |
0 | 835 } |
836 | |
837 if (!_need_verify || length <= 1) { | |
838 return interfaces; | |
839 } | |
840 | |
841 // Check if there's any duplicates in interfaces | |
842 ResourceMark rm(THREAD); | |
843 NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD( | |
844 THREAD, NameSigHash*, HASH_ROW_SIZE); | |
845 initialize_hashtable(interface_names); | |
846 bool dup = false; | |
847 { | |
848 debug_only(No_Safepoint_Verifier nsv;) | |
849 for (index = 0; index < length; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
850 Klass* k = interfaces->at(index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
851 Symbol* name = InstanceKlass::cast(k)->name(); |
0 | 852 // If no duplicates, add (name, NULL) in hashtable interface_names. |
853 if (!put_after_lookup(name, NULL, interface_names)) { | |
854 dup = true; | |
855 break; | |
856 } | |
857 } | |
858 } | |
859 if (dup) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
860 classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL); |
0 | 861 } |
862 | |
863 return interfaces; | |
864 } | |
865 | |
866 | |
867 void ClassFileParser::verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS) { | |
868 // Make sure the constant pool entry is of a type appropriate to this field | |
869 guarantee_property( | |
870 (constantvalue_index > 0 && | |
871 constantvalue_index < cp->length()), | |
872 "Bad initial value index %u in ConstantValue attribute in class file %s", | |
873 constantvalue_index, CHECK); | |
874 constantTag value_type = cp->tag_at(constantvalue_index); | |
875 switch ( cp->basic_type_for_signature_at(signature_index) ) { | |
876 case T_LONG: | |
877 guarantee_property(value_type.is_long(), "Inconsistent constant value type in class file %s", CHECK); | |
878 break; | |
879 case T_FLOAT: | |
880 guarantee_property(value_type.is_float(), "Inconsistent constant value type in class file %s", CHECK); | |
881 break; | |
882 case T_DOUBLE: | |
883 guarantee_property(value_type.is_double(), "Inconsistent constant value type in class file %s", CHECK); | |
884 break; | |
885 case T_BYTE: case T_CHAR: case T_SHORT: case T_BOOLEAN: case T_INT: | |
886 guarantee_property(value_type.is_int(), "Inconsistent constant value type in class file %s", CHECK); | |
887 break; | |
888 case T_OBJECT: | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1108
diff
changeset
|
889 guarantee_property((cp->symbol_at(signature_index)->equals("Ljava/lang/String;") |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
890 && value_type.is_string()), |
0 | 891 "Bad string initial value in class file %s", CHECK); |
892 break; | |
893 default: | |
894 classfile_parse_error( | |
895 "Unable to set initial value %u in class file %s", | |
896 constantvalue_index, CHECK); | |
897 } | |
898 } | |
899 | |
900 | |
901 // Parse attributes for a field. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
902 void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
903 constantPoolHandle cp, |
0 | 904 u2 attributes_count, |
905 bool is_static, u2 signature_index, | |
906 u2* constantvalue_index_addr, | |
907 bool* is_synthetic_addr, | |
908 u2* generic_signature_index_addr, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
909 AnnotationArray** field_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
910 AnnotationArray** field_type_annotations, |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
911 ClassFileParser::FieldAnnotationCollector* parsed_annotations, |
0 | 912 TRAPS) { |
913 ClassFileStream* cfs = stream(); | |
914 assert(attributes_count > 0, "length should be greater than 0"); | |
915 u2 constantvalue_index = 0; | |
916 u2 generic_signature_index = 0; | |
917 bool is_synthetic = false; | |
918 u1* runtime_visible_annotations = NULL; | |
919 int runtime_visible_annotations_length = 0; | |
920 u1* runtime_invisible_annotations = NULL; | |
921 int runtime_invisible_annotations_length = 0; | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
922 u1* runtime_visible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
923 int runtime_visible_type_annotations_length = 0; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
924 u1* runtime_invisible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
925 int runtime_invisible_type_annotations_length = 0; |
0 | 926 while (attributes_count--) { |
927 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length | |
928 u2 attribute_name_index = cfs->get_u2_fast(); | |
929 u4 attribute_length = cfs->get_u4_fast(); | |
930 check_property(valid_cp_range(attribute_name_index, cp->length()) && | |
931 cp->tag_at(attribute_name_index).is_utf8(), | |
932 "Invalid field attribute index %u in class file %s", | |
933 attribute_name_index, | |
934 CHECK); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
935 Symbol* attribute_name = cp->symbol_at(attribute_name_index); |
0 | 936 if (is_static && attribute_name == vmSymbols::tag_constant_value()) { |
937 // ignore if non-static | |
938 if (constantvalue_index != 0) { | |
939 classfile_parse_error("Duplicate ConstantValue attribute in class file %s", CHECK); | |
940 } | |
941 check_property( | |
942 attribute_length == 2, | |
943 "Invalid ConstantValue field attribute length %u in class file %s", | |
944 attribute_length, CHECK); | |
945 constantvalue_index = cfs->get_u2(CHECK); | |
946 if (_need_verify) { | |
947 verify_constantvalue(constantvalue_index, signature_index, cp, CHECK); | |
948 } | |
949 } else if (attribute_name == vmSymbols::tag_synthetic()) { | |
950 if (attribute_length != 0) { | |
951 classfile_parse_error( | |
952 "Invalid Synthetic field attribute length %u in class file %s", | |
953 attribute_length, CHECK); | |
954 } | |
955 is_synthetic = true; | |
956 } else if (attribute_name == vmSymbols::tag_deprecated()) { // 4276120 | |
957 if (attribute_length != 0) { | |
958 classfile_parse_error( | |
959 "Invalid Deprecated field attribute length %u in class file %s", | |
960 attribute_length, CHECK); | |
961 } | |
962 } else if (_major_version >= JAVA_1_5_VERSION) { | |
963 if (attribute_name == vmSymbols::tag_signature()) { | |
964 if (attribute_length != 2) { | |
965 classfile_parse_error( | |
966 "Wrong size %u for field's Signature attribute in class file %s", | |
967 attribute_length, CHECK); | |
968 } | |
969 generic_signature_index = cfs->get_u2(CHECK); | |
970 } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { | |
971 runtime_visible_annotations_length = attribute_length; | |
972 runtime_visible_annotations = cfs->get_u1_buffer(); | |
973 assert(runtime_visible_annotations != NULL, "null visible annotations"); | |
974 cfs->skip_u1(runtime_visible_annotations_length, CHECK); | |
975 } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { | |
976 runtime_invisible_annotations_length = attribute_length; | |
977 runtime_invisible_annotations = cfs->get_u1_buffer(); | |
978 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); | |
979 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
980 } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
981 runtime_visible_type_annotations_length = attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
982 runtime_visible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
983 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
984 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
985 } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
986 runtime_invisible_type_annotations_length = attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
987 runtime_invisible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
988 assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
989 cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); |
0 | 990 } else { |
991 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes | |
992 } | |
993 } else { | |
994 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes | |
995 } | |
996 } | |
997 | |
998 *constantvalue_index_addr = constantvalue_index; | |
999 *is_synthetic_addr = is_synthetic; | |
1000 *generic_signature_index_addr = generic_signature_index; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1001 *field_annotations = assemble_annotations(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1002 runtime_visible_annotations, |
0 | 1003 runtime_visible_annotations_length, |
1004 runtime_invisible_annotations, | |
1005 runtime_invisible_annotations_length, | |
1006 CHECK); | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1007 *field_type_annotations = assemble_annotations(loader_data, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1008 runtime_visible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1009 runtime_visible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1010 runtime_invisible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1011 runtime_invisible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1012 CHECK); |
0 | 1013 return; |
1014 } | |
1015 | |
1016 | |
1017 // Field allocation types. Used for computing field offsets. | |
1018 | |
1019 enum FieldAllocationType { | |
1020 STATIC_OOP, // Oops | |
1021 STATIC_BYTE, // Boolean, Byte, char | |
1022 STATIC_SHORT, // shorts | |
1023 STATIC_WORD, // ints | |
3938 | 1024 STATIC_DOUBLE, // aligned long or double |
0 | 1025 NONSTATIC_OOP, |
1026 NONSTATIC_BYTE, | |
1027 NONSTATIC_SHORT, | |
1028 NONSTATIC_WORD, | |
1029 NONSTATIC_DOUBLE, | |
3938 | 1030 MAX_FIELD_ALLOCATION_TYPE, |
1031 BAD_ALLOCATION_TYPE = -1 | |
0 | 1032 }; |
1033 | |
3938 | 1034 static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = { |
1035 BAD_ALLOCATION_TYPE, // 0 | |
1036 BAD_ALLOCATION_TYPE, // 1 | |
1037 BAD_ALLOCATION_TYPE, // 2 | |
1038 BAD_ALLOCATION_TYPE, // 3 | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1039 NONSTATIC_BYTE , // T_BOOLEAN = 4, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1040 NONSTATIC_SHORT, // T_CHAR = 5, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1041 NONSTATIC_WORD, // T_FLOAT = 6, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1042 NONSTATIC_DOUBLE, // T_DOUBLE = 7, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1043 NONSTATIC_BYTE, // T_BYTE = 8, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1044 NONSTATIC_SHORT, // T_SHORT = 9, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1045 NONSTATIC_WORD, // T_INT = 10, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1046 NONSTATIC_DOUBLE, // T_LONG = 11, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1047 NONSTATIC_OOP, // T_OBJECT = 12, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1048 NONSTATIC_OOP, // T_ARRAY = 13, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1049 BAD_ALLOCATION_TYPE, // T_VOID = 14, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1050 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1051 BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1052 BAD_ALLOCATION_TYPE, // T_METADATA = 17, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1053 BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1054 BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, |
3938 | 1055 BAD_ALLOCATION_TYPE, // 0 |
1056 BAD_ALLOCATION_TYPE, // 1 | |
1057 BAD_ALLOCATION_TYPE, // 2 | |
1058 BAD_ALLOCATION_TYPE, // 3 | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1059 STATIC_BYTE , // T_BOOLEAN = 4, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1060 STATIC_SHORT, // T_CHAR = 5, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1061 STATIC_WORD, // T_FLOAT = 6, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1062 STATIC_DOUBLE, // T_DOUBLE = 7, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1063 STATIC_BYTE, // T_BYTE = 8, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1064 STATIC_SHORT, // T_SHORT = 9, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1065 STATIC_WORD, // T_INT = 10, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1066 STATIC_DOUBLE, // T_LONG = 11, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1067 STATIC_OOP, // T_OBJECT = 12, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1068 STATIC_OOP, // T_ARRAY = 13, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1069 BAD_ALLOCATION_TYPE, // T_VOID = 14, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1070 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1071 BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1072 BAD_ALLOCATION_TYPE, // T_METADATA = 17, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1073 BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6735
diff
changeset
|
1074 BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, |
0 | 1075 }; |
1076 | |
3938 | 1077 static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) { |
1078 assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values"); | |
1079 FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)]; | |
1080 assert(result != BAD_ALLOCATION_TYPE, "bad type"); | |
1081 return result; | |
1082 } | |
1083 | |
1084 class FieldAllocationCount: public ResourceObj { | |
1085 public: | |
4744
cd5d8cafcc84
7123315: instanceKlass::_static_oop_field_count and instanceKlass::_java_fields_count should be u2 type.
jiangli
parents:
3938
diff
changeset
|
1086 u2 count[MAX_FIELD_ALLOCATION_TYPE]; |
3938 | 1087 |
1088 FieldAllocationCount() { | |
1089 for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) { | |
1090 count[i] = 0; | |
1091 } | |
1092 } | |
1093 | |
1094 FieldAllocationType update(bool is_static, BasicType type) { | |
1095 FieldAllocationType atype = basic_type_to_atype(is_static, type); | |
4744
cd5d8cafcc84
7123315: instanceKlass::_static_oop_field_count and instanceKlass::_java_fields_count should be u2 type.
jiangli
parents:
3938
diff
changeset
|
1096 // Make sure there is no overflow with injected fields. |
cd5d8cafcc84
7123315: instanceKlass::_static_oop_field_count and instanceKlass::_java_fields_count should be u2 type.
jiangli
parents:
3938
diff
changeset
|
1097 assert(count[atype] < 0xFFFF, "More than 65535 fields"); |
3938 | 1098 count[atype]++; |
1099 return atype; | |
1100 } | |
1101 }; | |
1102 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1103 Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1104 Symbol* class_name, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
1105 constantPoolHandle cp, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
1106 bool is_interface, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
1107 FieldAllocationCount *fac, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1108 Array<AnnotationArray*>** fields_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1109 Array<AnnotationArray*>** fields_type_annotations, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
1110 u2* java_fields_count_ptr, TRAPS) { |
0 | 1111 ClassFileStream* cfs = stream(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1112 cfs->guarantee_more(2, CHECK_NULL); // length |
0 | 1113 u2 length = cfs->get_u2_fast(); |
3938 | 1114 *java_fields_count_ptr = length; |
1115 | |
1116 int num_injected = 0; | |
1117 InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected); | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1118 int total_fields = length + num_injected; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1119 |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1120 // The field array starts with tuples of shorts |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1121 // [access, name index, sig index, initial value index, byte offset]. |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1122 // A generic signature slot only exists for field with generic |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1123 // signature attribute. And the access flag is set with |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1124 // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1125 // signature slots are at the end of the field array and after all |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1126 // other fields data. |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1127 // |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1128 // f1: [access, name index, sig index, initial value index, low_offset, high_offset] |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1129 // f2: [access, name index, sig index, initial value index, low_offset, high_offset] |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1130 // ... |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1131 // fn: [access, name index, sig index, initial value index, low_offset, high_offset] |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1132 // [generic signature index] |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1133 // [generic signature index] |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1134 // ... |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1135 // |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1136 // Allocate a temporary resource array for field data. For each field, |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1137 // a slot is reserved in the temporary array for the generic signature |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1138 // index. After parsing all fields, the data are copied to a permanent |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1139 // array and any unused slots will be discarded. |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1140 ResourceMark rm(THREAD); |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1141 u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD( |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1142 THREAD, u2, total_fields * (FieldInfo::field_slots + 1)); |
0 | 1143 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1144 AnnotationArray* field_annotations = NULL; |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1145 AnnotationArray* field_type_annotations = NULL; |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1146 // The generic signature slots start after all other fields' data. |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1147 int generic_signature_slot = total_fields * FieldInfo::field_slots; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1148 int num_generic_signature = 0; |
0 | 1149 for (int n = 0; n < length; n++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1150 cfs->guarantee_more(8, CHECK_NULL); // access_flags, name_index, descriptor_index, attributes_count |
0 | 1151 |
1152 AccessFlags access_flags; | |
1153 jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1154 verify_legal_field_modifiers(flags, is_interface, CHECK_NULL); |
0 | 1155 access_flags.set_flags(flags); |
1156 | |
1157 u2 name_index = cfs->get_u2_fast(); | |
1158 int cp_size = cp->length(); | |
1159 check_property( | |
1160 valid_cp_range(name_index, cp_size) && cp->tag_at(name_index).is_utf8(), | |
1161 "Invalid constant pool index %u for field name in class file %s", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1162 name_index, CHECK_NULL); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1163 Symbol* name = cp->symbol_at(name_index); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1164 verify_legal_field_name(name, CHECK_NULL); |
0 | 1165 |
1166 u2 signature_index = cfs->get_u2_fast(); | |
1167 check_property( | |
1168 valid_cp_range(signature_index, cp_size) && | |
1169 cp->tag_at(signature_index).is_utf8(), | |
1170 "Invalid constant pool index %u for field signature in class file %s", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1171 signature_index, CHECK_NULL); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1172 Symbol* sig = cp->symbol_at(signature_index); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1173 verify_legal_field_signature(name, sig, CHECK_NULL); |
0 | 1174 |
1175 u2 constantvalue_index = 0; | |
1176 bool is_synthetic = false; | |
1177 u2 generic_signature_index = 0; | |
1178 bool is_static = access_flags.is_static(); | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1179 FieldAnnotationCollector parsed_annotations; |
0 | 1180 |
1181 u2 attributes_count = cfs->get_u2_fast(); | |
1182 if (attributes_count > 0) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1183 parse_field_attributes(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1184 cp, attributes_count, is_static, signature_index, |
0 | 1185 &constantvalue_index, &is_synthetic, |
1186 &generic_signature_index, &field_annotations, | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1187 &field_type_annotations, &parsed_annotations, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1188 CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1189 if (field_annotations != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1190 if (*fields_annotations == NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1191 *fields_annotations = MetadataFactory::new_array<AnnotationArray*>( |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1192 loader_data, length, NULL, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1193 CHECK_NULL); |
0 | 1194 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1195 (*fields_annotations)->at_put(n, field_annotations); |
0 | 1196 } |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1197 if (field_type_annotations != NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1198 if (*fields_type_annotations == NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1199 *fields_type_annotations = MetadataFactory::new_array<AnnotationArray*>( |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1200 loader_data, length, NULL, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1201 CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1202 } |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1203 (*fields_type_annotations)->at_put(n, field_type_annotations); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1204 } |
0 | 1205 if (is_synthetic) { |
1206 access_flags.set_is_synthetic(); | |
1207 } | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1208 if (generic_signature_index != 0) { |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1209 access_flags.set_field_has_generic_signature(); |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1210 fa[generic_signature_slot] = generic_signature_index; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1211 generic_signature_slot ++; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1212 num_generic_signature ++; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1213 } |
0 | 1214 } |
1215 | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1216 FieldInfo* field = FieldInfo::from_field_array(fa, n); |
3938 | 1217 field->initialize(access_flags.as_short(), |
1218 name_index, | |
1219 signature_index, | |
1220 constantvalue_index, | |
1221 0); | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1222 if (parsed_annotations.has_any_annotations()) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1223 parsed_annotations.apply_to(field); |
3938 | 1224 |
1225 BasicType type = cp->basic_type_for_signature_at(signature_index); | |
0 | 1226 |
1227 // Remember how many oops we encountered and compute allocation type | |
3938 | 1228 FieldAllocationType atype = fac->update(is_static, type); |
0 | 1229 |
1230 // The correct offset is computed later (all oop fields will be located together) | |
1231 // We temporarily store the allocation type in the offset field | |
3938 | 1232 field->set_offset(atype); |
1233 } | |
1234 | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1235 int index = length; |
3938 | 1236 if (num_injected != 0) { |
1237 for (int n = 0; n < num_injected; n++) { | |
1238 // Check for duplicates | |
1239 if (injected[n].may_be_java) { | |
1240 Symbol* name = injected[n].name(); | |
1241 Symbol* signature = injected[n].signature(); | |
1242 bool duplicate = false; | |
1243 for (int i = 0; i < length; i++) { | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1244 FieldInfo* f = FieldInfo::from_field_array(fa, i); |
3938 | 1245 if (name == cp->symbol_at(f->name_index()) && |
1246 signature == cp->symbol_at(f->signature_index())) { | |
1247 // Symbol is desclared in Java so skip this one | |
1248 duplicate = true; | |
1249 break; | |
1250 } | |
1251 } | |
1252 if (duplicate) { | |
1253 // These will be removed from the field array at the end | |
1254 continue; | |
1255 } | |
1256 } | |
1257 | |
1258 // Injected field | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1259 FieldInfo* field = FieldInfo::from_field_array(fa, index); |
3938 | 1260 field->initialize(JVM_ACC_FIELD_INTERNAL, |
1261 injected[n].name_index, | |
1262 injected[n].signature_index, | |
1263 0, | |
1264 0); | |
1265 | |
1266 BasicType type = FieldType::basic_type(injected[n].signature()); | |
1267 | |
1268 // Remember how many oops we encountered and compute allocation type | |
1269 FieldAllocationType atype = fac->update(false, type); | |
1270 | |
1271 // The correct offset is computed later (all oop fields will be located together) | |
1272 // We temporarily store the allocation type in the offset field | |
1273 field->set_offset(atype); | |
1274 index++; | |
1275 } | |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1276 } |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1277 |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1278 // Now copy the fields' data from the temporary resource array. |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1279 // Sometimes injected fields already exist in the Java source so |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1280 // the fields array could be too long. In that case the |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1281 // fields array is trimed. Also unused slots that were reserved |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1282 // for generic signature indexes are discarded. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1283 Array<u2>* fields = MetadataFactory::new_array<u2>( |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1284 loader_data, index * FieldInfo::field_slots + num_generic_signature, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1285 CHECK_NULL); |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1286 { |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1287 int i = 0; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1288 for (; i < index * FieldInfo::field_slots; i++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1289 fields->at_put(i, fa[i]); |
3938 | 1290 } |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1291 for (int j = total_fields * FieldInfo::field_slots; |
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1292 j < generic_signature_slot; j++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1293 fields->at_put(i++, fa[j]); |
6100
71afdabfd05b
7168280: Eliminate the generic signature index slot from field array for field without generic signature.
jiangli
parents:
6038
diff
changeset
|
1294 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1295 assert(i == fields->length(), ""); |
0 | 1296 } |
1297 | |
1298 if (_need_verify && length > 1) { | |
1299 // Check duplicated fields | |
1300 ResourceMark rm(THREAD); | |
1301 NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( | |
1302 THREAD, NameSigHash*, HASH_ROW_SIZE); | |
1303 initialize_hashtable(names_and_sigs); | |
1304 bool dup = false; | |
1305 { | |
1306 debug_only(No_Safepoint_Verifier nsv;) | |
3938 | 1307 for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { |
1308 Symbol* name = fs.name(); | |
1309 Symbol* sig = fs.signature(); | |
0 | 1310 // If no duplicates, add name/signature in hashtable names_and_sigs. |
1311 if (!put_after_lookup(name, sig, names_and_sigs)) { | |
1312 dup = true; | |
1313 break; | |
1314 } | |
1315 } | |
1316 } | |
1317 if (dup) { | |
1318 classfile_parse_error("Duplicate field name&signature in class file %s", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1319 CHECK_NULL); |
0 | 1320 } |
1321 } | |
1322 | |
1323 return fields; | |
1324 } | |
1325 | |
1326 | |
1327 static void copy_u2_with_conversion(u2* dest, u2* src, int length) { | |
1328 while (length-- > 0) { | |
1329 *dest++ = Bytes::get_Java_u2((u1*) (src++)); | |
1330 } | |
1331 } | |
1332 | |
1333 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1334 u2* ClassFileParser::parse_exception_table(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1335 u4 code_length, |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1336 u4 exception_table_length, |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1337 constantPoolHandle cp, |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1338 TRAPS) { |
0 | 1339 ClassFileStream* cfs = stream(); |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1340 |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1341 u2* exception_table_start = cfs->get_u2_buffer(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1342 assert(exception_table_start != NULL, "null exception table"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1343 cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1344 // Will check legal target after parsing code array in verifier. |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1345 if (_need_verify) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1346 for (unsigned int i = 0; i < exception_table_length; i++) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1347 u2 start_pc = cfs->get_u2_fast(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1348 u2 end_pc = cfs->get_u2_fast(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1349 u2 handler_pc = cfs->get_u2_fast(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1350 u2 catch_type_index = cfs->get_u2_fast(); |
0 | 1351 guarantee_property((start_pc < end_pc) && (end_pc <= code_length), |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1352 "Illegal exception table range in class file %s", |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1353 CHECK_NULL); |
0 | 1354 guarantee_property(handler_pc < code_length, |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1355 "Illegal exception table handler in class file %s", |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1356 CHECK_NULL); |
0 | 1357 if (catch_type_index != 0) { |
1358 guarantee_property(valid_cp_range(catch_type_index, cp->length()) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
1359 is_klass_reference(cp, catch_type_index), |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1360 "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); |
0 | 1361 } |
1362 } | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1363 } else { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1364 cfs->skip_u2_fast(exception_table_length * 4); |
0 | 1365 } |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1366 return exception_table_start; |
0 | 1367 } |
1368 | |
1369 void ClassFileParser::parse_linenumber_table( | |
1370 u4 code_attribute_length, u4 code_length, | |
1371 CompressedLineNumberWriteStream** write_stream, TRAPS) { | |
1372 ClassFileStream* cfs = stream(); | |
1373 unsigned int num_entries = cfs->get_u2(CHECK); | |
1374 | |
1375 // Each entry is a u2 start_pc, and a u2 line_number | |
1376 unsigned int length_in_bytes = num_entries * (sizeof(u2) + sizeof(u2)); | |
1377 | |
1378 // Verify line number attribute and table length | |
1379 check_property( | |
1380 code_attribute_length == sizeof(u2) + length_in_bytes, | |
1381 "LineNumberTable attribute has wrong length in class file %s", CHECK); | |
1382 | |
1383 cfs->guarantee_more(length_in_bytes, CHECK); | |
1384 | |
1385 if ((*write_stream) == NULL) { | |
1386 if (length_in_bytes > fixed_buffer_size) { | |
1387 (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes); | |
1388 } else { | |
1389 (*write_stream) = new CompressedLineNumberWriteStream( | |
1390 linenumbertable_buffer, fixed_buffer_size); | |
1391 } | |
1392 } | |
1393 | |
1394 while (num_entries-- > 0) { | |
1395 u2 bci = cfs->get_u2_fast(); // start_pc | |
1396 u2 line = cfs->get_u2_fast(); // line_number | |
1397 guarantee_property(bci < code_length, | |
1398 "Invalid pc in LineNumberTable in class file %s", CHECK); | |
1399 (*write_stream)->write_pair(bci, line); | |
1400 } | |
1401 } | |
1402 | |
1403 | |
1404 // Class file LocalVariableTable elements. | |
1405 class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC { | |
1406 public: | |
1407 u2 start_bci; | |
1408 u2 length; | |
1409 u2 name_cp_index; | |
1410 u2 descriptor_cp_index; | |
1411 u2 slot; | |
1412 }; | |
1413 | |
1414 | |
6197 | 1415 class LVT_Hash: public CHeapObj<mtClass> { |
0 | 1416 public: |
1417 LocalVariableTableElement *_elem; // element | |
1418 LVT_Hash* _next; // Next entry in hash table | |
1419 }; | |
1420 | |
1421 unsigned int hash(LocalVariableTableElement *elem) { | |
1422 unsigned int raw_hash = elem->start_bci; | |
1423 | |
1424 raw_hash = elem->length + raw_hash * 37; | |
1425 raw_hash = elem->name_cp_index + raw_hash * 37; | |
1426 raw_hash = elem->slot + raw_hash * 37; | |
1427 | |
1428 return raw_hash % HASH_ROW_SIZE; | |
1429 } | |
1430 | |
1431 void initialize_hashtable(LVT_Hash** table) { | |
1432 for (int i = 0; i < HASH_ROW_SIZE; i++) { | |
1433 table[i] = NULL; | |
1434 } | |
1435 } | |
1436 | |
1437 void clear_hashtable(LVT_Hash** table) { | |
1438 for (int i = 0; i < HASH_ROW_SIZE; i++) { | |
1439 LVT_Hash* current = table[i]; | |
1440 LVT_Hash* next; | |
1441 while (current != NULL) { | |
1442 next = current->_next; | |
1443 current->_next = NULL; | |
1444 delete(current); | |
1445 current = next; | |
1446 } | |
1447 table[i] = NULL; | |
1448 } | |
1449 } | |
1450 | |
1451 LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) { | |
1452 LVT_Hash* entry = table[index]; | |
1453 | |
1454 /* | |
1455 * 3-tuple start_bci/length/slot has to be unique key, | |
1456 * so the following comparison seems to be redundant: | |
1457 * && elem->name_cp_index == entry->_elem->name_cp_index | |
1458 */ | |
1459 while (entry != NULL) { | |
1460 if (elem->start_bci == entry->_elem->start_bci | |
1461 && elem->length == entry->_elem->length | |
1462 && elem->name_cp_index == entry->_elem->name_cp_index | |
1463 && elem->slot == entry->_elem->slot | |
1464 ) { | |
1465 return entry; | |
1466 } | |
1467 entry = entry->_next; | |
1468 } | |
1469 return NULL; | |
1470 } | |
1471 | |
1472 // Return false if the local variable is found in table. | |
1473 // Return true if no duplicate is found. | |
1474 // And local variable is added as a new entry in table. | |
1475 bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) { | |
1476 // First lookup for duplicates | |
1477 int index = hash(elem); | |
1478 LVT_Hash* entry = LVT_lookup(elem, index, table); | |
1479 | |
1480 if (entry != NULL) { | |
1481 return false; | |
1482 } | |
1483 // No duplicate is found, allocate a new entry and fill it. | |
1484 if ((entry = new LVT_Hash()) == NULL) { | |
1485 return false; | |
1486 } | |
1487 entry->_elem = elem; | |
1488 | |
1489 // Insert into hash table | |
1490 entry->_next = table[index]; | |
1491 table[index] = entry; | |
1492 | |
1493 return true; | |
1494 } | |
1495 | |
1496 void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) { | |
1497 lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci); | |
1498 lvt->length = Bytes::get_Java_u2((u1*) &src->length); | |
1499 lvt->name_cp_index = Bytes::get_Java_u2((u1*) &src->name_cp_index); | |
1500 lvt->descriptor_cp_index = Bytes::get_Java_u2((u1*) &src->descriptor_cp_index); | |
1501 lvt->signature_cp_index = 0; | |
1502 lvt->slot = Bytes::get_Java_u2((u1*) &src->slot); | |
1503 } | |
1504 | |
1505 // Function is used to parse both attributes: | |
1506 // LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT) | |
1507 u2* ClassFileParser::parse_localvariable_table(u4 code_length, | |
1508 u2 max_locals, | |
1509 u4 code_attribute_length, | |
1510 constantPoolHandle cp, | |
1511 u2* localvariable_table_length, | |
1512 bool isLVTT, | |
1513 TRAPS) { | |
1514 ClassFileStream* cfs = stream(); | |
1515 const char * tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable"; | |
1516 *localvariable_table_length = cfs->get_u2(CHECK_NULL); | |
1517 unsigned int size = (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2); | |
1518 // Verify local variable table attribute has right length | |
1519 if (_need_verify) { | |
1520 guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)), | |
1521 "%s has wrong length in class file %s", tbl_name, CHECK_NULL); | |
1522 } | |
1523 u2* localvariable_table_start = cfs->get_u2_buffer(); | |
1524 assert(localvariable_table_start != NULL, "null local variable table"); | |
1525 if (!_need_verify) { | |
1526 cfs->skip_u2_fast(size); | |
1527 } else { | |
1528 cfs->guarantee_more(size * 2, CHECK_NULL); | |
1529 for(int i = 0; i < (*localvariable_table_length); i++) { | |
1530 u2 start_pc = cfs->get_u2_fast(); | |
1531 u2 length = cfs->get_u2_fast(); | |
1532 u2 name_index = cfs->get_u2_fast(); | |
1533 u2 descriptor_index = cfs->get_u2_fast(); | |
1534 u2 index = cfs->get_u2_fast(); | |
1535 // Assign to a u4 to avoid overflow | |
1536 u4 end_pc = (u4)start_pc + (u4)length; | |
1537 | |
1538 if (start_pc >= code_length) { | |
1539 classfile_parse_error( | |
1540 "Invalid start_pc %u in %s in class file %s", | |
1541 start_pc, tbl_name, CHECK_NULL); | |
1542 } | |
1543 if (end_pc > code_length) { | |
1544 classfile_parse_error( | |
1545 "Invalid length %u in %s in class file %s", | |
1546 length, tbl_name, CHECK_NULL); | |
1547 } | |
1548 int cp_size = cp->length(); | |
1549 guarantee_property( | |
1550 valid_cp_range(name_index, cp_size) && | |
1551 cp->tag_at(name_index).is_utf8(), | |
1552 "Name index %u in %s has bad constant type in class file %s", | |
1553 name_index, tbl_name, CHECK_NULL); | |
1554 guarantee_property( | |
1555 valid_cp_range(descriptor_index, cp_size) && | |
1556 cp->tag_at(descriptor_index).is_utf8(), | |
1557 "Signature index %u in %s has bad constant type in class file %s", | |
1558 descriptor_index, tbl_name, CHECK_NULL); | |
1559 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1560 Symbol* name = cp->symbol_at(name_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1561 Symbol* sig = cp->symbol_at(descriptor_index); |
0 | 1562 verify_legal_field_name(name, CHECK_NULL); |
1563 u2 extra_slot = 0; | |
1564 if (!isLVTT) { | |
1565 verify_legal_field_signature(name, sig, CHECK_NULL); | |
1566 | |
1567 // 4894874: check special cases for double and long local variables | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1568 if (sig == vmSymbols::type_signature(T_DOUBLE) || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1569 sig == vmSymbols::type_signature(T_LONG)) { |
0 | 1570 extra_slot = 1; |
1571 } | |
1572 } | |
1573 guarantee_property((index + extra_slot) < max_locals, | |
1574 "Invalid index %u in %s in class file %s", | |
1575 index, tbl_name, CHECK_NULL); | |
1576 } | |
1577 } | |
1578 return localvariable_table_start; | |
1579 } | |
1580 | |
1581 | |
1582 void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index, | |
1583 u1* u1_array, u2* u2_array, constantPoolHandle cp, TRAPS) { | |
1584 ClassFileStream* cfs = stream(); | |
1585 u2 index = 0; // index in the array with long/double occupying two slots | |
1586 u4 i1 = *u1_index; | |
1587 u4 i2 = *u2_index + 1; | |
1588 for(int i = 0; i < array_length; i++) { | |
1589 u1 tag = u1_array[i1++] = cfs->get_u1(CHECK); | |
1590 index++; | |
1591 if (tag == ITEM_Long || tag == ITEM_Double) { | |
1592 index++; | |
1593 } else if (tag == ITEM_Object) { | |
1594 u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK); | |
1595 guarantee_property(valid_cp_range(class_index, cp->length()) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
1596 is_klass_reference(cp, class_index), |
0 | 1597 "Bad class index %u in StackMap in class file %s", |
1598 class_index, CHECK); | |
1599 } else if (tag == ITEM_Uninitialized) { | |
1600 u2 offset = u2_array[i2++] = cfs->get_u2(CHECK); | |
1601 guarantee_property( | |
1602 offset < code_length, | |
1603 "Bad uninitialized type offset %u in StackMap in class file %s", | |
1604 offset, CHECK); | |
1605 } else { | |
1606 guarantee_property( | |
1607 tag <= (u1)ITEM_Uninitialized, | |
1608 "Unknown variable type %u in StackMap in class file %s", | |
1609 tag, CHECK); | |
1610 } | |
1611 } | |
1612 u2_array[*u2_index] = index; | |
1613 *u1_index = i1; | |
1614 *u2_index = i2; | |
1615 } | |
1616 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1617 Array<u1>* ClassFileParser::parse_stackmap_table( |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1618 ClassLoaderData* loader_data, |
0 | 1619 u4 code_attribute_length, TRAPS) { |
1620 if (code_attribute_length == 0) | |
1621 return NULL; | |
1622 | |
1623 ClassFileStream* cfs = stream(); | |
1624 u1* stackmap_table_start = cfs->get_u1_buffer(); | |
1625 assert(stackmap_table_start != NULL, "null stackmap table"); | |
1626 | |
1627 // check code_attribute_length first | |
1628 stream()->skip_u1(code_attribute_length, CHECK_NULL); | |
1629 | |
1630 if (!_need_verify && !DumpSharedSpaces) { | |
1631 return NULL; | |
1632 } | |
1633 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1634 Array<u1>* stackmap_data = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1635 MetadataFactory::new_array<u1>(loader_data, code_attribute_length, 0, CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1636 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1637 memcpy((void*)stackmap_data->adr_at(0), |
0 | 1638 (void*)stackmap_table_start, code_attribute_length); |
1639 return stackmap_data; | |
1640 } | |
1641 | |
1642 u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length, | |
1643 u4 method_attribute_length, | |
1644 constantPoolHandle cp, TRAPS) { | |
1645 ClassFileStream* cfs = stream(); | |
1646 cfs->guarantee_more(2, CHECK_NULL); // checked_exceptions_length | |
1647 *checked_exceptions_length = cfs->get_u2_fast(); | |
1648 unsigned int size = (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2); | |
1649 u2* checked_exceptions_start = cfs->get_u2_buffer(); | |
1650 assert(checked_exceptions_start != NULL, "null checked exceptions"); | |
1651 if (!_need_verify) { | |
1652 cfs->skip_u2_fast(size); | |
1653 } else { | |
1654 // Verify each value in the checked exception table | |
1655 u2 checked_exception; | |
1656 u2 len = *checked_exceptions_length; | |
1657 cfs->guarantee_more(2 * len, CHECK_NULL); | |
1658 for (int i = 0; i < len; i++) { | |
1659 checked_exception = cfs->get_u2_fast(); | |
1660 check_property( | |
1661 valid_cp_range(checked_exception, cp->length()) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
1662 is_klass_reference(cp, checked_exception), |
0 | 1663 "Exception name has bad type at constant pool %u in class file %s", |
1664 checked_exception, CHECK_NULL); | |
1665 } | |
1666 } | |
1667 // check exceptions attribute length | |
1668 if (_need_verify) { | |
1669 guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) + | |
1670 sizeof(u2) * size), | |
1671 "Exceptions attribute has wrong length in class file %s", CHECK_NULL); | |
1672 } | |
1673 return checked_exceptions_start; | |
1674 } | |
1675 | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1676 void ClassFileParser::throwIllegalSignature( |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1677 const char* type, Symbol* name, Symbol* sig, TRAPS) { |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1678 ResourceMark rm(THREAD); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1679 Exceptions::fthrow(THREAD_AND_LOCATION, |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1680 vmSymbols::java_lang_ClassFormatError(), |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1681 "%s \"%s\" in class %s has illegal signature \"%s\"", type, |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1682 name->as_C_string(), _class_name->as_C_string(), sig->as_C_string()); |
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
1683 } |
0 | 1684 |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1685 // Skip an annotation. Return >=limit if there is any problem. |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1686 int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1687 // annotation := atype:u2 do(nmem:u2) {member:u2 value} |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1688 // value := switch (tag:u1) { ... } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1689 index += 2; // skip atype |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1690 if ((index += 2) >= limit) return limit; // read nmem |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1691 int nmem = Bytes::get_Java_u2(buffer+index-2); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1692 while (--nmem >= 0 && index < limit) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1693 index += 2; // skip member |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1694 index = skip_annotation_value(buffer, limit, index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1695 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1696 return index; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1697 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1698 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1699 // Skip an annotation value. Return >=limit if there is any problem. |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1700 int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1701 // value := switch (tag:u1) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1702 // case B, C, I, S, Z, D, F, J, c: con:u2; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1703 // case e: e_class:u2 e_name:u2; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1704 // case s: s_con:u2; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1705 // case [: do(nval:u2) {value}; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1706 // case @: annotation; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1707 // case s: s_con:u2; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1708 // } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1709 if ((index += 1) >= limit) return limit; // read tag |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1710 u1 tag = buffer[index-1]; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1711 switch (tag) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1712 case 'B': case 'C': case 'I': case 'S': case 'Z': |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1713 case 'D': case 'F': case 'J': case 'c': case 's': |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1714 index += 2; // skip con or s_con |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1715 break; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1716 case 'e': |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1717 index += 4; // skip e_class, e_name |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1718 break; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1719 case '[': |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1720 { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1721 if ((index += 2) >= limit) return limit; // read nval |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1722 int nval = Bytes::get_Java_u2(buffer+index-2); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1723 while (--nval >= 0 && index < limit) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1724 index = skip_annotation_value(buffer, limit, index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1725 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1726 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1727 break; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1728 case '@': |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1729 index = skip_annotation(buffer, limit, index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1730 break; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1731 default: |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1732 assert(false, "annotation tag"); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1733 return limit; // bad tag byte |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1734 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1735 return index; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1736 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1737 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1738 // Sift through annotations, looking for those significant to the VM: |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1739 void ClassFileParser::parse_annotations(u1* buffer, int limit, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1740 constantPoolHandle cp, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1741 ClassFileParser::AnnotationCollector* coll, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1742 TRAPS) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1743 // annotations := do(nann:u2) {annotation} |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1744 int index = 0; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1745 if ((index += 2) >= limit) return; // read nann |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1746 int nann = Bytes::get_Java_u2(buffer+index-2); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1747 enum { // initial annotation layout |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1748 atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1749 count_off = 2, // u2 such as 1 (one value) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1750 member_off = 4, // utf8 such as 'value' |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1751 tag_off = 6, // u1 such as 'c' (type) or 'e' (enum) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1752 e_tag_val = 'e', |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1753 e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1754 e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1755 e_size = 11, // end of 'e' annotation |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1756 c_tag_val = 'c', |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1757 c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;' |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1758 c_size = 9, // end of 'c' annotation |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1759 min_size = 6 // smallest possible size (zero members) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1760 }; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1761 while ((--nann) >= 0 && (index-2 + min_size <= limit)) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1762 int index0 = index; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1763 index = skip_annotation(buffer, limit, index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1764 u1* abase = buffer + index0; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1765 int atype = Bytes::get_Java_u2(abase + atype_off); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1766 int count = Bytes::get_Java_u2(abase + count_off); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1767 Symbol* aname = check_symbol_at(cp, atype); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1768 if (aname == NULL) break; // invalid annotation name |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1769 Symbol* member = NULL; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1770 if (count >= 1) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1771 int member_index = Bytes::get_Java_u2(abase + member_off); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1772 member = check_symbol_at(cp, member_index); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1773 if (member == NULL) break; // invalid member name |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1774 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1775 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1776 // Here is where parsing particular annotations will take place. |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1777 AnnotationCollector::ID id = coll->annotation_index(aname); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1778 if (id == AnnotationCollector::_unknown) continue; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1779 coll->set_annotation(id); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1780 // If there are no values, just set the bit and move on: |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1781 if (count == 0) continue; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1782 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1783 // For the record, here is how annotation payloads can be collected. |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1784 // Suppose we want to capture @Retention.value. Here is how: |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1785 //if (id == AnnotationCollector::_class_Retention) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1786 // Symbol* payload = NULL; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1787 // if (count == 1 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1788 // && e_size == (index0 - index) // match size |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1789 // && e_tag_val == *(abase + tag_off) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1790 // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off)) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1791 // == vmSymbols::RetentionPolicy_signature()) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1792 // && member == vmSymbols::value_name()) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1793 // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off)); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1794 // } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1795 // check_property(payload != NULL, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1796 // "Invalid @Retention annotation at offset %u in class file %s", |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1797 // index0, CHECK); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1798 // if (payload != NULL) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1799 // payload->increment_refcount(); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1800 // coll->_class_RetentionPolicy = payload; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1801 // } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1802 //} |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1803 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1804 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1805 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1806 ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1807 vmSymbols::SID sid = vmSymbols::find_sid(name); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1808 switch (sid) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1809 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1810 if (_location != _in_method) break; // only allow for methods |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1811 return _method_ForceInline; |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1812 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1813 if (_location != _in_method) break; // only allow for methods |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1814 return _method_DontInline; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1815 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1816 if (_location != _in_method) break; // only allow for methods |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1817 return _method_LambdaForm_Compiled; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1818 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1819 if (_location != _in_method) break; // only allow for methods |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1820 return _method_LambdaForm_Hidden; |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1821 default: break; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1822 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1823 return AnnotationCollector::_unknown; |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1824 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1825 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1826 void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1827 fatal("no field annotations yet"); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1828 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1829 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1830 void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1831 if (has_annotation(_method_ForceInline)) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1832 m->set_force_inline(true); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1833 if (has_annotation(_method_DontInline)) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1834 m->set_dont_inline(true); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1835 if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1836 m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1837 if (has_annotation(_method_LambdaForm_Hidden)) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
1838 m->set_hidden(true); |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1839 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1840 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1841 void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1842 fatal("no class annotations yet"); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1843 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1844 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1845 |
0 | 1846 #define MAX_ARGS_SIZE 255 |
1847 #define MAX_CODE_SIZE 65535 | |
1848 #define INITIAL_MAX_LVT_NUMBER 256 | |
1849 | |
1850 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1851 // attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1852 // Method* to save footprint, so we only know the size of the resulting Method* when the |
0 | 1853 // entire method attribute is parsed. |
1854 // | |
1855 // The promoted_flags parameter is used to pass relevant access_flags | |
1856 // from the method back up to the containing klass. These flag values | |
1857 // are added to klass's access_flags. | |
1858 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1859 methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1860 constantPoolHandle cp, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1861 bool is_interface, |
0 | 1862 AccessFlags *promoted_flags, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1863 AnnotationArray** method_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1864 AnnotationArray** method_parameter_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1865 AnnotationArray** method_default_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1866 AnnotationArray** method_type_annotations, |
0 | 1867 TRAPS) { |
1868 ClassFileStream* cfs = stream(); | |
1869 methodHandle nullHandle; | |
1870 ResourceMark rm(THREAD); | |
1871 // Parse fixed parts | |
1872 cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count | |
1873 | |
1874 int flags = cfs->get_u2_fast(); | |
1875 u2 name_index = cfs->get_u2_fast(); | |
1876 int cp_size = cp->length(); | |
1877 check_property( | |
1878 valid_cp_range(name_index, cp_size) && | |
1879 cp->tag_at(name_index).is_utf8(), | |
1880 "Illegal constant pool index %u for method name in class file %s", | |
1881 name_index, CHECK_(nullHandle)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1882 Symbol* name = cp->symbol_at(name_index); |
0 | 1883 verify_legal_method_name(name, CHECK_(nullHandle)); |
1884 | |
1885 u2 signature_index = cfs->get_u2_fast(); | |
1886 guarantee_property( | |
1887 valid_cp_range(signature_index, cp_size) && | |
1888 cp->tag_at(signature_index).is_utf8(), | |
1889 "Illegal constant pool index %u for method signature in class file %s", | |
1890 signature_index, CHECK_(nullHandle)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1891 Symbol* signature = cp->symbol_at(signature_index); |
0 | 1892 |
1893 AccessFlags access_flags; | |
1894 if (name == vmSymbols::class_initializer_name()) { | |
2334
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1895 // We ignore the other access flags for a valid class initializer. |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1896 // (JVM Spec 2nd ed., chapter 4.6) |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1897 if (_major_version < 51) { // backward compatibility |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1898 flags = JVM_ACC_STATIC; |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1899 } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) { |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1900 flags &= JVM_ACC_STATIC | JVM_ACC_STRICT; |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2226
diff
changeset
|
1901 } |
0 | 1902 } else { |
1903 verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle)); | |
1904 } | |
1905 | |
1906 int args_size = -1; // only used when _need_verify is true | |
1907 if (_need_verify) { | |
1908 args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) + | |
1909 verify_legal_method_signature(name, signature, CHECK_(nullHandle)); | |
1910 if (args_size > MAX_ARGS_SIZE) { | |
1911 classfile_parse_error("Too many arguments in method signature in class file %s", CHECK_(nullHandle)); | |
1912 } | |
1913 } | |
1914 | |
1915 access_flags.set_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS); | |
1916 | |
1917 // Default values for code and exceptions attribute elements | |
1918 u2 max_stack = 0; | |
1919 u2 max_locals = 0; | |
1920 u4 code_length = 0; | |
1921 u1* code_start = 0; | |
1922 u2 exception_table_length = 0; | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
1923 u2* exception_table_start = NULL; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1924 Array<int>* exception_handlers = Universe::the_empty_int_array(); |
0 | 1925 u2 checked_exceptions_length = 0; |
1926 u2* checked_exceptions_start = NULL; | |
1927 CompressedLineNumberWriteStream* linenumber_table = NULL; | |
1928 int linenumber_table_length = 0; | |
1929 int total_lvt_length = 0; | |
1930 u2 lvt_cnt = 0; | |
1931 u2 lvtt_cnt = 0; | |
1932 bool lvt_allocated = false; | |
1933 u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER; | |
1934 u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER; | |
1935 u2* localvariable_table_length; | |
1936 u2** localvariable_table_start; | |
1937 u2* localvariable_type_table_length; | |
1938 u2** localvariable_type_table_start; | |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
1939 u2 method_parameters_length = 0; |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
1940 u1* method_parameters_data = NULL; |
0 | 1941 bool parsed_code_attribute = false; |
1942 bool parsed_checked_exceptions_attribute = false; | |
1943 bool parsed_stackmap_attribute = false; | |
1944 // stackmap attribute - JDK1.5 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1945 Array<u1>* stackmap_data = NULL; |
0 | 1946 u2 generic_signature_index = 0; |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
1947 MethodAnnotationCollector parsed_annotations; |
0 | 1948 u1* runtime_visible_annotations = NULL; |
1949 int runtime_visible_annotations_length = 0; | |
1950 u1* runtime_invisible_annotations = NULL; | |
1951 int runtime_invisible_annotations_length = 0; | |
1952 u1* runtime_visible_parameter_annotations = NULL; | |
1953 int runtime_visible_parameter_annotations_length = 0; | |
1954 u1* runtime_invisible_parameter_annotations = NULL; | |
1955 int runtime_invisible_parameter_annotations_length = 0; | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1956 u1* runtime_visible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1957 int runtime_visible_type_annotations_length = 0; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1958 u1* runtime_invisible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
1959 int runtime_invisible_type_annotations_length = 0; |
0 | 1960 u1* annotation_default = NULL; |
1961 int annotation_default_length = 0; | |
1962 | |
1963 // Parse code and exceptions attribute | |
1964 u2 method_attributes_count = cfs->get_u2_fast(); | |
1965 while (method_attributes_count--) { | |
1966 cfs->guarantee_more(6, CHECK_(nullHandle)); // method_attribute_name_index, method_attribute_length | |
1967 u2 method_attribute_name_index = cfs->get_u2_fast(); | |
1968 u4 method_attribute_length = cfs->get_u4_fast(); | |
1969 check_property( | |
1970 valid_cp_range(method_attribute_name_index, cp_size) && | |
1971 cp->tag_at(method_attribute_name_index).is_utf8(), | |
1972 "Invalid method attribute name index %u in class file %s", | |
1973 method_attribute_name_index, CHECK_(nullHandle)); | |
1974 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
1975 Symbol* method_attribute_name = cp->symbol_at(method_attribute_name_index); |
0 | 1976 if (method_attribute_name == vmSymbols::tag_code()) { |
1977 // Parse Code attribute | |
1978 if (_need_verify) { | |
6934 | 1979 guarantee_property( |
1980 !access_flags.is_native() && !access_flags.is_abstract(), | |
0 | 1981 "Code attribute in native or abstract methods in class file %s", |
1982 CHECK_(nullHandle)); | |
1983 } | |
1984 if (parsed_code_attribute) { | |
1985 classfile_parse_error("Multiple Code attributes in class file %s", CHECK_(nullHandle)); | |
1986 } | |
1987 parsed_code_attribute = true; | |
1988 | |
1989 // Stack size, locals size, and code size | |
1990 if (_major_version == 45 && _minor_version <= 2) { | |
1991 cfs->guarantee_more(4, CHECK_(nullHandle)); | |
1992 max_stack = cfs->get_u1_fast(); | |
1993 max_locals = cfs->get_u1_fast(); | |
1994 code_length = cfs->get_u2_fast(); | |
1995 } else { | |
1996 cfs->guarantee_more(8, CHECK_(nullHandle)); | |
1997 max_stack = cfs->get_u2_fast(); | |
1998 max_locals = cfs->get_u2_fast(); | |
1999 code_length = cfs->get_u4_fast(); | |
2000 } | |
2001 if (_need_verify) { | |
2002 guarantee_property(args_size <= max_locals, | |
2003 "Arguments can't fit into locals in class file %s", CHECK_(nullHandle)); | |
2004 guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE, | |
2005 "Invalid method Code length %u in class file %s", | |
2006 code_length, CHECK_(nullHandle)); | |
2007 } | |
2008 // Code pointer | |
2009 code_start = cfs->get_u1_buffer(); | |
2010 assert(code_start != NULL, "null code start"); | |
2011 cfs->guarantee_more(code_length, CHECK_(nullHandle)); | |
2012 cfs->skip_u1_fast(code_length); | |
2013 | |
2014 // Exception handler table | |
2015 cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length | |
2016 exception_table_length = cfs->get_u2_fast(); | |
2017 if (exception_table_length > 0) { | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2018 exception_table_start = |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2019 parse_exception_table(loader_data, code_length, exception_table_length, cp, CHECK_(nullHandle)); |
0 | 2020 } |
2021 | |
2022 // Parse additional attributes in code attribute | |
2023 cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count | |
2024 u2 code_attributes_count = cfs->get_u2_fast(); | |
92
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2025 |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2026 unsigned int calculated_attribute_length = 0; |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2027 |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2028 if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) { |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2029 calculated_attribute_length = |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2030 sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length); |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2031 } else { |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2032 // max_stack, locals and length are smaller in pre-version 45.2 classes |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2033 calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2); |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2034 } |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2035 calculated_attribute_length += |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2036 code_length + |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2037 sizeof(exception_table_length) + |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2038 sizeof(code_attributes_count) + |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2039 exception_table_length * |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2040 ( sizeof(u2) + // start_pc |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2041 sizeof(u2) + // end_pc |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2042 sizeof(u2) + // handler_pc |
ebec5b9731e2
6615981: JVM class file parser incorrectly rejects class files with version < 45.2
kamg
parents:
0
diff
changeset
|
2043 sizeof(u2) ); // catch_type_index |
0 | 2044 |
2045 while (code_attributes_count--) { | |
2046 cfs->guarantee_more(6, CHECK_(nullHandle)); // code_attribute_name_index, code_attribute_length | |
2047 u2 code_attribute_name_index = cfs->get_u2_fast(); | |
2048 u4 code_attribute_length = cfs->get_u4_fast(); | |
2049 calculated_attribute_length += code_attribute_length + | |
2050 sizeof(code_attribute_name_index) + | |
2051 sizeof(code_attribute_length); | |
2052 check_property(valid_cp_range(code_attribute_name_index, cp_size) && | |
2053 cp->tag_at(code_attribute_name_index).is_utf8(), | |
2054 "Invalid code attribute name index %u in class file %s", | |
2055 code_attribute_name_index, | |
2056 CHECK_(nullHandle)); | |
2057 if (LoadLineNumberTables && | |
2058 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) { | |
2059 // Parse and compress line number table | |
2060 parse_linenumber_table(code_attribute_length, code_length, | |
2061 &linenumber_table, CHECK_(nullHandle)); | |
2062 | |
2063 } else if (LoadLocalVariableTables && | |
2064 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) { | |
2065 // Parse local variable table | |
2066 if (!lvt_allocated) { | |
2067 localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2068 THREAD, u2, INITIAL_MAX_LVT_NUMBER); | |
2069 localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2070 THREAD, u2*, INITIAL_MAX_LVT_NUMBER); | |
2071 localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2072 THREAD, u2, INITIAL_MAX_LVT_NUMBER); | |
2073 localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2074 THREAD, u2*, INITIAL_MAX_LVT_NUMBER); | |
2075 lvt_allocated = true; | |
2076 } | |
2077 if (lvt_cnt == max_lvt_cnt) { | |
2078 max_lvt_cnt <<= 1; | |
2079 REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); | |
2080 REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); | |
2081 } | |
2082 localvariable_table_start[lvt_cnt] = | |
2083 parse_localvariable_table(code_length, | |
2084 max_locals, | |
2085 code_attribute_length, | |
2086 cp, | |
2087 &localvariable_table_length[lvt_cnt], | |
2088 false, // is not LVTT | |
2089 CHECK_(nullHandle)); | |
2090 total_lvt_length += localvariable_table_length[lvt_cnt]; | |
2091 lvt_cnt++; | |
2092 } else if (LoadLocalVariableTypeTables && | |
2093 _major_version >= JAVA_1_5_VERSION && | |
2094 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) { | |
2095 if (!lvt_allocated) { | |
2096 localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2097 THREAD, u2, INITIAL_MAX_LVT_NUMBER); | |
2098 localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2099 THREAD, u2*, INITIAL_MAX_LVT_NUMBER); | |
2100 localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2101 THREAD, u2, INITIAL_MAX_LVT_NUMBER); | |
2102 localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2103 THREAD, u2*, INITIAL_MAX_LVT_NUMBER); | |
2104 lvt_allocated = true; | |
2105 } | |
2106 // Parse local variable type table | |
2107 if (lvtt_cnt == max_lvtt_cnt) { | |
2108 max_lvtt_cnt <<= 1; | |
2109 REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); | |
2110 REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); | |
2111 } | |
2112 localvariable_type_table_start[lvtt_cnt] = | |
2113 parse_localvariable_table(code_length, | |
2114 max_locals, | |
2115 code_attribute_length, | |
2116 cp, | |
2117 &localvariable_type_table_length[lvtt_cnt], | |
2118 true, // is LVTT | |
2119 CHECK_(nullHandle)); | |
2120 lvtt_cnt++; | |
2121 } else if (UseSplitVerifier && | |
2122 _major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION && | |
2123 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) { | |
2124 // Stack map is only needed by the new verifier in JDK1.5. | |
2125 if (parsed_stackmap_attribute) { | |
2126 classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_(nullHandle)); | |
2127 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2128 stackmap_data = parse_stackmap_table(loader_data, code_attribute_length, CHECK_(nullHandle)); |
0 | 2129 parsed_stackmap_attribute = true; |
2130 } else { | |
2131 // Skip unknown attributes | |
2132 cfs->skip_u1(code_attribute_length, CHECK_(nullHandle)); | |
2133 } | |
2134 } | |
2135 // check method attribute length | |
2136 if (_need_verify) { | |
2137 guarantee_property(method_attribute_length == calculated_attribute_length, | |
2138 "Code segment has wrong length in class file %s", CHECK_(nullHandle)); | |
2139 } | |
2140 } else if (method_attribute_name == vmSymbols::tag_exceptions()) { | |
2141 // Parse Exceptions attribute | |
2142 if (parsed_checked_exceptions_attribute) { | |
2143 classfile_parse_error("Multiple Exceptions attributes in class file %s", CHECK_(nullHandle)); | |
2144 } | |
2145 parsed_checked_exceptions_attribute = true; | |
2146 checked_exceptions_start = | |
2147 parse_checked_exceptions(&checked_exceptions_length, | |
2148 method_attribute_length, | |
2149 cp, CHECK_(nullHandle)); | |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2150 } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2151 method_parameters_length = cfs->get_u1_fast(); |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2152 // Track the actual size (note: this is written for clarity; a |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2153 // decent compiler will CSE and constant-fold this into a single |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2154 // expression) |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2155 u2 actual_size = 1; |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2156 method_parameters_data = cfs->get_u1_buffer(); |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2157 actual_size += 2 * method_parameters_length; |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2158 cfs->skip_u2_fast(method_parameters_length); |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2159 actual_size += 4 * method_parameters_length; |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2160 cfs->skip_u4_fast(method_parameters_length); |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2161 // Enforce attribute length |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2162 if (method_attribute_length != actual_size) { |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2163 classfile_parse_error( |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2164 "Invalid MethodParameters method attribute length %u in class file %s", |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2165 method_attribute_length, CHECK_(nullHandle)); |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2166 } |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2167 // ignore this attribute if it cannot be reflected |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2168 if (!SystemDictionary::Parameter_klass_loaded()) |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2169 method_parameters_length = 0; |
0 | 2170 } else if (method_attribute_name == vmSymbols::tag_synthetic()) { |
2171 if (method_attribute_length != 0) { | |
2172 classfile_parse_error( | |
2173 "Invalid Synthetic method attribute length %u in class file %s", | |
2174 method_attribute_length, CHECK_(nullHandle)); | |
2175 } | |
2176 // Should we check that there hasn't already been a synthetic attribute? | |
2177 access_flags.set_is_synthetic(); | |
2178 } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120 | |
2179 if (method_attribute_length != 0) { | |
2180 classfile_parse_error( | |
2181 "Invalid Deprecated method attribute length %u in class file %s", | |
2182 method_attribute_length, CHECK_(nullHandle)); | |
2183 } | |
2184 } else if (_major_version >= JAVA_1_5_VERSION) { | |
2185 if (method_attribute_name == vmSymbols::tag_signature()) { | |
2186 if (method_attribute_length != 2) { | |
2187 classfile_parse_error( | |
2188 "Invalid Signature attribute length %u in class file %s", | |
2189 method_attribute_length, CHECK_(nullHandle)); | |
2190 } | |
2191 cfs->guarantee_more(2, CHECK_(nullHandle)); // generic_signature_index | |
2192 generic_signature_index = cfs->get_u2_fast(); | |
2193 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { | |
2194 runtime_visible_annotations_length = method_attribute_length; | |
2195 runtime_visible_annotations = cfs->get_u1_buffer(); | |
2196 assert(runtime_visible_annotations != NULL, "null visible annotations"); | |
6934 | 2197 parse_annotations(runtime_visible_annotations, |
2198 runtime_visible_annotations_length, cp, &parsed_annotations, | |
2199 CHECK_(nullHandle)); | |
0 | 2200 cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); |
2201 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { | |
2202 runtime_invisible_annotations_length = method_attribute_length; | |
2203 runtime_invisible_annotations = cfs->get_u1_buffer(); | |
2204 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); | |
2205 cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle)); | |
2206 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) { | |
2207 runtime_visible_parameter_annotations_length = method_attribute_length; | |
2208 runtime_visible_parameter_annotations = cfs->get_u1_buffer(); | |
2209 assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations"); | |
2210 cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle)); | |
2211 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { | |
2212 runtime_invisible_parameter_annotations_length = method_attribute_length; | |
2213 runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); | |
2214 assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); | |
2215 cfs->skip_u1(runtime_invisible_parameter_annotations_length, CHECK_(nullHandle)); | |
2216 } else if (method_attribute_name == vmSymbols::tag_annotation_default()) { | |
2217 annotation_default_length = method_attribute_length; | |
2218 annotation_default = cfs->get_u1_buffer(); | |
2219 assert(annotation_default != NULL, "null annotation default"); | |
2220 cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2221 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2222 runtime_visible_type_annotations_length = method_attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2223 runtime_visible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2224 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2225 // No need for the VM to parse Type annotations |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2226 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2227 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2228 runtime_invisible_type_annotations_length = method_attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2229 runtime_invisible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2230 assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2231 cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); |
0 | 2232 } else { |
2233 // Skip unknown attributes | |
2234 cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); | |
2235 } | |
2236 } else { | |
2237 // Skip unknown attributes | |
2238 cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); | |
2239 } | |
2240 } | |
2241 | |
2242 if (linenumber_table != NULL) { | |
2243 linenumber_table->write_terminator(); | |
2244 linenumber_table_length = linenumber_table->position(); | |
2245 } | |
2246 | |
2247 // Make sure there's at least one Code attribute in non-native/non-abstract method | |
2248 if (_need_verify) { | |
2249 guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, | |
2250 "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); | |
2251 } | |
2252 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2253 // All sizing information for a Method* is finally available, now create it |
6934 | 2254 Method* m = Method::allocate( |
2255 loader_data, code_length, access_flags, linenumber_table_length, | |
2256 total_lvt_length, exception_table_length, checked_exceptions_length, | |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2257 method_parameters_length, generic_signature_index, |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2258 ConstMethod::NORMAL, CHECK_(nullHandle)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2259 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2260 ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); |
0 | 2261 |
2262 // Fill in information from fixed part (access_flags already set) | |
2263 m->set_constants(cp()); | |
2264 m->set_name_index(name_index); | |
2265 m->set_signature_index(signature_index); | |
2266 #ifdef CC_INTERP | |
2267 // hmm is there a gc issue here?? | |
2268 ResultTypeFinder rtf(cp->symbol_at(signature_index)); | |
2269 m->set_result_index(rtf.type()); | |
2270 #endif | |
2271 | |
2272 if (args_size >= 0) { | |
2273 m->set_size_of_parameters(args_size); | |
2274 } else { | |
2275 m->compute_size_of_parameters(THREAD); | |
2276 } | |
2277 #ifdef ASSERT | |
2278 if (args_size >= 0) { | |
2279 m->compute_size_of_parameters(THREAD); | |
2280 assert(args_size == m->size_of_parameters(), ""); | |
2281 } | |
2282 #endif | |
2283 | |
2284 // Fill in code attribute information | |
2285 m->set_max_stack(max_stack); | |
2286 m->set_max_locals(max_locals); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2287 m->constMethod()->set_stackmap_data(stackmap_data); |
0 | 2288 |
2289 // Copy byte codes | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1108
diff
changeset
|
2290 m->set_code(code_start); |
0 | 2291 |
2292 // Copy line number table | |
2293 if (linenumber_table != NULL) { | |
2294 memcpy(m->compressed_linenumber_table(), | |
2295 linenumber_table->buffer(), linenumber_table_length); | |
2296 } | |
2297 | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2298 // Copy exception table |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2299 if (exception_table_length > 0) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2300 int size = |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2301 exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2302 copy_u2_with_conversion((u2*) m->exception_table_start(), |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2303 exception_table_start, size); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2304 } |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6100
diff
changeset
|
2305 |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2306 // Copy method parameters |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2307 if (method_parameters_length > 0) { |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2308 MethodParametersElement* elem = m->constMethod()->method_parameters_start(); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2309 for(int i = 0; i < method_parameters_length; i++) { |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2310 elem[i].name_cp_index = |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2311 Bytes::get_Java_u2(method_parameters_data); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2312 method_parameters_data += 2; |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2313 u4 flags = Bytes::get_Java_u4(method_parameters_data); |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2314 // This caused an alignment fault on Sparc, if flags was a u4 |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2315 elem[i].flags_lo = extract_low_short_from_int(flags); |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7579
diff
changeset
|
2316 elem[i].flags_hi = extract_high_short_from_int(flags); |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2317 method_parameters_data += 4; |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2318 } |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2319 } |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
2320 |
0 | 2321 // Copy checked exceptions |
2322 if (checked_exceptions_length > 0) { | |
2323 int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); | |
2324 copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size); | |
2325 } | |
2326 | |
2327 /* Copy class file LVT's/LVTT's into the HotSpot internal LVT. | |
2328 * | |
2329 * Rules for LVT's and LVTT's are: | |
2330 * - There can be any number of LVT's and LVTT's. | |
2331 * - If there are n LVT's, it is the same as if there was just | |
2332 * one LVT containing all the entries from the n LVT's. | |
2333 * - There may be no more than one LVT entry per local variable. | |
2334 * Two LVT entries are 'equal' if these fields are the same: | |
2335 * start_pc, length, name, slot | |
2336 * - There may be no more than one LVTT entry per each LVT entry. | |
2337 * Each LVTT entry has to match some LVT entry. | |
2338 * - HotSpot internal LVT keeps natural ordering of class file LVT entries. | |
2339 */ | |
2340 if (total_lvt_length > 0) { | |
2341 int tbl_no, idx; | |
2342 | |
2343 promoted_flags->set_has_localvariable_table(); | |
2344 | |
2345 LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE); | |
2346 initialize_hashtable(lvt_Hash); | |
2347 | |
2348 // To fill LocalVariableTable in | |
2349 Classfile_LVT_Element* cf_lvt; | |
2350 LocalVariableTableElement* lvt = m->localvariable_table_start(); | |
2351 | |
2352 for (tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) { | |
2353 cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no]; | |
2354 for (idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) { | |
2355 copy_lvt_element(&cf_lvt[idx], lvt); | |
2356 // If no duplicates, add LVT elem in hashtable lvt_Hash. | |
2357 if (LVT_put_after_lookup(lvt, lvt_Hash) == false | |
2358 && _need_verify | |
2359 && _major_version >= JAVA_1_5_VERSION ) { | |
2360 clear_hashtable(lvt_Hash); | |
2361 classfile_parse_error("Duplicated LocalVariableTable attribute " | |
2362 "entry for '%s' in class file %s", | |
2363 cp->symbol_at(lvt->name_cp_index)->as_utf8(), | |
2364 CHECK_(nullHandle)); | |
2365 } | |
2366 } | |
2367 } | |
2368 | |
2369 // To merge LocalVariableTable and LocalVariableTypeTable | |
2370 Classfile_LVT_Element* cf_lvtt; | |
2371 LocalVariableTableElement lvtt_elem; | |
2372 | |
2373 for (tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) { | |
2374 cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no]; | |
2375 for (idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) { | |
2376 copy_lvt_element(&cf_lvtt[idx], &lvtt_elem); | |
2377 int index = hash(&lvtt_elem); | |
2378 LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash); | |
2379 if (entry == NULL) { | |
2380 if (_need_verify) { | |
2381 clear_hashtable(lvt_Hash); | |
2382 classfile_parse_error("LVTT entry for '%s' in class file %s " | |
2383 "does not match any LVT entry", | |
2384 cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), | |
2385 CHECK_(nullHandle)); | |
2386 } | |
2387 } else if (entry->_elem->signature_cp_index != 0 && _need_verify) { | |
2388 clear_hashtable(lvt_Hash); | |
2389 classfile_parse_error("Duplicated LocalVariableTypeTable attribute " | |
2390 "entry for '%s' in class file %s", | |
2391 cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), | |
2392 CHECK_(nullHandle)); | |
2393 } else { | |
2394 // to add generic signatures into LocalVariableTable | |
2395 entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index; | |
2396 } | |
2397 } | |
2398 } | |
2399 clear_hashtable(lvt_Hash); | |
2400 } | |
2401 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2402 if (parsed_annotations.has_any_annotations()) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2403 parsed_annotations.apply_to(m); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2404 *method_annotations = assemble_annotations(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2405 runtime_visible_annotations, |
0 | 2406 runtime_visible_annotations_length, |
2407 runtime_invisible_annotations, | |
2408 runtime_invisible_annotations_length, | |
2409 CHECK_(nullHandle)); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2410 *method_parameter_annotations = assemble_annotations(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2411 runtime_visible_parameter_annotations, |
0 | 2412 runtime_visible_parameter_annotations_length, |
2413 runtime_invisible_parameter_annotations, | |
2414 runtime_invisible_parameter_annotations_length, | |
2415 CHECK_(nullHandle)); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2416 *method_default_annotations = assemble_annotations(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2417 annotation_default, |
0 | 2418 annotation_default_length, |
2419 NULL, | |
2420 0, | |
2421 CHECK_(nullHandle)); | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2422 *method_type_annotations = assemble_annotations(loader_data, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2423 runtime_visible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2424 runtime_visible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2425 runtime_invisible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2426 runtime_invisible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2427 CHECK_(nullHandle)); |
0 | 2428 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2429 if (name == vmSymbols::finalize_method_name() && |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2430 signature == vmSymbols::void_method_signature()) { |
0 | 2431 if (m->is_empty_method()) { |
2432 _has_empty_finalizer = true; | |
2433 } else { | |
2434 _has_finalizer = true; | |
2435 } | |
2436 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2437 if (name == vmSymbols::object_initializer_name() && |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2438 signature == vmSymbols::void_method_signature() && |
0 | 2439 m->is_vanilla_constructor()) { |
2440 _has_vanilla_constructor = true; | |
2441 } | |
2442 | |
2443 return m; | |
2444 } | |
2445 | |
2446 | |
2447 // The promoted_flags parameter is used to pass relevant access_flags | |
2448 // from the methods back up to the containing klass. These flag values | |
2449 // are added to klass's access_flags. | |
2450 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2451 Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2452 constantPoolHandle cp, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2453 bool is_interface, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2454 AccessFlags* promoted_flags, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2455 bool* has_final_method, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2456 Array<AnnotationArray*>** methods_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2457 Array<AnnotationArray*>** methods_parameter_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2458 Array<AnnotationArray*>** methods_default_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2459 Array<AnnotationArray*>** methods_type_annotations, |
6934 | 2460 bool* has_default_methods, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2461 TRAPS) { |
0 | 2462 ClassFileStream* cfs = stream(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2463 AnnotationArray* method_annotations = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2464 AnnotationArray* method_parameter_annotations = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2465 AnnotationArray* method_default_annotations = NULL; |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2466 AnnotationArray* method_type_annotations = NULL; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2467 cfs->guarantee_more(2, CHECK_NULL); // length |
0 | 2468 u2 length = cfs->get_u2_fast(); |
2469 if (length == 0) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2470 return Universe::the_empty_method_array(); |
0 | 2471 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2472 // FIXME: Handle leaks at later failures. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2473 Array<Method*>* methods = MetadataFactory::new_array<Method*>(loader_data, length, NULL, CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2474 |
0 | 2475 HandleMark hm(THREAD); |
2476 for (int index = 0; index < length; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2477 methodHandle method = parse_method(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2478 cp, is_interface, |
0 | 2479 promoted_flags, |
2480 &method_annotations, | |
2481 &method_parameter_annotations, | |
2482 &method_default_annotations, | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2483 &method_type_annotations, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2484 CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2485 |
0 | 2486 if (method->is_final()) { |
2487 *has_final_method = true; | |
2488 } | |
6934 | 2489 if (is_interface && !method->is_abstract() && !method->is_static()) { |
2490 // default method | |
2491 *has_default_methods = true; | |
2492 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2493 methods->at_put(index, method()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2494 if (*methods_annotations == NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2495 *methods_annotations = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2496 MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL); |
0 | 2497 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2498 (*methods_annotations)->at_put(index, method_annotations); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2499 if (*methods_parameter_annotations == NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2500 *methods_parameter_annotations = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2501 MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL); |
0 | 2502 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2503 (*methods_parameter_annotations)->at_put(index, method_parameter_annotations); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2504 if (*methods_default_annotations == NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2505 *methods_default_annotations = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2506 MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL); |
0 | 2507 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2508 (*methods_default_annotations)->at_put(index, method_default_annotations); |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2509 if (*methods_type_annotations == NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2510 *methods_type_annotations = |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2511 MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2512 } |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2513 (*methods_type_annotations)->at_put(index, method_type_annotations); |
0 | 2514 } |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2515 |
0 | 2516 if (_need_verify && length > 1) { |
2517 // Check duplicated methods | |
2518 ResourceMark rm(THREAD); | |
2519 NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( | |
2520 THREAD, NameSigHash*, HASH_ROW_SIZE); | |
2521 initialize_hashtable(names_and_sigs); | |
2522 bool dup = false; | |
2523 { | |
2524 debug_only(No_Safepoint_Verifier nsv;) | |
2525 for (int i = 0; i < length; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2526 Method* m = methods->at(i); |
0 | 2527 // If no duplicates, add name/signature in hashtable names_and_sigs. |
2528 if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) { | |
2529 dup = true; | |
2530 break; | |
2531 } | |
2532 } | |
2533 } | |
2534 if (dup) { | |
2535 classfile_parse_error("Duplicate method name&signature in class file %s", | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2536 CHECK_NULL); |
0 | 2537 } |
2538 } | |
2539 return methods; | |
2540 } | |
2541 } | |
2542 | |
2543 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2544 Array<int>* ClassFileParser::sort_methods(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2545 Array<Method*>* methods, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2546 Array<AnnotationArray*>* methods_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2547 Array<AnnotationArray*>* methods_parameter_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2548 Array<AnnotationArray*>* methods_default_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2549 Array<AnnotationArray*>* methods_type_annotations, |
0 | 2550 TRAPS) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2551 int length = methods->length(); |
3245
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2552 // If JVMTI original method ordering or sharing is enabled we have to |
0 | 2553 // remember the original class file ordering. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2554 // We temporarily use the vtable_index field in the Method* to store the |
0 | 2555 // class file index, so we can read in after calling qsort. |
3245
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2556 // Put the method ordering in the shared archive. |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2557 if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { |
0 | 2558 for (int index = 0; index < length; index++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2559 Method* m = methods->at(index); |
0 | 2560 assert(!m->valid_vtable_index(), "vtable index should not be set"); |
2561 m->set_vtable_index(index); | |
2562 } | |
2563 } | |
2564 // Sort method array by ascending method name (for faster lookups & vtable construction) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2565 // Note that the ordering is not alphabetical, see Symbol::fast_compare |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2566 Method::sort_methods(methods, methods_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2567 methods_parameter_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2568 methods_default_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2569 methods_type_annotations); |
0 | 2570 |
3245
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2571 // If JVMTI original method ordering or sharing is enabled construct int |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2572 // array remembering the original ordering |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2461
diff
changeset
|
2573 if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2574 Array<int>* method_ordering = MetadataFactory::new_array<int>(loader_data, length, CHECK_NULL); |
0 | 2575 for (int index = 0; index < length; index++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2576 Method* m = methods->at(index); |
0 | 2577 int old_index = m->vtable_index(); |
2578 assert(old_index >= 0 && old_index < length, "invalid method index"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2579 method_ordering->at_put(index, old_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2580 m->set_vtable_index(Method::invalid_vtable_index); |
0 | 2581 } |
2582 return method_ordering; | |
2583 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2584 return Universe::the_empty_int_array(); |
0 | 2585 } |
2586 } | |
2587 | |
2588 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2589 void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS) { |
0 | 2590 ClassFileStream* cfs = stream(); |
2591 cfs->guarantee_more(2, CHECK); // sourcefile_index | |
2592 u2 sourcefile_index = cfs->get_u2_fast(); | |
2593 check_property( | |
2594 valid_cp_range(sourcefile_index, cp->length()) && | |
2595 cp->tag_at(sourcefile_index).is_utf8(), | |
2596 "Invalid SourceFile attribute at constant pool index %u in class file %s", | |
2597 sourcefile_index, CHECK); | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2598 set_class_sourcefile(cp->symbol_at(sourcefile_index)); |
0 | 2599 } |
2600 | |
2601 | |
2602 | |
2603 void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, | |
2604 int length, TRAPS) { | |
2605 ClassFileStream* cfs = stream(); | |
2606 u1* sde_buffer = cfs->get_u1_buffer(); | |
2607 assert(sde_buffer != NULL, "null sde buffer"); | |
2608 | |
2609 // Don't bother storing it if there is no way to retrieve it | |
2610 if (JvmtiExport::can_get_source_debug_extension()) { | |
6226 | 2611 assert((length+1) > length, "Overflow checking"); |
2612 u1* sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1); | |
2613 for (int i = 0; i < length; i++) { | |
2614 sde[i] = sde_buffer[i]; | |
2615 } | |
2616 sde[length] = '\0'; | |
2617 set_class_sde_buffer((char*)sde, length); | |
0 | 2618 } |
2619 // Got utf8 string, set stream position forward | |
2620 cfs->skip_u1(length, CHECK); | |
2621 } | |
2622 | |
2623 | |
2624 // Inner classes can be static, private or protected (classic VM does this) | |
2625 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) | |
2626 | |
2627 // Return number of classes in the inner classes attribute table | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2628 u2 ClassFileParser::parse_classfile_inner_classes_attribute(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2629 u1* inner_classes_attribute_start, |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2630 bool parsed_enclosingmethod_attribute, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2631 u2 enclosing_method_class_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2632 u2 enclosing_method_method_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2633 constantPoolHandle cp, |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2634 TRAPS) { |
0 | 2635 ClassFileStream* cfs = stream(); |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2636 u1* current_mark = cfs->current(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2637 u2 length = 0; |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2638 if (inner_classes_attribute_start != NULL) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2639 cfs->set_current(inner_classes_attribute_start); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2640 cfs->guarantee_more(2, CHECK_0); // length |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2641 length = cfs->get_u2_fast(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2642 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2643 |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2644 // 4-tuples of shorts of inner classes data and 2 shorts of enclosing |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2645 // method data: |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2646 // [inner_class_info_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2647 // outer_class_info_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2648 // inner_name_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2649 // inner_class_access_flags, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2650 // ... |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2651 // enclosing_method_class_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2652 // enclosing_method_method_index] |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2653 int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2654 // FIXME: Will leak on exceptions. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2655 Array<u2>* inner_classes = MetadataFactory::new_array<u2>(loader_data, size, CHECK_0); |
0 | 2656 int index = 0; |
2657 int cp_size = cp->length(); | |
2658 cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 | |
2659 for (int n = 0; n < length; n++) { | |
2660 // Inner class index | |
2661 u2 inner_class_info_index = cfs->get_u2_fast(); | |
2662 check_property( | |
2663 inner_class_info_index == 0 || | |
2664 (valid_cp_range(inner_class_info_index, cp_size) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
2665 is_klass_reference(cp, inner_class_info_index)), |
0 | 2666 "inner_class_info_index %u has bad constant type in class file %s", |
2667 inner_class_info_index, CHECK_0); | |
2668 // Outer class index | |
2669 u2 outer_class_info_index = cfs->get_u2_fast(); | |
2670 check_property( | |
2671 outer_class_info_index == 0 || | |
2672 (valid_cp_range(outer_class_info_index, cp_size) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
2673 is_klass_reference(cp, outer_class_info_index)), |
0 | 2674 "outer_class_info_index %u has bad constant type in class file %s", |
2675 outer_class_info_index, CHECK_0); | |
2676 // Inner class name | |
2677 u2 inner_name_index = cfs->get_u2_fast(); | |
2678 check_property( | |
2679 inner_name_index == 0 || (valid_cp_range(inner_name_index, cp_size) && | |
2680 cp->tag_at(inner_name_index).is_utf8()), | |
2681 "inner_name_index %u has bad constant type in class file %s", | |
2682 inner_name_index, CHECK_0); | |
2683 if (_need_verify) { | |
2684 guarantee_property(inner_class_info_index != outer_class_info_index, | |
2685 "Class is both outer and inner class in class file %s", CHECK_0); | |
2686 } | |
2687 // Access flags | |
2688 AccessFlags inner_access_flags; | |
2689 jint flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS; | |
2690 if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { | |
2691 // Set abstract bit for old class files for backward compatibility | |
2692 flags |= JVM_ACC_ABSTRACT; | |
2693 } | |
2694 verify_legal_class_modifiers(flags, CHECK_0); | |
2695 inner_access_flags.set_flags(flags); | |
2696 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2697 inner_classes->at_put(index++, inner_class_info_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2698 inner_classes->at_put(index++, outer_class_info_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2699 inner_classes->at_put(index++, inner_name_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2700 inner_classes->at_put(index++, inner_access_flags.as_short()); |
0 | 2701 } |
2702 | |
2703 // 4347400: make sure there's no duplicate entry in the classes array | |
2704 if (_need_verify && _major_version >= JAVA_1_5_VERSION) { | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2705 for(int i = 0; i < length * 4; i += 4) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2706 for(int j = i + 4; j < length * 4; j += 4) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2707 guarantee_property((inner_classes->at(i) != inner_classes->at(j) || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2708 inner_classes->at(i+1) != inner_classes->at(j+1) || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2709 inner_classes->at(i+2) != inner_classes->at(j+2) || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2710 inner_classes->at(i+3) != inner_classes->at(j+3)), |
0 | 2711 "Duplicate entry in InnerClasses in class file %s", |
2712 CHECK_0); | |
2713 } | |
2714 } | |
2715 } | |
2716 | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2717 // Set EnclosingMethod class and method indexes. |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2718 if (parsed_enclosingmethod_attribute) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2719 inner_classes->at_put(index++, enclosing_method_class_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2720 inner_classes->at_put(index++, enclosing_method_method_index); |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2721 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2722 assert(index == size, "wrong size"); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2723 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2724 // Update InstanceKlass with inner class info. |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2725 set_class_inner_classes(inner_classes); |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2726 |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2727 // Restore buffer's current position. |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2728 cfs->set_current(current_mark); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2729 |
0 | 2730 return length; |
2731 } | |
2732 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2733 void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2734 set_class_synthetic_flag(true); |
0 | 2735 } |
2736 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2737 void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS) { |
0 | 2738 ClassFileStream* cfs = stream(); |
2739 u2 signature_index = cfs->get_u2(CHECK); | |
2740 check_property( | |
2741 valid_cp_range(signature_index, cp->length()) && | |
2742 cp->tag_at(signature_index).is_utf8(), | |
2743 "Invalid constant pool index %u in Signature attribute in class file %s", | |
2744 signature_index, CHECK); | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2745 set_class_generic_signature(cp->symbol_at(signature_index)); |
0 | 2746 } |
2747 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2748 void ClassFileParser::parse_classfile_bootstrap_methods_attribute(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2749 constantPoolHandle cp, |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2750 u4 attribute_byte_length, TRAPS) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2751 ClassFileStream* cfs = stream(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2752 u1* current_start = cfs->current(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2753 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2754 cfs->guarantee_more(2, CHECK); // length |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2755 int attribute_array_length = cfs->get_u2_fast(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2756 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2757 guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2758 "Short length on BootstrapMethods in class file %s", |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2759 CHECK); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2760 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2761 // The attribute contains a counted array of counted tuples of shorts, |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2762 // represending bootstrap specifiers: |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2763 // length*{bootstrap_method_index, argument_count*{argument_index}} |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2764 int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2765 // operand_count = number of shorts in attr, except for leading length |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2766 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2767 // The attribute is copied into a short[] array. |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2768 // The array begins with a series of short[2] pairs, one for each tuple. |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2769 int index_size = (attribute_array_length * 2); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2770 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2771 Array<u2>* operands = MetadataFactory::new_array<u2>(loader_data, index_size + operand_count, CHECK); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2772 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2773 int operand_fill_index = index_size; |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2774 int cp_size = cp->length(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2775 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2776 for (int n = 0; n < attribute_array_length; n++) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2777 // Store a 32-bit offset into the header of the operand array. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2778 ConstantPool::operand_offset_at_put(operands, n, operand_fill_index); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2779 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2780 // Read a bootstrap specifier. |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2781 cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2782 u2 bootstrap_method_index = cfs->get_u2_fast(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2783 u2 argument_count = cfs->get_u2_fast(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2784 check_property( |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2785 valid_cp_range(bootstrap_method_index, cp_size) && |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2786 cp->tag_at(bootstrap_method_index).is_method_handle(), |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2787 "bootstrap_method_index %u has bad constant type in class file %s", |
2085 | 2788 bootstrap_method_index, |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2789 CHECK); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2790 operands->at_put(operand_fill_index++, bootstrap_method_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2791 operands->at_put(operand_fill_index++, argument_count); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2792 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2793 cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc] |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2794 for (int j = 0; j < argument_count; j++) { |
2085 | 2795 u2 argument_index = cfs->get_u2_fast(); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2796 check_property( |
2085 | 2797 valid_cp_range(argument_index, cp_size) && |
2798 cp->tag_at(argument_index).is_loadable_constant(), | |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2799 "argument_index %u has bad constant type in class file %s", |
2085 | 2800 argument_index, |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2801 CHECK); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2802 operands->at_put(operand_fill_index++, argument_index); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2803 } |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2804 } |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2805 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2806 assert(operand_fill_index == operands->length(), "exact fill"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2807 assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode"); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2808 |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2809 u1* current_end = cfs->current(); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2810 guarantee_property(current_end == current_start + attribute_byte_length, |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2811 "Bad length on BootstrapMethods in class file %s", |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2812 CHECK); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2813 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2814 cp->set_operands(operands); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2815 } |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2816 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2817 void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2818 constantPoolHandle cp, |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2819 ClassFileParser::ClassAnnotationCollector* parsed_annotations, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2820 TRAPS) { |
0 | 2821 ClassFileStream* cfs = stream(); |
2822 // Set inner classes attribute to default sentinel | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2823 set_class_inner_classes(Universe::the_empty_short_array()); |
0 | 2824 cfs->guarantee_more(2, CHECK); // attributes_count |
2825 u2 attributes_count = cfs->get_u2_fast(); | |
2826 bool parsed_sourcefile_attribute = false; | |
2827 bool parsed_innerclasses_attribute = false; | |
2828 bool parsed_enclosingmethod_attribute = false; | |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2829 bool parsed_bootstrap_methods_attribute = false; |
0 | 2830 u1* runtime_visible_annotations = NULL; |
2831 int runtime_visible_annotations_length = 0; | |
2832 u1* runtime_invisible_annotations = NULL; | |
2833 int runtime_invisible_annotations_length = 0; | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2834 u1* runtime_visible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2835 int runtime_visible_type_annotations_length = 0; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2836 u1* runtime_invisible_type_annotations = NULL; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2837 int runtime_invisible_type_annotations_length = 0; |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2838 u1* inner_classes_attribute_start = NULL; |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2839 u4 inner_classes_attribute_length = 0; |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2840 u2 enclosing_method_class_index = 0; |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2841 u2 enclosing_method_method_index = 0; |
0 | 2842 // Iterate over attributes |
2843 while (attributes_count--) { | |
2844 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length | |
2845 u2 attribute_name_index = cfs->get_u2_fast(); | |
2846 u4 attribute_length = cfs->get_u4_fast(); | |
2847 check_property( | |
2848 valid_cp_range(attribute_name_index, cp->length()) && | |
2849 cp->tag_at(attribute_name_index).is_utf8(), | |
2850 "Attribute name has bad constant pool index %u in class file %s", | |
2851 attribute_name_index, CHECK); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
2852 Symbol* tag = cp->symbol_at(attribute_name_index); |
0 | 2853 if (tag == vmSymbols::tag_source_file()) { |
2854 // Check for SourceFile tag | |
2855 if (_need_verify) { | |
2856 guarantee_property(attribute_length == 2, "Wrong SourceFile attribute length in class file %s", CHECK); | |
2857 } | |
2858 if (parsed_sourcefile_attribute) { | |
2859 classfile_parse_error("Multiple SourceFile attributes in class file %s", CHECK); | |
2860 } else { | |
2861 parsed_sourcefile_attribute = true; | |
2862 } | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2863 parse_classfile_sourcefile_attribute(cp, CHECK); |
0 | 2864 } else if (tag == vmSymbols::tag_source_debug_extension()) { |
2865 // Check for SourceDebugExtension tag | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2866 parse_classfile_source_debug_extension_attribute(cp, (int)attribute_length, CHECK); |
0 | 2867 } else if (tag == vmSymbols::tag_inner_classes()) { |
2868 // Check for InnerClasses tag | |
2869 if (parsed_innerclasses_attribute) { | |
2870 classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); | |
2871 } else { | |
2872 parsed_innerclasses_attribute = true; | |
2873 } | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2874 inner_classes_attribute_start = cfs->get_u1_buffer(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2875 inner_classes_attribute_length = attribute_length; |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2876 cfs->skip_u1(inner_classes_attribute_length, CHECK); |
0 | 2877 } else if (tag == vmSymbols::tag_synthetic()) { |
2878 // Check for Synthetic tag | |
2879 // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec | |
2880 if (attribute_length != 0) { | |
2881 classfile_parse_error( | |
2882 "Invalid Synthetic classfile attribute length %u in class file %s", | |
2883 attribute_length, CHECK); | |
2884 } | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2885 parse_classfile_synthetic_attribute(cp, CHECK); |
0 | 2886 } else if (tag == vmSymbols::tag_deprecated()) { |
2887 // Check for Deprecatd tag - 4276120 | |
2888 if (attribute_length != 0) { | |
2889 classfile_parse_error( | |
2890 "Invalid Deprecated classfile attribute length %u in class file %s", | |
2891 attribute_length, CHECK); | |
2892 } | |
2893 } else if (_major_version >= JAVA_1_5_VERSION) { | |
2894 if (tag == vmSymbols::tag_signature()) { | |
2895 if (attribute_length != 2) { | |
2896 classfile_parse_error( | |
2897 "Wrong Signature attribute length %u in class file %s", | |
2898 attribute_length, CHECK); | |
2899 } | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2900 parse_classfile_signature_attribute(cp, CHECK); |
0 | 2901 } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { |
2902 runtime_visible_annotations_length = attribute_length; | |
2903 runtime_visible_annotations = cfs->get_u1_buffer(); | |
2904 assert(runtime_visible_annotations != NULL, "null visible annotations"); | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2905 parse_annotations(runtime_visible_annotations, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2906 runtime_visible_annotations_length, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2907 cp, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2908 parsed_annotations, |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2909 CHECK); |
0 | 2910 cfs->skip_u1(runtime_visible_annotations_length, CHECK); |
2911 } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { | |
2912 runtime_invisible_annotations_length = attribute_length; | |
2913 runtime_invisible_annotations = cfs->get_u1_buffer(); | |
2914 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); | |
2915 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); | |
2916 } else if (tag == vmSymbols::tag_enclosing_method()) { | |
2917 if (parsed_enclosingmethod_attribute) { | |
2918 classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); | |
2919 } else { | |
2920 parsed_enclosingmethod_attribute = true; | |
2921 } | |
2922 cfs->guarantee_more(4, CHECK); // class_index, method_index | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2923 enclosing_method_class_index = cfs->get_u2_fast(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2924 enclosing_method_method_index = cfs->get_u2_fast(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2925 if (enclosing_method_class_index == 0) { |
0 | 2926 classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); |
2927 } | |
2928 // Validate the constant pool indices and types | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2929 if (!cp->is_within_bounds(enclosing_method_class_index) || |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2930 !is_klass_reference(cp, enclosing_method_class_index)) { |
0 | 2931 classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); |
2932 } | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2933 if (enclosing_method_method_index != 0 && |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2934 (!cp->is_within_bounds(enclosing_method_method_index) || |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2935 !cp->tag_at(enclosing_method_method_index).is_name_and_type())) { |
0 | 2936 classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); |
2937 } | |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2938 } else if (tag == vmSymbols::tag_bootstrap_methods() && |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2939 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2940 if (parsed_bootstrap_methods_attribute) |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2941 classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2942 parsed_bootstrap_methods_attribute = true; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2943 parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK); |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2944 } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2945 runtime_visible_type_annotations_length = attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2946 runtime_visible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2947 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2948 // No need for the VM to parse Type annotations |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2949 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2950 } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2951 runtime_invisible_type_annotations_length = attribute_length; |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2952 runtime_invisible_type_annotations = cfs->get_u1_buffer(); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2953 assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2954 cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); |
0 | 2955 } else { |
2956 // Unknown attribute | |
2957 cfs->skip_u1(attribute_length, CHECK); | |
2958 } | |
2959 } else { | |
2960 // Unknown attribute | |
2961 cfs->skip_u1(attribute_length, CHECK); | |
2962 } | |
2963 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2964 AnnotationArray* annotations = assemble_annotations(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2965 runtime_visible_annotations, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2966 runtime_visible_annotations_length, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2967 runtime_invisible_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2968 runtime_invisible_annotations_length, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
2969 CHECK); |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2970 set_class_annotations(annotations); |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2971 AnnotationArray* type_annotations = assemble_annotations(loader_data, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2972 runtime_visible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2973 runtime_visible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2974 runtime_invisible_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2975 runtime_invisible_type_annotations_length, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2976 CHECK); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
2977 set_class_type_annotations(type_annotations); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2978 |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2979 if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2980 u2 num_of_classes = parse_classfile_inner_classes_attribute( |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2981 loader_data, |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2982 inner_classes_attribute_start, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2983 parsed_innerclasses_attribute, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2984 enclosing_method_class_index, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2985 enclosing_method_method_index, |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
2986 cp, CHECK); |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2987 if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2988 guarantee_property( |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2989 inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2990 "Wrong InnerClasses attribute length in class file %s", CHECK); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2991 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2992 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4755
diff
changeset
|
2993 |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2994 if (_max_bootstrap_specifier_index >= 0) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2995 guarantee_property(parsed_bootstrap_methods_attribute, |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2996 "Missing BootstrapMethods attribute in class file %s", CHECK); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
2997 } |
0 | 2998 } |
2999 | |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3000 void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3001 if (_synthetic_flag) |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3002 k->set_is_synthetic(); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3003 if (_sourcefile != NULL) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3004 _sourcefile->increment_refcount(); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3005 k->set_source_file_name(_sourcefile); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3006 } |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3007 if (_generic_signature != NULL) { |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3008 _generic_signature->increment_refcount(); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3009 k->set_generic_signature(_generic_signature); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3010 } |
6226 | 3011 if (_sde_buffer != NULL) { |
3012 k->set_source_debug_extension(_sde_buffer, _sde_length); | |
3013 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3014 k->set_inner_classes(_inner_classes); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3015 if (_annotations != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3016 k->annotations()->set_class_annotations(_annotations); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3017 } |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3018 } |
0 | 3019 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3020 AnnotationArray* ClassFileParser::assemble_annotations(ClassLoaderData* loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3021 u1* runtime_visible_annotations, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3022 int runtime_visible_annotations_length, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3023 u1* runtime_invisible_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3024 int runtime_invisible_annotations_length, TRAPS) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3025 AnnotationArray* annotations = NULL; |
0 | 3026 if (runtime_visible_annotations != NULL || |
3027 runtime_invisible_annotations != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3028 annotations = MetadataFactory::new_array<u1>(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3029 runtime_visible_annotations_length + |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3030 runtime_invisible_annotations_length, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3031 CHECK_(annotations)); |
0 | 3032 if (runtime_visible_annotations != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3033 for (int i = 0; i < runtime_visible_annotations_length; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3034 annotations->at_put(i, runtime_visible_annotations[i]); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3035 } |
0 | 3036 } |
3037 if (runtime_invisible_annotations != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3038 for (int i = 0; i < runtime_invisible_annotations_length; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3039 int append = runtime_visible_annotations_length+i; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3040 annotations->at_put(append, runtime_invisible_annotations[i]); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3041 } |
0 | 3042 } |
3043 } | |
3044 return annotations; | |
3045 } | |
3046 | |
3047 | |
6934 | 3048 #ifndef PRODUCT |
3049 static void parseAndPrintGenericSignatures( | |
3050 instanceKlassHandle this_klass, TRAPS) { | |
3051 assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise"); | |
3052 ResourceMark rm; | |
3053 | |
3054 if (this_klass->generic_signature() != NULL) { | |
3055 using namespace generic; | |
3056 ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK); | |
3057 | |
3058 tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string()); | |
3059 spec->print_on(tty); | |
3060 | |
3061 for (int i = 0; i < this_klass->methods()->length(); ++i) { | |
3062 Method* m = this_klass->methods()->at(i); | |
3063 MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec); | |
3064 Symbol* sig = m->generic_signature(); | |
3065 if (sig == NULL) { | |
3066 sig = m->signature(); | |
3067 } | |
3068 tty->print_cr("Parsing %s", sig->as_C_string()); | |
3069 method_spec->print_on(tty); | |
3070 } | |
3071 } | |
3072 } | |
3073 #endif // ndef PRODUCT | |
3074 | |
3075 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3076 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6983
diff
changeset
|
3077 ClassLoaderData* loader_data, |
0 | 3078 Handle protection_domain, |
710 | 3079 KlassHandle host_klass, |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3080 GrowableArray<Handle>* cp_patches, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3081 TempNewSymbol& parsed_name, |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
879
diff
changeset
|
3082 bool verify, |
0 | 3083 TRAPS) { |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
3084 |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3085 // When a retransformable agent is attached, JVMTI caches the |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3086 // class bytes that existed before the first retransformation. |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3087 // If RedefineClasses() was used before the retransformable |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3088 // agent attached, then the cached class bytes may not be the |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3089 // original class bytes. |
0 | 3090 unsigned char *cached_class_file_bytes = NULL; |
3091 jint cached_class_file_length; | |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6983
diff
changeset
|
3092 Handle class_loader(THREAD, loader_data->class_loader()); |
6934 | 3093 bool has_default_methods = false; |
3094 ResourceMark rm(THREAD); | |
0 | 3095 |
3096 ClassFileStream* cfs = stream(); | |
3097 // Timing | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3098 assert(THREAD->is_Java_thread(), "must be a JavaThread"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3099 JavaThread* jt = (JavaThread*) THREAD; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3100 |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3101 PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3102 ClassLoader::perf_class_parse_selftime(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3103 NULL, |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3104 jt->get_thread_stat()->perf_recursion_counts_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3105 jt->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3106 PerfClassTraceTime::PARSE_CLASS); |
0 | 3107 |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3108 init_parsed_class_attributes(); |
0 | 3109 |
3110 if (JvmtiExport::should_post_class_file_load_hook()) { | |
4751
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3111 // Get the cached class file bytes (if any) from the class that |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3112 // is being redefined or retransformed. We use jvmti_thread_state() |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3113 // instead of JvmtiThreadState::state_for(jt) so we don't allocate |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3114 // a JvmtiThreadState any earlier than necessary. This will help |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3115 // avoid the bug described by 7126851. |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3116 JvmtiThreadState *state = jt->jvmti_thread_state(); |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3117 if (state != NULL) { |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3118 KlassHandle *h_class_being_redefined = |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3119 state->get_class_being_redefined(); |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3120 if (h_class_being_redefined != NULL) { |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3121 instanceKlassHandle ikh_class_being_redefined = |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3122 instanceKlassHandle(THREAD, (*h_class_being_redefined)()); |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3123 cached_class_file_bytes = |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3124 ikh_class_being_redefined->get_cached_class_file_bytes(); |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3125 cached_class_file_length = |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3126 ikh_class_being_redefined->get_cached_class_file_len(); |
5b58979183f9
7127032: fix for 7122253 adds a JvmtiThreadState earlier than necessary
dcubed
parents:
4731
diff
changeset
|
3127 } |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3128 } |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3129 |
0 | 3130 unsigned char* ptr = cfs->buffer(); |
3131 unsigned char* end_ptr = cfs->buffer() + cfs->length(); | |
3132 | |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6983
diff
changeset
|
3133 JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain, |
0 | 3134 &ptr, &end_ptr, |
3135 &cached_class_file_bytes, | |
3136 &cached_class_file_length); | |
3137 | |
3138 if (ptr != cfs->buffer()) { | |
3139 // JVMTI agent has modified class file data. | |
3140 // Set new class file stream using JVMTI agent modified | |
3141 // class file data. | |
3142 cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source()); | |
3143 set_stream(cfs); | |
3144 } | |
3145 } | |
3146 | |
710 | 3147 _host_klass = host_klass; |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3148 _cp_patches = cp_patches; |
0 | 3149 |
3150 instanceKlassHandle nullHandle; | |
3151 | |
3152 // Figure out whether we can skip format checking (matching classic VM behavior) | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
879
diff
changeset
|
3153 _need_verify = Verifier::should_verify_for(class_loader(), verify); |
0 | 3154 |
3155 // Set the verify flag in stream | |
3156 cfs->set_verify(_need_verify); | |
3157 | |
3158 // Save the class file name for easier error message printing. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3159 _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name(); |
0 | 3160 |
3161 cfs->guarantee_more(8, CHECK_(nullHandle)); // magic, major, minor | |
3162 // Magic value | |
3163 u4 magic = cfs->get_u4_fast(); | |
3164 guarantee_property(magic == JAVA_CLASSFILE_MAGIC, | |
3165 "Incompatible magic value %u in class file %s", | |
3166 magic, CHECK_(nullHandle)); | |
3167 | |
3168 // Version numbers | |
3169 u2 minor_version = cfs->get_u2_fast(); | |
3170 u2 major_version = cfs->get_u2_fast(); | |
3171 | |
3172 // Check version numbers - we check this even with verifier off | |
3173 if (!is_supported_version(major_version, minor_version)) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3174 if (name == NULL) { |
0 | 3175 Exceptions::fthrow( |
3176 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3177 vmSymbols::java_lang_UnsupportedClassVersionError(), |
0 | 3178 "Unsupported major.minor version %u.%u", |
3179 major_version, | |
3180 minor_version); | |
3181 } else { | |
3182 ResourceMark rm(THREAD); | |
3183 Exceptions::fthrow( | |
3184 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3185 vmSymbols::java_lang_UnsupportedClassVersionError(), |
0 | 3186 "%s : Unsupported major.minor version %u.%u", |
3187 name->as_C_string(), | |
3188 major_version, | |
3189 minor_version); | |
3190 } | |
3191 return nullHandle; | |
3192 } | |
3193 | |
3194 _major_version = major_version; | |
3195 _minor_version = minor_version; | |
3196 | |
3197 | |
3198 // Check if verification needs to be relaxed for this class file | |
3199 // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376) | |
3200 _relax_verify = Verifier::relax_verify_for(class_loader()); | |
3201 | |
3202 // Constant pool | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3203 constantPoolHandle cp = parse_constant_pool(loader_data, CHECK_(nullHandle)); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3204 ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3205 |
0 | 3206 int cp_size = cp->length(); |
3207 | |
3208 cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len | |
3209 | |
3210 // Access flags | |
3211 AccessFlags access_flags; | |
3212 jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS; | |
3213 | |
3214 if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { | |
3215 // Set abstract bit for old class files for backward compatibility | |
3216 flags |= JVM_ACC_ABSTRACT; | |
3217 } | |
3218 verify_legal_class_modifiers(flags, CHECK_(nullHandle)); | |
3219 access_flags.set_flags(flags); | |
3220 | |
3221 // This class and superclass | |
3222 instanceKlassHandle super_klass; | |
3223 u2 this_class_index = cfs->get_u2_fast(); | |
3224 check_property( | |
3225 valid_cp_range(this_class_index, cp_size) && | |
3226 cp->tag_at(this_class_index).is_unresolved_klass(), | |
3227 "Invalid this class index %u in constant pool in class file %s", | |
3228 this_class_index, CHECK_(nullHandle)); | |
3229 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3230 Symbol* class_name = cp->unresolved_klass_at(this_class_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3231 assert(class_name != NULL, "class_name can't be null"); |
0 | 3232 |
3233 // It's important to set parsed_name *before* resolving the super class. | |
3234 // (it's used for cleanup by the caller if parsing fails) | |
3235 parsed_name = class_name; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3236 // parsed_name is returned and can be used if there's an error, so add to |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3237 // its reference count. Caller will decrement the refcount. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3238 parsed_name->increment_refcount(); |
0 | 3239 |
3240 // Update _class_name which could be null previously to be class_name | |
3241 _class_name = class_name; | |
3242 | |
3243 // Don't need to check whether this class name is legal or not. | |
3244 // It has been checked when constant pool is parsed. | |
3245 // However, make sure it is not an array type. | |
3246 if (_need_verify) { | |
3247 guarantee_property(class_name->byte_at(0) != JVM_SIGNATURE_ARRAY, | |
3248 "Bad class name in class file %s", | |
3249 CHECK_(nullHandle)); | |
3250 } | |
3251 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3252 Klass* preserve_this_klass; // for storing result across HandleMark |
0 | 3253 |
3254 // release all handles when parsing is done | |
3255 { HandleMark hm(THREAD); | |
3256 | |
3257 // Checks if name in class file matches requested name | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3258 if (name != NULL && class_name != name) { |
0 | 3259 ResourceMark rm(THREAD); |
3260 Exceptions::fthrow( | |
3261 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3262 vmSymbols::java_lang_NoClassDefFoundError(), |
0 | 3263 "%s (wrong name: %s)", |
3264 name->as_C_string(), | |
3265 class_name->as_C_string() | |
3266 ); | |
3267 return nullHandle; | |
3268 } | |
3269 | |
3270 if (TraceClassLoadingPreorder) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3271 tty->print("[Loading %s", name->as_klass_external_name()); |
0 | 3272 if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); |
3273 tty->print_cr("]"); | |
3274 } | |
3275 | |
3276 u2 super_class_index = cfs->get_u2_fast(); | |
3277 if (super_class_index == 0) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3278 check_property(class_name == vmSymbols::java_lang_Object(), |
0 | 3279 "Invalid superclass index %u in class file %s", |
3280 super_class_index, | |
3281 CHECK_(nullHandle)); | |
3282 } else { | |
3283 check_property(valid_cp_range(super_class_index, cp_size) && | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3284 is_klass_reference(cp, super_class_index), |
0 | 3285 "Invalid superclass index %u in class file %s", |
3286 super_class_index, | |
3287 CHECK_(nullHandle)); | |
3288 // The class name should be legal because it is checked when parsing constant pool. | |
3289 // However, make sure it is not an array type. | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3290 bool is_array = false; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3291 if (cp->tag_at(super_class_index).is_klass()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3292 super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3293 if (_need_verify) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3294 is_array = super_klass->oop_is_array(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3295 } else if (_need_verify) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3296 is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3297 } |
0 | 3298 if (_need_verify) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3299 guarantee_property(!is_array, |
0 | 3300 "Bad superclass name in class file %s", CHECK_(nullHandle)); |
3301 } | |
3302 } | |
3303 | |
3304 // Interfaces | |
3305 u2 itfs_len = cfs->get_u2_fast(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3306 Array<Klass*>* local_interfaces; |
0 | 3307 if (itfs_len == 0) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3308 local_interfaces = Universe::the_empty_klass_array(); |
0 | 3309 } else { |
6934 | 3310 local_interfaces = parse_interfaces( |
3311 cp, itfs_len, loader_data, protection_domain, _class_name, | |
3312 &has_default_methods, CHECK_(nullHandle)); | |
0 | 3313 } |
3314 | |
4744
cd5d8cafcc84
7123315: instanceKlass::_static_oop_field_count and instanceKlass::_java_fields_count should be u2 type.
jiangli
parents:
3938
diff
changeset
|
3315 u2 java_fields_count = 0; |
0 | 3316 // Fields (offsets are filled in later) |
3938 | 3317 FieldAllocationCount fac; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3318 Array<AnnotationArray*>* fields_annotations = NULL; |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3319 Array<AnnotationArray*>* fields_type_annotations = NULL; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3320 Array<u2>* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3321 &fields_type_annotations, |
3938 | 3322 &java_fields_count, |
3323 CHECK_(nullHandle)); | |
0 | 3324 // Methods |
3325 bool has_final_method = false; | |
3326 AccessFlags promoted_flags; | |
3327 promoted_flags.set_flags(0); | |
3328 // These need to be oop pointers because they are allocated lazily | |
3329 // inside parse_methods inside a nested HandleMark | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3330 Array<AnnotationArray*>* methods_annotations = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3331 Array<AnnotationArray*>* methods_parameter_annotations = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3332 Array<AnnotationArray*>* methods_default_annotations = NULL; |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3333 Array<AnnotationArray*>* methods_type_annotations = NULL; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3334 Array<Method*>* methods = parse_methods(loader_data, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3335 cp, access_flags.is_interface(), |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3336 &promoted_flags, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3337 &has_final_method, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3338 &methods_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3339 &methods_parameter_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3340 &methods_default_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3341 &methods_type_annotations, |
6934 | 3342 &has_default_methods, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3343 CHECK_(nullHandle)); |
0 | 3344 |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3345 // Additional attributes |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3346 ClassAnnotationCollector parsed_annotations; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3347 parse_classfile_attributes(loader_data, cp, &parsed_annotations, CHECK_(nullHandle)); |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3348 |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3349 // Make sure this is the end of class file stream |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3350 guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); |
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3351 |
0 | 3352 // We check super class after class file is parsed and format is checked |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3353 if (super_class_index > 0 && super_klass.is_null()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3354 Symbol* sk = cp->klass_name_at(super_class_index); |
0 | 3355 if (access_flags.is_interface()) { |
3356 // Before attempting to resolve the superclass, check for class format | |
3357 // errors not checked yet. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3358 guarantee_property(sk == vmSymbols::java_lang_Object(), |
0 | 3359 "Interfaces must have java.lang.Object as superclass in class file %s", |
3360 CHECK_(nullHandle)); | |
3361 } | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3362 Klass* k = SystemDictionary::resolve_super_or_fail(class_name, sk, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3363 class_loader, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3364 protection_domain, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3365 true, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3366 CHECK_(nullHandle)); |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
710
diff
changeset
|
3367 |
0 | 3368 KlassHandle kh (THREAD, k); |
3369 super_klass = instanceKlassHandle(THREAD, kh()); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3370 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
3371 if (super_klass.not_null()) { |
6934 | 3372 |
3373 if (super_klass->has_default_methods()) { | |
3374 has_default_methods = true; | |
3375 } | |
3376 | |
0 | 3377 if (super_klass->is_interface()) { |
3378 ResourceMark rm(THREAD); | |
3379 Exceptions::fthrow( | |
3380 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3381 vmSymbols::java_lang_IncompatibleClassChangeError(), |
0 | 3382 "class %s has interface %s as super class", |
3383 class_name->as_klass_external_name(), | |
3384 super_klass->external_name() | |
3385 ); | |
3386 return nullHandle; | |
3387 } | |
3388 // Make sure super class is not final | |
3389 if (super_klass->is_final()) { | |
3390 THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle); | |
3391 } | |
3392 } | |
3393 | |
3394 // Compute the transitive list of all unique interfaces implemented by this class | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3395 Array<Klass*>* transitive_interfaces = compute_transitive_interfaces(loader_data, super_klass, local_interfaces, CHECK_(nullHandle)); |
0 | 3396 |
3397 // sort methods | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3398 Array<int>* method_ordering = sort_methods(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3399 methods, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3400 methods_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3401 methods_parameter_annotations, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3402 methods_default_annotations, |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3403 methods_type_annotations, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3404 CHECK_(nullHandle)); |
0 | 3405 |
3406 // promote flags from parse_methods() to the klass' flags | |
3407 access_flags.add_promoted_flags(promoted_flags.as_int()); | |
3408 | |
3409 // Size of Java vtable (in words) | |
3410 int vtable_size = 0; | |
3411 int itable_size = 0; | |
3412 int num_miranda_methods = 0; | |
3413 | |
6934 | 3414 GrowableArray<Method*> all_mirandas(20); |
3415 | |
3416 klassVtable::compute_vtable_size_and_num_mirandas( | |
3417 &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods, | |
3418 access_flags, class_loader, class_name, local_interfaces, | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
579
diff
changeset
|
3419 CHECK_(nullHandle)); |
0 | 3420 |
3421 // Size of Java itable (in words) | |
3422 itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces); | |
3423 | |
3424 // Field size and offset computation | |
3425 int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size(); | |
3426 #ifndef PRODUCT | |
3427 int orig_nonstatic_field_size = 0; | |
3428 #endif | |
3429 int static_field_size = 0; | |
3430 int next_static_oop_offset; | |
3431 int next_static_double_offset; | |
3432 int next_static_word_offset; | |
3433 int next_static_short_offset; | |
3434 int next_static_byte_offset; | |
3435 int next_static_type_offset; | |
3436 int next_nonstatic_oop_offset; | |
3437 int next_nonstatic_double_offset; | |
3438 int next_nonstatic_word_offset; | |
3439 int next_nonstatic_short_offset; | |
3440 int next_nonstatic_byte_offset; | |
3441 int next_nonstatic_type_offset; | |
3442 int first_nonstatic_oop_offset; | |
3443 int first_nonstatic_field_offset; | |
3444 int next_nonstatic_field_offset; | |
3445 | |
3446 // Calculate the starting byte offsets | |
6735
aed758eda82a
7195833: NPG: Rename instanceClassLoaderKlass, instanceRefKlass and instanceMirrorKlass
coleenp
parents:
6725
diff
changeset
|
3447 next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); |
0 | 3448 next_static_double_offset = next_static_oop_offset + |
3938 | 3449 (fac.count[STATIC_OOP] * heapOopSize); |
3450 if ( fac.count[STATIC_DOUBLE] && | |
0 | 3451 (Universe::field_type_should_be_aligned(T_DOUBLE) || |
3452 Universe::field_type_should_be_aligned(T_LONG)) ) { | |
3453 next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); | |
3454 } | |
3455 | |
3456 next_static_word_offset = next_static_double_offset + | |
3938 | 3457 (fac.count[STATIC_DOUBLE] * BytesPerLong); |
0 | 3458 next_static_short_offset = next_static_word_offset + |
3938 | 3459 (fac.count[STATIC_WORD] * BytesPerInt); |
0 | 3460 next_static_byte_offset = next_static_short_offset + |
3938 | 3461 (fac.count[STATIC_SHORT] * BytesPerShort); |
0 | 3462 next_static_type_offset = align_size_up((next_static_byte_offset + |
3938 | 3463 fac.count[STATIC_BYTE] ), wordSize ); |
0 | 3464 static_field_size = (next_static_type_offset - |
3465 next_static_oop_offset) / wordSize; | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
3466 |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3467 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3468 nonstatic_field_size * heapOopSize; |
0 | 3469 next_nonstatic_field_offset = first_nonstatic_field_offset; |
3470 | |
3938 | 3471 unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE]; |
3472 unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD]; | |
3473 unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT]; | |
3474 unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE]; | |
3475 unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP]; | |
0 | 3476 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3477 bool super_has_nonstatic_fields = |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3478 (super_klass() != NULL && super_klass->has_nonstatic_fields()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3479 bool has_nonstatic_fields = super_has_nonstatic_fields || |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3480 ((nonstatic_double_count + nonstatic_word_count + |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3481 nonstatic_short_count + nonstatic_byte_count + |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3482 nonstatic_oop_count) != 0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3483 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3484 |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3485 // Prepare list of oops for oop map generation. |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3486 int* nonstatic_oop_offsets; |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3487 unsigned int* nonstatic_oop_counts; |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3488 unsigned int nonstatic_oop_map_count = 0; |
0 | 3489 |
3490 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3491 THREAD, int, nonstatic_oop_count + 1); |
938 | 3492 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3493 THREAD, unsigned int, nonstatic_oop_count + 1); |
0 | 3494 |
3938 | 3495 first_nonstatic_oop_offset = 0; // will be set for first oop field |
0 | 3496 |
3497 #ifndef PRODUCT | |
3498 if( PrintCompactFieldsSavings ) { | |
3499 next_nonstatic_double_offset = next_nonstatic_field_offset + | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3500 (nonstatic_oop_count * heapOopSize); |
0 | 3501 if ( nonstatic_double_count > 0 ) { |
3502 next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong); | |
3503 } | |
3504 next_nonstatic_word_offset = next_nonstatic_double_offset + | |
3505 (nonstatic_double_count * BytesPerLong); | |
3506 next_nonstatic_short_offset = next_nonstatic_word_offset + | |
3507 (nonstatic_word_count * BytesPerInt); | |
3508 next_nonstatic_byte_offset = next_nonstatic_short_offset + | |
3509 (nonstatic_short_count * BytesPerShort); | |
3510 next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset + | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3511 nonstatic_byte_count ), heapOopSize ); |
0 | 3512 orig_nonstatic_field_size = nonstatic_field_size + |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3513 ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize); |
0 | 3514 } |
3515 #endif | |
3516 bool compact_fields = CompactFields; | |
3517 int allocation_style = FieldsAllocationStyle; | |
1366
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3518 if( allocation_style < 0 || allocation_style > 2 ) { // Out of range? |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3519 assert(false, "0 <= FieldsAllocationStyle <= 2"); |
0 | 3520 allocation_style = 1; // Optimistic |
3521 } | |
3522 | |
3523 // The next classes have predefined hard-coded fields offsets | |
3524 // (see in JavaClasses::compute_hard_coded_offsets()). | |
3525 // Use default fields allocation order for them. | |
3526 if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() && | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3527 (class_name == vmSymbols::java_lang_AssertionStatusDirectives() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3528 class_name == vmSymbols::java_lang_Class() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3529 class_name == vmSymbols::java_lang_ClassLoader() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3530 class_name == vmSymbols::java_lang_ref_Reference() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3531 class_name == vmSymbols::java_lang_ref_SoftReference() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3532 class_name == vmSymbols::java_lang_StackTraceElement() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3533 class_name == vmSymbols::java_lang_String() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3534 class_name == vmSymbols::java_lang_Throwable() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3535 class_name == vmSymbols::java_lang_Boolean() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3536 class_name == vmSymbols::java_lang_Character() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3537 class_name == vmSymbols::java_lang_Float() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3538 class_name == vmSymbols::java_lang_Double() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3539 class_name == vmSymbols::java_lang_Byte() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3540 class_name == vmSymbols::java_lang_Short() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3541 class_name == vmSymbols::java_lang_Integer() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3542 class_name == vmSymbols::java_lang_Long())) { |
0 | 3543 allocation_style = 0; // Allocate oops first |
3544 compact_fields = false; // Don't compact fields | |
3545 } | |
3546 | |
3547 if( allocation_style == 0 ) { | |
3548 // Fields order: oops, longs/doubles, ints, shorts/chars, bytes | |
3549 next_nonstatic_oop_offset = next_nonstatic_field_offset; | |
3550 next_nonstatic_double_offset = next_nonstatic_oop_offset + | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3551 (nonstatic_oop_count * heapOopSize); |
0 | 3552 } else if( allocation_style == 1 ) { |
3553 // Fields order: longs/doubles, ints, shorts/chars, bytes, oops | |
3554 next_nonstatic_double_offset = next_nonstatic_field_offset; | |
1366
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3555 } else if( allocation_style == 2 ) { |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3556 // Fields allocation: oops fields in super and sub classes are together. |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3557 if( nonstatic_field_size > 0 && super_klass() != NULL && |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3558 super_klass->nonstatic_oop_map_size() > 0 ) { |
3786
498c6cf70f7e
7058036: FieldsAllocationStyle=2 does not work in 32-bit VM
kvn
parents:
3245
diff
changeset
|
3559 int map_count = super_klass->nonstatic_oop_map_count(); |
1366
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3560 OopMapBlock* first_map = super_klass->start_of_nonstatic_oop_maps(); |
3786
498c6cf70f7e
7058036: FieldsAllocationStyle=2 does not work in 32-bit VM
kvn
parents:
3245
diff
changeset
|
3561 OopMapBlock* last_map = first_map + map_count - 1; |
1366
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3562 int next_offset = last_map->offset() + (last_map->count() * heapOopSize); |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3563 if (next_offset == next_nonstatic_field_offset) { |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3564 allocation_style = 0; // allocate oops first |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3565 next_nonstatic_oop_offset = next_nonstatic_field_offset; |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3566 next_nonstatic_double_offset = next_nonstatic_oop_offset + |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3567 (nonstatic_oop_count * heapOopSize); |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3568 } |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3569 } |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3570 if( allocation_style == 2 ) { |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3571 allocation_style = 1; // allocate oops last |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3572 next_nonstatic_double_offset = next_nonstatic_field_offset; |
b9d85fcdf743
6940733: allocate non static oop fields in super and sub classes together
kvn
parents:
1144
diff
changeset
|
3573 } |
0 | 3574 } else { |
3575 ShouldNotReachHere(); | |
3576 } | |
3577 | |
3578 int nonstatic_oop_space_count = 0; | |
3579 int nonstatic_word_space_count = 0; | |
3580 int nonstatic_short_space_count = 0; | |
3581 int nonstatic_byte_space_count = 0; | |
3582 int nonstatic_oop_space_offset; | |
3583 int nonstatic_word_space_offset; | |
3584 int nonstatic_short_space_offset; | |
3585 int nonstatic_byte_space_offset; | |
3586 | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3587 if( nonstatic_double_count > 0 ) { |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3588 int offset = next_nonstatic_double_offset; |
0 | 3589 next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); |
3590 if( compact_fields && offset != next_nonstatic_double_offset ) { | |
3591 // Allocate available fields into the gap before double field. | |
3592 int length = next_nonstatic_double_offset - offset; | |
3593 assert(length == BytesPerInt, ""); | |
3594 nonstatic_word_space_offset = offset; | |
3595 if( nonstatic_word_count > 0 ) { | |
3596 nonstatic_word_count -= 1; | |
3597 nonstatic_word_space_count = 1; // Only one will fit | |
3598 length -= BytesPerInt; | |
3599 offset += BytesPerInt; | |
3600 } | |
3601 nonstatic_short_space_offset = offset; | |
3602 while( length >= BytesPerShort && nonstatic_short_count > 0 ) { | |
3603 nonstatic_short_count -= 1; | |
3604 nonstatic_short_space_count += 1; | |
3605 length -= BytesPerShort; | |
3606 offset += BytesPerShort; | |
3607 } | |
3608 nonstatic_byte_space_offset = offset; | |
3609 while( length > 0 && nonstatic_byte_count > 0 ) { | |
3610 nonstatic_byte_count -= 1; | |
3611 nonstatic_byte_space_count += 1; | |
3612 length -= 1; | |
3613 } | |
3614 // Allocate oop field in the gap if there are no other fields for that. | |
3615 nonstatic_oop_space_offset = offset; | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3616 if( length >= heapOopSize && nonstatic_oop_count > 0 && |
0 | 3617 allocation_style != 0 ) { // when oop fields not first |
3618 nonstatic_oop_count -= 1; | |
3619 nonstatic_oop_space_count = 1; // Only one will fit | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3620 length -= heapOopSize; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3621 offset += heapOopSize; |
0 | 3622 } |
3623 } | |
3624 } | |
3625 | |
3626 next_nonstatic_word_offset = next_nonstatic_double_offset + | |
3627 (nonstatic_double_count * BytesPerLong); | |
3628 next_nonstatic_short_offset = next_nonstatic_word_offset + | |
3629 (nonstatic_word_count * BytesPerInt); | |
3630 next_nonstatic_byte_offset = next_nonstatic_short_offset + | |
3631 (nonstatic_short_count * BytesPerShort); | |
3632 | |
3633 int notaligned_offset; | |
3634 if( allocation_style == 0 ) { | |
3635 notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count; | |
3636 } else { // allocation_style == 1 | |
3637 next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count; | |
3638 if( nonstatic_oop_count > 0 ) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3639 next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); |
0 | 3640 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3641 notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); |
0 | 3642 } |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3643 next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); |
0 | 3644 nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3645 - first_nonstatic_field_offset)/heapOopSize); |
0 | 3646 |
3647 // Iterate over fields again and compute correct offsets. | |
3648 // The field allocation type was temporarily stored in the offset slot. | |
3649 // oop fields are located before non-oop fields (static and non-static). | |
3938 | 3650 for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { |
0 | 3651 int real_offset; |
3938 | 3652 FieldAllocationType atype = (FieldAllocationType) fs.offset(); |
0 | 3653 switch (atype) { |
3654 case STATIC_OOP: | |
3655 real_offset = next_static_oop_offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3656 next_static_oop_offset += heapOopSize; |
0 | 3657 break; |
3658 case STATIC_BYTE: | |
3659 real_offset = next_static_byte_offset; | |
3660 next_static_byte_offset += 1; | |
3661 break; | |
3662 case STATIC_SHORT: | |
3663 real_offset = next_static_short_offset; | |
3664 next_static_short_offset += BytesPerShort; | |
3665 break; | |
3666 case STATIC_WORD: | |
3667 real_offset = next_static_word_offset; | |
3668 next_static_word_offset += BytesPerInt; | |
3669 break; | |
3670 case STATIC_DOUBLE: | |
3671 real_offset = next_static_double_offset; | |
3672 next_static_double_offset += BytesPerLong; | |
3673 break; | |
3674 case NONSTATIC_OOP: | |
3675 if( nonstatic_oop_space_count > 0 ) { | |
3676 real_offset = nonstatic_oop_space_offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3677 nonstatic_oop_space_offset += heapOopSize; |
0 | 3678 nonstatic_oop_space_count -= 1; |
3679 } else { | |
3680 real_offset = next_nonstatic_oop_offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
92
diff
changeset
|
3681 next_nonstatic_oop_offset += heapOopSize; |
0 | 3682 } |
3683 // Update oop maps | |
3684 if( nonstatic_oop_map_count > 0 && | |
3685 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3686 real_offset - |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3687 int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) * |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3688 heapOopSize ) { |
0 | 3689 // Extend current oop map |
938 | 3690 nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; |
0 | 3691 } else { |
3692 // Create new oop map | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3693 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; |
938 | 3694 nonstatic_oop_counts [nonstatic_oop_map_count] = 1; |
0 | 3695 nonstatic_oop_map_count += 1; |
3696 if( first_nonstatic_oop_offset == 0 ) { // Undefined | |
3697 first_nonstatic_oop_offset = real_offset; | |
3698 } | |
3699 } | |
3700 break; | |
3701 case NONSTATIC_BYTE: | |
3702 if( nonstatic_byte_space_count > 0 ) { | |
3703 real_offset = nonstatic_byte_space_offset; | |
3704 nonstatic_byte_space_offset += 1; | |
3705 nonstatic_byte_space_count -= 1; | |
3706 } else { | |
3707 real_offset = next_nonstatic_byte_offset; | |
3708 next_nonstatic_byte_offset += 1; | |
3709 } | |
3710 break; | |
3711 case NONSTATIC_SHORT: | |
3712 if( nonstatic_short_space_count > 0 ) { | |
3713 real_offset = nonstatic_short_space_offset; | |
3714 nonstatic_short_space_offset += BytesPerShort; | |
3715 nonstatic_short_space_count -= 1; | |
3716 } else { | |
3717 real_offset = next_nonstatic_short_offset; | |
3718 next_nonstatic_short_offset += BytesPerShort; | |
3719 } | |
3720 break; | |
3721 case NONSTATIC_WORD: | |
3722 if( nonstatic_word_space_count > 0 ) { | |
3723 real_offset = nonstatic_word_space_offset; | |
3724 nonstatic_word_space_offset += BytesPerInt; | |
3725 nonstatic_word_space_count -= 1; | |
3726 } else { | |
3727 real_offset = next_nonstatic_word_offset; | |
3728 next_nonstatic_word_offset += BytesPerInt; | |
3729 } | |
3730 break; | |
3731 case NONSTATIC_DOUBLE: | |
3732 real_offset = next_nonstatic_double_offset; | |
3733 next_nonstatic_double_offset += BytesPerLong; | |
3734 break; | |
3735 default: | |
3736 ShouldNotReachHere(); | |
3737 } | |
3938 | 3738 fs.set_offset(real_offset); |
0 | 3739 } |
3740 | |
3741 // Size of instances | |
3742 int instance_size; | |
3743 | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3744 next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); |
0 | 3745 instance_size = align_object_size(next_nonstatic_type_offset / wordSize); |
3746 | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
3747 assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); |
0 | 3748 |
938 | 3749 // Number of non-static oop map blocks allocated at end of klass. |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3750 const unsigned int total_oop_map_count = |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3751 compute_oop_map_count(super_klass, nonstatic_oop_map_count, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
3752 first_nonstatic_oop_offset); |
0 | 3753 |
3754 // Compute reference type | |
3755 ReferenceType rt; | |
3756 if (super_klass() == NULL) { | |
3757 rt = REF_NONE; | |
3758 } else { | |
3759 rt = super_klass->reference_type(); | |
3760 } | |
3761 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3762 // We can now create the basic Klass* for this klass |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3763 int total_oop_map_size2 = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3764 InstanceKlass::nonstatic_oop_map_size(total_oop_map_count); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3765 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3766 Klass* ik = InstanceKlass::allocate_instance_klass(loader_data, |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3767 vtable_size, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3768 itable_size, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3769 static_field_size, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3770 total_oop_map_size2, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3771 rt, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3772 access_flags, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3773 name, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3774 super_klass(), |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3775 host_klass, |
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6735
diff
changeset
|
3776 CHECK_(nullHandle)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3777 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3778 // Add all classes to our internal class loader list here, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3779 // including classes in the bootstrap (NULL) class loader. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3780 loader_data->add_class(ik); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3781 |
0 | 3782 instanceKlassHandle this_klass (THREAD, ik); |
3783 | |
938 | 3784 assert(this_klass->static_field_size() == static_field_size, "sanity"); |
3785 assert(this_klass->nonstatic_oop_map_count() == total_oop_map_count, | |
3786 "sanity"); | |
0 | 3787 |
3788 // Fill in information already parsed | |
975 | 3789 this_klass->set_should_verify_class(verify); |
0 | 3790 jint lh = Klass::instance_layout_helper(instance_size, false); |
3791 this_klass->set_layout_helper(lh); | |
3792 assert(this_klass->oop_is_instance(), "layout is correct"); | |
3793 assert(this_klass->size_helper() == instance_size, "correct size_helper"); | |
3794 // Not yet: supers are done below to support the new subtype-checking fields | |
3795 //this_klass->set_super(super_klass()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3796 this_klass->set_class_loader_data(loader_data); |
0 | 3797 this_klass->set_nonstatic_field_size(nonstatic_field_size); |
975 | 3798 this_klass->set_has_nonstatic_fields(has_nonstatic_fields); |
3938 | 3799 this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]); |
0 | 3800 cp->set_pool_holder(this_klass()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
3801 error_handler.set_in_error(false); // turn off error handler for cp |
0 | 3802 this_klass->set_constants(cp()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3803 this_klass->set_local_interfaces(local_interfaces); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3804 this_klass->set_fields(fields, java_fields_count); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3805 this_klass->set_methods(methods); |
0 | 3806 if (has_final_method) { |
3807 this_klass->set_has_final_method(); | |
3808 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3809 this_klass->set_method_ordering(method_ordering); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3810 // The InstanceKlass::_methods_jmethod_ids cache and the |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3811 // InstanceKlass::_methods_cached_itable_indices cache are |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
975
diff
changeset
|
3812 // both managed on the assumption that the initial cache |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
975
diff
changeset
|
3813 // size is equal to the number of methods in the class. If |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3814 // that changes, then InstanceKlass::idnum_can_increment() |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
975
diff
changeset
|
3815 // has to be changed accordingly. |
0 | 3816 this_klass->set_initial_method_idnum(methods->length()); |
3817 this_klass->set_name(cp->klass_name_at(this_class_index)); | |
6852 | 3818 if (is_anonymous()) // I am well known to myself |
474
7a018855d2f0
6779339: turn off LinkWellKnownClasses by default pending further testing
jrose
parents:
431
diff
changeset
|
3819 cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3820 |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3821 // Allocate an annotation type if needed. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3822 if (fields_annotations != NULL || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3823 methods_annotations != NULL || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3824 methods_parameter_annotations != NULL || |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3825 methods_default_annotations != NULL || |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3826 fields_type_annotations != NULL || |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3827 methods_type_annotations != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3828 Annotations* anno = Annotations::allocate(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3829 fields_annotations, methods_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3830 methods_parameter_annotations, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3831 methods_default_annotations, CHECK_(nullHandle)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3832 this_klass->set_annotations(anno); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3833 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3834 this_klass->set_annotations(NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3835 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3836 |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3837 if (fields_type_annotations != NULL || |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3838 methods_type_annotations != NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3839 assert(this_klass->annotations() != NULL, "annotations should have been allocated"); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3840 Annotations* anno = Annotations::allocate(loader_data, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3841 fields_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3842 methods_type_annotations, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3843 NULL, |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3844 NULL, CHECK_(nullHandle)); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3845 this_klass->annotations()->set_type_annotations(anno); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3846 } |
0 | 3847 |
3848 this_klass->set_minor_version(minor_version); | |
3849 this_klass->set_major_version(major_version); | |
6934 | 3850 this_klass->set_has_default_methods(has_default_methods); |
0 | 3851 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3852 // Set up Method*::intrinsic_id as soon as we know the names of methods. |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3853 // (We used to do this lazily, but now we query it in Rewriter, |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3854 // which is eagerly done for every method, so we might as well do it now, |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3855 // when everything is fresh in memory.) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3856 if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) { |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3857 for (int j = 0; j < methods->length(); j++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3858 methods->at(j)->init_intrinsic_id(); |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3859 } |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3860 } |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
3861 |
0 | 3862 if (cached_class_file_bytes != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3863 // JVMTI: we have an InstanceKlass now, tell it about the cached bytes |
0 | 3864 this_klass->set_cached_class_file(cached_class_file_bytes, |
3865 cached_class_file_length); | |
3866 } | |
3867 | |
6934 | 3868 // Fill in field values obtained by parse_classfile_attributes |
3869 if (parsed_annotations.has_any_annotations()) | |
3870 parsed_annotations.apply_to(this_klass); | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3871 |
6934 | 3872 // Create annotations |
3873 if (_annotations != NULL && this_klass->annotations() == NULL) { | |
3874 Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); | |
3875 this_klass->set_annotations(anno); | |
3876 } | |
3877 apply_parsed_class_attributes(this_klass); | |
3878 | |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3879 // Create type annotations |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3880 if (_type_annotations != NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3881 if (this_klass->annotations() == NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3882 Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3883 this_klass->set_annotations(anno); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3884 } |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3885 if (this_klass->annotations()->type_annotations() == NULL) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3886 Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3887 this_klass->annotations()->set_type_annotations(anno); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3888 } |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3889 this_klass->annotations()->type_annotations()->set_class_annotations(_type_annotations); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3890 } |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
7187
diff
changeset
|
3891 |
0 | 3892 // Miranda methods |
3893 if ((num_miranda_methods > 0) || | |
3894 // if this class introduced new miranda methods or | |
3895 (super_klass.not_null() && (super_klass->has_miranda_methods())) | |
3896 // super class exists and this class inherited miranda methods | |
3897 ) { | |
3898 this_klass->set_has_miranda_methods(); // then set a flag | |
3899 } | |
3900 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3901 this_klass->set_transitive_interfaces(transitive_interfaces); |
0 | 3902 |
3903 // Fill in information needed to compute superclasses. | |
3904 this_klass->initialize_supers(super_klass(), CHECK_(nullHandle)); | |
3905 | |
3906 // Initialize itable offset tables | |
3907 klassItable::setup_itable_offset_table(this_klass); | |
3908 | |
6934 | 3909 // Compute transitive closure of interfaces this class implements |
0 | 3910 // Do final class setup |
938 | 3911 fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts); |
0 | 3912 |
6222
6d8f36bcef55
6711908: JVM needs direct access to some annotations
jrose
parents:
6100
diff
changeset
|
3913 // Fill in has_finalizer, has_vanilla_constructor, and layout_helper |
0 | 3914 set_precomputed_flags(this_klass); |
3915 | |
3916 // reinitialize modifiers, using the InnerClasses attribute | |
3917 int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle)); | |
3918 this_klass->set_modifier_flags(computed_modifiers); | |
3919 | |
3920 // check if this class can access its super class | |
3921 check_super_class_access(this_klass, CHECK_(nullHandle)); | |
3922 | |
3923 // check if this class can access its superinterfaces | |
3924 check_super_interface_access(this_klass, CHECK_(nullHandle)); | |
3925 | |
3926 // check if this class overrides any final method | |
3927 check_final_method_override(this_klass, CHECK_(nullHandle)); | |
3928 | |
3929 // check that if this class is an interface then it doesn't have static methods | |
3930 if (this_klass->is_interface()) { | |
7579
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
3931 /* An interface in a JAVA 8 classfile can be static */ |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
3932 if (_major_version < JAVA_8_VERSION) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
3933 check_illegal_static_method(this_klass, CHECK_(nullHandle)); |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
3934 } |
0 | 3935 } |
3936 | |
6934 | 3937 |
3938 #ifdef ASSERT | |
3939 if (ParseAllGenericSignatures) { | |
3940 parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle)); | |
3941 } | |
3942 #endif | |
3943 | |
3944 // Generate any default methods - default methods are interface methods | |
3945 // that have a default implementation. This is new with Lambda project. | |
3946 if (has_default_methods && !access_flags.is_interface() && | |
3947 local_interfaces->length() > 0) { | |
3948 DefaultMethods::generate_default_methods( | |
3949 this_klass(), &all_mirandas, CHECK_(nullHandle)); | |
3950 } | |
3951 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
3952 // Allocate mirror and initialize static fields |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
3953 java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle)); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
3954 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3955 // Allocate a simple java object for locking during class initialization. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3956 // This needs to be a java object because it can be held across a java call. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3957 typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3958 this_klass->set_init_lock(r); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3959 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3960 // TODO: Move these oops to the mirror |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3961 this_klass->set_protection_domain(protection_domain()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3962 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3963 // Update the loader_data graph. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3964 record_defined_class_dependencies(this_klass, CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3965 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3966 ClassLoadingService::notify_class_loaded(InstanceKlass::cast(this_klass()), |
0 | 3967 false /* not shared class */); |
3968 | |
3969 if (TraceClassLoading) { | |
6934 | 3970 ResourceMark rm; |
0 | 3971 // print in a single call to reduce interleaving of output |
3972 if (cfs->source() != NULL) { | |
3973 tty->print("[Loaded %s from %s]\n", this_klass->external_name(), | |
3974 cfs->source()); | |
3975 } else if (class_loader.is_null()) { | |
3976 if (THREAD->is_Java_thread()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3977 Klass* caller = ((JavaThread*)THREAD)->security_get_caller_class(1); |
0 | 3978 tty->print("[Loaded %s by instance of %s]\n", |
3979 this_klass->external_name(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3980 InstanceKlass::cast(caller)->external_name()); |
0 | 3981 } else { |
3982 tty->print("[Loaded %s]\n", this_klass->external_name()); | |
3983 } | |
3984 } else { | |
3985 tty->print("[Loaded %s from %s]\n", this_klass->external_name(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3986 InstanceKlass::cast(class_loader->klass())->external_name()); |
0 | 3987 } |
3988 } | |
3989 | |
3990 if (TraceClassResolution) { | |
6934 | 3991 ResourceMark rm; |
0 | 3992 // print out the superclass. |
6983 | 3993 const char * from = this_klass()->external_name(); |
0 | 3994 if (this_klass->java_super() != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3995 tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name()); |
0 | 3996 } |
3997 // print out each of the interface classes referred to by this class. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3998 Array<Klass*>* local_interfaces = this_klass->local_interfaces(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
3999 if (local_interfaces != NULL) { |
0 | 4000 int length = local_interfaces->length(); |
4001 for (int i = 0; i < length; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4002 Klass* k = local_interfaces->at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4003 InstanceKlass* to_class = InstanceKlass::cast(k); |
0 | 4004 const char * to = to_class->external_name(); |
657
715dceaa89b7
6603316: Improve instrumentation for classes loaded at startup
acorn
parents:
652
diff
changeset
|
4005 tty->print("RESOLVE %s %s (interface)\n", from, to); |
0 | 4006 } |
4007 } | |
4008 } | |
4009 | |
4010 #ifndef PRODUCT | |
4011 if( PrintCompactFieldsSavings ) { | |
6934 | 4012 ResourceMark rm; |
0 | 4013 if( nonstatic_field_size < orig_nonstatic_field_size ) { |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4014 tty->print("[Saved %d of %d bytes in %s]\n", |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4015 (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize, |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4016 orig_nonstatic_field_size*heapOopSize, |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4017 this_klass->external_name()); |
0 | 4018 } else if( nonstatic_field_size > orig_nonstatic_field_size ) { |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4019 tty->print("[Wasted %d over %d bytes in %s]\n", |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4020 (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize, |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4021 orig_nonstatic_field_size*heapOopSize, |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
136
diff
changeset
|
4022 this_klass->external_name()); |
0 | 4023 } |
4024 } | |
4025 #endif | |
4026 | |
4027 // preserve result across HandleMark | |
4028 preserve_this_klass = this_klass(); | |
4029 } | |
4030 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4031 // Create new handle outside HandleMark (might be needed for |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4032 // Extended Class Redefinition) |
0 | 4033 instanceKlassHandle this_klass (THREAD, preserve_this_klass); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4034 debug_only(this_klass->verify();) |
0 | 4035 |
4036 return this_klass; | |
4037 } | |
4038 | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4039 unsigned int |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4040 ClassFileParser::compute_oop_map_count(instanceKlassHandle super, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4041 unsigned int nonstatic_oop_map_count, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4042 int first_nonstatic_oop_offset) { |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4043 unsigned int map_count = |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4044 super.is_null() ? 0 : super->nonstatic_oop_map_count(); |
0 | 4045 if (nonstatic_oop_map_count > 0) { |
4046 // We have oops to add to map | |
938 | 4047 if (map_count == 0) { |
4048 map_count = nonstatic_oop_map_count; | |
0 | 4049 } else { |
938 | 4050 // Check whether we should add a new map block or whether the last one can |
4051 // be extended | |
4052 OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps(); | |
4053 OopMapBlock* const last_map = first_map + map_count - 1; | |
4054 | |
4055 int next_offset = last_map->offset() + last_map->count() * heapOopSize; | |
0 | 4056 if (next_offset == first_nonstatic_oop_offset) { |
4057 // There is no gap bettwen superklass's last oop field and first | |
4058 // local oop field, merge maps. | |
4059 nonstatic_oop_map_count -= 1; | |
4060 } else { | |
4061 // Superklass didn't end with a oop field, add extra maps | |
938 | 4062 assert(next_offset < first_nonstatic_oop_offset, "just checking"); |
0 | 4063 } |
938 | 4064 map_count += nonstatic_oop_map_count; |
0 | 4065 } |
4066 } | |
938 | 4067 return map_count; |
0 | 4068 } |
4069 | |
4070 | |
4071 void ClassFileParser::fill_oop_maps(instanceKlassHandle k, | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4072 unsigned int nonstatic_oop_map_count, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4073 int* nonstatic_oop_offsets, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4074 unsigned int* nonstatic_oop_counts) { |
0 | 4075 OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4076 const InstanceKlass* const super = k->superklass(); |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4077 const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0; |
938 | 4078 if (super_count > 0) { |
4079 // Copy maps from superklass | |
0 | 4080 OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
4081 for (unsigned int i = 0; i < super_count; ++i) { |
0 | 4082 *this_oop_map++ = *super_oop_map++; |
4083 } | |
4084 } | |
938 | 4085 |
0 | 4086 if (nonstatic_oop_map_count > 0) { |
938 | 4087 if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) { |
4088 // The counts differ because there is no gap between superklass's last oop | |
4089 // field and the first local oop field. Extend the last oop map copied | |
0 | 4090 // from the superklass instead of creating new one. |
4091 nonstatic_oop_map_count--; | |
4092 nonstatic_oop_offsets++; | |
4093 this_oop_map--; | |
938 | 4094 this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++); |
0 | 4095 this_oop_map++; |
4096 } | |
938 | 4097 |
0 | 4098 // Add new map blocks, fill them |
4099 while (nonstatic_oop_map_count-- > 0) { | |
4100 this_oop_map->set_offset(*nonstatic_oop_offsets++); | |
938 | 4101 this_oop_map->set_count(*nonstatic_oop_counts++); |
0 | 4102 this_oop_map++; |
4103 } | |
938 | 4104 assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() == |
4105 this_oop_map, "sanity"); | |
0 | 4106 } |
4107 } | |
4108 | |
4109 | |
4110 void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4111 Klass* super = k->super(); |
0 | 4112 |
4113 // Check if this klass has an empty finalize method (i.e. one with return bytecode only), | |
4114 // in which case we don't have to register objects as finalizable | |
4115 if (!_has_empty_finalizer) { | |
4116 if (_has_finalizer || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4117 (super != NULL && super->has_finalizer())) { |
0 | 4118 k->set_has_finalizer(); |
4119 } | |
4120 } | |
4121 | |
4122 #ifdef ASSERT | |
4123 bool f = false; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4124 Method* m = k->lookup_method(vmSymbols::finalize_method_name(), |
0 | 4125 vmSymbols::void_method_signature()); |
4126 if (m != NULL && !m->is_empty_method()) { | |
4127 f = true; | |
4128 } | |
4129 assert(f == k->has_finalizer(), "inconsistent has_finalizer"); | |
4130 #endif | |
4131 | |
4132 // Check if this klass supports the java.lang.Cloneable interface | |
1142 | 4133 if (SystemDictionary::Cloneable_klass_loaded()) { |
4134 if (k->is_subtype_of(SystemDictionary::Cloneable_klass())) { | |
0 | 4135 k->set_is_cloneable(); |
4136 } | |
4137 } | |
4138 | |
4139 // Check if this klass has a vanilla default constructor | |
4140 if (super == NULL) { | |
4141 // java.lang.Object has empty default constructor | |
4142 k->set_has_vanilla_constructor(); | |
4143 } else { | |
6983 | 4144 if (super->has_vanilla_constructor() && |
0 | 4145 _has_vanilla_constructor) { |
4146 k->set_has_vanilla_constructor(); | |
4147 } | |
4148 #ifdef ASSERT | |
4149 bool v = false; | |
6983 | 4150 if (super->has_vanilla_constructor()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4151 Method* constructor = k->find_method(vmSymbols::object_initializer_name( |
0 | 4152 ), vmSymbols::void_method_signature()); |
4153 if (constructor != NULL && constructor->is_vanilla_constructor()) { | |
4154 v = true; | |
4155 } | |
4156 } | |
4157 assert(v == k->has_vanilla_constructor(), "inconsistent has_vanilla_constructor"); | |
4158 #endif | |
4159 } | |
4160 | |
4161 // If it cannot be fast-path allocated, set a bit in the layout helper. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4162 // See documentation of InstanceKlass::can_be_fastpath_allocated(). |
0 | 4163 assert(k->size_helper() > 0, "layout_helper is initialized"); |
4164 if ((!RegisterFinalizersAtInit && k->has_finalizer()) | |
4165 || k->is_abstract() || k->is_interface() | |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6983
diff
changeset
|
4166 || (k->name() == vmSymbols::java_lang_Class() && k->class_loader() == NULL) |
0 | 4167 || k->size_helper() >= FastAllocateSizeLimit) { |
4168 // Forbid fast-path allocation. | |
4169 jint lh = Klass::instance_layout_helper(k->size_helper(), true); | |
4170 k->set_layout_helper(lh); | |
4171 } | |
4172 } | |
4173 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4174 // Attach super classes and interface classes to class loader data |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4175 void ClassFileParser::record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4176 ClassLoaderData * defining_loader_data = defined_klass->class_loader_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4177 if (defining_loader_data->is_the_null_class_loader_data()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4178 // Dependencies to null class loader data are implicit. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4179 return; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4180 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4181 // add super class dependency |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4182 Klass* super = defined_klass->super(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4183 if (super != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4184 defining_loader_data->record_dependency(super, CHECK); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4185 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4186 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4187 // add super interface dependencies |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4188 Array<Klass*>* local_interfaces = defined_klass->local_interfaces(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4189 if (local_interfaces != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4190 int length = local_interfaces->length(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4191 for (int i = 0; i < length; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4192 defining_loader_data->record_dependency(local_interfaces->at(i), CHECK); |
0 | 4193 } |
4194 } | |
4195 } | |
4196 } | |
4197 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4198 // utility method for appending and array with check for duplicates |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4199 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4200 void append_interfaces(GrowableArray<Klass*>* result, Array<Klass*>* ifs) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4201 // iterate over new interfaces |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4202 for (int i = 0; i < ifs->length(); i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4203 Klass* e = ifs->at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4204 assert(e->is_klass() && InstanceKlass::cast(e)->is_interface(), "just checking"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4205 // add new interface |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4206 result->append_if_missing(e); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4207 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4208 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4209 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4210 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4211 Array<Klass*>* ClassFileParser::compute_transitive_interfaces(ClassLoaderData* loader_data, instanceKlassHandle super, Array<Klass*>* local_ifs, TRAPS) { |
0 | 4212 // Compute maximum size for transitive interfaces |
4213 int max_transitive_size = 0; | |
4214 int super_size = 0; | |
4215 // Add superclass transitive interfaces size | |
4216 if (super.not_null()) { | |
4217 super_size = super->transitive_interfaces()->length(); | |
4218 max_transitive_size += super_size; | |
4219 } | |
4220 // Add local interfaces' super interfaces | |
4221 int local_size = local_ifs->length(); | |
4222 for (int i = 0; i < local_size; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4223 Klass* l = local_ifs->at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4224 max_transitive_size += InstanceKlass::cast(l)->transitive_interfaces()->length(); |
0 | 4225 } |
4226 // Finally add local interfaces | |
4227 max_transitive_size += local_size; | |
4228 // Construct array | |
4229 if (max_transitive_size == 0) { | |
4230 // no interfaces, use canonicalized array | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4231 return Universe::the_empty_klass_array(); |
0 | 4232 } else if (max_transitive_size == super_size) { |
4233 // no new local interfaces added, share superklass' transitive interface array | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4234 return super->transitive_interfaces(); |
0 | 4235 } else if (max_transitive_size == local_size) { |
4236 // only local interfaces added, share local interface array | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4237 return local_ifs; |
0 | 4238 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4239 ResourceMark rm; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4240 GrowableArray<Klass*>* result = new GrowableArray<Klass*>(max_transitive_size); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4241 |
0 | 4242 // Copy down from superclass |
4243 if (super.not_null()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4244 append_interfaces(result, super->transitive_interfaces()); |
0 | 4245 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4246 |
0 | 4247 // Copy down from local interfaces' superinterfaces |
4248 for (int i = 0; i < local_ifs->length(); i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4249 Klass* l = local_ifs->at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4250 append_interfaces(result, InstanceKlass::cast(l)->transitive_interfaces()); |
0 | 4251 } |
4252 // Finally add local interfaces | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4253 append_interfaces(result, local_ifs); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4254 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4255 // length will be less than the max_transitive_size if duplicates were removed |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4256 int length = result->length(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4257 assert(length <= max_transitive_size, "just checking"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4258 Array<Klass*>* new_result = MetadataFactory::new_array<Klass*>(loader_data, length, CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4259 for (int i = 0; i < length; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4260 Klass* e = result->at(i); |
0 | 4261 assert(e != NULL, "just checking"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4262 new_result->at_put(i, e); |
0 | 4263 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4264 return new_result; |
0 | 4265 } |
4266 } | |
4267 | |
4268 | |
4269 void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4270 Klass* super = this_klass->super(); |
0 | 4271 if ((super != NULL) && |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4272 (!Reflection::verify_class_access(this_klass(), super, false))) { |
0 | 4273 ResourceMark rm(THREAD); |
4274 Exceptions::fthrow( | |
4275 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4276 vmSymbols::java_lang_IllegalAccessError(), |
0 | 4277 "class %s cannot access its superclass %s", |
4278 this_klass->external_name(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4279 InstanceKlass::cast(super)->external_name() |
0 | 4280 ); |
4281 return; | |
4282 } | |
4283 } | |
4284 | |
4285 | |
4286 void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klass, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4287 Array<Klass*>* local_interfaces = this_klass->local_interfaces(); |
0 | 4288 int lng = local_interfaces->length(); |
4289 for (int i = lng - 1; i >= 0; i--) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4290 Klass* k = local_interfaces->at(i); |
6983 | 4291 assert (k != NULL && k->is_interface(), "invalid interface"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4292 if (!Reflection::verify_class_access(this_klass(), k, false)) { |
0 | 4293 ResourceMark rm(THREAD); |
4294 Exceptions::fthrow( | |
4295 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4296 vmSymbols::java_lang_IllegalAccessError(), |
0 | 4297 "class %s cannot access its superinterface %s", |
4298 this_klass->external_name(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4299 InstanceKlass::cast(k)->external_name() |
0 | 4300 ); |
4301 return; | |
4302 } | |
4303 } | |
4304 } | |
4305 | |
4306 | |
4307 void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4308 Array<Method*>* methods = this_klass->methods(); |
0 | 4309 int num_methods = methods->length(); |
4310 | |
4311 // go thru each method and check if it overrides a final method | |
4312 for (int index = 0; index < num_methods; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4313 Method* m = methods->at(index); |
0 | 4314 |
4315 // skip private, static and <init> methods | |
4316 if ((!m->is_private()) && | |
4317 (!m->is_static()) && | |
4318 (m->name() != vmSymbols::object_initializer_name())) { | |
4319 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4320 Symbol* name = m->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4321 Symbol* signature = m->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4322 Klass* k = this_klass->super(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4323 Method* super_m = NULL; |
0 | 4324 while (k != NULL) { |
4325 // skip supers that don't have final methods. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4326 if (k->has_final_method()) { |
0 | 4327 // lookup a matching method in the super class hierarchy |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4328 super_m = InstanceKlass::cast(k)->lookup_method(name, signature); |
0 | 4329 if (super_m == NULL) { |
4330 break; // didn't find any match; get out | |
4331 } | |
4332 | |
4333 if (super_m->is_final() && | |
4334 // matching method in super is final | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4335 (Reflection::verify_field_access(this_klass(), |
0 | 4336 super_m->method_holder(), |
4337 super_m->method_holder(), | |
4338 super_m->access_flags(), false)) | |
4339 // this class can access super final method and therefore override | |
4340 ) { | |
4341 ResourceMark rm(THREAD); | |
4342 Exceptions::fthrow( | |
4343 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4344 vmSymbols::java_lang_VerifyError(), |
0 | 4345 "class %s overrides final method %s.%s", |
4346 this_klass->external_name(), | |
4347 name->as_C_string(), | |
4348 signature->as_C_string() | |
4349 ); | |
4350 return; | |
4351 } | |
4352 | |
4353 // continue to look from super_m's holder's super. | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
4354 k = super_m->method_holder()->super(); |
0 | 4355 continue; |
4356 } | |
4357 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4358 k = k->super(); |
0 | 4359 } |
4360 } | |
4361 } | |
4362 } | |
4363 | |
4364 | |
4365 // assumes that this_klass is an interface | |
4366 void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass, TRAPS) { | |
4367 assert(this_klass->is_interface(), "not an interface"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4368 Array<Method*>* methods = this_klass->methods(); |
0 | 4369 int num_methods = methods->length(); |
4370 | |
4371 for (int index = 0; index < num_methods; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
4372 Method* m = methods->at(index); |
0 | 4373 // if m is static and not the init method, throw a verify error |
4374 if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) { | |
4375 ResourceMark rm(THREAD); | |
4376 Exceptions::fthrow( | |
4377 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4378 vmSymbols::java_lang_VerifyError(), |
0 | 4379 "Illegal static method %s in interface %s", |
4380 m->name()->as_C_string(), | |
4381 this_klass->external_name() | |
4382 ); | |
4383 return; | |
4384 } | |
4385 } | |
4386 } | |
4387 | |
4388 // utility methods for format checking | |
4389 | |
4390 void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) { | |
4391 if (!_need_verify) { return; } | |
4392 | |
4393 const bool is_interface = (flags & JVM_ACC_INTERFACE) != 0; | |
4394 const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; | |
4395 const bool is_final = (flags & JVM_ACC_FINAL) != 0; | |
4396 const bool is_super = (flags & JVM_ACC_SUPER) != 0; | |
4397 const bool is_enum = (flags & JVM_ACC_ENUM) != 0; | |
4398 const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0; | |
4399 const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; | |
4400 | |
4401 if ((is_abstract && is_final) || | |
4402 (is_interface && !is_abstract) || | |
4403 (is_interface && major_gte_15 && (is_super || is_enum)) || | |
4404 (!is_interface && major_gte_15 && is_annotation)) { | |
4405 ResourceMark rm(THREAD); | |
4406 Exceptions::fthrow( | |
4407 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4408 vmSymbols::java_lang_ClassFormatError(), |
0 | 4409 "Illegal class modifiers in class %s: 0x%X", |
4410 _class_name->as_C_string(), flags | |
4411 ); | |
4412 return; | |
4413 } | |
4414 } | |
4415 | |
4416 bool ClassFileParser::has_illegal_visibility(jint flags) { | |
4417 const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; | |
4418 const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; | |
4419 const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; | |
4420 | |
4421 return ((is_public && is_protected) || | |
4422 (is_public && is_private) || | |
4423 (is_protected && is_private)); | |
4424 } | |
4425 | |
4426 bool ClassFileParser::is_supported_version(u2 major, u2 minor) { | |
1124
2e8bdfdd3ba2
6899467: System property java.class.version out-of-sync with VM for jdk 5.0 with HS 16 in nightly build
xlu
parents:
977
diff
changeset
|
4427 u2 max_version = |
2e8bdfdd3ba2
6899467: System property java.class.version out-of-sync with VM for jdk 5.0 with HS 16 in nightly build
xlu
parents:
977
diff
changeset
|
4428 JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION : |
2e8bdfdd3ba2
6899467: System property java.class.version out-of-sync with VM for jdk 5.0 with HS 16 in nightly build
xlu
parents:
977
diff
changeset
|
4429 (JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION); |
0 | 4430 return (major >= JAVA_MIN_SUPPORTED_VERSION) && |
176
6b648fefb395
6705523: Fix for 6695506 will violate spec when used in JDK6
kamg
parents:
136
diff
changeset
|
4431 (major <= max_version) && |
6b648fefb395
6705523: Fix for 6695506 will violate spec when used in JDK6
kamg
parents:
136
diff
changeset
|
4432 ((major != max_version) || |
0 | 4433 (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION)); |
4434 } | |
4435 | |
4436 void ClassFileParser::verify_legal_field_modifiers( | |
4437 jint flags, bool is_interface, TRAPS) { | |
4438 if (!_need_verify) { return; } | |
4439 | |
4440 const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; | |
4441 const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; | |
4442 const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; | |
4443 const bool is_static = (flags & JVM_ACC_STATIC) != 0; | |
4444 const bool is_final = (flags & JVM_ACC_FINAL) != 0; | |
4445 const bool is_volatile = (flags & JVM_ACC_VOLATILE) != 0; | |
4446 const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0; | |
4447 const bool is_enum = (flags & JVM_ACC_ENUM) != 0; | |
4448 const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; | |
4449 | |
4450 bool is_illegal = false; | |
4451 | |
4452 if (is_interface) { | |
4453 if (!is_public || !is_static || !is_final || is_private || | |
4454 is_protected || is_volatile || is_transient || | |
4455 (major_gte_15 && is_enum)) { | |
4456 is_illegal = true; | |
4457 } | |
4458 } else { // not interface | |
4459 if (has_illegal_visibility(flags) || (is_final && is_volatile)) { | |
4460 is_illegal = true; | |
4461 } | |
4462 } | |
4463 | |
4464 if (is_illegal) { | |
4465 ResourceMark rm(THREAD); | |
4466 Exceptions::fthrow( | |
4467 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4468 vmSymbols::java_lang_ClassFormatError(), |
0 | 4469 "Illegal field modifiers in class %s: 0x%X", |
4470 _class_name->as_C_string(), flags); | |
4471 return; | |
4472 } | |
4473 } | |
4474 | |
4475 void ClassFileParser::verify_legal_method_modifiers( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4476 jint flags, bool is_interface, Symbol* name, TRAPS) { |
0 | 4477 if (!_need_verify) { return; } |
4478 | |
4479 const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; | |
4480 const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; | |
4481 const bool is_static = (flags & JVM_ACC_STATIC) != 0; | |
4482 const bool is_final = (flags & JVM_ACC_FINAL) != 0; | |
4483 const bool is_native = (flags & JVM_ACC_NATIVE) != 0; | |
4484 const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; | |
4485 const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0; | |
4486 const bool is_strict = (flags & JVM_ACC_STRICT) != 0; | |
4487 const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0; | |
7579
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4488 const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; |
0 | 4489 const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; |
6934 | 4490 const bool major_gte_8 = _major_version >= JAVA_8_VERSION; |
0 | 4491 const bool is_initializer = (name == vmSymbols::object_initializer_name()); |
4492 | |
4493 bool is_illegal = false; | |
4494 | |
4495 if (is_interface) { | |
7579
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4496 if (major_gte_8) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4497 // Class file version is JAVA_8_VERSION or later Methods of |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4498 // interfaces may set any of the flags except ACC_PROTECTED, |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4499 // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4500 // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set. |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4501 if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */ |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4502 (is_native || is_protected || is_final || is_synchronized) || |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4503 // If a specific method of a class or interface has its |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4504 // ACC_ABSTRACT flag set, it must not have any of its |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4505 // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4506 // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4507 // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4508 // those flags are illegal irrespective of ACC_ABSTRACT being set or not. |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4509 (is_abstract && (is_private || is_static || is_strict))) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4510 is_illegal = true; |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4511 } |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4512 } else if (major_gte_15) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4513 // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION) |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4514 if (!is_public || is_static || is_final || is_synchronized || |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4515 is_native || !is_abstract || is_strict) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4516 is_illegal = true; |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4517 } |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4518 } else { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4519 // Class file version is pre-JAVA_1_5_VERSION |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4520 if (!is_public || is_static || is_final || is_native || !is_abstract) { |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4521 is_illegal = true; |
adc176e95bf2
8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests
acorn
parents:
7462
diff
changeset
|
4522 } |
0 | 4523 } |
4524 } else { // not interface | |
4525 if (is_initializer) { | |
4526 if (is_static || is_final || is_synchronized || is_native || | |
4527 is_abstract || (major_gte_15 && is_bridge)) { | |
4528 is_illegal = true; | |
4529 } | |
4530 } else { // not initializer | |
4531 if (is_abstract) { | |
4532 if ((is_final || is_native || is_private || is_static || | |
4533 (major_gte_15 && (is_synchronized || is_strict)))) { | |
4534 is_illegal = true; | |
4535 } | |
4536 } | |
4537 if (has_illegal_visibility(flags)) { | |
4538 is_illegal = true; | |
4539 } | |
4540 } | |
4541 } | |
4542 | |
4543 if (is_illegal) { | |
4544 ResourceMark rm(THREAD); | |
4545 Exceptions::fthrow( | |
4546 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4547 vmSymbols::java_lang_ClassFormatError(), |
0 | 4548 "Method %s in class %s has illegal modifiers: 0x%X", |
4549 name->as_C_string(), _class_name->as_C_string(), flags); | |
4550 return; | |
4551 } | |
4552 } | |
4553 | |
4554 void ClassFileParser::verify_legal_utf8(const unsigned char* buffer, int length, TRAPS) { | |
4555 assert(_need_verify, "only called when _need_verify is true"); | |
4556 int i = 0; | |
4557 int count = length >> 2; | |
4558 for (int k=0; k<count; k++) { | |
4559 unsigned char b0 = buffer[i]; | |
4560 unsigned char b1 = buffer[i+1]; | |
4561 unsigned char b2 = buffer[i+2]; | |
4562 unsigned char b3 = buffer[i+3]; | |
4563 // For an unsigned char v, | |
4564 // (v | v - 1) is < 128 (highest bit 0) for 0 < v < 128; | |
4565 // (v | v - 1) is >= 128 (highest bit 1) for v == 0 or v >= 128. | |
4566 unsigned char res = b0 | b0 - 1 | | |
4567 b1 | b1 - 1 | | |
4568 b2 | b2 - 1 | | |
4569 b3 | b3 - 1; | |
4570 if (res >= 128) break; | |
4571 i += 4; | |
4572 } | |
4573 for(; i < length; i++) { | |
4574 unsigned short c; | |
4575 // no embedded zeros | |
4576 guarantee_property((buffer[i] != 0), "Illegal UTF8 string in constant pool in class file %s", CHECK); | |
4577 if(buffer[i] < 128) { | |
4578 continue; | |
4579 } | |
4580 if ((i + 5) < length) { // see if it's legal supplementary character | |
4581 if (UTF8::is_supplementary_character(&buffer[i])) { | |
4582 c = UTF8::get_supplementary_character(&buffer[i]); | |
4583 i += 5; | |
4584 continue; | |
4585 } | |
4586 } | |
4587 switch (buffer[i] >> 4) { | |
4588 default: break; | |
4589 case 0x8: case 0x9: case 0xA: case 0xB: case 0xF: | |
4590 classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); | |
4591 case 0xC: case 0xD: // 110xxxxx 10xxxxxx | |
4592 c = (buffer[i] & 0x1F) << 6; | |
4593 i++; | |
4594 if ((i < length) && ((buffer[i] & 0xC0) == 0x80)) { | |
4595 c += buffer[i] & 0x3F; | |
4596 if (_major_version <= 47 || c == 0 || c >= 0x80) { | |
4597 // for classes with major > 47, c must a null or a character in its shortest form | |
4598 break; | |
4599 } | |
4600 } | |
4601 classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); | |
4602 case 0xE: // 1110xxxx 10xxxxxx 10xxxxxx | |
4603 c = (buffer[i] & 0xF) << 12; | |
4604 i += 2; | |
4605 if ((i < length) && ((buffer[i-1] & 0xC0) == 0x80) && ((buffer[i] & 0xC0) == 0x80)) { | |
4606 c += ((buffer[i-1] & 0x3F) << 6) + (buffer[i] & 0x3F); | |
4607 if (_major_version <= 47 || c >= 0x800) { | |
4608 // for classes with major > 47, c must be in its shortest form | |
4609 break; | |
4610 } | |
4611 } | |
4612 classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); | |
4613 } // end of switch | |
4614 } // end of for | |
4615 } | |
4616 | |
4617 // Checks if name is a legal class name. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4618 void ClassFileParser::verify_legal_class_name(Symbol* name, TRAPS) { |
0 | 4619 if (!_need_verify || _relax_verify) { return; } |
4620 | |
4621 char buf[fixed_buffer_size]; | |
4622 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); | |
4623 unsigned int length = name->utf8_length(); | |
4624 bool legal = false; | |
4625 | |
4626 if (length > 0) { | |
4627 char* p; | |
4628 if (bytes[0] == JVM_SIGNATURE_ARRAY) { | |
4629 p = skip_over_field_signature(bytes, false, length, CHECK); | |
4630 legal = (p != NULL) && ((p - bytes) == (int)length); | |
4631 } else if (_major_version < JAVA_1_5_VERSION) { | |
4632 if (bytes[0] != '<') { | |
4633 p = skip_over_field_name(bytes, true, length); | |
4634 legal = (p != NULL) && ((p - bytes) == (int)length); | |
4635 } | |
4636 } else { | |
4637 // 4900761: relax the constraints based on JSR202 spec | |
4638 // Class names may be drawn from the entire Unicode character set. | |
4639 // Identifiers between '/' must be unqualified names. | |
4640 // The utf8 string has been verified when parsing cpool entries. | |
4641 legal = verify_unqualified_name(bytes, length, LegalClass); | |
4642 } | |
4643 } | |
4644 if (!legal) { | |
4645 ResourceMark rm(THREAD); | |
4646 Exceptions::fthrow( | |
4647 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4648 vmSymbols::java_lang_ClassFormatError(), |
0 | 4649 "Illegal class name \"%s\" in class file %s", bytes, |
4650 _class_name->as_C_string() | |
4651 ); | |
4652 return; | |
4653 } | |
4654 } | |
4655 | |
4656 // Checks if name is a legal field name. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4657 void ClassFileParser::verify_legal_field_name(Symbol* name, TRAPS) { |
0 | 4658 if (!_need_verify || _relax_verify) { return; } |
4659 | |
4660 char buf[fixed_buffer_size]; | |
4661 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); | |
4662 unsigned int length = name->utf8_length(); | |
4663 bool legal = false; | |
4664 | |
4665 if (length > 0) { | |
4666 if (_major_version < JAVA_1_5_VERSION) { | |
4667 if (bytes[0] != '<') { | |
4668 char* p = skip_over_field_name(bytes, false, length); | |
4669 legal = (p != NULL) && ((p - bytes) == (int)length); | |
4670 } | |
4671 } else { | |
4672 // 4881221: relax the constraints based on JSR202 spec | |
4673 legal = verify_unqualified_name(bytes, length, LegalField); | |
4674 } | |
4675 } | |
4676 | |
4677 if (!legal) { | |
4678 ResourceMark rm(THREAD); | |
4679 Exceptions::fthrow( | |
4680 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4681 vmSymbols::java_lang_ClassFormatError(), |
0 | 4682 "Illegal field name \"%s\" in class %s", bytes, |
4683 _class_name->as_C_string() | |
4684 ); | |
4685 return; | |
4686 } | |
4687 } | |
4688 | |
4689 // Checks if name is a legal method name. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4690 void ClassFileParser::verify_legal_method_name(Symbol* name, TRAPS) { |
0 | 4691 if (!_need_verify || _relax_verify) { return; } |
4692 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4693 assert(name != NULL, "method name is null"); |
0 | 4694 char buf[fixed_buffer_size]; |
4695 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); | |
4696 unsigned int length = name->utf8_length(); | |
4697 bool legal = false; | |
4698 | |
4699 if (length > 0) { | |
4700 if (bytes[0] == '<') { | |
4701 if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) { | |
4702 legal = true; | |
4703 } | |
4704 } else if (_major_version < JAVA_1_5_VERSION) { | |
4705 char* p; | |
4706 p = skip_over_field_name(bytes, false, length); | |
4707 legal = (p != NULL) && ((p - bytes) == (int)length); | |
4708 } else { | |
4709 // 4881221: relax the constraints based on JSR202 spec | |
4710 legal = verify_unqualified_name(bytes, length, LegalMethod); | |
4711 } | |
4712 } | |
4713 | |
4714 if (!legal) { | |
4715 ResourceMark rm(THREAD); | |
4716 Exceptions::fthrow( | |
4717 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4718 vmSymbols::java_lang_ClassFormatError(), |
0 | 4719 "Illegal method name \"%s\" in class %s", bytes, |
4720 _class_name->as_C_string() | |
4721 ); | |
4722 return; | |
4723 } | |
4724 } | |
4725 | |
4726 | |
4727 // Checks if signature is a legal field signature. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4728 void ClassFileParser::verify_legal_field_signature(Symbol* name, Symbol* signature, TRAPS) { |
0 | 4729 if (!_need_verify) { return; } |
4730 | |
4731 char buf[fixed_buffer_size]; | |
4732 char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); | |
4733 unsigned int length = signature->utf8_length(); | |
4734 char* p = skip_over_field_signature(bytes, false, length, CHECK); | |
4735 | |
4736 if (p == NULL || (p - bytes) != (int)length) { | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
4737 throwIllegalSignature("Field", name, signature, CHECK); |
0 | 4738 } |
4739 } | |
4740 | |
4741 // Checks if signature is a legal method signature. | |
4742 // Returns number of parameters | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4743 int ClassFileParser::verify_legal_method_signature(Symbol* name, Symbol* signature, TRAPS) { |
0 | 4744 if (!_need_verify) { |
4745 // make sure caller's args_size will be less than 0 even for non-static | |
4746 // method so it will be recomputed in compute_size_of_parameters(). | |
4747 return -2; | |
4748 } | |
4749 | |
4750 unsigned int args_size = 0; | |
4751 char buf[fixed_buffer_size]; | |
4752 char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); | |
4753 unsigned int length = signature->utf8_length(); | |
4754 char* nextp; | |
4755 | |
4756 // The first character must be a '(' | |
4757 if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) { | |
4758 length--; | |
4759 // Skip over legal field signatures | |
4760 nextp = skip_over_field_signature(p, false, length, CHECK_0); | |
4761 while ((length > 0) && (nextp != NULL)) { | |
4762 args_size++; | |
4763 if (p[0] == 'J' || p[0] == 'D') { | |
4764 args_size++; | |
4765 } | |
4766 length -= nextp - p; | |
4767 p = nextp; | |
4768 nextp = skip_over_field_signature(p, false, length, CHECK_0); | |
4769 } | |
4770 // The first non-signature thing better be a ')' | |
4771 if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) { | |
4772 length--; | |
4773 if (name->utf8_length() > 0 && name->byte_at(0) == '<') { | |
4774 // All internal methods must return void | |
4775 if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) { | |
4776 return args_size; | |
4777 } | |
4778 } else { | |
4779 // Now we better just have a return value | |
4780 nextp = skip_over_field_signature(p, true, length, CHECK_0); | |
4781 if (nextp && ((int)length == (nextp - p))) { | |
4782 return args_size; | |
4783 } | |
4784 } | |
4785 } | |
4786 } | |
4787 // Report error | |
1586
086d73ccd6c0
6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
kamg
parents:
1513
diff
changeset
|
4788 throwIllegalSignature("Method", name, signature, CHECK_0); |
0 | 4789 return 0; |
4790 } | |
4791 | |
4792 | |
1881
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4793 // Unqualified names may not contain the characters '.', ';', '[', or '/'. |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4794 // Method names also may not contain the characters '<' or '>', unless <init> |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4795 // or <clinit>. Note that method names may not be <init> or <clinit> in this |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4796 // method. Because these names have been checked as special cases before |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4797 // calling this method in verify_legal_method_name. |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4798 bool ClassFileParser::verify_unqualified_name( |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4799 char* name, unsigned int length, int type) { |
0 | 4800 jchar ch; |
4801 | |
4802 for (char* p = name; p != name + length; ) { | |
4803 ch = *p; | |
4804 if (ch < 128) { | |
4805 p++; | |
1881
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4806 if (ch == '.' || ch == ';' || ch == '[' ) { |
6412b3805cd6
6891959: HotSpot should not throw ClassFormatError if a class has a field with '>' and/or '<' in its name
kamg
parents:
1847
diff
changeset
|
4807 return false; // do not permit '.', ';', or '[' |
0 | 4808 } |
4809 if (type != LegalClass && ch == '/') { | |
4810 return false; // do not permit '/' unless it's class name | |
4811 } | |
4812 if (type == LegalMethod && (ch == '<' || ch == '>')) { | |
4813 return false; // do not permit '<' or '>' in method names | |
4814 } | |
4815 } else { | |
4816 char* tmp_p = UTF8::next(p, &ch); | |
4817 p = tmp_p; | |
4818 } | |
4819 } | |
4820 return true; | |
4821 } | |
4822 | |
4823 | |
4824 // Take pointer to a string. Skip over the longest part of the string that could | |
4825 // be taken as a fieldname. Allow '/' if slash_ok is true. | |
4826 // Return a pointer to just past the fieldname. | |
4827 // Return NULL if no fieldname at all was found, or in the case of slash_ok | |
4828 // being true, we saw consecutive slashes (meaning we were looking for a | |
4829 // qualified path but found something that was badly-formed). | |
4830 char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned int length) { | |
4831 char* p; | |
4832 jchar ch; | |
4833 jboolean last_is_slash = false; | |
4834 jboolean not_first_ch = false; | |
4835 | |
4836 for (p = name; p != name + length; not_first_ch = true) { | |
4837 char* old_p = p; | |
4838 ch = *p; | |
4839 if (ch < 128) { | |
4840 p++; | |
4841 // quick check for ascii | |
4842 if ((ch >= 'a' && ch <= 'z') || | |
4843 (ch >= 'A' && ch <= 'Z') || | |
4844 (ch == '_' || ch == '$') || | |
4845 (not_first_ch && ch >= '0' && ch <= '9')) { | |
4846 last_is_slash = false; | |
4847 continue; | |
4848 } | |
4849 if (slash_ok && ch == '/') { | |
4850 if (last_is_slash) { | |
4851 return NULL; // Don't permit consecutive slashes | |
4852 } | |
4853 last_is_slash = true; | |
4854 continue; | |
4855 } | |
4856 } else { | |
4857 jint unicode_ch; | |
4858 char* tmp_p = UTF8::next_character(p, &unicode_ch); | |
4859 p = tmp_p; | |
4860 last_is_slash = false; | |
4861 // Check if ch is Java identifier start or is Java identifier part | |
4862 // 4672820: call java.lang.Character methods directly without generating separate tables. | |
4863 EXCEPTION_MARK; | |
1142 | 4864 instanceKlassHandle klass (THREAD, SystemDictionary::Character_klass()); |
0 | 4865 |
4866 // return value | |
4867 JavaValue result(T_BOOLEAN); | |
4868 // Set up the arguments to isJavaIdentifierStart and isJavaIdentifierPart | |
4869 JavaCallArguments args; | |
4870 args.push_int(unicode_ch); | |
4871 | |
4872 // public static boolean isJavaIdentifierStart(char ch); | |
4873 JavaCalls::call_static(&result, | |
4874 klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4875 vmSymbols::isJavaIdentifierStart_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4876 vmSymbols::int_bool_signature(), |
0 | 4877 &args, |
4878 THREAD); | |
4879 | |
4880 if (HAS_PENDING_EXCEPTION) { | |
4881 CLEAR_PENDING_EXCEPTION; | |
4882 return 0; | |
4883 } | |
4884 if (result.get_jboolean()) { | |
4885 continue; | |
4886 } | |
4887 | |
4888 if (not_first_ch) { | |
4889 // public static boolean isJavaIdentifierPart(char ch); | |
4890 JavaCalls::call_static(&result, | |
4891 klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4892 vmSymbols::isJavaIdentifierPart_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2085
diff
changeset
|
4893 vmSymbols::int_bool_signature(), |
0 | 4894 &args, |
4895 THREAD); | |
4896 | |
4897 if (HAS_PENDING_EXCEPTION) { | |
4898 CLEAR_PENDING_EXCEPTION; | |
4899 return 0; | |
4900 } | |
4901 | |
4902 if (result.get_jboolean()) { | |
4903 continue; | |
4904 } | |
4905 } | |
4906 } | |
4907 return (not_first_ch) ? old_p : NULL; | |
4908 } | |
4909 return (not_first_ch) ? p : NULL; | |
4910 } | |
4911 | |
4912 | |
4913 // Take pointer to a string. Skip over the longest part of the string that could | |
4914 // be taken as a field signature. Allow "void" if void_ok. | |
4915 // Return a pointer to just past the signature. | |
4916 // Return NULL if no legal signature is found. | |
4917 char* ClassFileParser::skip_over_field_signature(char* signature, | |
4918 bool void_ok, | |
4919 unsigned int length, | |
4920 TRAPS) { | |
4921 unsigned int array_dim = 0; | |
4922 while (length > 0) { | |
4923 switch (signature[0]) { | |
4924 case JVM_SIGNATURE_VOID: if (!void_ok) { return NULL; } | |
4925 case JVM_SIGNATURE_BOOLEAN: | |
4926 case JVM_SIGNATURE_BYTE: | |
4927 case JVM_SIGNATURE_CHAR: | |
4928 case JVM_SIGNATURE_SHORT: | |
4929 case JVM_SIGNATURE_INT: | |
4930 case JVM_SIGNATURE_FLOAT: | |
4931 case JVM_SIGNATURE_LONG: | |
4932 case JVM_SIGNATURE_DOUBLE: | |
4933 return signature + 1; | |
4934 case JVM_SIGNATURE_CLASS: { | |
4935 if (_major_version < JAVA_1_5_VERSION) { | |
4936 // Skip over the class name if one is there | |
4937 char* p = skip_over_field_name(signature + 1, true, --length); | |
4938 | |
4939 // The next character better be a semicolon | |
4940 if (p && (p - signature) > 1 && p[0] == ';') { | |
4941 return p + 1; | |
4942 } | |
4943 } else { | |
4944 // 4900761: For class version > 48, any unicode is allowed in class name. | |
4945 length--; | |
4946 signature++; | |
4947 while (length > 0 && signature[0] != ';') { | |
4948 if (signature[0] == '.') { | |
4949 classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0); | |
4950 } | |
4951 length--; | |
4952 signature++; | |
4953 } | |
4954 if (signature[0] == ';') { return signature + 1; } | |
4955 } | |
4956 | |
4957 return NULL; | |
4958 } | |
4959 case JVM_SIGNATURE_ARRAY: | |
4960 array_dim++; | |
4961 if (array_dim > 255) { | |
4962 // 4277370: array descriptor is valid only if it represents 255 or fewer dimensions. | |
4963 classfile_parse_error("Array type descriptor has more than 255 dimensions in class file %s", CHECK_0); | |
4964 } | |
4965 // The rest of what's there better be a legal signature | |
4966 signature++; | |
4967 length--; | |
4968 void_ok = false; | |
4969 break; | |
4970 | |
4971 default: | |
4972 return NULL; | |
4973 } | |
4974 } | |
4975 return NULL; | |
4976 } |