annotate src/hotspot/share/classfile/classFileParser.cpp @ 51450:a73848f8d0ad

8199940: Print more information about class loaders in IllegalAccessErrors. Reviewed-by: lfoltan, mchung
author goetz
date Wed, 27 Jun 2018 09:52:23 +0200
parents cb07f4b539fc
children a5557f24b4d4 9d49099287b1
rev   line source
duke@1 1 /*
hseigel@49805 2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
stefank@7397 24 #include "precompiled.hpp"
coleenp@47946 25 #include "jvm.h"
kvn@42650 26 #include "aot/aotLoader.hpp"
stefank@7397 27 #include "classfile/classFileParser.hpp"
mgronlun@34666 28 #include "classfile/classFileStream.hpp"
stefank@7397 29 #include "classfile/classLoader.hpp"
coleenp@13728 30 #include "classfile/classLoaderData.inline.hpp"
kamg@14385 31 #include "classfile/defaultMethods.hpp"
kvn@42650 32 #include "classfile/dictionary.hpp"
stefank@29081 33 #include "classfile/javaClasses.inline.hpp"
alanb@36508 34 #include "classfile/moduleEntry.hpp"
stefank@7397 35 #include "classfile/symbolTable.hpp"
stefank@7397 36 #include "classfile/systemDictionary.hpp"
stefank@7397 37 #include "classfile/verificationType.hpp"
stefank@7397 38 #include "classfile/verifier.hpp"
stefank@7397 39 #include "classfile/vmSymbols.hpp"
mockner@35917 40 #include "logging/log.hpp"
stuefe@46701 41 #include "logging/logStream.hpp"
stefank@7397 42 #include "memory/allocation.hpp"
coleenp@13728 43 #include "memory/metadataFactory.hpp"
stefank@7397 44 #include "memory/oopFactory.hpp"
stefank@29201 45 #include "memory/resourceArea.hpp"
stefank@49824 46 #include "memory/universe.hpp"
mgronlun@34666 47 #include "oops/annotations.hpp"
hseigel@49805 48 #include "oops/constantPool.inline.hpp"
never@10546 49 #include "oops/fieldStreams.hpp"
stefank@7397 50 #include "oops/instanceKlass.hpp"
never@8725 51 #include "oops/instanceMirrorKlass.hpp"
stefank@7397 52 #include "oops/klass.inline.hpp"
stefank@7397 53 #include "oops/klassVtable.hpp"
mgronlun@34666 54 #include "oops/metadata.hpp"
coleenp@13728 55 #include "oops/method.hpp"
mgronlun@34666 56 #include "oops/oop.inline.hpp"
coleenp@8076 57 #include "oops/symbol.hpp"
stefank@7397 58 #include "prims/jvmtiExport.hpp"
dcubed@11399 59 #include "prims/jvmtiThreadState.hpp"
hseigel@50211 60 #include "runtime/arguments.hpp"
coleenp@49945 61 #include "runtime/handles.inline.hpp"
stefank@7397 62 #include "runtime/javaCalls.hpp"
stefank@7397 63 #include "runtime/perfData.hpp"
stefank@7397 64 #include "runtime/reflection.hpp"
stefank@50089 65 #include "runtime/safepointVerifiers.hpp"
stefank@7397 66 #include "runtime/signature.hpp"
stefank@7397 67 #include "runtime/timer.hpp"
stefank@7397 68 #include "services/classLoadingService.hpp"
stefank@7397 69 #include "services/threadService.hpp"
stefank@46625 70 #include "utilities/align.hpp"
tschatzl@46502 71 #include "utilities/bitMap.inline.hpp"
stefank@50088 72 #include "utilities/copy.hpp"
pliden@30764 73 #include "utilities/exceptions.hpp"
coleenp@15194 74 #include "utilities/globalDefinitions.hpp"
hseigel@46448 75 #include "utilities/growableArray.hpp"
stefank@27683 76 #include "utilities/macros.hpp"
iklam@26135 77 #include "utilities/ostream.hpp"
coleenp@28817 78 #include "utilities/resourceHash.hpp"
stefank@27683 79 #if INCLUDE_CDS
stefank@27683 80 #include "classfile/systemDictionaryShared.hpp"
stefank@27683 81 #endif
egahlin@50662 82 #if INCLUDE_JFR
egahlin@50662 83 #include "jfr/support/jfrTraceIdExtension.hpp"
egahlin@50662 84 #endif
duke@1 85
kamg@5709 86 // We generally try to create the oops directly when parsing, rather than
kamg@5709 87 // allocating temporary data structures and copying the bytes twice. A
kamg@5709 88 // temporary area is only needed when parsing utf8 entries in the constant
kamg@5709 89 // pool and when parsing line number tables.
duke@1 90
duke@1 91 // We add assert in debug mode when class format is not checked.
duke@1 92
duke@1 93 #define JAVA_CLASSFILE_MAGIC 0xCAFEBABE
duke@1 94 #define JAVA_MIN_SUPPORTED_VERSION 45
hseigel@50211 95 #define JAVA_PREVIEW_MINOR_VERSION 65535
duke@1 96
duke@1 97 // Used for two backward compatibility reasons:
duke@1 98 // - to check for new additions to the class file format in JDK1.5
duke@1 99 // - to check for bug fixes in the format checker in JDK1.5
duke@1 100 #define JAVA_1_5_VERSION 49
duke@1 101
duke@1 102 // Used for backward compatibility reasons:
duke@1 103 // - to check for javac bug fixes that happened after 1.5
kamg@602 104 // - also used as the max version when running in jdk6
duke@1 105 #define JAVA_6_VERSION 50
duke@1 106
kamg@5709 107 // Used for backward compatibility reasons:
hseigel@33799 108 // - to disallow argument and require ACC_STATIC for <clinit> methods
kamg@5709 109 #define JAVA_7_VERSION 51
kamg@5709 110
kamg@14385 111 // Extension method support.
kamg@14385 112 #define JAVA_8_VERSION 52
kamg@14385 113
hseigel@35941 114 #define JAVA_9_VERSION 53
hseigel@35941 115
psandoz@48297 116 #define JAVA_10_VERSION 54
psandoz@48297 117
psandoz@48610 118 #define JAVA_11_VERSION 55
psandoz@48610 119
hseigel@44239 120 void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
hseigel@44239 121 assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
hseigel@44239 122 "Unexpected bad constant pool entry");
hseigel@44239 123 if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
hseigel@44239 124 }
hseigel@44239 125
mgronlun@34666 126 void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
mgronlun@34666 127 ConstantPool* cp,
mgronlun@34666 128 const int length,
mgronlun@34666 129 TRAPS) {
mgronlun@34666 130 assert(stream != NULL, "invariant");
mgronlun@34666 131 assert(cp != NULL, "invariant");
mgronlun@34666 132
duke@1 133 // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
duke@1 134 // this function (_current can be allocated in a register, with scalar
duke@1 135 // replacement of aggregates). The _current pointer is copied back to
duke@1 136 // stream() when this function returns. DON'T call another method within
duke@1 137 // this method that uses stream().
mgronlun@34666 138 const ClassFileStream cfs1 = *stream;
mgronlun@34666 139 const ClassFileStream* const cfs = &cfs1;
mgronlun@34666 140
mgronlun@34666 141 assert(cfs->allocated_on_stack(), "should be local");
mgronlun@34666 142 debug_only(const u1* const old_current = stream->current();)
duke@1 143
duke@1 144 // Used for batching symbol allocations.
duke@1 145 const char* names[SymbolTable::symbol_alloc_batch_size];
duke@1 146 int lengths[SymbolTable::symbol_alloc_batch_size];
duke@1 147 int indices[SymbolTable::symbol_alloc_batch_size];
duke@1 148 unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
duke@1 149 int names_count = 0;
duke@1 150
duke@1 151 // parsing Index 0 is unused
duke@1 152 for (int index = 1; index < length; index++) {
duke@1 153 // Each of the following case guarantees one more byte in the stream
duke@1 154 // for the following tag or the access_flags following constant pool,
duke@1 155 // so we don't need bounds-check for reading tag.
mgronlun@34666 156 const u1 tag = cfs->get_u1_fast();
duke@1 157 switch (tag) {
mgronlun@34666 158 case JVM_CONSTANT_Class : {
mgronlun@34666 159 cfs->guarantee_more(3, CHECK); // name_index, tag/access_flags
mgronlun@34666 160 const u2 name_index = cfs->get_u2_fast();
mgronlun@34666 161 cp->klass_index_at_put(index, name_index);
duke@1 162 break;
mgronlun@34666 163 }
mgronlun@34666 164 case JVM_CONSTANT_Fieldref: {
mgronlun@34666 165 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags
mgronlun@34666 166 const u2 class_index = cfs->get_u2_fast();
mgronlun@34666 167 const u2 name_and_type_index = cfs->get_u2_fast();
mgronlun@34666 168 cp->field_at_put(index, class_index, name_and_type_index);
duke@1 169 break;
mgronlun@34666 170 }
mgronlun@34666 171 case JVM_CONSTANT_Methodref: {
mgronlun@34666 172 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags
mgronlun@34666 173 const u2 class_index = cfs->get_u2_fast();
mgronlun@34666 174 const u2 name_and_type_index = cfs->get_u2_fast();
mgronlun@34666 175 cp->method_at_put(index, class_index, name_and_type_index);
duke@1 176 break;
mgronlun@34666 177 }
mgronlun@34666 178 case JVM_CONSTANT_InterfaceMethodref: {
mgronlun@34666 179 cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags
mgronlun@34666 180 const u2 class_index = cfs->get_u2_fast();
mgronlun@34666 181 const u2 name_and_type_index = cfs->get_u2_fast();
mgronlun@34666 182 cp->interface_method_at_put(index, class_index, name_and_type_index);
duke@1 183 break;
mgronlun@34666 184 }
mgronlun@34666 185 case JVM_CONSTANT_String : {
mgronlun@34666 186 cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags
mgronlun@34666 187 const u2 string_index = cfs->get_u2_fast();
mgronlun@34666 188 cp->string_index_at_put(index, string_index);
duke@1 189 break;
mgronlun@34666 190 }
jrose@5882 191 case JVM_CONSTANT_MethodHandle :
mgronlun@34666 192 case JVM_CONSTANT_MethodType: {
jrose@8675 193 if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
jrose@5882 194 classfile_parse_error(
jrose@8675 195 "Class file version does not support constant tag %u in class file %s",
jrose@8675 196 tag, CHECK);
jrose@8675 197 }
jrose@5882 198 if (tag == JVM_CONSTANT_MethodHandle) {
jrose@5882 199 cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags
mgronlun@34666 200 const u1 ref_kind = cfs->get_u1_fast();
mgronlun@34666 201 const u2 method_index = cfs->get_u2_fast();
mgronlun@34666 202 cp->method_handle_index_at_put(index, ref_kind, method_index);
mgronlun@34666 203 }
mgronlun@34666 204 else if (tag == JVM_CONSTANT_MethodType) {
jrose@5882 205 cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags
mgronlun@34666 206 const u2 signature_index = cfs->get_u2_fast();
mgronlun@34666 207 cp->method_type_index_at_put(index, signature_index);
mgronlun@34666 208 }
mgronlun@34666 209 else {
jrose@5882 210 ShouldNotReachHere();
jrose@5882 211 }
jrose@5882 212 break;
mgronlun@34666 213 }
psandoz@49210 214 case JVM_CONSTANT_Dynamic : {
psandoz@49210 215 if (_major_version < Verifier::DYNAMICCONSTANT_MAJOR_VERSION) {
psandoz@49210 216 classfile_parse_error(
psandoz@49210 217 "Class file version does not support constant tag %u in class file %s",
psandoz@49210 218 tag, CHECK);
psandoz@49210 219 }
psandoz@49210 220 cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags
psandoz@49210 221 const u2 bootstrap_specifier_index = cfs->get_u2_fast();
psandoz@49210 222 const u2 name_and_type_index = cfs->get_u2_fast();
psandoz@49210 223 if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) {
psandoz@49210 224 _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later
psandoz@49210 225 }
psandoz@49210 226 cp->dynamic_constant_at_put(index, bootstrap_specifier_index, name_and_type_index);
psandoz@49210 227 break;
psandoz@49210 228 }
mgronlun@34666 229 case JVM_CONSTANT_InvokeDynamic : {
mgronlun@34666 230 if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
mgronlun@34666 231 classfile_parse_error(
jrose@8675 232 "Class file version does not support constant tag %u in class file %s",
jrose@8675 233 tag, CHECK);
jrose@6062 234 }
mgronlun@34666 235 cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags
mgronlun@34666 236 const u2 bootstrap_specifier_index = cfs->get_u2_fast();
mgronlun@34666 237 const u2 name_and_type_index = cfs->get_u2_fast();
mgronlun@34666 238 if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) {
mgronlun@34666 239 _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later
mgronlun@34666 240 }
mgronlun@34666 241 cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);
jrose@6062 242 break;
mgronlun@34666 243 }
mgronlun@34666 244 case JVM_CONSTANT_Integer: {
mgronlun@34666 245 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags
mgronlun@34666 246 const u4 bytes = cfs->get_u4_fast();
mgronlun@34666 247 cp->int_at_put(index, (jint)bytes);
duke@1 248 break;
mgronlun@34666 249 }
mgronlun@34666 250 case JVM_CONSTANT_Float: {
mgronlun@34666 251 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags
mgronlun@34666 252 const u4 bytes = cfs->get_u4_fast();
mgronlun@34666 253 cp->float_at_put(index, *(jfloat*)&bytes);
duke@1 254 break;
mgronlun@34666 255 }
mgronlun@34666 256 case JVM_CONSTANT_Long: {
mgronlun@34666 257 // A mangled type might cause you to overrun allocated memory
mgronlun@34666 258 guarantee_property(index + 1 < length,
mgronlun@34666 259 "Invalid constant pool entry %u in class file %s",
mgronlun@34666 260 index,
mgronlun@34666 261 CHECK);
mgronlun@34666 262 cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags
mgronlun@34666 263 const u8 bytes = cfs->get_u8_fast();
mgronlun@34666 264 cp->long_at_put(index, bytes);
mgronlun@34666 265 index++; // Skip entry following eigth-byte constant, see JVM book p. 98
mgronlun@34666 266 break;
mgronlun@34666 267 }
mgronlun@34666 268 case JVM_CONSTANT_Double: {
duke@1 269 // A mangled type might cause you to overrun allocated memory
duke@1 270 guarantee_property(index+1 < length,
duke@1 271 "Invalid constant pool entry %u in class file %s",
mgronlun@34666 272 index,
mgronlun@34666 273 CHECK);
mgronlun@34666 274 cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags
mgronlun@34666 275 const u8 bytes = cfs->get_u8_fast();
mgronlun@34666 276 cp->double_at_put(index, *(jdouble*)&bytes);
duke@1 277 index++; // Skip entry following eigth-byte constant, see JVM book p. 98
duke@1 278 break;
mgronlun@34666 279 }
mgronlun@34666 280 case JVM_CONSTANT_NameAndType: {
mgronlun@34666 281 cfs->guarantee_more(5, CHECK); // name_index, signature_index, tag/access_flags
mgronlun@34666 282 const u2 name_index = cfs->get_u2_fast();
mgronlun@34666 283 const u2 signature_index = cfs->get_u2_fast();
mgronlun@34666 284 cp->name_and_type_at_put(index, name_index, signature_index);
mgronlun@34666 285 break;
mgronlun@34666 286 }
mgronlun@34666 287 case JVM_CONSTANT_Utf8 : {
mgronlun@34666 288 cfs->guarantee_more(2, CHECK); // utf8_length
mgronlun@34666 289 u2 utf8_length = cfs->get_u2_fast();
mikael@46504 290 const u1* utf8_buffer = cfs->current();
mgronlun@34666 291 assert(utf8_buffer != NULL, "null utf8 buffer");
mgronlun@34666 292 // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
mgronlun@34666 293 cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
mgronlun@34666 294 cfs->skip_u1_fast(utf8_length);
mgronlun@34666 295
mgronlun@34666 296 // Before storing the symbol, make sure it's legal
mgronlun@34666 297 if (_need_verify) {
mgronlun@34666 298 verify_legal_utf8(utf8_buffer, utf8_length, CHECK);
duke@1 299 }
mgronlun@34666 300
mgronlun@34666 301 if (has_cp_patch_at(index)) {
mgronlun@34666 302 Handle patch = clear_cp_patch_at(index);
mgronlun@34666 303 guarantee_property(java_lang_String::is_instance(patch()),
mgronlun@34666 304 "Illegal utf8 patch at %d in class file %s",
mgronlun@34666 305 index,
mgronlun@34666 306 CHECK);
mgronlun@34666 307 const char* const str = java_lang_String::as_utf8_string(patch());
mgronlun@34666 308 // (could use java_lang_String::as_symbol instead, but might as well batch them)
mgronlun@34666 309 utf8_buffer = (const u1*) str;
mgronlun@34666 310 utf8_length = (int) strlen(str);
mgronlun@34666 311 }
mgronlun@34666 312
mgronlun@34666 313 unsigned int hash;
mgronlun@34666 314 Symbol* const result = SymbolTable::lookup_only((const char*)utf8_buffer,
mgronlun@34666 315 utf8_length,
mgronlun@34666 316 hash);
mgronlun@34666 317 if (result == NULL) {
mgronlun@34666 318 names[names_count] = (const char*)utf8_buffer;
mgronlun@34666 319 lengths[names_count] = utf8_length;
mgronlun@34666 320 indices[names_count] = index;
mgronlun@34666 321 hashValues[names_count++] = hash;
mgronlun@34666 322 if (names_count == SymbolTable::symbol_alloc_batch_size) {
mgronlun@34666 323 SymbolTable::new_symbols(_loader_data,
mgronlun@34666 324 cp,
mgronlun@34666 325 names_count,
mgronlun@34666 326 names,
mgronlun@34666 327 lengths,
mgronlun@34666 328 indices,
mgronlun@34666 329 hashValues,
mgronlun@34666 330 CHECK);
mgronlun@34666 331 names_count = 0;
mgronlun@34666 332 }
mgronlun@34666 333 } else {
mgronlun@34666 334 cp->symbol_at_put(index, result);
duke@1 335 }
duke@1 336 break;
mgronlun@34666 337 }
hseigel@44239 338 case 19:
hseigel@44239 339 case 20: {
hseigel@44239 340 // Record that an error occurred in these two cases but keep parsing so
hseigel@44239 341 // that ACC_Module can be checked for in the access_flags. Need to
hseigel@44239 342 // throw NoClassDefFoundError in that case.
hseigel@44239 343 if (_major_version >= JAVA_9_VERSION) {
hseigel@44239 344 cfs->guarantee_more(3, CHECK);
hseigel@44239 345 cfs->get_u2_fast();
hseigel@44239 346 set_class_bad_constant_seen(tag);
hseigel@44239 347 break;
hseigel@44239 348 }
hseigel@44239 349 }
mgronlun@34666 350 default: {
mgronlun@34666 351 classfile_parse_error("Unknown constant tag %u in class file %s",
mgronlun@34666 352 tag,
mgronlun@34666 353 CHECK);
duke@1 354 break;
mgronlun@34666 355 }
mgronlun@34666 356 } // end of switch(tag)
mgronlun@34666 357 } // end of for
duke@1 358
duke@1 359 // Allocate the remaining symbols
duke@1 360 if (names_count > 0) {
mgronlun@34666 361 SymbolTable::new_symbols(_loader_data,
mgronlun@34666 362 cp,
mgronlun@34666 363 names_count,
mgronlun@34666 364 names,
mgronlun@34666 365 lengths,
mgronlun@34666 366 indices,
mgronlun@34666 367 hashValues,
mgronlun@34666 368 CHECK);
duke@1 369 }
duke@1 370
mgronlun@34666 371 // Copy _current pointer of local copy back to stream.
mgronlun@34666 372 assert(stream->current() == old_current, "non-exclusive use of stream");
mgronlun@34666 373 stream->set_current(cfs1.current());
mgronlun@34666 374
duke@1 375 }
duke@1 376
mgronlun@34666 377 static inline bool valid_cp_range(int index, int length) {
mgronlun@34666 378 return (index > 0 && index < length);
mgronlun@34666 379 }
mgronlun@34666 380
mgronlun@34666 381 static inline Symbol* check_symbol_at(const ConstantPool* cp, int index) {
mgronlun@34666 382 assert(cp != NULL, "invariant");
mgronlun@34666 383 if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8()) {
jrose@13291 384 return cp->symbol_at(index);
mgronlun@34666 385 }
mgronlun@34666 386 return NULL;
jrose@13291 387 }
jrose@13291 388
goetz@33604 389 #ifdef ASSERT
stefank@29201 390 PRAGMA_DIAG_PUSH
stefank@29201 391 PRAGMA_FORMAT_NONLITERAL_IGNORED
mgronlun@34666 392 void ClassFileParser::report_assert_property_failure(const char* msg, TRAPS) const {
stefank@29201 393 ResourceMark rm(THREAD);
david@33105 394 fatal(msg, _class_name->as_C_string());
stefank@29201 395 }
stefank@29201 396
mgronlun@34666 397 void ClassFileParser::report_assert_property_failure(const char* msg,
mgronlun@34666 398 int index,
mgronlun@34666 399 TRAPS) const {
stefank@29201 400 ResourceMark rm(THREAD);
david@33105 401 fatal(msg, index, _class_name->as_C_string());
stefank@29201 402 }
stefank@29201 403 PRAGMA_DIAG_POP
goetz@33604 404 #endif
stefank@29201 405
mgronlun@34666 406 void ClassFileParser::parse_constant_pool(const ClassFileStream* const stream,
hseigel@44239 407 ConstantPool* const cp,
hseigel@44239 408 const int length,
hseigel@44239 409 TRAPS) {
mgronlun@34666 410 assert(cp != NULL, "invariant");
mgronlun@34666 411 assert(stream != NULL, "invariant");
duke@1 412
duke@1 413 // parsing constant pool entries
mgronlun@34666 414 parse_constant_pool_entries(stream, cp, length, CHECK);
hseigel@44239 415 if (class_bad_constant_seen() != 0) {
hseigel@44239 416 // a bad CP entry has been detected previously so stop parsing and just return.
hseigel@44239 417 return;
hseigel@44239 418 }
duke@1 419
duke@1 420 int index = 1; // declared outside of loops for portability
iklam@46427 421 int num_klasses = 0;
duke@1 422
mgronlun@34666 423 // first verification pass - validate cross references
mgronlun@34666 424 // and fixup class and string constants
duke@1 425 for (index = 1; index < length; index++) { // Index 0 is unused
mgronlun@34666 426 const jbyte tag = cp->tag_at(index).value();
jrose@7436 427 switch (tag) {
mgronlun@34666 428 case JVM_CONSTANT_Class: {
duke@1 429 ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present
duke@1 430 break;
mgronlun@34666 431 }
mgronlun@34666 432 case JVM_CONSTANT_Fieldref:
duke@1 433 // fall through
mgronlun@34666 434 case JVM_CONSTANT_Methodref:
duke@1 435 // fall through
mgronlun@34666 436 case JVM_CONSTANT_InterfaceMethodref: {
duke@1 437 if (!_need_verify) break;
mgronlun@34666 438 const int klass_ref_index = cp->klass_ref_index_at(index);
mgronlun@34666 439 const int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
coleenp@15935 440 check_property(valid_klass_reference_at(klass_ref_index),
duke@1 441 "Invalid constant pool index %u in class file %s",
mgronlun@34666 442 klass_ref_index, CHECK);
duke@1 443 check_property(valid_cp_range(name_and_type_ref_index, length) &&
mgronlun@34666 444 cp->tag_at(name_and_type_ref_index).is_name_and_type(),
mgronlun@34666 445 "Invalid constant pool index %u in class file %s",
mgronlun@34666 446 name_and_type_ref_index, CHECK);
duke@1 447 break;
duke@1 448 }
mgronlun@34666 449 case JVM_CONSTANT_String: {
duke@1 450 ShouldNotReachHere(); // Only JVM_CONSTANT_StringIndex should be present
duke@1 451 break;
mgronlun@34666 452 }
mgronlun@34666 453 case JVM_CONSTANT_Integer:
duke@1 454 break;
mgronlun@34666 455 case JVM_CONSTANT_Float:
duke@1 456 break;
mgronlun@34666 457 case JVM_CONSTANT_Long:
mgronlun@34666 458 case JVM_CONSTANT_Double: {
duke@1 459 index++;
duke@1 460 check_property(
duke@1 461 (index < length && cp->tag_at(index).is_invalid()),
duke@1 462 "Improper constant pool long/double index %u in class file %s",
mgronlun@34666 463 index, CHECK);
duke@1 464 break;
duke@1 465 }
mgronlun@34666 466 case JVM_CONSTANT_NameAndType: {
mgronlun@34666 467 if (!_need_verify) break;
mgronlun@34666 468 const int name_ref_index = cp->name_ref_index_at(index);
mgronlun@34666 469 const int signature_ref_index = cp->signature_ref_index_at(index);
mgronlun@34666 470 check_property(valid_symbol_at(name_ref_index),
mgronlun@34666 471 "Invalid constant pool index %u in class file %s",
mgronlun@34666 472 name_ref_index, CHECK);
mgronlun@34666 473 check_property(valid_symbol_at(signature_ref_index),
mgronlun@34666 474 "Invalid constant pool index %u in class file %s",
mgronlun@34666 475 signature_ref_index, CHECK);
duke@1 476 break;
mgronlun@34666 477 }
mgronlun@34666 478 case JVM_CONSTANT_Utf8:
mgronlun@34666 479 break;
mgronlun@34666 480 case JVM_CONSTANT_UnresolvedClass: // fall-through
mgronlun@34666 481 case JVM_CONSTANT_UnresolvedClassInError: {
duke@1 482 ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present
duke@1 483 break;
mgronlun@34666 484 }
mgronlun@34666 485 case JVM_CONSTANT_ClassIndex: {
mgronlun@34666 486 const int class_index = cp->klass_index_at(index);
mgronlun@34666 487 check_property(valid_symbol_at(class_index),
mgronlun@34666 488 "Invalid constant pool index %u in class file %s",
mgronlun@34666 489 class_index, CHECK);
iklam@46427 490 cp->unresolved_klass_at_put(index, class_index, num_klasses++);
duke@1 491 break;
mgronlun@34666 492 }
mgronlun@34666 493 case JVM_CONSTANT_StringIndex: {
mgronlun@34666 494 const int string_index = cp->string_index_at(index);
mgronlun@34666 495 check_property(valid_symbol_at(string_index),
mgronlun@34666 496 "Invalid constant pool index %u in class file %s",
mgronlun@34666 497 string_index, CHECK);
mgronlun@34666 498 Symbol* const sym = cp->symbol_at(string_index);
mgronlun@34666 499 cp->unresolved_string_at_put(index, sym);
duke@1 500 break;
mgronlun@34666 501 }
mgronlun@34666 502 case JVM_CONSTANT_MethodHandle: {
mgronlun@34666 503 const int ref_index = cp->method_handle_index_at(index);
mgronlun@34666 504 check_property(valid_cp_range(ref_index, length),
mgronlun@34666 505 "Invalid constant pool index %u in class file %s",
mgronlun@34666 506 ref_index, CHECK);
mgronlun@34666 507 const constantTag tag = cp->tag_at(ref_index);
mgronlun@34666 508 const int ref_kind = cp->method_handle_ref_kind_at(index);
mgronlun@34666 509
mgronlun@34666 510 switch (ref_kind) {
jrose@5882 511 case JVM_REF_getField:
jrose@5882 512 case JVM_REF_getStatic:
jrose@5882 513 case JVM_REF_putField:
mgronlun@34666 514 case JVM_REF_putStatic: {
jrose@5882 515 check_property(
jrose@5882 516 tag.is_field(),
jrose@5882 517 "Invalid constant pool index %u in class file %s (not a field)",
mgronlun@34666 518 ref_index, CHECK);
jrose@5882 519 break;
mgronlun@34666 520 }
jrose@5882 521 case JVM_REF_invokeVirtual:
mgronlun@34666 522 case JVM_REF_newInvokeSpecial: {
jrose@5882 523 check_property(
jrose@5882 524 tag.is_method(),
jrose@5882 525 "Invalid constant pool index %u in class file %s (not a method)",
mgronlun@34666 526 ref_index, CHECK);
jrose@5882 527 break;
mgronlun@34666 528 }
bharadwaj@17024 529 case JVM_REF_invokeStatic:
mgronlun@34666 530 case JVM_REF_invokeSpecial: {
mgronlun@34666 531 check_property(
mgronlun@34666 532 tag.is_method() ||
mgronlun@34666 533 ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
mgronlun@34666 534 "Invalid constant pool index %u in class file %s (not a method)",
mgronlun@34666 535 ref_index, CHECK);
mgronlun@34666 536 break;
mgronlun@34666 537 }
mgronlun@34666 538 case JVM_REF_invokeInterface: {
jrose@5882 539 check_property(
jrose@5882 540 tag.is_interface_method(),
jrose@5882 541 "Invalid constant pool index %u in class file %s (not an interface method)",
mgronlun@34666 542 ref_index, CHECK);
jrose@5882 543 break;
mgronlun@34666 544 }
mgronlun@34666 545 default: {
jrose@5882 546 classfile_parse_error(
jrose@5882 547 "Bad method handle kind at constant pool index %u in class file %s",
mgronlun@34666 548 index, CHECK);
jrose@5882 549 }
mgronlun@34666 550 } // switch(refkind)
mgronlun@34666 551 // Keep the ref_index unchanged. It will be indirected at link-time.
jrose@5882 552 break;
mgronlun@34666 553 } // case MethodHandle
mgronlun@34666 554 case JVM_CONSTANT_MethodType: {
mgronlun@34666 555 const int ref_index = cp->method_type_index_at(index);
mgronlun@34666 556 check_property(valid_symbol_at(ref_index),
mgronlun@34666 557 "Invalid constant pool index %u in class file %s",
mgronlun@34666 558 ref_index, CHECK);
jrose@5882 559 break;
mgronlun@34666 560 }
psandoz@49210 561 case JVM_CONSTANT_Dynamic: {
psandoz@49210 562 const int name_and_type_ref_index =
psandoz@49210 563 cp->invoke_dynamic_name_and_type_ref_index_at(index);
psandoz@49210 564
psandoz@49210 565 check_property(valid_cp_range(name_and_type_ref_index, length) &&
psandoz@49210 566 cp->tag_at(name_and_type_ref_index).is_name_and_type(),
psandoz@49210 567 "Invalid constant pool index %u in class file %s",
psandoz@49210 568 name_and_type_ref_index, CHECK);
psandoz@49210 569 // bootstrap specifier index must be checked later,
psandoz@49210 570 // when BootstrapMethods attr is available
psandoz@49210 571
psandoz@49210 572 // Mark the constant pool as having a CONSTANT_Dynamic_info structure
psandoz@49210 573 cp->set_has_dynamic_constant();
psandoz@49210 574 break;
psandoz@49210 575 }
mgronlun@34666 576 case JVM_CONSTANT_InvokeDynamic: {
mgronlun@34666 577 const int name_and_type_ref_index =
mgronlun@34666 578 cp->invoke_dynamic_name_and_type_ref_index_at(index);
mgronlun@34666 579
mgronlun@34666 580 check_property(valid_cp_range(name_and_type_ref_index, length) &&
mgronlun@34666 581 cp->tag_at(name_and_type_ref_index).is_name_and_type(),
mgronlun@34666 582 "Invalid constant pool index %u in class file %s",
mgronlun@34666 583 name_and_type_ref_index, CHECK);
mgronlun@34666 584 // bootstrap specifier index must be checked later,
mgronlun@34666 585 // when BootstrapMethods attr is available
mgronlun@34666 586 break;
mgronlun@34666 587 }
mgronlun@34666 588 default: {
david@33105 589 fatal("bad constant pool tag value %u", cp->tag_at(index).value());
duke@1 590 ShouldNotReachHere();
duke@1 591 break;
mgronlun@34666 592 }
mgronlun@34666 593 } // switch(tag)
duke@1 594 } // end of for
duke@1 595
iklam@46427 596 _first_patched_klass_resolved_index = num_klasses;
iklam@46427 597 cp->allocate_resolved_klasses(_loader_data, num_klasses + _max_num_patched_klasses, CHECK);
iklam@46427 598
jrose@1550 599 if (_cp_patches != NULL) {
jrose@1550 600 // need to treat this_class specially...
iklam@46427 601
iklam@46427 602 // Add dummy utf8 entries in the space reserved for names of patched classes. We'll use "*"
iklam@46427 603 // for now. These will be replaced with actual names of the patched classes in patch_class().
iklam@46427 604 Symbol* s = vmSymbols::star_name();
iklam@46427 605 for (int n=_orig_cp_size; n<cp->length(); n++) {
iklam@46427 606 cp->symbol_at_put(n, s);
iklam@46427 607 }
iklam@46427 608
jrose@1550 609 int this_class_index;
jrose@1550 610 {
mgronlun@34666 611 stream->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len
mgronlun@34666 612 const u1* const mark = stream->current();
mgronlun@34666 613 stream->skip_u2_fast(1); // skip flags
mgronlun@34666 614 this_class_index = stream->get_u2_fast();
mgronlun@34666 615 stream->set_current(mark); // revert to mark
jrose@1550 616 }
jrose@1550 617
jrose@1550 618 for (index = 1; index < length; index++) { // Index 0 is unused
jrose@1550 619 if (has_cp_patch_at(index)) {
jrose@1550 620 guarantee_property(index != this_class_index,
mgronlun@34666 621 "Illegal constant pool patch to self at %d in class file %s",
mgronlun@34666 622 index, CHECK);
mgronlun@34666 623 patch_constant_pool(cp, index, cp_patch_at(index), CHECK);
jrose@1550 624 }
jrose@1550 625 }
jrose@1550 626 }
jrose@1550 627
duke@1 628 if (!_need_verify) {
mgronlun@34666 629 return;
duke@1 630 }
duke@1 631
duke@1 632 // second verification pass - checks the strings are of the right format.
jrose@1550 633 // but not yet to the other entries
duke@1 634 for (index = 1; index < length; index++) {
mgronlun@34666 635 const jbyte tag = cp->tag_at(index).value();
duke@1 636 switch (tag) {
duke@1 637 case JVM_CONSTANT_UnresolvedClass: {
mgronlun@34666 638 const Symbol* const class_name = cp->klass_name_at(index);
jrose@1550 639 // check the name, even if _cp_patches will overwrite it
mgronlun@34666 640 verify_legal_class_name(class_name, CHECK);
duke@1 641 break;
duke@1 642 }
kamg@5709 643 case JVM_CONSTANT_NameAndType: {
rprotacio@40920 644 if (_need_verify) {
mgronlun@34666 645 const int sig_index = cp->signature_ref_index_at(index);
mgronlun@34666 646 const int name_index = cp->name_ref_index_at(index);
mgronlun@34666 647 const Symbol* const name = cp->symbol_at(name_index);
mgronlun@34666 648 const Symbol* const sig = cp->symbol_at(sig_index);
hseigel@35218 649 guarantee_property(sig->utf8_length() != 0,
hseigel@35218 650 "Illegal zero length constant pool entry at %d in class %s",
hseigel@35218 651 sig_index, CHECK);
rprotacio@40920 652 guarantee_property(name->utf8_length() != 0,
rprotacio@40920 653 "Illegal zero length constant pool entry at %d in class %s",
rprotacio@40920 654 name_index, CHECK);
rprotacio@40920 655
kamg@5709 656 if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) {
rprotacio@40920 657 // Format check method name and signature
rprotacio@40920 658 verify_legal_method_name(name, CHECK);
mgronlun@34666 659 verify_legal_method_signature(name, sig, CHECK);
kamg@5709 660 } else {
rprotacio@40920 661 // Format check field name and signature
rprotacio@40920 662 verify_legal_field_name(name, CHECK);
mgronlun@34666 663 verify_legal_field_signature(name, sig, CHECK);
kamg@5709 664 }
kamg@5709 665 }
kamg@5709 666 break;
kamg@5709 667 }
psandoz@49210 668 case JVM_CONSTANT_Dynamic: {
psandoz@49210 669 const int name_and_type_ref_index =
psandoz@49210 670 cp->name_and_type_ref_index_at(index);
psandoz@49210 671 // already verified to be utf8
psandoz@49210 672 const int name_ref_index =
psandoz@49210 673 cp->name_ref_index_at(name_and_type_ref_index);
psandoz@49210 674 // already verified to be utf8
psandoz@49210 675 const int signature_ref_index =
psandoz@49210 676 cp->signature_ref_index_at(name_and_type_ref_index);
psandoz@49210 677 const Symbol* const name = cp->symbol_at(name_ref_index);
psandoz@49210 678 const Symbol* const signature = cp->symbol_at(signature_ref_index);
psandoz@49210 679 if (_need_verify) {
psandoz@49210 680 // CONSTANT_Dynamic's name and signature are verified above, when iterating NameAndType_info.
psandoz@49210 681 // Need only to be sure signature is non-zero length and the right type.
psandoz@49210 682 if (signature->utf8_length() == 0 ||
psandoz@49210 683 signature->byte_at(0) == JVM_SIGNATURE_FUNC) {
psandoz@49210 684 throwIllegalSignature("CONSTANT_Dynamic", name, signature, CHECK);
psandoz@49210 685 }
psandoz@49210 686 }
psandoz@49210 687 break;
psandoz@49210 688 }
jrose@9117 689 case JVM_CONSTANT_InvokeDynamic:
duke@1 690 case JVM_CONSTANT_Fieldref:
duke@1 691 case JVM_CONSTANT_Methodref:
duke@1 692 case JVM_CONSTANT_InterfaceMethodref: {
mgronlun@34666 693 const int name_and_type_ref_index =
mgronlun@34666 694 cp->name_and_type_ref_index_at(index);
duke@1 695 // already verified to be utf8
mgronlun@34666 696 const int name_ref_index =
mgronlun@34666 697 cp->name_ref_index_at(name_and_type_ref_index);
duke@1 698 // already verified to be utf8
mgronlun@34666 699 const int signature_ref_index =
mgronlun@34666 700 cp->signature_ref_index_at(name_and_type_ref_index);
mgronlun@34666 701 const Symbol* const name = cp->symbol_at(name_ref_index);
mgronlun@34666 702 const Symbol* const signature = cp->symbol_at(signature_ref_index);
duke@1 703 if (tag == JVM_CONSTANT_Fieldref) {
rprotacio@40920 704 if (_need_verify) {
rprotacio@40920 705 // Field name and signature are verified above, when iterating NameAndType_info.
rprotacio@40920 706 // Need only to be sure signature is non-zero length and the right type.
hseigel@35218 707 if (signature->utf8_length() == 0 ||
hseigel@35218 708 signature->byte_at(0) == JVM_SIGNATURE_FUNC) {
rprotacio@40920 709 throwIllegalSignature("Field", name, signature, CHECK);
kamg@5709 710 }
kamg@5709 711 }
duke@1 712 } else {
rprotacio@40920 713 if (_need_verify) {
rprotacio@40920 714 // Method name and signature are verified above, when iterating NameAndType_info.
rprotacio@40920 715 // Need only to be sure signature is non-zero length and the right type.
hseigel@35218 716 if (signature->utf8_length() == 0 ||
hseigel@35218 717 signature->byte_at(0) != JVM_SIGNATURE_FUNC) {
rprotacio@40920 718 throwIllegalSignature("Method", name, signature, CHECK);
kamg@5709 719 }
kamg@5709 720 }
rprotacio@40920 721 // 4509014: If a class method name begins with '<', it must be "<init>"
rprotacio@40920 722 const unsigned int name_len = name->utf8_length();
rprotacio@40920 723 if (tag == JVM_CONSTANT_Methodref &&
rprotacio@40920 724 name_len != 0 &&
rprotacio@40920 725 name->byte_at(0) == '<' &&
rprotacio@40920 726 name != vmSymbols::object_initializer_name()) {
rprotacio@40920 727 classfile_parse_error(
rprotacio@40920 728 "Bad method name at constant pool index %u in class file %s",
rprotacio@40920 729 name_ref_index, CHECK);
duke@1 730 }
duke@1 731 }
duke@1 732 break;
duke@1 733 }
jrose@5882 734 case JVM_CONSTANT_MethodHandle: {
mgronlun@34666 735 const int ref_index = cp->method_handle_index_at(index);
mgronlun@34666 736 const int ref_kind = cp->method_handle_ref_kind_at(index);
jrose@5882 737 switch (ref_kind) {
mgronlun@34666 738 case JVM_REF_invokeVirtual:
mgronlun@34666 739 case JVM_REF_invokeStatic:
mgronlun@34666 740 case JVM_REF_invokeSpecial:
mgronlun@34666 741 case JVM_REF_newInvokeSpecial: {
mgronlun@34666 742 const int name_and_type_ref_index =
mgronlun@34666 743 cp->name_and_type_ref_index_at(ref_index);
mgronlun@34666 744 const int name_ref_index =
mgronlun@34666 745 cp->name_ref_index_at(name_and_type_ref_index);
mgronlun@34666 746 const Symbol* const name = cp->symbol_at(name_ref_index);
jrose@5882 747 if (ref_kind == JVM_REF_newInvokeSpecial) {
coleenp@8076 748 if (name != vmSymbols::object_initializer_name()) {
jrose@5882 749 classfile_parse_error(
jrose@5882 750 "Bad constructor name at constant pool index %u in class file %s",
mgronlun@34666 751 name_ref_index, CHECK);
jrose@5882 752 }
jrose@5882 753 } else {
coleenp@8076 754 if (name == vmSymbols::object_initializer_name()) {
jrose@5882 755 classfile_parse_error(
jrose@5882 756 "Bad method name at constant pool index %u in class file %s",
mgronlun@34666 757 name_ref_index, CHECK);
jrose@5882 758 }
jrose@5882 759 }
mgronlun@34666 760 break;
jrose@5882 761 }
jrose@5882 762 // Other ref_kinds are already fully checked in previous pass.
mgronlun@34666 763 } // switch(ref_kind)
jrose@5882 764 break;
jrose@5882 765 }
jrose@5882 766 case JVM_CONSTANT_MethodType: {
mgronlun@34666 767 const Symbol* const no_name = vmSymbols::type_name(); // place holder
mgronlun@34666 768 const Symbol* const signature = cp->method_type_signature_at(index);
mgronlun@34666 769 verify_legal_method_signature(no_name, signature, CHECK);
jrose@5882 770 break;
jrose@5882 771 }
coleenp@8076 772 case JVM_CONSTANT_Utf8: {
coleenp@8076 773 assert(cp->symbol_at(index)->refcount() != 0, "count corrupted");
coleenp@8076 774 }
mgronlun@34666 775 } // switch(tag)
duke@1 776 } // end of for
duke@1 777 }
duke@1 778
coleenp@49945 779 Handle ClassFileParser::clear_cp_patch_at(int index) {
coleenp@49945 780 Handle patch = cp_patch_at(index);
coleenp@49945 781 _cp_patches->at_put(index, Handle());
coleenp@49945 782 assert(!has_cp_patch_at(index), "");
coleenp@49945 783 return patch;
coleenp@49945 784 }
coleenp@49945 785
iklam@46427 786 void ClassFileParser::patch_class(ConstantPool* cp, int class_index, Klass* k, Symbol* name) {
iklam@46427 787 int name_index = _orig_cp_size + _num_patched_klasses;
iklam@46427 788 int resolved_klass_index = _first_patched_klass_resolved_index + _num_patched_klasses;
iklam@46427 789
iklam@46427 790 cp->klass_at_put(class_index, name_index, resolved_klass_index, k, name);
iklam@46427 791 _num_patched_klasses ++;
iklam@46427 792 }
iklam@46427 793
mgronlun@34666 794 void ClassFileParser::patch_constant_pool(ConstantPool* cp,
mgronlun@34666 795 int index,
mgronlun@34666 796 Handle patch,
mgronlun@34666 797 TRAPS) {
mgronlun@34666 798 assert(cp != NULL, "invariant");
mgronlun@34666 799
jrose@1550 800 BasicType patch_type = T_VOID;
coleenp@13728 801
jrose@1550 802 switch (cp->tag_at(index).value()) {
jrose@1550 803
mgronlun@34666 804 case JVM_CONSTANT_UnresolvedClass: {
mgronlun@34666 805 // Patching a class means pre-resolving it.
mgronlun@34666 806 // The name in the constant pool is ignored.
mgronlun@34666 807 if (java_lang_Class::is_instance(patch())) {
mgronlun@34666 808 guarantee_property(!java_lang_Class::is_primitive(patch()),
mgronlun@34666 809 "Illegal class patch at %d in class file %s",
mgronlun@34666 810 index, CHECK);
iklam@46427 811 Klass* k = java_lang_Class::as_Klass(patch());
iklam@46427 812 patch_class(cp, index, k, k->name());
mgronlun@34666 813 } else {
mgronlun@34666 814 guarantee_property(java_lang_String::is_instance(patch()),
mgronlun@34666 815 "Illegal class patch at %d in class file %s",
mgronlun@34666 816 index, CHECK);
mgronlun@34666 817 Symbol* const name = java_lang_String::as_symbol(patch(), CHECK);
iklam@46427 818 patch_class(cp, index, NULL, name);
mgronlun@34666 819 }
mgronlun@34666 820 break;
jrose@1550 821 }
mgronlun@34666 822
mgronlun@34666 823 case JVM_CONSTANT_String: {
mgronlun@34666 824 // skip this patch and don't clear it. Needs the oop array for resolved
mgronlun@34666 825 // references to be created first.
mgronlun@34666 826 return;
mgronlun@34666 827 }
mgronlun@34666 828 case JVM_CONSTANT_Integer: patch_type = T_INT; goto patch_prim;
mgronlun@34666 829 case JVM_CONSTANT_Float: patch_type = T_FLOAT; goto patch_prim;
mgronlun@34666 830 case JVM_CONSTANT_Long: patch_type = T_LONG; goto patch_prim;
mgronlun@34666 831 case JVM_CONSTANT_Double: patch_type = T_DOUBLE; goto patch_prim;
mgronlun@34666 832 patch_prim:
jrose@1550 833 {
jrose@1550 834 jvalue value;
jrose@1550 835 BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
jrose@1550 836 guarantee_property(value_type == patch_type,
jrose@1550 837 "Illegal primitive patch at %d in class file %s",
jrose@1550 838 index, CHECK);
jrose@1550 839 switch (value_type) {
mgronlun@34666 840 case T_INT: cp->int_at_put(index, value.i); break;
mgronlun@34666 841 case T_FLOAT: cp->float_at_put(index, value.f); break;
mgronlun@34666 842 case T_LONG: cp->long_at_put(index, value.j); break;
mgronlun@34666 843 case T_DOUBLE: cp->double_at_put(index, value.d); break;
mgronlun@34666 844 default: assert(false, "");
jrose@1550 845 }
mgronlun@34666 846 } // end patch_prim label
mgronlun@34666 847 break;
mgronlun@34666 848
mgronlun@34666 849 default: {
mgronlun@34666 850 // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
mgronlun@34666 851 guarantee_property(!has_cp_patch_at(index),
mgronlun@34666 852 "Illegal unexpected patch at %d in class file %s",
mgronlun@34666 853 index, CHECK);
mgronlun@34666 854 return;
jrose@1550 855 }
mgronlun@34666 856 } // end of switch(tag)
jrose@1550 857
jrose@1550 858 // On fall-through, mark the patch as used.
jrose@1550 859 clear_cp_patch_at(index);
jrose@1550 860 }
duke@1 861 class NameSigHash: public ResourceObj {
duke@1 862 public:
mgronlun@34666 863 const Symbol* _name; // name
mgronlun@34666 864 const Symbol* _sig; // signature
mgronlun@34666 865 NameSigHash* _next; // Next entry in hash table
duke@1 866 };
duke@1 867
mgronlun@34666 868 static const int HASH_ROW_SIZE = 256;
mgronlun@34666 869
mgronlun@34666 870 static unsigned int hash(const Symbol* name, const Symbol* sig) {
duke@1 871 unsigned int raw_hash = 0;
duke@1 872 raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2);
duke@1 873 raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize;
duke@1 874
duke@1 875 return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE;
duke@1 876 }
duke@1 877
duke@1 878
mgronlun@34666 879 static void initialize_hashtable(NameSigHash** table) {
duke@1 880 memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE);
duke@1 881 }
duke@1 882 // Return false if the name/sig combination is found in table.
duke@1 883 // Return true if no duplicate is found. And name/sig is added as a new entry in table.
duke@1 884 // The old format checker uses heap sort to find duplicates.
duke@1 885 // NOTE: caller should guarantee that GC doesn't happen during the life cycle
coleenp@8076 886 // of table since we don't expect Symbol*'s to move.
mgronlun@34666 887 static bool put_after_lookup(const Symbol* name, const Symbol* sig, NameSigHash** table) {
duke@1 888 assert(name != NULL, "name in constant pool is NULL");
duke@1 889
duke@1 890 // First lookup for duplicates
duke@1 891 int index = hash(name, sig);
duke@1 892 NameSigHash* entry = table[index];
duke@1 893 while (entry != NULL) {
duke@1 894 if (entry->_name == name && entry->_sig == sig) {
duke@1 895 return false;
duke@1 896 }
duke@1 897 entry = entry->_next;
duke@1 898 }
duke@1 899
duke@1 900 // No duplicate is found, allocate a new entry and fill it.
duke@1 901 entry = new NameSigHash();
duke@1 902 entry->_name = name;
duke@1 903 entry->_sig = sig;
duke@1 904
duke@1 905 // Insert into hash table
duke@1 906 entry->_next = table[index];
duke@1 907 table[index] = entry;
duke@1 908
duke@1 909 return true;
duke@1 910 }
duke@1 911
mgronlun@34666 912 // Side-effects: populates the _local_interfaces field
mgronlun@34666 913 void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
mgronlun@34666 914 const int itfs_len,
mgronlun@34666 915 ConstantPool* const cp,
dholmes@41669 916 bool* const has_nonstatic_concrete_methods,
mgronlun@34666 917 TRAPS) {
mgronlun@34666 918 assert(stream != NULL, "invariant");
mgronlun@34666 919 assert(cp != NULL, "invariant");
dholmes@41669 920 assert(has_nonstatic_concrete_methods != NULL, "invariant");
mgronlun@34666 921
mgronlun@34666 922 if (itfs_len == 0) {
coleenp@15935 923 _local_interfaces = Universe::the_empty_klass_array();
coleenp@15935 924 } else {
mgronlun@34666 925 assert(itfs_len > 0, "only called for len>0");
mgronlun@34666 926 _local_interfaces = MetadataFactory::new_array<Klass*>(_loader_data, itfs_len, NULL, CHECK);
coleenp@15935 927
coleenp@15935 928 int index;
mgronlun@34666 929 for (index = 0; index < itfs_len; index++) {
mgronlun@34666 930 const u2 interface_index = stream->get_u2(CHECK);
coleenp@46329 931 Klass* interf;
coleenp@15935 932 check_property(
coleenp@15935 933 valid_klass_reference_at(interface_index),
coleenp@15935 934 "Interface name has bad constant pool index %u in class file %s",
mgronlun@34666 935 interface_index, CHECK);
mgronlun@34666 936 if (cp->tag_at(interface_index).is_klass()) {
coleenp@46329 937 interf = cp->resolved_klass_at(interface_index);
coleenp@15935 938 } else {
mgronlun@34666 939 Symbol* const unresolved_klass = cp->klass_name_at(interface_index);
coleenp@15935 940
coleenp@15935 941 // Don't need to check legal name because it's checked when parsing constant pool.
coleenp@15935 942 // But need to make sure it's not an array type.
coleenp@15935 943 guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
mgronlun@34666 944 "Bad interface name in class file %s", CHECK);
coleenp@15935 945
coleenp@15935 946 // Call resolve_super so classcircularity is checked
coleenp@46329 947 interf = SystemDictionary::resolve_super_or_fail(
coleenp@46329 948 _class_name,
mgronlun@34666 949 unresolved_klass,
coleenp@46271 950 Handle(THREAD, _loader_data->class_loader()),
mgronlun@34666 951 _protection_domain,
mgronlun@34666 952 false,
mgronlun@34666 953 CHECK);
coleenp@15935 954 }
coleenp@15935 955
coleenp@46329 956 if (!interf->is_interface()) {
mgronlun@34666 957 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
lfoltan@51395 958 err_msg("class %s can not implement %s, because it is not an interface (%s)",
goetz@51267 959 _class_name->as_klass_external_name(),
lfoltan@51395 960 interf->external_name(),
lfoltan@51395 961 interf->class_in_module_of_loader()));
coleenp@15935 962 }
mgronlun@34666 963
coleenp@46329 964 if (InstanceKlass::cast(interf)->has_nonstatic_concrete_methods()) {
dholmes@41669 965 *has_nonstatic_concrete_methods = true;
coleenp@15935 966 }
coleenp@46329 967 _local_interfaces->at_put(index, interf);
jrose@1550 968 }
duke@1 969
mgronlun@34666 970 if (!_need_verify || itfs_len <= 1) {
mgronlun@34666 971 return;
duke@1 972 }
coleenp@15935 973
coleenp@15935 974 // Check if there's any duplicates in interfaces
coleenp@15935 975 ResourceMark rm(THREAD);
mgronlun@34666 976 NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,
mgronlun@34666 977 NameSigHash*,
mgronlun@34666 978 HASH_ROW_SIZE);
coleenp@15935 979 initialize_hashtable(interface_names);
coleenp@15935 980 bool dup = false;
shshahma@46301 981 const Symbol* name = NULL;
coleenp@15935 982 {
david@35492 983 debug_only(NoSafepointVerifier nsv;)
mgronlun@34666 984 for (index = 0; index < itfs_len; index++) {
mgronlun@34666 985 const Klass* const k = _local_interfaces->at(index);
shshahma@46301 986 name = InstanceKlass::cast(k)->name();
coleenp@15935 987 // If no duplicates, add (name, NULL) in hashtable interface_names.
coleenp@15935 988 if (!put_after_lookup(name, NULL, interface_names)) {
coleenp@15935 989 dup = true;
coleenp@15935 990 break;
coleenp@15935 991 }
duke@1 992 }
duke@1 993 }
coleenp@15935 994 if (dup) {
shshahma@46301 995 classfile_parse_error("Duplicate interface name \"%s\" in class file %s",
shshahma@46301 996 name->as_C_string(), CHECK);
coleenp@15935 997 }
duke@1 998 }
duke@1 999 }
duke@1 1000
mgronlun@34666 1001 void ClassFileParser::verify_constantvalue(const ConstantPool* const cp,
mgronlun@34666 1002 int constantvalue_index,
mgronlun@34666 1003 int signature_index,
mgronlun@34666 1004 TRAPS) const {
duke@1 1005 // Make sure the constant pool entry is of a type appropriate to this field
duke@1 1006 guarantee_property(
duke@1 1007 (constantvalue_index > 0 &&
mgronlun@34666 1008 constantvalue_index < cp->length()),
duke@1 1009 "Bad initial value index %u in ConstantValue attribute in class file %s",
duke@1 1010 constantvalue_index, CHECK);
mgronlun@34666 1011
mgronlun@34666 1012 const constantTag value_type = cp->tag_at(constantvalue_index);
mgronlun@34666 1013 switch(cp->basic_type_for_signature_at(signature_index)) {
mgronlun@34666 1014 case T_LONG: {
mgronlun@34666 1015 guarantee_property(value_type.is_long(),
mgronlun@34666 1016 "Inconsistent constant value type in class file %s",
mgronlun@34666 1017 CHECK);
duke@1 1018 break;
mgronlun@34666 1019 }
mgronlun@34666 1020 case T_FLOAT: {
mgronlun@34666 1021 guarantee_property(value_type.is_float(),
mgronlun@34666 1022 "Inconsistent constant value type in class file %s",
mgronlun@34666 1023 CHECK);
duke@1 1024 break;
mgronlun@34666 1025 }
mgronlun@34666 1026 case T_DOUBLE: {
mgronlun@34666 1027 guarantee_property(value_type.is_double(),
mgronlun@34666 1028 "Inconsistent constant value type in class file %s",
mgronlun@34666 1029 CHECK);
duke@1 1030 break;
mgronlun@34666 1031 }
mgronlun@34666 1032 case T_BYTE:
mgronlun@34666 1033 case T_CHAR:
mgronlun@34666 1034 case T_SHORT:
mgronlun@34666 1035 case T_BOOLEAN:
mgronlun@34666 1036 case T_INT: {
mgronlun@34666 1037 guarantee_property(value_type.is_int(),
mgronlun@34666 1038 "Inconsistent constant value type in class file %s",
mgronlun@34666 1039 CHECK);
duke@1 1040 break;
mgronlun@34666 1041 }
mgronlun@34666 1042 case T_OBJECT: {
mgronlun@34666 1043 guarantee_property((cp->symbol_at(signature_index)->equals("Ljava/lang/String;")
coleenp@13728 1044 && value_type.is_string()),
mgronlun@34666 1045 "Bad string initial value in class file %s",
mgronlun@34666 1046 CHECK);
mgronlun@34666 1047 break;
mgronlun@34666 1048 }
mgronlun@34666 1049 default: {
mgronlun@34666 1050 classfile_parse_error("Unable to set initial value %u in class file %s",
mgronlun@34666 1051 constantvalue_index,
mgronlun@34666 1052 CHECK);
mgronlun@34666 1053 }
mgronlun@34666 1054 }
mgronlun@34666 1055 }
mgronlun@34666 1056
mgronlun@34666 1057 class AnnotationCollector : public ResourceObj{
mgronlun@34666 1058 public:
mgronlun@34666 1059 enum Location { _in_field, _in_method, _in_class };
mgronlun@34666 1060 enum ID {
mgronlun@34666 1061 _unknown = 0,
mgronlun@34666 1062 _method_CallerSensitive,
mgronlun@34666 1063 _method_ForceInline,
mgronlun@34666 1064 _method_DontInline,
mgronlun@34666 1065 _method_InjectedProfile,
mgronlun@34666 1066 _method_LambdaForm_Compiled,
mgronlun@34666 1067 _method_LambdaForm_Hidden,
mgronlun@34666 1068 _method_HotSpotIntrinsicCandidate,
mgronlun@34666 1069 _jdk_internal_vm_annotation_Contended,
mgronlun@34666 1070 _field_Stable,
fparain@35071 1071 _jdk_internal_vm_annotation_ReservedStackAccess,
mgronlun@34666 1072 _annotation_LIMIT
mgronlun@34666 1073 };
mgronlun@34666 1074 const Location _location;
mgronlun@34666 1075 int _annotations_present;
mgronlun@34666 1076 u2 _contended_group;
mgronlun@34666 1077
mgronlun@34666 1078 AnnotationCollector(Location location)
mgronlun@34666 1079 : _location(location), _annotations_present(0)
mgronlun@34666 1080 {
mgronlun@34666 1081 assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
mgronlun@34666 1082 }
mgronlun@34666 1083 // If this annotation name has an ID, report it (or _none).
mgronlun@34666 1084 ID annotation_index(const ClassLoaderData* loader_data, const Symbol* name);
mgronlun@34666 1085 // Set the annotation name:
mgronlun@34666 1086 void set_annotation(ID id) {
mgronlun@34666 1087 assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
mgronlun@34666 1088 _annotations_present |= nth_bit((int)id);
mgronlun@34666 1089 }
mgronlun@34666 1090
mgronlun@34666 1091 void remove_annotation(ID id) {
mgronlun@34666 1092 assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
mgronlun@34666 1093 _annotations_present &= ~nth_bit((int)id);
mgronlun@34666 1094 }
mgronlun@34666 1095
mgronlun@34666 1096 // Report if the annotation is present.
mgronlun@34666 1097 bool has_any_annotations() const { return _annotations_present != 0; }
mgronlun@34666 1098 bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; }
mgronlun@34666 1099
mgronlun@34666 1100 void set_contended_group(u2 group) { _contended_group = group; }
mgronlun@34666 1101 u2 contended_group() const { return _contended_group; }
mgronlun@34666 1102
mgronlun@34666 1103 bool is_contended() const { return has_annotation(_jdk_internal_vm_annotation_Contended); }
mgronlun@34666 1104
mgronlun@34666 1105 void set_stable(bool stable) { set_annotation(_field_Stable); }
mgronlun@34666 1106 bool is_stable() const { return has_annotation(_field_Stable); }
mgronlun@34666 1107 };
mgronlun@34666 1108
mgronlun@34666 1109 // This class also doubles as a holder for metadata cleanup.
mgronlun@34666 1110 class ClassFileParser::FieldAnnotationCollector : public AnnotationCollector {
mgronlun@34666 1111 private:
mgronlun@34666 1112 ClassLoaderData* _loader_data;
mgronlun@34666 1113 AnnotationArray* _field_annotations;
mgronlun@34666 1114 AnnotationArray* _field_type_annotations;
mgronlun@34666 1115 public:
mgronlun@34666 1116 FieldAnnotationCollector(ClassLoaderData* loader_data) :
mgronlun@34666 1117 AnnotationCollector(_in_field),
mgronlun@34666 1118 _loader_data(loader_data),
mgronlun@34666 1119 _field_annotations(NULL),
mgronlun@34666 1120 _field_type_annotations(NULL) {}
mgronlun@34666 1121 ~FieldAnnotationCollector();
mgronlun@34666 1122 void apply_to(FieldInfo* f);
mgronlun@34666 1123 AnnotationArray* field_annotations() { return _field_annotations; }
mgronlun@34666 1124 AnnotationArray* field_type_annotations() { return _field_type_annotations; }
mgronlun@34666 1125
mgronlun@34666 1126 void set_field_annotations(AnnotationArray* a) { _field_annotations = a; }
mgronlun@34666 1127 void set_field_type_annotations(AnnotationArray* a) { _field_type_annotations = a; }
mgronlun@34666 1128 };
mgronlun@34666 1129
mgronlun@34666 1130 class MethodAnnotationCollector : public AnnotationCollector{
mgronlun@34666 1131 public:
mgronlun@34666 1132 MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
coleenp@46727 1133 void apply_to(const methodHandle& m);
mgronlun@34666 1134 };
mgronlun@34666 1135
mgronlun@34666 1136 class ClassFileParser::ClassAnnotationCollector : public AnnotationCollector{
mgronlun@34666 1137 public:
mgronlun@34666 1138 ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
mgronlun@34666 1139 void apply_to(InstanceKlass* ik);
mgronlun@34666 1140 };
mgronlun@34666 1141
mgronlun@34666 1142
mgronlun@34666 1143 static int skip_annotation_value(const u1*, int, int); // fwd decl
mgronlun@34666 1144
rprotacio@43177 1145 // Safely increment index by val if does not pass limit
rprotacio@43177 1146 #define SAFE_ADD(index, limit, val) \
rprotacio@43177 1147 if (index >= limit - val) return limit; \
rprotacio@43177 1148 index += val;
rprotacio@43177 1149
mgronlun@34666 1150 // Skip an annotation. Return >=limit if there is any problem.
mgronlun@34666 1151 static int skip_annotation(const u1* buffer, int limit, int index) {
mgronlun@34666 1152 assert(buffer != NULL, "invariant");
mgronlun@34666 1153 // annotation := atype:u2 do(nmem:u2) {member:u2 value}
mgronlun@34666 1154 // value := switch (tag:u1) { ... }
rprotacio@43177 1155 SAFE_ADD(index, limit, 4); // skip atype and read nmem
mgronlun@34666 1156 int nmem = Bytes::get_Java_u2((address)buffer + index - 2);
mgronlun@34666 1157 while (--nmem >= 0 && index < limit) {
rprotacio@43177 1158 SAFE_ADD(index, limit, 2); // skip member
mgronlun@34666 1159 index = skip_annotation_value(buffer, limit, index);
mgronlun@34666 1160 }
mgronlun@34666 1161 return index;
mgronlun@34666 1162 }
mgronlun@34666 1163
mgronlun@34666 1164 // Skip an annotation value. Return >=limit if there is any problem.
mgronlun@34666 1165 static int skip_annotation_value(const u1* buffer, int limit, int index) {
mgronlun@34666 1166 assert(buffer != NULL, "invariant");
mgronlun@34666 1167
mgronlun@34666 1168 // value := switch (tag:u1) {
mgronlun@34666 1169 // case B, C, I, S, Z, D, F, J, c: con:u2;
mgronlun@34666 1170 // case e: e_class:u2 e_name:u2;
mgronlun@34666 1171 // case s: s_con:u2;
mgronlun@34666 1172 // case [: do(nval:u2) {value};
mgronlun@34666 1173 // case @: annotation;
mgronlun@34666 1174 // case s: s_con:u2;
mgronlun@34666 1175 // }
rprotacio@43177 1176 SAFE_ADD(index, limit, 1); // read tag
mgronlun@34666 1177 const u1 tag = buffer[index - 1];
mgronlun@34666 1178 switch (tag) {
mgronlun@34666 1179 case 'B':
mgronlun@34666 1180 case 'C':
mgronlun@34666 1181 case 'I':
mgronlun@34666 1182 case 'S':
mgronlun@34666 1183 case 'Z':
mgronlun@34666 1184 case 'D':
mgronlun@34666 1185 case 'F':
mgronlun@34666 1186 case 'J':
mgronlun@34666 1187 case 'c':
mgronlun@34666 1188 case 's':
rprotacio@43177 1189 SAFE_ADD(index, limit, 2); // skip con or s_con
mgronlun@34666 1190 break;
mgronlun@34666 1191 case 'e':
rprotacio@43177 1192 SAFE_ADD(index, limit, 4); // skip e_class, e_name
mgronlun@34666 1193 break;
mgronlun@34666 1194 case '[':
mgronlun@34666 1195 {
rprotacio@43177 1196 SAFE_ADD(index, limit, 2); // read nval
mgronlun@34666 1197 int nval = Bytes::get_Java_u2((address)buffer + index - 2);
mgronlun@34666 1198 while (--nval >= 0 && index < limit) {
mgronlun@34666 1199 index = skip_annotation_value(buffer, limit, index);
mgronlun@34666 1200 }
mgronlun@34666 1201 }
mgronlun@34666 1202 break;
mgronlun@34666 1203 case '@':
mgronlun@34666 1204 index = skip_annotation(buffer, limit, index);
duke@1 1205 break;
duke@1 1206 default:
mgronlun@34666 1207 return limit; // bad tag byte
mgronlun@34666 1208 }
mgronlun@34666 1209 return index;
mgronlun@34666 1210 }
mgronlun@34666 1211
mgronlun@34666 1212 // Sift through annotations, looking for those significant to the VM:
mgronlun@34666 1213 static void parse_annotations(const ConstantPool* const cp,
mgronlun@34666 1214 const u1* buffer, int limit,
mgronlun@34666 1215 AnnotationCollector* coll,
mgronlun@34666 1216 ClassLoaderData* loader_data,
mgronlun@34666 1217 TRAPS) {
mgronlun@34666 1218
mgronlun@34666 1219 assert(cp != NULL, "invariant");
mgronlun@34666 1220 assert(buffer != NULL, "invariant");
mgronlun@34666 1221 assert(coll != NULL, "invariant");
mgronlun@34666 1222 assert(loader_data != NULL, "invariant");
mgronlun@34666 1223
mgronlun@34666 1224 // annotations := do(nann:u2) {annotation}
rprotacio@43177 1225 int index = 2; // read nann
rprotacio@43177 1226 if (index >= limit) return;
mgronlun@34666 1227 int nann = Bytes::get_Java_u2((address)buffer + index - 2);
mgronlun@34666 1228 enum { // initial annotation layout
mgronlun@34666 1229 atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
mgronlun@34666 1230 count_off = 2, // u2 such as 1 (one value)
mgronlun@34666 1231 member_off = 4, // utf8 such as 'value'
mgronlun@34666 1232 tag_off = 6, // u1 such as 'c' (type) or 'e' (enum)
mgronlun@34666 1233 e_tag_val = 'e',
mgronlun@34666 1234 e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
mgronlun@34666 1235 e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
mgronlun@34666 1236 e_size = 11, // end of 'e' annotation
mgronlun@34666 1237 c_tag_val = 'c', // payload is type
mgronlun@34666 1238 c_con_off = 7, // utf8 payload, such as 'I'
mgronlun@34666 1239 c_size = 9, // end of 'c' annotation
mgronlun@34666 1240 s_tag_val = 's', // payload is String
mgronlun@34666 1241 s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;'
mgronlun@34666 1242 s_size = 9,
mgronlun@34666 1243 min_size = 6 // smallest possible size (zero members)
mgronlun@34666 1244 };
rprotacio@43177 1245 // Cannot add min_size to index in case of overflow MAX_INT
rprotacio@43177 1246 while ((--nann) >= 0 && (index - 2 <= limit - min_size)) {
mgronlun@34666 1247 int index0 = index;
mgronlun@34666 1248 index = skip_annotation(buffer, limit, index);
mgronlun@34666 1249 const u1* const abase = buffer + index0;
mgronlun@34666 1250 const int atype = Bytes::get_Java_u2((address)abase + atype_off);
mgronlun@34666 1251 const int count = Bytes::get_Java_u2((address)abase + count_off);
mgronlun@34666 1252 const Symbol* const aname = check_symbol_at(cp, atype);
mgronlun@34666 1253 if (aname == NULL) break; // invalid annotation name
mgronlun@34666 1254 const Symbol* member = NULL;
mgronlun@34666 1255 if (count >= 1) {
mgronlun@34666 1256 const int member_index = Bytes::get_Java_u2((address)abase + member_off);
mgronlun@34666 1257 member = check_symbol_at(cp, member_index);
mgronlun@34666 1258 if (member == NULL) break; // invalid member name
mgronlun@34666 1259 }
mgronlun@34666 1260
mgronlun@34666 1261 // Here is where parsing particular annotations will take place.
mgronlun@34666 1262 AnnotationCollector::ID id = coll->annotation_index(loader_data, aname);
mgronlun@34666 1263 if (AnnotationCollector::_unknown == id) continue;
mgronlun@34666 1264 coll->set_annotation(id);
mgronlun@34666 1265
mgronlun@34666 1266 if (AnnotationCollector::_jdk_internal_vm_annotation_Contended == id) {
mgronlun@34666 1267 // @Contended can optionally specify the contention group.
mgronlun@34666 1268 //
mgronlun@34666 1269 // Contended group defines the equivalence class over the fields:
mgronlun@34666 1270 // the fields within the same contended group are not treated distinct.
mgronlun@34666 1271 // The only exception is default group, which does not incur the
mgronlun@34666 1272 // equivalence. Naturally, contention group for classes is meaningless.
mgronlun@34666 1273 //
mgronlun@34666 1274 // While the contention group is specified as String, annotation
mgronlun@34666 1275 // values are already interned, and we might as well use the constant
mgronlun@34666 1276 // pool index as the group tag.
mgronlun@34666 1277 //
mgronlun@34666 1278 u2 group_index = 0; // default contended group
mgronlun@34666 1279 if (count == 1
mgronlun@34666 1280 && s_size == (index - index0) // match size
mgronlun@34666 1281 && s_tag_val == *(abase + tag_off)
mgronlun@34666 1282 && member == vmSymbols::value_name()) {
mgronlun@34666 1283 group_index = Bytes::get_Java_u2((address)abase + s_con_off);
mgronlun@34666 1284 if (cp->symbol_at(group_index)->utf8_length() == 0) {
mgronlun@34666 1285 group_index = 0; // default contended group
mgronlun@34666 1286 }
mgronlun@34666 1287 }
mgronlun@34666 1288 coll->set_contended_group(group_index);
mgronlun@34666 1289 }
duke@1 1290 }
duke@1 1291 }
duke@1 1292
duke@1 1293
duke@1 1294 // Parse attributes for a field.
mgronlun@34666 1295 void ClassFileParser::parse_field_attributes(const ClassFileStream* const cfs,
mgronlun@34666 1296 u2 attributes_count,
duke@1 1297 bool is_static, u2 signature_index,
mgronlun@34666 1298 u2* const constantvalue_index_addr,
mgronlun@34666 1299 bool* const is_synthetic_addr,
mgronlun@34666 1300 u2* const generic_signature_index_addr,
jrose@13291 1301 ClassFileParser::FieldAnnotationCollector* parsed_annotations,
duke@1 1302 TRAPS) {
mgronlun@34666 1303 assert(cfs != NULL, "invariant");
mgronlun@34666 1304 assert(constantvalue_index_addr != NULL, "invariant");
mgronlun@34666 1305 assert(is_synthetic_addr != NULL, "invariant");
mgronlun@34666 1306 assert(generic_signature_index_addr != NULL, "invariant");
mgronlun@34666 1307 assert(parsed_annotations != NULL, "invariant");
mgronlun@34666 1308 assert(attributes_count > 0, "attributes_count should be greater than 0");
mgronlun@34666 1309
duke@1 1310 u2 constantvalue_index = 0;
duke@1 1311 u2 generic_signature_index = 0;
duke@1 1312 bool is_synthetic = false;
mgronlun@34666 1313 const u1* runtime_visible_annotations = NULL;
duke@1 1314 int runtime_visible_annotations_length = 0;
mgronlun@34666 1315 const u1* runtime_invisible_annotations = NULL;
duke@1 1316 int runtime_invisible_annotations_length = 0;
mgronlun@34666 1317 const u1* runtime_visible_type_annotations = NULL;
stefank@15097 1318 int runtime_visible_type_annotations_length = 0;
mgronlun@34666 1319 const u1* runtime_invisible_type_annotations = NULL;
stefank@15097 1320 int runtime_invisible_type_annotations_length = 0;
hseigel@24432 1321 bool runtime_invisible_annotations_exists = false;
hseigel@19954 1322 bool runtime_invisible_type_annotations_exists = false;
mgronlun@34666 1323 const ConstantPool* const cp = _cp;
mgronlun@34666 1324
duke@1 1325 while (attributes_count--) {
duke@1 1326 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
mgronlun@34666 1327 const u2 attribute_name_index = cfs->get_u2_fast();
mgronlun@34666 1328 const u4 attribute_length = cfs->get_u4_fast();
coleenp@15935 1329 check_property(valid_symbol_at(attribute_name_index),
duke@1 1330 "Invalid field attribute index %u in class file %s",
duke@1 1331 attribute_name_index,
duke@1 1332 CHECK);
mgronlun@34666 1333
mgronlun@34666 1334 const Symbol* const attribute_name = cp->symbol_at(attribute_name_index);
duke@1 1335 if (is_static && attribute_name == vmSymbols::tag_constant_value()) {
duke@1 1336 // ignore if non-static
duke@1 1337 if (constantvalue_index != 0) {
duke@1 1338 classfile_parse_error("Duplicate ConstantValue attribute in class file %s", CHECK);
duke@1 1339 }
duke@1 1340 check_property(
duke@1 1341 attribute_length == 2,
duke@1 1342 "Invalid ConstantValue field attribute length %u in class file %s",
duke@1 1343 attribute_length, CHECK);
mgronlun@34666 1344
duke@1 1345 constantvalue_index = cfs->get_u2(CHECK);
duke@1 1346 if (_need_verify) {
mgronlun@34666 1347 verify_constantvalue(cp, constantvalue_index, signature_index, CHECK);
duke@1 1348 }
duke@1 1349 } else if (attribute_name == vmSymbols::tag_synthetic()) {
duke@1 1350 if (attribute_length != 0) {
duke@1 1351 classfile_parse_error(
duke@1 1352 "Invalid Synthetic field attribute length %u in class file %s",
duke@1 1353 attribute_length, CHECK);
duke@1 1354 }
duke@1 1355 is_synthetic = true;
duke@1 1356 } else if (attribute_name == vmSymbols::tag_deprecated()) { // 4276120
duke@1 1357 if (attribute_length != 0) {
duke@1 1358 classfile_parse_error(
duke@1 1359 "Invalid Deprecated field attribute length %u in class file %s",
duke@1 1360 attribute_length, CHECK);
duke@1 1361 }
duke@1 1362 } else if (_major_version >= JAVA_1_5_VERSION) {
duke@1 1363 if (attribute_name == vmSymbols::tag_signature()) {
hseigel@44243 1364 if (generic_signature_index != 0) {
hseigel@44243 1365 classfile_parse_error(
hseigel@44243 1366 "Multiple Signature attributes for field in class file %s", CHECK);
hseigel@44243 1367 }
duke@1 1368 if (attribute_length != 2) {
duke@1 1369 classfile_parse_error(
duke@1 1370 "Wrong size %u for field's Signature attribute in class file %s",
duke@1 1371 attribute_length, CHECK);
duke@1 1372 }
mgronlun@34666 1373 generic_signature_index = parse_generic_signature_attribute(cfs, CHECK);
duke@1 1374 } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
hseigel@24432 1375 if (runtime_visible_annotations != NULL) {
hseigel@24432 1376 classfile_parse_error(
hseigel@24432 1377 "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", CHECK);
hseigel@24432 1378 }
duke@1 1379 runtime_visible_annotations_length = attribute_length;
mikael@46504 1380 runtime_visible_annotations = cfs->current();
duke@1 1381 assert(runtime_visible_annotations != NULL, "null visible annotations");
rprotacio@43177 1382 cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
mgronlun@34666 1383 parse_annotations(cp,
mgronlun@34666 1384 runtime_visible_annotations,
jwilhelm@15193 1385 runtime_visible_annotations_length,
mgronlun@34666 1386 parsed_annotations,
mgronlun@34666 1387 _loader_data,
mgronlun@34666 1388 CHECK);
rprotacio@43177 1389 cfs->skip_u1_fast(runtime_visible_annotations_length);
hseigel@24432 1390 } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
hseigel@24432 1391 if (runtime_invisible_annotations_exists) {
hseigel@24432 1392 classfile_parse_error(
hseigel@24432 1393 "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", CHECK);
hseigel@24432 1394 }
hseigel@24432 1395 runtime_invisible_annotations_exists = true;
hseigel@24432 1396 if (PreserveAllAnnotations) {
hseigel@24432 1397 runtime_invisible_annotations_length = attribute_length;
mikael@46504 1398 runtime_invisible_annotations = cfs->current();
hseigel@24432 1399 assert(runtime_invisible_annotations != NULL, "null invisible annotations");
hseigel@24432 1400 }
hseigel@24432 1401 cfs->skip_u1(attribute_length, CHECK);
stefank@15097 1402 } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
hseigel@19954 1403 if (runtime_visible_type_annotations != NULL) {
hseigel@19954 1404 classfile_parse_error(
hseigel@19954 1405 "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK);
hseigel@19954 1406 }
stefank@15097 1407 runtime_visible_type_annotations_length = attribute_length;
mikael@46504 1408 runtime_visible_type_annotations = cfs->current();
stefank@15097 1409 assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
stefank@15097 1410 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
hseigel@19954 1411 } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
hseigel@19954 1412 if (runtime_invisible_type_annotations_exists) {
hseigel@19954 1413 classfile_parse_error(
hseigel@19954 1414 "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK);
hseigel@19954 1415 } else {
hseigel@19954 1416 runtime_invisible_type_annotations_exists = true;
hseigel@19954 1417 }
hseigel@19954 1418 if (PreserveAllAnnotations) {
hseigel@19954 1419 runtime_invisible_type_annotations_length = attribute_length;
mikael@46504 1420 runtime_invisible_type_annotations = cfs->current();
hseigel@19954 1421 assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
hseigel@19954 1422 }
hseigel@19954 1423 cfs->skip_u1(attribute_length, CHECK);
duke@1 1424 } else {
duke@1 1425 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
duke@1 1426 }
duke@1 1427 } else {
duke@1 1428 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
duke@1 1429 }
duke@1 1430 }
duke@1 1431
duke@1 1432 *constantvalue_index_addr = constantvalue_index;
duke@1 1433 *is_synthetic_addr = is_synthetic;
duke@1 1434 *generic_signature_index_addr = generic_signature_index;
coleenp@15935 1435 AnnotationArray* a = assemble_annotations(runtime_visible_annotations,
duke@1 1436 runtime_visible_annotations_length,
duke@1 1437 runtime_invisible_annotations,
duke@1 1438 runtime_invisible_annotations_length,
duke@1 1439 CHECK);
coleenp@15935 1440 parsed_annotations->set_field_annotations(a);
coleenp@15935 1441 a = assemble_annotations(runtime_visible_type_annotations,
coleenp@15935 1442 runtime_visible_type_annotations_length,
coleenp@15935 1443 runtime_invisible_type_annotations,
coleenp@15935 1444 runtime_invisible_type_annotations_length,
coleenp@15935 1445 CHECK);
coleenp@15935 1446 parsed_annotations->set_field_type_annotations(a);
duke@1 1447 return;
duke@1 1448 }
duke@1 1449
duke@1 1450
duke@1 1451 // Field allocation types. Used for computing field offsets.
duke@1 1452
duke@1 1453 enum FieldAllocationType {
duke@1 1454 STATIC_OOP, // Oops
duke@1 1455 STATIC_BYTE, // Boolean, Byte, char
duke@1 1456 STATIC_SHORT, // shorts
duke@1 1457 STATIC_WORD, // ints
never@10546 1458 STATIC_DOUBLE, // aligned long or double
duke@1 1459 NONSTATIC_OOP,
duke@1 1460 NONSTATIC_BYTE,
duke@1 1461 NONSTATIC_SHORT,
duke@1 1462 NONSTATIC_WORD,
duke@1 1463 NONSTATIC_DOUBLE,
never@10546 1464 MAX_FIELD_ALLOCATION_TYPE,
never@10546 1465 BAD_ALLOCATION_TYPE = -1
duke@1 1466 };
duke@1 1467
never@10546 1468 static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = {
never@10546 1469 BAD_ALLOCATION_TYPE, // 0
never@10546 1470 BAD_ALLOCATION_TYPE, // 1
never@10546 1471 BAD_ALLOCATION_TYPE, // 2
never@10546 1472 BAD_ALLOCATION_TYPE, // 3
roland@13969 1473 NONSTATIC_BYTE , // T_BOOLEAN = 4,
roland@13969 1474 NONSTATIC_SHORT, // T_CHAR = 5,
roland@13969 1475 NONSTATIC_WORD, // T_FLOAT = 6,
roland@13969 1476 NONSTATIC_DOUBLE, // T_DOUBLE = 7,
roland@13969 1477 NONSTATIC_BYTE, // T_BYTE = 8,
roland@13969 1478 NONSTATIC_SHORT, // T_SHORT = 9,
roland@13969 1479 NONSTATIC_WORD, // T_INT = 10,
roland@13969 1480 NONSTATIC_DOUBLE, // T_LONG = 11,
roland@13969 1481 NONSTATIC_OOP, // T_OBJECT = 12,
roland@13969 1482 NONSTATIC_OOP, // T_ARRAY = 13,
roland@13969 1483 BAD_ALLOCATION_TYPE, // T_VOID = 14,
roland@13969 1484 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
roland@13969 1485 BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16,
roland@13969 1486 BAD_ALLOCATION_TYPE, // T_METADATA = 17,
roland@13969 1487 BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18,
roland@13969 1488 BAD_ALLOCATION_TYPE, // T_CONFLICT = 19,
never@10546 1489 BAD_ALLOCATION_TYPE, // 0
never@10546 1490 BAD_ALLOCATION_TYPE, // 1
never@10546 1491 BAD_ALLOCATION_TYPE, // 2
never@10546 1492 BAD_ALLOCATION_TYPE, // 3
roland@13969 1493 STATIC_BYTE , // T_BOOLEAN = 4,
roland@13969 1494 STATIC_SHORT, // T_CHAR = 5,
roland@13969 1495 STATIC_WORD, // T_FLOAT = 6,
roland@13969 1496 STATIC_DOUBLE, // T_DOUBLE = 7,
roland@13969 1497 STATIC_BYTE, // T_BYTE = 8,
roland@13969 1498 STATIC_SHORT, // T_SHORT = 9,
roland@13969 1499 STATIC_WORD, // T_INT = 10,
roland@13969 1500 STATIC_DOUBLE, // T_LONG = 11,
roland@13969 1501 STATIC_OOP, // T_OBJECT = 12,
roland@13969 1502 STATIC_OOP, // T_ARRAY = 13,
roland@13969 1503 BAD_ALLOCATION_TYPE, // T_VOID = 14,
roland@13969 1504 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
roland@13969 1505 BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16,
roland@13969 1506 BAD_ALLOCATION_TYPE, // T_METADATA = 17,
roland@13969 1507 BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18,
roland@13969 1508 BAD_ALLOCATION_TYPE, // T_CONFLICT = 19,
duke@1 1509 };
duke@1 1510
never@10546 1511 static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) {
never@10546 1512 assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values");
never@10546 1513 FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)];
never@10546 1514 assert(result != BAD_ALLOCATION_TYPE, "bad type");
never@10546 1515 return result;
never@10546 1516 }
never@10546 1517
mgronlun@34666 1518 class ClassFileParser::FieldAllocationCount : public ResourceObj {
never@10546 1519 public:
jiangli@11412 1520 u2 count[MAX_FIELD_ALLOCATION_TYPE];
never@10546 1521
never@10546 1522 FieldAllocationCount() {
never@10546 1523 for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) {
never@10546 1524 count[i] = 0;
never@10546 1525 }
never@10546 1526 }
never@10546 1527
never@10546 1528 FieldAllocationType update(bool is_static, BasicType type) {
never@10546 1529 FieldAllocationType atype = basic_type_to_atype(is_static, type);
goetz@38658 1530 if (atype != BAD_ALLOCATION_TYPE) {
goetz@38658 1531 // Make sure there is no overflow with injected fields.
goetz@38658 1532 assert(count[atype] < 0xFFFF, "More than 65535 fields");
goetz@38658 1533 count[atype]++;
goetz@38658 1534 }
never@10546 1535 return atype;
never@10546 1536 }
never@10546 1537 };
never@10546 1538
mgronlun@34666 1539 // Side-effects: populates the _fields, _fields_annotations,
mgronlun@34666 1540 // _fields_type_annotations fields
mgronlun@34666 1541 void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
mgronlun@34666 1542 bool is_interface,
mgronlun@34666 1543 FieldAllocationCount* const fac,
mgronlun@34666 1544 ConstantPool* cp,
mgronlun@34666 1545 const int cp_size,
mgronlun@34666 1546 u2* const java_fields_count_ptr,
mgronlun@34666 1547 TRAPS) {
mgronlun@34666 1548
mgronlun@34666 1549 assert(cfs != NULL, "invariant");
mgronlun@34666 1550 assert(fac != NULL, "invariant");
mgronlun@34666 1551 assert(cp != NULL, "invariant");
mgronlun@34666 1552 assert(java_fields_count_ptr != NULL, "invariant");
mgronlun@34666 1553
mgronlun@34666 1554 assert(NULL == _fields, "invariant");
mgronlun@34666 1555 assert(NULL == _fields_annotations, "invariant");
mgronlun@34666 1556 assert(NULL == _fields_type_annotations, "invariant");
mgronlun@34666 1557
mgronlun@34666 1558 cfs->guarantee_more(2, CHECK); // length
mgronlun@34666 1559 const u2 length = cfs->get_u2_fast();
never@10546 1560 *java_fields_count_ptr = length;
never@10546 1561
never@10546 1562 int num_injected = 0;
mgronlun@34666 1563 const InjectedField* const injected = JavaClasses::get_injected(_class_name,
mgronlun@34666 1564 &num_injected);
mgronlun@34666 1565 const int total_fields = length + num_injected;
jiangli@12772 1566
jiangli@12772 1567 // The field array starts with tuples of shorts
jiangli@12772 1568 // [access, name index, sig index, initial value index, byte offset].
jiangli@12772 1569 // A generic signature slot only exists for field with generic
jiangli@12772 1570 // signature attribute. And the access flag is set with
jiangli@12772 1571 // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic
jiangli@12772 1572 // signature slots are at the end of the field array and after all
jiangli@12772 1573 // other fields data.
jiangli@12772 1574 //
jiangli@12772 1575 // f1: [access, name index, sig index, initial value index, low_offset, high_offset]
jiangli@12772 1576 // f2: [access, name index, sig index, initial value index, low_offset, high_offset]
jiangli@12772 1577 // ...
jiangli@12772 1578 // fn: [access, name index, sig index, initial value index, low_offset, high_offset]
jiangli@12772 1579 // [generic signature index]
jiangli@12772 1580 // [generic signature index]
jiangli@12772 1581 // ...
jiangli@12772 1582 //
jiangli@12772 1583 // Allocate a temporary resource array for field data. For each field,
jiangli@12772 1584 // a slot is reserved in the temporary array for the generic signature
jiangli@12772 1585 // index. After parsing all fields, the data are copied to a permanent
jiangli@12772 1586 // array and any unused slots will be discarded.
jiangli@12772 1587 ResourceMark rm(THREAD);
mgronlun@34666 1588 u2* const fa = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,
mgronlun@34666 1589 u2,
mgronlun@34666 1590 total_fields * (FieldInfo::field_slots + 1));
duke@1 1591
jiangli@12772 1592 // The generic signature slots start after all other fields' data.
jiangli@12772 1593 int generic_signature_slot = total_fields * FieldInfo::field_slots;
jiangli@12772 1594 int num_generic_signature = 0;
duke@1 1595 for (int n = 0; n < length; n++) {
mgronlun@34666 1596 // access_flags, name_index, descriptor_index, attributes_count
mgronlun@34666 1597 cfs->guarantee_more(8, CHECK);
duke@1 1598
duke@1 1599 AccessFlags access_flags;
mgronlun@34666 1600 const jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS;
mgronlun@34666 1601 verify_legal_field_modifiers(flags, is_interface, CHECK);
duke@1 1602 access_flags.set_flags(flags);
duke@1 1603
mgronlun@34666 1604 const u2 name_index = cfs->get_u2_fast();
coleenp@15935 1605 check_property(valid_symbol_at(name_index),
duke@1 1606 "Invalid constant pool index %u for field name in class file %s",
mgronlun@34666 1607 name_index, CHECK);
mgronlun@34666 1608 const Symbol* const name = cp->symbol_at(name_index);
mgronlun@34666 1609 verify_legal_field_name(name, CHECK);
mgronlun@34666 1610
mgronlun@34666 1611 const u2 signature_index = cfs->get_u2_fast();
coleenp@15935 1612 check_property(valid_symbol_at(signature_index),
duke@1 1613 "Invalid constant pool index %u for field signature in class file %s",
mgronlun@34666 1614 signature_index, CHECK);
mgronlun@34666 1615 const Symbol* const sig = cp->symbol_at(signature_index);
mgronlun@34666 1616 verify_legal_field_signature(name, sig, CHECK);
duke@1 1617
duke@1 1618 u2 constantvalue_index = 0;
duke@1 1619 bool is_synthetic = false;
duke@1 1620 u2 generic_signature_index = 0;
mgronlun@34666 1621 const bool is_static = access_flags.is_static();
coleenp@15935 1622 FieldAnnotationCollector parsed_annotations(_loader_data);
duke@1 1623
mgronlun@34666 1624 const u2 attributes_count = cfs->get_u2_fast();
duke@1 1625 if (attributes_count > 0) {
mgronlun@34666 1626 parse_field_attributes(cfs,
mgronlun@34666 1627 attributes_count,
mgronlun@34666 1628 is_static,
mgronlun@34666 1629 signature_index,
mgronlun@34666 1630 &constantvalue_index,
mgronlun@34666 1631 &is_synthetic,
mgronlun@34666 1632 &generic_signature_index,
mgronlun@34666 1633 &parsed_annotations,
mgronlun@34666 1634 CHECK);
mgronlun@34666 1635
coleenp@15935 1636 if (parsed_annotations.field_annotations() != NULL) {
coleenp@15935 1637 if (_fields_annotations == NULL) {
coleenp@15935 1638 _fields_annotations = MetadataFactory::new_array<AnnotationArray*>(
coleenp@15935 1639 _loader_data, length, NULL,
mgronlun@34666 1640 CHECK);
duke@1 1641 }
coleenp@15935 1642 _fields_annotations->at_put(n, parsed_annotations.field_annotations());
coleenp@15935 1643 parsed_annotations.set_field_annotations(NULL);
duke@1 1644 }
coleenp@15935 1645 if (parsed_annotations.field_type_annotations() != NULL) {
coleenp@15935 1646 if (_fields_type_annotations == NULL) {
mgronlun@34666 1647 _fields_type_annotations =
mgronlun@34666 1648 MetadataFactory::new_array<AnnotationArray*>(_loader_data,
mgronlun@34666 1649 length,
mgronlun@34666 1650 NULL,
mgronlun@34666 1651 CHECK);
stefank@15097 1652 }
coleenp@15935 1653 _fields_type_annotations->at_put(n, parsed_annotations.field_type_annotations());
coleenp@15935 1654 parsed_annotations.set_field_type_annotations(NULL);
stefank@15097 1655 }
coleenp@15935 1656
duke@1 1657 if (is_synthetic) {
duke@1 1658 access_flags.set_is_synthetic();
duke@1 1659 }
jiangli@12772 1660 if (generic_signature_index != 0) {
jiangli@12772 1661 access_flags.set_field_has_generic_signature();
jiangli@12772 1662 fa[generic_signature_slot] = generic_signature_index;
jiangli@12772 1663 generic_signature_slot ++;
jiangli@12772 1664 num_generic_signature ++;
jiangli@12772 1665 }
duke@1 1666 }
duke@1 1667
mgronlun@34666 1668 FieldInfo* const field = FieldInfo::from_field_array(fa, n);
never@10546 1669 field->initialize(access_flags.as_short(),
never@10546 1670 name_index,
never@10546 1671 signature_index,
jwilhelm@15193 1672 constantvalue_index);
mgronlun@34666 1673 const BasicType type = cp->basic_type_for_signature_at(signature_index);
jwilhelm@15193 1674
jwilhelm@15193 1675 // Remember how many oops we encountered and compute allocation type
mgronlun@34666 1676 const FieldAllocationType atype = fac->update(is_static, type);
jwilhelm@15193 1677 field->set_allocation_type(atype);
jwilhelm@15193 1678
jwilhelm@15193 1679 // After field is initialized with type, we can augment it with aux info
jrose@13291 1680 if (parsed_annotations.has_any_annotations())
jrose@13291 1681 parsed_annotations.apply_to(field);
never@10546 1682 }
never@10546 1683
jiangli@12772 1684 int index = length;
never@10546 1685 if (num_injected != 0) {
never@10546 1686 for (int n = 0; n < num_injected; n++) {
never@10546 1687 // Check for duplicates
never@10546 1688 if (injected[n].may_be_java) {
mgronlun@34666 1689 const Symbol* const name = injected[n].name();
mgronlun@34666 1690 const Symbol* const signature = injected[n].signature();
never@10546 1691 bool duplicate = false;
never@10546 1692 for (int i = 0; i < length; i++) {
mgronlun@34666 1693 const FieldInfo* const f = FieldInfo::from_field_array(fa, i);
mgronlun@34666 1694 if (name == cp->symbol_at(f->name_index()) &&
mgronlun@34666 1695 signature == cp->symbol_at(f->signature_index())) {
never@10546 1696 // Symbol is desclared in Java so skip this one
never@10546 1697 duplicate = true;
never@10546 1698 break;
never@10546 1699 }
never@10546 1700 }
never@10546 1701 if (duplicate) {
never@10546 1702 // These will be removed from the field array at the end
never@10546 1703 continue;
never@10546 1704 }
never@10546 1705 }
never@10546 1706
never@10546 1707 // Injected field
mgronlun@34666 1708 FieldInfo* const field = FieldInfo::from_field_array(fa, index);
never@10546 1709 field->initialize(JVM_ACC_FIELD_INTERNAL,
never@10546 1710 injected[n].name_index,
never@10546 1711 injected[n].signature_index,
never@10546 1712 0);
never@10546 1713
mgronlun@34666 1714 const BasicType type = FieldType::basic_type(injected[n].signature());
never@10546 1715
never@10546 1716 // Remember how many oops we encountered and compute allocation type
mgronlun@34666 1717 const FieldAllocationType atype = fac->update(false, type);
jwilhelm@15193 1718 field->set_allocation_type(atype);
never@10546 1719 index++;
never@10546 1720 }
jiangli@12772 1721 }
jiangli@12772 1722
mgronlun@34666 1723 assert(NULL == _fields, "invariant");
mgronlun@34666 1724
mgronlun@34666 1725 _fields =
mgronlun@34666 1726 MetadataFactory::new_array<u2>(_loader_data,
mgronlun@34666 1727 index * FieldInfo::field_slots + num_generic_signature,
mgronlun@34666 1728 CHECK);
jiangli@12772 1729 // Sometimes injected fields already exist in the Java source so
jiangli@12772 1730 // the fields array could be too long. In that case the
jiangli@12772 1731 // fields array is trimed. Also unused slots that were reserved
jiangli@12772 1732 // for generic signature indexes are discarded.
jiangli@12772 1733 {
jiangli@12772 1734 int i = 0;
jiangli@12772 1735 for (; i < index * FieldInfo::field_slots; i++) {
mgronlun@34666 1736 _fields->at_put(i, fa[i]);
never@10546 1737 }
jiangli@12772 1738 for (int j = total_fields * FieldInfo::field_slots;
jiangli@12772 1739 j < generic_signature_slot; j++) {
mgronlun@34666 1740 _fields->at_put(i++, fa[j]);
jiangli@12772 1741 }
mgronlun@34666 1742 assert(_fields->length() == i, "");
duke@1 1743 }
duke@1 1744
duke@1 1745 if (_need_verify && length > 1) {
duke@1 1746 // Check duplicated fields
duke@1 1747 ResourceMark rm(THREAD);
duke@1 1748 NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 1749 THREAD, NameSigHash*, HASH_ROW_SIZE);
duke@1 1750 initialize_hashtable(names_and_sigs);
duke@1 1751 bool dup = false;
shshahma@46301 1752 const Symbol* name = NULL;
shshahma@46301 1753 const Symbol* sig = NULL;
duke@1 1754 {
david@35492 1755 debug_only(NoSafepointVerifier nsv;)
mgronlun@34666 1756 for (AllFieldStream fs(_fields, cp); !fs.done(); fs.next()) {
shshahma@46301 1757 name = fs.name();
shshahma@46301 1758 sig = fs.signature();
duke@1 1759 // If no duplicates, add name/signature in hashtable names_and_sigs.
duke@1 1760 if (!put_after_lookup(name, sig, names_and_sigs)) {
duke@1 1761 dup = true;
duke@1 1762 break;
duke@1 1763 }
duke@1 1764 }
duke@1 1765 }
duke@1 1766 if (dup) {
shshahma@46301 1767 classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s",
shshahma@46301 1768 name->as_C_string(), sig->as_klass_external_name(), CHECK);
duke@1 1769 }
duke@1 1770 }
duke@1 1771 }
duke@1 1772
duke@1 1773
mikael@46513 1774 const ClassFileParser::unsafe_u2* ClassFileParser::parse_exception_table(const ClassFileStream* const cfs,
mikael@46513 1775 u4 code_length,
mikael@46513 1776 u4 exception_table_length,
mikael@46513 1777 TRAPS) {
mgronlun@34666 1778 assert(cfs != NULL, "invariant");
mgronlun@34666 1779
mikael@46513 1780 const unsafe_u2* const exception_table_start = cfs->current();
jiangli@13282 1781 assert(exception_table_start != NULL, "null exception table");
mgronlun@34666 1782
mgronlun@34666 1783 cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc,
mgronlun@34666 1784 // end_pc,
mgronlun@34666 1785 // handler_pc,
mgronlun@34666 1786 // catch_type_index
mgronlun@34666 1787
jiangli@13282 1788 // Will check legal target after parsing code array in verifier.
jiangli@13282 1789 if (_need_verify) {
jiangli@13282 1790 for (unsigned int i = 0; i < exception_table_length; i++) {
mgronlun@34666 1791 const u2 start_pc = cfs->get_u2_fast();
mgronlun@34666 1792 const u2 end_pc = cfs->get_u2_fast();
mgronlun@34666 1793 const u2 handler_pc = cfs->get_u2_fast();
mgronlun@34666 1794 const u2 catch_type_index = cfs->get_u2_fast();
duke@1 1795 guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
jiangli@13282 1796 "Illegal exception table range in class file %s",
jiangli@13282 1797 CHECK_NULL);
duke@1 1798 guarantee_property(handler_pc < code_length,
jiangli@13282 1799 "Illegal exception table handler in class file %s",
jiangli@13282 1800 CHECK_NULL);
duke@1 1801 if (catch_type_index != 0) {
coleenp@15935 1802 guarantee_property(valid_klass_reference_at(catch_type_index),
jiangli@13282 1803 "Catch type in exception table has bad constant type in class file %s", CHECK_NULL);
duke@1 1804 }
duke@1 1805 }
jiangli@13282 1806 } else {
jiangli@13282 1807 cfs->skip_u2_fast(exception_table_length * 4);
duke@1 1808 }
jiangli@13282 1809 return exception_table_start;
duke@1 1810 }
duke@1 1811
mgronlun@34666 1812 void ClassFileParser::parse_linenumber_table(u4 code_attribute_length,
mgronlun@34666 1813 u4 code_length,
mgronlun@34666 1814 CompressedLineNumberWriteStream**const write_stream,
mgronlun@34666 1815 TRAPS) {
mgronlun@34666 1816
mgronlun@34666 1817 const ClassFileStream* const cfs = _stream;
duke@1 1818 unsigned int num_entries = cfs->get_u2(CHECK);
duke@1 1819
duke@1 1820 // Each entry is a u2 start_pc, and a u2 line_number
mgronlun@34666 1821 const unsigned int length_in_bytes = num_entries * (sizeof(u2) * 2);
duke@1 1822
duke@1 1823 // Verify line number attribute and table length
duke@1 1824 check_property(
duke@1 1825 code_attribute_length == sizeof(u2) + length_in_bytes,
duke@1 1826 "LineNumberTable attribute has wrong length in class file %s", CHECK);
duke@1 1827
duke@1 1828 cfs->guarantee_more(length_in_bytes, CHECK);
duke@1 1829
duke@1 1830 if ((*write_stream) == NULL) {
duke@1 1831 if (length_in_bytes > fixed_buffer_size) {
duke@1 1832 (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes);
duke@1 1833 } else {
duke@1 1834 (*write_stream) = new CompressedLineNumberWriteStream(
mgronlun@34666 1835 _linenumbertable_buffer, fixed_buffer_size);
duke@1 1836 }
duke@1 1837 }
duke@1 1838
duke@1 1839 while (num_entries-- > 0) {
mgronlun@34666 1840 const u2 bci = cfs->get_u2_fast(); // start_pc
mgronlun@34666 1841 const u2 line = cfs->get_u2_fast(); // line_number
duke@1 1842 guarantee_property(bci < code_length,
duke@1 1843 "Invalid pc in LineNumberTable in class file %s", CHECK);
duke@1 1844 (*write_stream)->write_pair(bci, line);
duke@1 1845 }
duke@1 1846 }
duke@1 1847
duke@1 1848
coleenp@28817 1849 class LVT_Hash : public AllStatic {
coleenp@28817 1850 public:
coleenp@28817 1851
coleenp@28817 1852 static bool equals(LocalVariableTableElement const& e0, LocalVariableTableElement const& e1) {
coleenp@28817 1853 /*
coleenp@28817 1854 * 3-tuple start_bci/length/slot has to be unique key,
coleenp@28817 1855 * so the following comparison seems to be redundant:
coleenp@28817 1856 * && elem->name_cp_index == entry->_elem->name_cp_index
coleenp@28817 1857 */
coleenp@28817 1858 return (e0.start_bci == e1.start_bci &&
coleenp@28817 1859 e0.length == e1.length &&
coleenp@28817 1860 e0.name_cp_index == e1.name_cp_index &&
coleenp@28817 1861 e0.slot == e1.slot);
coleenp@28817 1862 }
coleenp@28817 1863
coleenp@28817 1864 static unsigned int hash(LocalVariableTableElement const& e0) {
coleenp@28817 1865 unsigned int raw_hash = e0.start_bci;
coleenp@28817 1866
coleenp@28817 1867 raw_hash = e0.length + raw_hash * 37;
coleenp@28817 1868 raw_hash = e0.name_cp_index + raw_hash * 37;
coleenp@28817 1869 raw_hash = e0.slot + raw_hash * 37;
coleenp@28817 1870
coleenp@28817 1871 return raw_hash;
coleenp@28817 1872 }
coleenp@28817 1873 };
coleenp@28817 1874
coleenp@28817 1875
duke@1 1876 // Class file LocalVariableTable elements.
coleenp@49829 1877 class Classfile_LVT_Element {
duke@1 1878 public:
duke@1 1879 u2 start_bci;
duke@1 1880 u2 length;
duke@1 1881 u2 name_cp_index;
duke@1 1882 u2 descriptor_cp_index;
duke@1 1883 u2 slot;
duke@1 1884 };
duke@1 1885
mgronlun@34666 1886 static void copy_lvt_element(const Classfile_LVT_Element* const src,
mgronlun@34666 1887 LocalVariableTableElement* const lvt) {
duke@1 1888 lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci);
duke@1 1889 lvt->length = Bytes::get_Java_u2((u1*) &src->length);
duke@1 1890 lvt->name_cp_index = Bytes::get_Java_u2((u1*) &src->name_cp_index);
duke@1 1891 lvt->descriptor_cp_index = Bytes::get_Java_u2((u1*) &src->descriptor_cp_index);
duke@1 1892 lvt->signature_cp_index = 0;
duke@1 1893 lvt->slot = Bytes::get_Java_u2((u1*) &src->slot);
duke@1 1894 }
duke@1 1895
duke@1 1896 // Function is used to parse both attributes:
mgronlun@34666 1897 // LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT)
mikael@46513 1898 const ClassFileParser::unsafe_u2* ClassFileParser::parse_localvariable_table(const ClassFileStream* cfs,
mikael@46513 1899 u4 code_length,
mikael@46513 1900 u2 max_locals,
mikael@46513 1901 u4 code_attribute_length,
mikael@46513 1902 u2* const localvariable_table_length,
mikael@46513 1903 bool isLVTT,
mikael@46513 1904 TRAPS) {
mgronlun@34666 1905 const char* const tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable";
duke@1 1906 *localvariable_table_length = cfs->get_u2(CHECK_NULL);
mgronlun@34666 1907 const unsigned int size =
mgronlun@34666 1908 (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2);
mgronlun@34666 1909
mgronlun@34666 1910 const ConstantPool* const cp = _cp;
mgronlun@34666 1911
duke@1 1912 // Verify local variable table attribute has right length
duke@1 1913 if (_need_verify) {
duke@1 1914 guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)),
duke@1 1915 "%s has wrong length in class file %s", tbl_name, CHECK_NULL);
duke@1 1916 }
mgronlun@34666 1917
mikael@46513 1918 const unsafe_u2* const localvariable_table_start = cfs->current();
duke@1 1919 assert(localvariable_table_start != NULL, "null local variable table");
duke@1 1920 if (!_need_verify) {
duke@1 1921 cfs->skip_u2_fast(size);
duke@1 1922 } else {
duke@1 1923 cfs->guarantee_more(size * 2, CHECK_NULL);
duke@1 1924 for(int i = 0; i < (*localvariable_table_length); i++) {
mgronlun@34666 1925 const u2 start_pc = cfs->get_u2_fast();
mgronlun@34666 1926 const u2 length = cfs->get_u2_fast();
mgronlun@34666 1927 const u2 name_index = cfs->get_u2_fast();
mgronlun@34666 1928 const u2 descriptor_index = cfs->get_u2_fast();
mgronlun@34666 1929 const u2 index = cfs->get_u2_fast();
duke@1 1930 // Assign to a u4 to avoid overflow
mgronlun@34666 1931 const u4 end_pc = (u4)start_pc + (u4)length;
duke@1 1932
duke@1 1933 if (start_pc >= code_length) {
duke@1 1934 classfile_parse_error(
duke@1 1935 "Invalid start_pc %u in %s in class file %s",
duke@1 1936 start_pc, tbl_name, CHECK_NULL);
duke@1 1937 }
duke@1 1938 if (end_pc > code_length) {
duke@1 1939 classfile_parse_error(
duke@1 1940 "Invalid length %u in %s in class file %s",
duke@1 1941 length, tbl_name, CHECK_NULL);
duke@1 1942 }
mgronlun@34666 1943 const int cp_size = cp->length();
coleenp@15935 1944 guarantee_property(valid_symbol_at(name_index),
duke@1 1945 "Name index %u in %s has bad constant type in class file %s",
duke@1 1946 name_index, tbl_name, CHECK_NULL);
coleenp@15935 1947 guarantee_property(valid_symbol_at(descriptor_index),
duke@1 1948 "Signature index %u in %s has bad constant type in class file %s",
duke@1 1949 descriptor_index, tbl_name, CHECK_NULL);
duke@1 1950
mgronlun@34666 1951 const Symbol* const name = cp->symbol_at(name_index);
mgronlun@34666 1952 const Symbol* const sig = cp->symbol_at(descriptor_index);
duke@1 1953 verify_legal_field_name(name, CHECK_NULL);
duke@1 1954 u2 extra_slot = 0;
duke@1 1955 if (!isLVTT) {
duke@1 1956 verify_legal_field_signature(name, sig, CHECK_NULL);
duke@1 1957
duke@1 1958 // 4894874: check special cases for double and long local variables
coleenp@8076 1959 if (sig == vmSymbols::type_signature(T_DOUBLE) ||
coleenp@8076 1960 sig == vmSymbols::type_signature(T_LONG)) {
duke@1 1961 extra_slot = 1;
duke@1 1962 }
duke@1 1963 }
duke@1 1964 guarantee_property((index + extra_slot) < max_locals,
duke@1 1965 "Invalid index %u in %s in class file %s",
duke@1 1966 index, tbl_name, CHECK_NULL);
duke@1 1967 }
duke@1 1968 }
duke@1 1969 return localvariable_table_start;
duke@1 1970 }
duke@1 1971
duke@1 1972
mgronlun@34666 1973 void ClassFileParser::parse_type_array(u2 array_length,
mgronlun@34666 1974 u4 code_length,
mgronlun@34666 1975 u4* const u1_index,
mgronlun@34666 1976 u4* const u2_index,
mgronlun@34666 1977 u1* const u1_array,
mgronlun@34666 1978 u2* const u2_array,
mgronlun@34666 1979 TRAPS) {
mgronlun@34666 1980 const ClassFileStream* const cfs = _stream;
duke@1 1981 u2 index = 0; // index in the array with long/double occupying two slots
duke@1 1982 u4 i1 = *u1_index;
duke@1 1983 u4 i2 = *u2_index + 1;
duke@1 1984 for(int i = 0; i < array_length; i++) {
mgronlun@34666 1985 const u1 tag = u1_array[i1++] = cfs->get_u1(CHECK);
duke@1 1986 index++;
duke@1 1987 if (tag == ITEM_Long || tag == ITEM_Double) {
duke@1 1988 index++;
duke@1 1989 } else if (tag == ITEM_Object) {
mgronlun@34666 1990 const u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
coleenp@15935 1991 guarantee_property(valid_klass_reference_at(class_index),
duke@1 1992 "Bad class index %u in StackMap in class file %s",
duke@1 1993 class_index, CHECK);
duke@1 1994 } else if (tag == ITEM_Uninitialized) {
mgronlun@34666 1995 const u2 offset = u2_array[i2++] = cfs->get_u2(CHECK);
duke@1 1996 guarantee_property(
duke@1 1997 offset < code_length,
duke@1 1998 "Bad uninitialized type offset %u in StackMap in class file %s",
duke@1 1999 offset, CHECK);
duke@1 2000 } else {
duke@1 2001 guarantee_property(
duke@1 2002 tag <= (u1)ITEM_Uninitialized,
duke@1 2003 "Unknown variable type %u in StackMap in class file %s",
duke@1 2004 tag, CHECK);
duke@1 2005 }
duke@1 2006 }
duke@1 2007 u2_array[*u2_index] = index;
duke@1 2008 *u1_index = i1;
duke@1 2009 *u2_index = i2;
duke@1 2010 }
duke@1 2011
mgronlun@34666 2012 static const u1* parse_stackmap_table(const ClassFileStream* const cfs,
mgronlun@34666 2013 u4 code_attribute_length,
mgronlun@34666 2014 bool need_verify,
mgronlun@34666 2015 TRAPS) {
mgronlun@34666 2016 assert(cfs != NULL, "invariant");
mgronlun@34666 2017
mgronlun@34666 2018 if (0 == code_attribute_length) {
duke@1 2019 return NULL;
mgronlun@34666 2020 }
mgronlun@34666 2021
mikael@46504 2022 const u1* const stackmap_table_start = cfs->current();
duke@1 2023 assert(stackmap_table_start != NULL, "null stackmap table");
duke@1 2024
duke@1 2025 // check code_attribute_length first
mgronlun@34666 2026 cfs->skip_u1(code_attribute_length, CHECK_NULL);
mgronlun@34666 2027
mgronlun@34666 2028 if (!need_verify && !DumpSharedSpaces) {
duke@1 2029 return NULL;
duke@1 2030 }
coleenp@15935 2031 return stackmap_table_start;
duke@1 2032 }
duke@1 2033
mikael@46513 2034 const ClassFileParser::unsafe_u2* ClassFileParser::parse_checked_exceptions(const ClassFileStream* const cfs,
mikael@46513 2035 u2* const checked_exceptions_length,
mikael@46513 2036 u4 method_attribute_length,
mikael@46513 2037 TRAPS) {
mgronlun@34666 2038 assert(cfs != NULL, "invariant");
mgronlun@34666 2039 assert(checked_exceptions_length != NULL, "invariant");
mgronlun@34666 2040
duke@1 2041 cfs->guarantee_more(2, CHECK_NULL); // checked_exceptions_length
duke@1 2042 *checked_exceptions_length = cfs->get_u2_fast();
mgronlun@34666 2043 const unsigned int size =
mgronlun@34666 2044 (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2);
mikael@46513 2045 const unsafe_u2* const checked_exceptions_start = cfs->current();
duke@1 2046 assert(checked_exceptions_start != NULL, "null checked exceptions");
duke@1 2047 if (!_need_verify) {
duke@1 2048 cfs->skip_u2_fast(size);
duke@1 2049 } else {
duke@1 2050 // Verify each value in the checked exception table
duke@1 2051 u2 checked_exception;
mgronlun@34666 2052 const u2 len = *checked_exceptions_length;
duke@1 2053 cfs->guarantee_more(2 * len, CHECK_NULL);
duke@1 2054 for (int i = 0; i < len; i++) {
duke@1 2055 checked_exception = cfs->get_u2_fast();
duke@1 2056 check_property(
coleenp@15935 2057 valid_klass_reference_at(checked_exception),
duke@1 2058 "Exception name has bad type at constant pool %u in class file %s",
duke@1 2059 checked_exception, CHECK_NULL);
duke@1 2060 }
duke@1 2061 }
duke@1 2062 // check exceptions attribute length
duke@1 2063 if (_need_verify) {
duke@1 2064 guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) +
duke@1 2065 sizeof(u2) * size),
duke@1 2066 "Exceptions attribute has wrong length in class file %s", CHECK_NULL);
duke@1 2067 }
duke@1 2068 return checked_exceptions_start;
duke@1 2069 }
duke@1 2070
mgronlun@34666 2071 void ClassFileParser::throwIllegalSignature(const char* type,
mgronlun@34666 2072 const Symbol* name,
mgronlun@34666 2073 const Symbol* sig,
mgronlun@34666 2074 TRAPS) const {
mgronlun@34666 2075 assert(name != NULL, "invariant");
mgronlun@34666 2076 assert(sig != NULL, "invariant");
mgronlun@34666 2077
kamg@5709 2078 ResourceMark rm(THREAD);
kamg@5709 2079 Exceptions::fthrow(THREAD_AND_LOCATION,
kamg@5709 2080 vmSymbols::java_lang_ClassFormatError(),
kamg@5709 2081 "%s \"%s\" in class %s has illegal signature \"%s\"", type,
kamg@5709 2082 name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
kamg@5709 2083 }
duke@1 2084
mgronlun@34666 2085 AnnotationCollector::ID
mgronlun@34666 2086 AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
mgronlun@34666 2087 const Symbol* name) {
mgronlun@34666 2088 const vmSymbols::SID sid = vmSymbols::find_sid(name);
kmo@15244 2089 // Privileged code can use all annotations. Other code silently drops some.
twisti@16617 2090 const bool privileged = loader_data->is_the_null_class_loader_data() ||
alanb@36508 2091 loader_data->is_platform_class_loader_data() ||
twisti@16617 2092 loader_data->is_anonymous();
jrose@13291 2093 switch (sid) {
chegar@37301 2094 case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): {
mgronlun@34666 2095 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2096 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2097 return _method_CallerSensitive;
mgronlun@34666 2098 }
twisti@35135 2099 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ForceInline_signature): {
mgronlun@34666 2100 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2101 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2102 return _method_ForceInline;
mgronlun@34666 2103 }
twisti@35135 2104 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_DontInline_signature): {
mgronlun@34666 2105 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2106 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2107 return _method_DontInline;
mgronlun@34666 2108 }
mgronlun@34666 2109 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InjectedProfile_signature): {
mgronlun@34666 2110 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2111 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2112 return _method_InjectedProfile;
mgronlun@34666 2113 }
mgronlun@34666 2114 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): {
mgronlun@34666 2115 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2116 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2117 return _method_LambdaForm_Compiled;
mgronlun@34666 2118 }
mgronlun@34666 2119 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): {
mgronlun@34666 2120 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2121 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2122 return _method_LambdaForm_Hidden;
mgronlun@34666 2123 }
mgronlun@34666 2124 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_HotSpotIntrinsicCandidate_signature): {
mgronlun@34666 2125 if (_location != _in_method) break; // only allow for methods
mgronlun@34666 2126 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2127 return _method_HotSpotIntrinsicCandidate;
mgronlun@34666 2128 }
twisti@35135 2129 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Stable_signature): {
mgronlun@34666 2130 if (_location != _in_field) break; // only allow for fields
mgronlun@34666 2131 if (!privileged) break; // only allow in privileged code
mgronlun@34666 2132 return _field_Stable;
mgronlun@34666 2133 }
mgronlun@34666 2134 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Contended_signature): {
mgronlun@34666 2135 if (_location != _in_field && _location != _in_class) {
mgronlun@34666 2136 break; // only allow for fields and classes
mgronlun@34666 2137 }
mgronlun@34666 2138 if (!EnableContended || (RestrictContended && !privileged)) {
mgronlun@34666 2139 break; // honor privileges
mgronlun@34666 2140 }
mgronlun@34666 2141 return _jdk_internal_vm_annotation_Contended;
mgronlun@34666 2142 }
fparain@35071 2143 case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ReservedStackAccess_signature): {
fparain@35071 2144 if (_location != _in_method) break; // only allow for methods
fparain@35071 2145 if (RestrictReservedStack && !privileged) break; // honor privileges
fparain@35071 2146 return _jdk_internal_vm_annotation_ReservedStackAccess;
fparain@35071 2147 }
mgronlun@34666 2148 default: {
mgronlun@34666 2149 break;
mgronlun@34666 2150 }
jrose@13291 2151 }
jrose@13291 2152 return AnnotationCollector::_unknown;
jrose@13291 2153 }
jrose@13291 2154
jrose@13291 2155 void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
jwilhelm@15193 2156 if (is_contended())
jwilhelm@15193 2157 f->set_contended_group(contended_group());
vlivanov@19770 2158 if (is_stable())
vlivanov@19770 2159 f->set_stable(true);
jrose@13291 2160 }
jrose@13291 2161
coleenp@15935 2162 ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
coleenp@15935 2163 // If there's an error deallocate metadata for field annotations
coleenp@15935 2164 MetadataFactory::free_array<u1>(_loader_data, _field_annotations);
coleenp@15935 2165 MetadataFactory::free_array<u1>(_loader_data, _field_type_annotations);
coleenp@15935 2166 }
coleenp@15935 2167
coleenp@46727 2168 void MethodAnnotationCollector::apply_to(const methodHandle& m) {
twisti@16617 2169 if (has_annotation(_method_CallerSensitive))
twisti@16617 2170 m->set_caller_sensitive(true);
jrose@13291 2171 if (has_annotation(_method_ForceInline))
jrose@13291 2172 m->set_force_inline(true);
twisti@13391 2173 if (has_annotation(_method_DontInline))
twisti@13391 2174 m->set_dont_inline(true);
vlivanov@31228 2175 if (has_annotation(_method_InjectedProfile))
vlivanov@31228 2176 m->set_has_injected_profile(true);
twisti@13391 2177 if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
twisti@13391 2178 m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
twisti@13391 2179 if (has_annotation(_method_LambdaForm_Hidden))
twisti@13391 2180 m->set_hidden(true);
zmajo@31587 2181 if (has_annotation(_method_HotSpotIntrinsicCandidate) && !m->is_synthetic())
zmajo@31587 2182 m->set_intrinsic_candidate(true);
fparain@35071 2183 if (has_annotation(_jdk_internal_vm_annotation_ReservedStackAccess))
fparain@35071 2184 m->set_has_reserved_stack_access(true);
jrose@13291 2185 }
jrose@13291 2186
mgronlun@34666 2187 void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
mgronlun@34666 2188 assert(ik != NULL, "invariant");
mgronlun@34666 2189 ik->set_is_contended(is_contended());
jrose@13291 2190 }
jrose@13291 2191
duke@1 2192 #define MAX_ARGS_SIZE 255
duke@1 2193 #define MAX_CODE_SIZE 65535
duke@1 2194 #define INITIAL_MAX_LVT_NUMBER 256
duke@1 2195
coleenp@15601 2196 /* Copy class file LVT's/LVTT's into the HotSpot internal LVT.
coleenp@15601 2197 *
coleenp@15601 2198 * Rules for LVT's and LVTT's are:
coleenp@15601 2199 * - There can be any number of LVT's and LVTT's.
coleenp@15601 2200 * - If there are n LVT's, it is the same as if there was just
coleenp@15601 2201 * one LVT containing all the entries from the n LVT's.
coleenp@15601 2202 * - There may be no more than one LVT entry per local variable.
coleenp@15601 2203 * Two LVT entries are 'equal' if these fields are the same:
coleenp@15601 2204 * start_pc, length, name, slot
coleenp@15601 2205 * - There may be no more than one LVTT entry per each LVT entry.
coleenp@15601 2206 * Each LVTT entry has to match some LVT entry.
coleenp@15601 2207 * - HotSpot internal LVT keeps natural ordering of class file LVT entries.
coleenp@15601 2208 */
mgronlun@34666 2209 void ClassFileParser::copy_localvariable_table(const ConstMethod* cm,
coleenp@15601 2210 int lvt_cnt,
mgronlun@34666 2211 u2* const localvariable_table_length,
mikael@46513 2212 const unsafe_u2** const localvariable_table_start,
coleenp@15601 2213 int lvtt_cnt,
mgronlun@34666 2214 u2* const localvariable_type_table_length,
mikael@46513 2215 const unsafe_u2** const localvariable_type_table_start,
coleenp@15601 2216 TRAPS) {
coleenp@15601 2217
coleenp@28817 2218 ResourceMark rm(THREAD);
coleenp@28817 2219
coleenp@28817 2220 typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
coleenp@28817 2221 &LVT_Hash::hash, &LVT_Hash::equals> LVT_HashTable;
coleenp@28817 2222
mgronlun@34666 2223 LVT_HashTable* const table = new LVT_HashTable();
coleenp@15601 2224
coleenp@15601 2225 // To fill LocalVariableTable in
mgronlun@34666 2226 const Classfile_LVT_Element* cf_lvt;
coleenp@15601 2227 LocalVariableTableElement* lvt = cm->localvariable_table_start();
coleenp@15601 2228
coleenp@15601 2229 for (int tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) {
coleenp@15601 2230 cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
coleenp@15601 2231 for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
coleenp@15601 2232 copy_lvt_element(&cf_lvt[idx], lvt);
coleenp@28817 2233 // If no duplicates, add LVT elem in hashtable.
coleenp@28817 2234 if (table->put(*lvt, lvt) == false
coleenp@15601 2235 && _need_verify
coleenp@15601 2236 && _major_version >= JAVA_1_5_VERSION) {
coleenp@15601 2237 classfile_parse_error("Duplicated LocalVariableTable attribute "
coleenp@15601 2238 "entry for '%s' in class file %s",
coleenp@15935 2239 _cp->symbol_at(lvt->name_cp_index)->as_utf8(),
coleenp@15601 2240 CHECK);
coleenp@15601 2241 }
coleenp@15601 2242 }
coleenp@15601 2243 }
coleenp@15601 2244
coleenp@15601 2245 // To merge LocalVariableTable and LocalVariableTypeTable
mgronlun@34666 2246 const Classfile_LVT_Element* cf_lvtt;
coleenp@15601 2247 LocalVariableTableElement lvtt_elem;
coleenp@15601 2248
coleenp@15601 2249 for (int tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) {
coleenp@15601 2250 cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
coleenp@15601 2251 for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
coleenp@15601 2252 copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
coleenp@28817 2253 LocalVariableTableElement** entry = table->get(lvtt_elem);
coleenp@15601 2254 if (entry == NULL) {
coleenp@15601 2255 if (_need_verify) {
coleenp@15601 2256 classfile_parse_error("LVTT entry for '%s' in class file %s "
coleenp@15601 2257 "does not match any LVT entry",
coleenp@15935 2258 _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
coleenp@15601 2259 CHECK);
coleenp@15601 2260 }
coleenp@28817 2261 } else if ((*entry)->signature_cp_index != 0 && _need_verify) {
coleenp@15601 2262 classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
coleenp@15601 2263 "entry for '%s' in class file %s",
coleenp@15935 2264 _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
coleenp@15601 2265 CHECK);
coleenp@15601 2266 } else {
coleenp@15601 2267 // to add generic signatures into LocalVariableTable
coleenp@28817 2268 (*entry)->signature_cp_index = lvtt_elem.descriptor_cp_index;
coleenp@15601 2269 }
coleenp@15601 2270 }
coleenp@15601 2271 }
coleenp@15601 2272 }
coleenp@15601 2273
coleenp@15601 2274
coleenp@15935 2275 void ClassFileParser::copy_method_annotations(ConstMethod* cm,
mgronlun@34666 2276 const u1* runtime_visible_annotations,
coleenp@15601 2277 int runtime_visible_annotations_length,
mgronlun@34666 2278 const u1* runtime_invisible_annotations,
coleenp@15601 2279 int runtime_invisible_annotations_length,
mgronlun@34666 2280 const u1* runtime_visible_parameter_annotations,
coleenp@15601 2281 int runtime_visible_parameter_annotations_length,
mgronlun@34666 2282 const u1* runtime_invisible_parameter_annotations,
coleenp@15601 2283 int runtime_invisible_parameter_annotations_length,
mgronlun@34666 2284 const u1* runtime_visible_type_annotations,
coleenp@15601 2285 int runtime_visible_type_annotations_length,
mgronlun@34666 2286 const u1* runtime_invisible_type_annotations,
coleenp@15601 2287 int runtime_invisible_type_annotations_length,
mgronlun@34666 2288 const u1* annotation_default,
coleenp@15601 2289 int annotation_default_length,
coleenp@15601 2290 TRAPS) {
coleenp@15601 2291
coleenp@15601 2292 AnnotationArray* a;
coleenp@15601 2293
coleenp@15601 2294 if (runtime_visible_annotations_length +
coleenp@15601 2295 runtime_invisible_annotations_length > 0) {
coleenp@15935 2296 a = assemble_annotations(runtime_visible_annotations,
coleenp@15601 2297 runtime_visible_annotations_length,
coleenp@15601 2298 runtime_invisible_annotations,
coleenp@15601 2299 runtime_invisible_annotations_length,
coleenp@15601 2300 CHECK);
coleenp@15601 2301 cm->set_method_annotations(a);
coleenp@15601 2302 }
coleenp@15601 2303
coleenp@15601 2304 if (runtime_visible_parameter_annotations_length +
coleenp@15601 2305 runtime_invisible_parameter_annotations_length > 0) {
coleenp@15935 2306 a = assemble_annotations(runtime_visible_parameter_annotations,
coleenp@15601 2307 runtime_visible_parameter_annotations_length,
coleenp@15601 2308 runtime_invisible_parameter_annotations,
coleenp@15601 2309 runtime_invisible_parameter_annotations_length,
coleenp@15601 2310 CHECK);
coleenp@15601 2311 cm->set_parameter_annotations(a);
coleenp@15601 2312 }
coleenp@15601 2313
coleenp@15601 2314 if (annotation_default_length > 0) {
coleenp@15935 2315 a = assemble_annotations(annotation_default,
coleenp@15601 2316 annotation_default_length,
coleenp@15601 2317 NULL,
coleenp@15601 2318 0,
coleenp@15601 2319 CHECK);
coleenp@15601 2320 cm->set_default_annotations(a);
coleenp@15601 2321 }
coleenp@15601 2322
coleenp@15601 2323 if (runtime_visible_type_annotations_length +
coleenp@15601 2324 runtime_invisible_type_annotations_length > 0) {
coleenp@15935 2325 a = assemble_annotations(runtime_visible_type_annotations,
coleenp@15601 2326 runtime_visible_type_annotations_length,
coleenp@15601 2327 runtime_invisible_type_annotations,
coleenp@15601 2328 runtime_invisible_type_annotations_length,
coleenp@15601 2329 CHECK);
coleenp@15601 2330 cm->set_type_annotations(a);
coleenp@15601 2331 }
coleenp@15601 2332 }
coleenp@15601 2333
coleenp@15601 2334
duke@1 2335 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions
jrose@13291 2336 // attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
coleenp@13728 2337 // Method* to save footprint, so we only know the size of the resulting Method* when the
duke@1 2338 // entire method attribute is parsed.
duke@1 2339 //
duke@1 2340 // The promoted_flags parameter is used to pass relevant access_flags
duke@1 2341 // from the method back up to the containing klass. These flag values
duke@1 2342 // are added to klass's access_flags.
duke@1 2343
mgronlun@34666 2344 Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
mgronlun@34666 2345 bool is_interface,
mgronlun@34666 2346 const ConstantPool* cp,
mgronlun@34666 2347 AccessFlags* const promoted_flags,
mgronlun@34666 2348 TRAPS) {
mgronlun@34666 2349 assert(cfs != NULL, "invariant");
mgronlun@34666 2350 assert(cp != NULL, "invariant");
mgronlun@34666 2351 assert(promoted_flags != NULL, "invariant");
mgronlun@34666 2352
duke@1 2353 ResourceMark rm(THREAD);
mgronlun@34666 2354 // Parse fixed parts:
mgronlun@34666 2355 // access_flags, name_index, descriptor_index, attributes_count
mgronlun@34666 2356 cfs->guarantee_more(8, CHECK_NULL);
duke@1 2357
duke@1 2358 int flags = cfs->get_u2_fast();
mgronlun@34666 2359 const u2 name_index = cfs->get_u2_fast();
mgronlun@34666 2360 const int cp_size = cp->length();
duke@1 2361 check_property(
coleenp@15935 2362 valid_symbol_at(name_index),
duke@1 2363 "Illegal constant pool index %u for method name in class file %s",
mgronlun@34666 2364 name_index, CHECK_NULL);
mgronlun@34666 2365 const Symbol* const name = cp->symbol_at(name_index);
mgronlun@34666 2366 verify_legal_method_name(name, CHECK_NULL);
mgronlun@34666 2367
mgronlun@34666 2368 const u2 signature_index = cfs->get_u2_fast();
duke@1 2369 guarantee_property(
coleenp@15935 2370 valid_symbol_at(signature_index),
duke@1 2371 "Illegal constant pool index %u for method signature in class file %s",
mgronlun@34666 2372 signature_index, CHECK_NULL);
mgronlun@34666 2373 const Symbol* const signature = cp->symbol_at(signature_index);
mgronlun@34666 2374
duke@1 2375 if (name == vmSymbols::class_initializer_name()) {
kamg@8653 2376 // We ignore the other access flags for a valid class initializer.
kamg@8653 2377 // (JVM Spec 2nd ed., chapter 4.6)
kamg@8653 2378 if (_major_version < 51) { // backward compatibility
kamg@8653 2379 flags = JVM_ACC_STATIC;
kamg@8653 2380 } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
kamg@8653 2381 flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
hseigel@32824 2382 } else {
mgronlun@34666 2383 classfile_parse_error("Method <clinit> is not static in class file %s", CHECK_NULL);
kamg@8653 2384 }
duke@1 2385 } else {
mgronlun@34666 2386 verify_legal_method_modifiers(flags, is_interface, name, CHECK_NULL);
duke@1 2387 }
duke@1 2388
hseigel@33207 2389 if (name == vmSymbols::object_initializer_name() && is_interface) {
mgronlun@34666 2390 classfile_parse_error("Interface cannot have a method named <init>, class file %s", CHECK_NULL);
hseigel@33207 2391 }
hseigel@33207 2392
duke@1 2393 int args_size = -1; // only used when _need_verify is true
duke@1 2394 if (_need_verify) {
duke@1 2395 args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) +
mgronlun@34666 2396 verify_legal_method_signature(name, signature, CHECK_NULL);
duke@1 2397 if (args_size > MAX_ARGS_SIZE) {
mgronlun@34666 2398 classfile_parse_error("Too many arguments in method signature in class file %s", CHECK_NULL);
duke@1 2399 }
duke@1 2400 }
duke@1 2401
mgronlun@34666 2402 AccessFlags access_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS);
duke@1 2403
duke@1 2404 // Default values for code and exceptions attribute elements
duke@1 2405 u2 max_stack = 0;
duke@1 2406 u2 max_locals = 0;
duke@1 2407 u4 code_length = 0;
mgronlun@34666 2408 const u1* code_start = 0;
duke@1 2409 u2 exception_table_length = 0;
mikael@46513 2410 const unsafe_u2* exception_table_start = NULL; // (potentially unaligned) pointer to array of u2 elements
coleenp@13728 2411 Array<int>* exception_handlers = Universe::the_empty_int_array();
duke@1 2412 u2 checked_exceptions_length = 0;
mikael@46513 2413 const unsafe_u2* checked_exceptions_start = NULL; // (potentially unaligned) pointer to array of u2 elements
duke@1 2414 CompressedLineNumberWriteStream* linenumber_table = NULL;
duke@1 2415 int linenumber_table_length = 0;
duke@1 2416 int total_lvt_length = 0;
duke@1 2417 u2 lvt_cnt = 0;
duke@1 2418 u2 lvtt_cnt = 0;
duke@1 2419 bool lvt_allocated = false;
duke@1 2420 u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER;
duke@1 2421 u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER;
ccheung@31851 2422 u2* localvariable_table_length = NULL;
mikael@46513 2423 const unsafe_u2** localvariable_table_start = NULL; // (potentially unaligned) pointer to array of LVT attributes
ccheung@31851 2424 u2* localvariable_type_table_length = NULL;
mikael@46513 2425 const unsafe_u2** localvariable_type_table_start = NULL; // (potentially unaligned) pointer to LVTT attributes
emc@27612 2426 int method_parameters_length = -1;
mgronlun@34666 2427 const u1* method_parameters_data = NULL;
emc@15464 2428 bool method_parameters_seen = false;
duke@1 2429 bool parsed_code_attribute = false;
duke@1 2430 bool parsed_checked_exceptions_attribute = false;
duke@1 2431 bool parsed_stackmap_attribute = false;
duke@1 2432 // stackmap attribute - JDK1.5
mgronlun@34666 2433 const u1* stackmap_data = NULL;
coleenp@15935 2434 int stackmap_data_length = 0;
duke@1 2435 u2 generic_signature_index = 0;
jrose@13291 2436 MethodAnnotationCollector parsed_annotations;
mgronlun@34666 2437 const u1* runtime_visible_annotations = NULL;
duke@1 2438 int runtime_visible_annotations_length = 0;
mgronlun@34666 2439 const u1* runtime_invisible_annotations = NULL;
duke@1 2440 int runtime_invisible_annotations_length = 0;
mgronlun@34666 2441 const u1* runtime_visible_parameter_annotations = NULL;
duke@1 2442 int runtime_visible_parameter_annotations_length = 0;
mgronlun@34666 2443 const u1* runtime_invisible_parameter_annotations = NULL;
duke@1 2444 int runtime_invisible_parameter_annotations_length = 0;
mgronlun@34666 2445 const u1* runtime_visible_type_annotations = NULL;
stefank@15097 2446 int runtime_visible_type_annotations_length = 0;
mgronlun@34666 2447 const u1* runtime_invisible_type_annotations = NULL;
stefank@15097 2448 int runtime_invisible_type_annotations_length = 0;
hseigel@24432 2449 bool runtime_invisible_annotations_exists = false;
hseigel@19954 2450 bool runtime_invisible_type_annotations_exists = false;
hseigel@24432 2451 bool runtime_invisible_parameter_annotations_exists = false;
mgronlun@34666 2452 const u1* annotation_default = NULL;
duke@1 2453 int annotation_default_length = 0;
duke@1 2454
duke@1 2455 // Parse code and exceptions attribute
duke@1 2456 u2 method_attributes_count = cfs->get_u2_fast();
duke@1 2457 while (method_attributes_count--) {
mgronlun@34666 2458 cfs->guarantee_more(6, CHECK_NULL); // method_attribute_name_index, method_attribute_length
mgronlun@34666 2459 const u2 method_attribute_name_index = cfs->get_u2_fast();
mgronlun@34666 2460 const u4 method_attribute_length = cfs->get_u4_fast();
duke@1 2461 check_property(
coleenp@15935 2462 valid_symbol_at(method_attribute_name_index),
duke@1 2463 "Invalid method attribute name index %u in class file %s",
mgronlun@34666 2464 method_attribute_name_index, CHECK_NULL);
mgronlun@34666 2465
mgronlun@34666 2466 const Symbol* const method_attribute_name = cp->symbol_at(method_attribute_name_index);
duke@1 2467 if (method_attribute_name == vmSymbols::tag_code()) {
duke@1 2468 // Parse Code attribute
duke@1 2469 if (_need_verify) {
kamg@14385 2470 guarantee_property(
kamg@14385 2471 !access_flags.is_native() && !access_flags.is_abstract(),
duke@1 2472 "Code attribute in native or abstract methods in class file %s",
mgronlun@34666 2473 CHECK_NULL);
duke@1 2474 }
duke@1 2475 if (parsed_code_attribute) {
mgronlun@34666 2476 classfile_parse_error("Multiple Code attributes in class file %s",
mgronlun@34666 2477 CHECK_NULL);
duke@1 2478 }
duke@1 2479 parsed_code_attribute = true;
duke@1 2480
duke@1 2481 // Stack size, locals size, and code size
duke@1 2482 if (_major_version == 45 && _minor_version <= 2) {
mgronlun@34666 2483 cfs->guarantee_more(4, CHECK_NULL);
duke@1 2484 max_stack = cfs->get_u1_fast();
duke@1 2485 max_locals = cfs->get_u1_fast();
duke@1 2486 code_length = cfs->get_u2_fast();
duke@1 2487 } else {
mgronlun@34666 2488 cfs->guarantee_more(8, CHECK_NULL);
duke@1 2489 max_stack = cfs->get_u2_fast();
duke@1 2490 max_locals = cfs->get_u2_fast();
duke@1 2491 code_length = cfs->get_u4_fast();
duke@1 2492 }
duke@1 2493 if (_need_verify) {
duke@1 2494 guarantee_property(args_size <= max_locals,
mgronlun@34666 2495 "Arguments can't fit into locals in class file %s",
mgronlun@34666 2496 CHECK_NULL);
duke@1 2497 guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE,
duke@1 2498 "Invalid method Code length %u in class file %s",
mgronlun@34666 2499 code_length, CHECK_NULL);
duke@1 2500 }
duke@1 2501 // Code pointer
mikael@46504 2502 code_start = cfs->current();
duke@1 2503 assert(code_start != NULL, "null code start");
mgronlun@34666 2504 cfs->guarantee_more(code_length, CHECK_NULL);
duke@1 2505 cfs->skip_u1_fast(code_length);
duke@1 2506
duke@1 2507 // Exception handler table
mgronlun@34666 2508 cfs->guarantee_more(2, CHECK_NULL); // exception_table_length
duke@1 2509 exception_table_length = cfs->get_u2_fast();
duke@1 2510 if (exception_table_length > 0) {
mgronlun@34666 2511 exception_table_start = parse_exception_table(cfs,
mgronlun@34666 2512 code_length,
mgronlun@34666 2513 exception_table_length,
mgronlun@34666 2514 CHECK_NULL);
duke@1 2515 }
duke@1 2516
duke@1 2517 // Parse additional attributes in code attribute
mgronlun@34666 2518 cfs->guarantee_more(2, CHECK_NULL); // code_attributes_count
duke@1 2519 u2 code_attributes_count = cfs->get_u2_fast();
kamg@339 2520
kamg@339 2521 unsigned int calculated_attribute_length = 0;
kamg@339 2522
kamg@339 2523 if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) {
kamg@339 2524 calculated_attribute_length =
kamg@339 2525 sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length);
kamg@339 2526 } else {
kamg@339 2527 // max_stack, locals and length are smaller in pre-version 45.2 classes
kamg@339 2528 calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2);
kamg@339 2529 }
kamg@339 2530 calculated_attribute_length +=
kamg@339 2531 code_length +
kamg@339 2532 sizeof(exception_table_length) +
kamg@339 2533 sizeof(code_attributes_count) +
kamg@339 2534 exception_table_length *
kamg@339 2535 ( sizeof(u2) + // start_pc
kamg@339 2536 sizeof(u2) + // end_pc
kamg@339 2537 sizeof(u2) + // handler_pc
kamg@339 2538 sizeof(u2) ); // catch_type_index
duke@1 2539
duke@1 2540 while (code_attributes_count--) {
mgronlun@34666 2541 cfs->guarantee_more(6, CHECK_NULL); // code_attribute_name_index, code_attribute_length
mgronlun@34666 2542 const u2 code_attribute_name_index = cfs->get_u2_fast();
mgronlun@34666 2543 const u4 code_attribute_length = cfs->get_u4_fast();
duke@1 2544 calculated_attribute_length += code_attribute_length +
duke@1 2545 sizeof(code_attribute_name_index) +
duke@1 2546 sizeof(code_attribute_length);
coleenp@15935 2547 check_property(valid_symbol_at(code_attribute_name_index),
duke@1 2548 "Invalid code attribute name index %u in class file %s",
duke@1 2549 code_attribute_name_index,
mgronlun@34666 2550 CHECK_NULL);
duke@1 2551 if (LoadLineNumberTables &&
mgronlun@34666 2552 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) {
duke@1 2553 // Parse and compress line number table
mgronlun@34666 2554 parse_linenumber_table(code_attribute_length,
mgronlun@34666 2555 code_length,
mgronlun@34666 2556 &linenumber_table,
mgronlun@34666 2557 CHECK_NULL);
duke@1 2558
duke@1 2559 } else if (LoadLocalVariableTables &&
mgronlun@34666 2560 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) {
duke@1 2561 // Parse local variable table
duke@1 2562 if (!lvt_allocated) {
duke@1 2563 localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 2564 THREAD, u2, INITIAL_MAX_LVT_NUMBER);
duke@1 2565 localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
mikael@46513 2566 THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
duke@1 2567 localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 2568 THREAD, u2, INITIAL_MAX_LVT_NUMBER);
duke@1 2569 localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
mikael@46513 2570 THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
duke@1 2571 lvt_allocated = true;
duke@1 2572 }
duke@1 2573 if (lvt_cnt == max_lvt_cnt) {
duke@1 2574 max_lvt_cnt <<= 1;
iklam@20668 2575 localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
mikael@46513 2576 localvariable_table_start = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
duke@1 2577 }
duke@1 2578 localvariable_table_start[lvt_cnt] =
mgronlun@34666 2579 parse_localvariable_table(cfs,
mgronlun@34666 2580 code_length,
duke@1 2581 max_locals,
duke@1 2582 code_attribute_length,
duke@1 2583 &localvariable_table_length[lvt_cnt],
duke@1 2584 false, // is not LVTT
mgronlun@34666 2585 CHECK_NULL);
duke@1 2586 total_lvt_length += localvariable_table_length[lvt_cnt];
duke@1 2587 lvt_cnt++;
duke@1 2588 } else if (LoadLocalVariableTypeTables &&
duke@1 2589 _major_version >= JAVA_1_5_VERSION &&
mgronlun@34666 2590 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) {
duke@1 2591 if (!lvt_allocated) {
duke@1 2592 localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 2593 THREAD, u2, INITIAL_MAX_LVT_NUMBER);
duke@1 2594 localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
mikael@46513 2595 THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
duke@1 2596 localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 2597 THREAD, u2, INITIAL_MAX_LVT_NUMBER);
duke@1 2598 localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
mikael@46513 2599 THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
duke@1 2600 lvt_allocated = true;
duke@1 2601 }
duke@1 2602 // Parse local variable type table
duke@1 2603 if (lvtt_cnt == max_lvtt_cnt) {
duke@1 2604 max_lvtt_cnt <<= 1;
iklam@20668 2605 localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
mikael@46513 2606 localvariable_type_table_start = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
duke@1 2607 }
duke@1 2608 localvariable_type_table_start[lvtt_cnt] =
mgronlun@34666 2609 parse_localvariable_table(cfs,
mgronlun@34666 2610 code_length,
duke@1 2611 max_locals,
duke@1 2612 code_attribute_length,
duke@1 2613 &localvariable_type_table_length[lvtt_cnt],
duke@1 2614 true, // is LVTT
mgronlun@34666 2615 CHECK_NULL);
duke@1 2616 lvtt_cnt++;
hseigel@16445 2617 } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION &&
mgronlun@34666 2618 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) {
duke@1 2619 // Stack map is only needed by the new verifier in JDK1.5.
duke@1 2620 if (parsed_stackmap_attribute) {
mgronlun@34666 2621 classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_NULL);
duke@1 2622 }
mgronlun@34666 2623 stackmap_data = parse_stackmap_table(cfs, code_attribute_length, _need_verify, CHECK_NULL);
coleenp@15935 2624 stackmap_data_length = code_attribute_length;
duke@1 2625 parsed_stackmap_attribute = true;
duke@1 2626 } else {
duke@1 2627 // Skip unknown attributes
mgronlun@34666 2628 cfs->skip_u1(code_attribute_length, CHECK_NULL);
duke@1 2629 }
duke@1 2630 }
duke@1 2631 // check method attribute length
duke@1 2632 if (_need_verify) {
duke@1 2633 guarantee_property(method_attribute_length == calculated_attribute_length,
mgronlun@34666 2634 "Code segment has wrong length in class file %s",
mgronlun@34666 2635 CHECK_NULL);
duke@1 2636 }
duke@1 2637 } else if (method_attribute_name == vmSymbols::tag_exceptions()) {
duke@1 2638 // Parse Exceptions attribute
duke@1 2639 if (parsed_checked_exceptions_attribute) {
mgronlun@34666 2640 classfile_parse_error("Multiple Exceptions attributes in class file %s",
mgronlun@34666 2641 CHECK_NULL);
duke@1 2642 }
duke@1 2643 parsed_checked_exceptions_attribute = true;
duke@1 2644 checked_exceptions_start =
mgronlun@34666 2645 parse_checked_exceptions(cfs,
mgronlun@34666 2646 &checked_exceptions_length,
duke@1 2647 method_attribute_length,
mgronlun@34666 2648 CHECK_NULL);
coleenp@15102 2649 } else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
emc@15464 2650 // reject multiple method parameters
emc@15464 2651 if (method_parameters_seen) {
mgronlun@34666 2652 classfile_parse_error("Multiple MethodParameters attributes in class file %s",
mgronlun@34666 2653 CHECK_NULL);
emc@15464 2654 }
emc@15464 2655 method_parameters_seen = true;
coleenp@15102 2656 method_parameters_length = cfs->get_u1_fast();
emc@27612 2657 const u2 real_length = (method_parameters_length * 4u) + 1u;
emc@27612 2658 if (method_attribute_length != real_length) {
emc@15464 2659 classfile_parse_error(
emc@15464 2660 "Invalid MethodParameters method attribute length %u in class file",
mgronlun@34666 2661 method_attribute_length, CHECK_NULL);
emc@15464 2662 }
mikael@46504 2663 method_parameters_data = cfs->current();
coleenp@15102 2664 cfs->skip_u2_fast(method_parameters_length);
emc@17080 2665 cfs->skip_u2_fast(method_parameters_length);
coleenp@15102 2666 // ignore this attribute if it cannot be reflected
coleenp@15102 2667 if (!SystemDictionary::Parameter_klass_loaded())
emc@27612 2668 method_parameters_length = -1;
duke@1 2669 } else if (method_attribute_name == vmSymbols::tag_synthetic()) {
duke@1 2670 if (method_attribute_length != 0) {
duke@1 2671 classfile_parse_error(
duke@1 2672 "Invalid Synthetic method attribute length %u in class file %s",
mgronlun@34666 2673 method_attribute_length, CHECK_NULL);
duke@1 2674 }
duke@1 2675 // Should we check that there hasn't already been a synthetic attribute?
duke@1 2676 access_flags.set_is_synthetic();
duke@1 2677 } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120
duke@1 2678 if (method_attribute_length != 0) {
duke@1 2679 classfile_parse_error(
duke@1 2680 "Invalid Deprecated method attribute length %u in class file %s",
mgronlun@34666 2681 method_attribute_length, CHECK_NULL);
duke@1 2682 }
duke@1 2683 } else if (_major_version >= JAVA_1_5_VERSION) {
duke@1 2684 if (method_attribute_name == vmSymbols::tag_signature()) {
hseigel@44243 2685 if (generic_signature_index != 0) {
hseigel@44243 2686 classfile_parse_error(
hseigel@44243 2687 "Multiple Signature attributes for method in class file %s",
hseigel@44243 2688 CHECK_NULL);
hseigel@44243 2689 }
duke@1 2690 if (method_attribute_length != 2) {
duke@1 2691 classfile_parse_error(
duke@1 2692 "Invalid Signature attribute length %u in class file %s",
mgronlun@34666 2693 method_attribute_length, CHECK_NULL);
duke@1 2694 }
mgronlun@34666 2695 generic_signature_index = parse_generic_signature_attribute(cfs, CHECK_NULL);
duke@1 2696 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
hseigel@24432 2697 if (runtime_visible_annotations != NULL) {
hseigel@24432 2698 classfile_parse_error(
mgronlun@34666 2699 "Multiple RuntimeVisibleAnnotations attributes for method in class file %s",
mgronlun@34666 2700 CHECK_NULL);
hseigel@24432 2701 }
duke@1 2702 runtime_visible_annotations_length = method_attribute_length;
mikael@46504 2703 runtime_visible_annotations = cfs->current();
duke@1 2704 assert(runtime_visible_annotations != NULL, "null visible annotations");
rprotacio@43177 2705 cfs->guarantee_more(runtime_visible_annotations_length, CHECK_NULL);
mgronlun@34666 2706 parse_annotations(cp,
mgronlun@34666 2707 runtime_visible_annotations,
mgronlun@34666 2708 runtime_visible_annotations_length,
mgronlun@34666 2709 &parsed_annotations,
mgronlun@34666 2710 _loader_data,
mgronlun@34666 2711 CHECK_NULL);
rprotacio@43177 2712 cfs->skip_u1_fast(runtime_visible_annotations_length);
hseigel@24432 2713 } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
hseigel@24432 2714 if (runtime_invisible_annotations_exists) {
hseigel@24432 2715 classfile_parse_error(
mgronlun@34666 2716 "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s",
mgronlun@34666 2717 CHECK_NULL);
hseigel@24432 2718 }
hseigel@24432 2719 runtime_invisible_annotations_exists = true;
hseigel@24432 2720 if (PreserveAllAnnotations) {
hseigel@24432 2721 runtime_invisible_annotations_length = method_attribute_length;
mikael@46504 2722 runtime_invisible_annotations = cfs->current();
hseigel@24432 2723 assert(runtime_invisible_annotations != NULL, "null invisible annotations");
hseigel@24432 2724 }
mgronlun@34666 2725 cfs->skip_u1(method_attribute_length, CHECK_NULL);
duke@1 2726 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) {
hseigel@24432 2727 if (runtime_visible_parameter_annotations != NULL) {
hseigel@24432 2728 classfile_parse_error(
mgronlun@34666 2729 "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s",
mgronlun@34666 2730 CHECK_NULL);
hseigel@24432 2731 }
duke@1 2732 runtime_visible_parameter_annotations_length = method_attribute_length;
mikael@46504 2733 runtime_visible_parameter_annotations = cfs->current();
duke@1 2734 assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations");
mgronlun@34666 2735 cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_NULL);
hseigel@24432 2736 } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) {
hseigel@24432 2737 if (runtime_invisible_parameter_annotations_exists) {
hseigel@24432 2738 classfile_parse_error(
mgronlun@34666 2739 "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s",
mgronlun@34666 2740 CHECK_NULL);
hseigel@24432 2741 }
hseigel@24432 2742 runtime_invisible_parameter_annotations_exists = true;
hseigel@24432 2743 if (PreserveAllAnnotations) {
hseigel@24432 2744 runtime_invisible_parameter_annotations_length = method_attribute_length;
mikael@46504 2745 runtime_invisible_parameter_annotations = cfs->current();
mgronlun@34666 2746 assert(runtime_invisible_parameter_annotations != NULL,
mgronlun@34666 2747 "null invisible parameter annotations");
hseigel@24432 2748 }
mgronlun@34666 2749 cfs->skip_u1(method_attribute_length, CHECK_NULL);
duke@1 2750 } else if (method_attribute_name == vmSymbols::tag_annotation_default()) {
hseigel@24432 2751 if (annotation_default != NULL) {
hseigel@24432 2752 classfile_parse_error(
hseigel@24432 2753 "Multiple AnnotationDefault attributes for method in class file %s",
mgronlun@34666 2754 CHECK_NULL);
hseigel@24432 2755 }
duke@1 2756 annotation_default_length = method_attribute_length;
mikael@46504 2757 annotation_default = cfs->current();
duke@1 2758 assert(annotation_default != NULL, "null annotation default");
mgronlun@34666 2759 cfs->skip_u1(annotation_default_length, CHECK_NULL);
stefank@15097 2760 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
hseigel@19954 2761 if (runtime_visible_type_annotations != NULL) {
hseigel@19954 2762 classfile_parse_error(
hseigel@19954 2763 "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s",
mgronlun@34666 2764 CHECK_NULL);
hseigel@19954 2765 }
stefank@15097 2766 runtime_visible_type_annotations_length = method_attribute_length;
mikael@46504 2767 runtime_visible_type_annotations = cfs->current();
stefank@15097 2768 assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
stefank@15097 2769 // No need for the VM to parse Type annotations
mgronlun@34666 2770 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_NULL);
hseigel@19954 2771 } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
hseigel@19954 2772 if (runtime_invisible_type_annotations_exists) {
hseigel@19954 2773 classfile_parse_error(
hseigel@19954 2774 "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s",
mgronlun@34666 2775 CHECK_NULL);
hseigel@19954 2776 } else {
hseigel@19954 2777 runtime_invisible_type_annotations_exists = true;
hseigel@19954 2778 }
hseigel@19954 2779 if (PreserveAllAnnotations) {
hseigel@19954 2780 runtime_invisible_type_annotations_length = method_attribute_length;
mikael@46504 2781 runtime_invisible_type_annotations = cfs->current();
hseigel@19954 2782 assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
hseigel@19954 2783 }
mgronlun@34666 2784 cfs->skip_u1(method_attribute_length, CHECK_NULL);
duke@1 2785 } else {
duke@1 2786 // Skip unknown attributes
mgronlun@34666 2787 cfs->skip_u1(method_attribute_length, CHECK_NULL);
duke@1 2788 }
duke@1 2789 } else {
duke@1 2790 // Skip unknown attributes
mgronlun@34666 2791 cfs->skip_u1(method_attribute_length, CHECK_NULL);
duke@1 2792 }
duke@1 2793 }
duke@1 2794
duke@1 2795 if (linenumber_table != NULL) {
duke@1 2796 linenumber_table->write_terminator();
duke@1 2797 linenumber_table_length = linenumber_table->position();
duke@1 2798 }
duke@1 2799
duke@1 2800 // Make sure there's at least one Code attribute in non-native/non-abstract method
duke@1 2801 if (_need_verify) {
mgronlun@34666 2802 guarantee_property(access_flags.is_native() ||
mgronlun@34666 2803 access_flags.is_abstract() ||
mgronlun@34666 2804 parsed_code_attribute,
mgronlun@34666 2805 "Absent Code attribute in method that is not native or abstract in class file %s",
mgronlun@34666 2806 CHECK_NULL);
duke@1 2807 }
duke@1 2808
coleenp@13728 2809 // All sizing information for a Method* is finally available, now create it
coleenp@15601 2810 InlineTableSizes sizes(
coleenp@15601 2811 total_lvt_length,
coleenp@15601 2812 linenumber_table_length,
coleenp@15601 2813 exception_table_length,
coleenp@15601 2814 checked_exceptions_length,
coleenp@15601 2815 method_parameters_length,
coleenp@15601 2816 generic_signature_index,
coleenp@15601 2817 runtime_visible_annotations_length +
coleenp@15601 2818 runtime_invisible_annotations_length,
coleenp@15601 2819 runtime_visible_parameter_annotations_length +
coleenp@15601 2820 runtime_invisible_parameter_annotations_length,
coleenp@15601 2821 runtime_visible_type_annotations_length +
coleenp@15601 2822 runtime_invisible_type_annotations_length,
coleenp@15601 2823 annotation_default_length,
coleenp@15601 2824 0);
coleenp@15601 2825
mgronlun@34666 2826 Method* const m = Method::allocate(_loader_data,
mgronlun@34666 2827 code_length,
mgronlun@34666 2828 access_flags,
mgronlun@34666 2829 &sizes,
mgronlun@34666 2830 ConstMethod::NORMAL,
mgronlun@34666 2831 CHECK_NULL);
coleenp@13728 2832
coleenp@35898 2833 ClassLoadingService::add_class_method_size(m->size()*wordSize);
duke@1 2834
duke@1 2835 // Fill in information from fixed part (access_flags already set)
coleenp@15935 2836 m->set_constants(_cp);
duke@1 2837 m->set_name_index(name_index);
duke@1 2838 m->set_signature_index(signature_index);
coleenp@37480 2839
mgronlun@34666 2840 ResultTypeFinder rtf(cp->symbol_at(signature_index));
coleenp@37480 2841 m->constMethod()->set_result_type(rtf.type());
duke@1 2842
duke@1 2843 if (args_size >= 0) {
duke@1 2844 m->set_size_of_parameters(args_size);
duke@1 2845 } else {
duke@1 2846 m->compute_size_of_parameters(THREAD);
duke@1 2847 }
duke@1 2848 #ifdef ASSERT
duke@1 2849 if (args_size >= 0) {
duke@1 2850 m->compute_size_of_parameters(THREAD);
duke@1 2851 assert(args_size == m->size_of_parameters(), "");
duke@1 2852 }
duke@1 2853 #endif
duke@1 2854
duke@1 2855 // Fill in code attribute information
duke@1 2856 m->set_max_stack(max_stack);
duke@1 2857 m->set_max_locals(max_locals);
coleenp@15935 2858 if (stackmap_data != NULL) {
mgronlun@34666 2859 m->constMethod()->copy_stackmap_data(_loader_data,
mgronlun@34666 2860 (u1*)stackmap_data,
mgronlun@34666 2861 stackmap_data_length,
mgronlun@34666 2862 CHECK_NULL);
coleenp@15935 2863 }
duke@1 2864
duke@1 2865 // Copy byte codes
mgronlun@34666 2866 m->set_code((u1*)code_start);
duke@1 2867
duke@1 2868 // Copy line number table
duke@1 2869 if (linenumber_table != NULL) {
duke@1 2870 memcpy(m->compressed_linenumber_table(),
mgronlun@34666 2871 linenumber_table->buffer(),
mgronlun@34666 2872 linenumber_table_length);
duke@1 2873 }
duke@1 2874
jiangli@13282 2875 // Copy exception table
jiangli@13282 2876 if (exception_table_length > 0) {
mikael@46504 2877 Copy::conjoint_swap_if_needed<Endian::JAVA>(exception_table_start,
mikael@46504 2878 m->exception_table_start(),
mikael@46504 2879 exception_table_length * sizeof(ExceptionTableElement),
mikael@46504 2880 sizeof(u2));
jiangli@13282 2881 }
jiangli@13282 2882
coleenp@15102 2883 // Copy method parameters
coleenp@15102 2884 if (method_parameters_length > 0) {
coleenp@15102 2885 MethodParametersElement* elem = m->constMethod()->method_parameters_start();
emc@15464 2886 for (int i = 0; i < method_parameters_length; i++) {
mgronlun@34666 2887 elem[i].name_cp_index = Bytes::get_Java_u2((address)method_parameters_data);
coleenp@15102 2888 method_parameters_data += 2;
mgronlun@34666 2889 elem[i].flags = Bytes::get_Java_u2((address)method_parameters_data);
emc@17080 2890 method_parameters_data += 2;
coleenp@15102 2891 }
coleenp@15102 2892 }
coleenp@15102 2893
duke@1 2894 // Copy checked exceptions
duke@1 2895 if (checked_exceptions_length > 0) {
mikael@46504 2896 Copy::conjoint_swap_if_needed<Endian::JAVA>(checked_exceptions_start,
mikael@46504 2897 m->checked_exceptions_start(),
mikael@46504 2898 checked_exceptions_length * sizeof(CheckedExceptionElement),
mikael@46504 2899 sizeof(u2));
duke@1 2900 }
duke@1 2901
coleenp@15601 2902 // Copy class file LVT's/LVTT's into the HotSpot internal LVT.
duke@1 2903 if (total_lvt_length > 0) {
duke@1 2904 promoted_flags->set_has_localvariable_table();
mgronlun@34666 2905 copy_localvariable_table(m->constMethod(),
mgronlun@34666 2906 lvt_cnt,
coleenp@15601 2907 localvariable_table_length,
coleenp@15601 2908 localvariable_table_start,
coleenp@15601 2909 lvtt_cnt,
coleenp@15601 2910 localvariable_type_table_length,
mgronlun@34666 2911 localvariable_type_table_start,
mgronlun@34666 2912 CHECK_NULL);
duke@1 2913 }
duke@1 2914
jrose@13291 2915 if (parsed_annotations.has_any_annotations())
jrose@13291 2916 parsed_annotations.apply_to(m);
coleenp@15601 2917
coleenp@15601 2918 // Copy annotations
coleenp@15935 2919 copy_method_annotations(m->constMethod(),
coleenp@15601 2920 runtime_visible_annotations,
coleenp@15601 2921 runtime_visible_annotations_length,
coleenp@15601 2922 runtime_invisible_annotations,
coleenp@15601 2923 runtime_invisible_annotations_length,
coleenp@15601 2924 runtime_visible_parameter_annotations,
coleenp@15601 2925 runtime_visible_parameter_annotations_length,
coleenp@15601 2926 runtime_invisible_parameter_annotations,
coleenp@15601 2927 runtime_invisible_parameter_annotations_length,
coleenp@15601 2928 runtime_visible_type_annotations,
coleenp@15601 2929 runtime_visible_type_annotations_length,
coleenp@15601 2930 runtime_invisible_type_annotations,
coleenp@15601 2931 runtime_invisible_type_annotations_length,
coleenp@15601 2932 annotation_default,
coleenp@15601 2933 annotation_default_length,
coleenp@15601 2934 CHECK_NULL);
duke@1 2935
coleenp@8076 2936 if (name == vmSymbols::finalize_method_name() &&
coleenp@8076 2937 signature == vmSymbols::void_method_signature()) {
duke@1 2938 if (m->is_empty_method()) {
duke@1 2939 _has_empty_finalizer = true;
duke@1 2940 } else {
duke@1 2941 _has_finalizer = true;
duke@1 2942 }
duke@1 2943 }
coleenp@8076 2944 if (name == vmSymbols::object_initializer_name() &&
coleenp@8076 2945 signature == vmSymbols::void_method_signature() &&
duke@1 2946 m->is_vanilla_constructor()) {
duke@1 2947 _has_vanilla_constructor = true;
duke@1 2948 }
duke@1 2949
coleenp@15601 2950 NOT_PRODUCT(m->verify());
duke@1 2951 return m;
duke@1 2952 }
duke@1 2953
duke@1 2954
duke@1 2955 // The promoted_flags parameter is used to pass relevant access_flags
duke@1 2956 // from the methods back up to the containing klass. These flag values
duke@1 2957 // are added to klass's access_flags.
mgronlun@34666 2958 // Side-effects: populates the _methods field in the parser
mgronlun@34666 2959 void ClassFileParser::parse_methods(const ClassFileStream* const cfs,
mgronlun@34666 2960 bool is_interface,
mgronlun@34666 2961 AccessFlags* promoted_flags,
mgronlun@34666 2962 bool* has_final_method,
dholmes@41669 2963 bool* declares_nonstatic_concrete_methods,
mgronlun@34666 2964 TRAPS) {
mgronlun@34666 2965 assert(cfs != NULL, "invariant");
mgronlun@34666 2966 assert(promoted_flags != NULL, "invariant");
mgronlun@34666 2967 assert(has_final_method != NULL, "invariant");
dholmes@41669 2968 assert(declares_nonstatic_concrete_methods != NULL, "invariant");
mgronlun@34666 2969
mgronlun@34666 2970 assert(NULL == _methods, "invariant");
mgronlun@34666 2971
mgronlun@34666 2972 cfs->guarantee_more(2, CHECK); // length
mgronlun@34666 2973 const u2 length = cfs->get_u2_fast();
duke@1 2974 if (length == 0) {
coleenp@15935 2975 _methods = Universe::the_empty_method_array();
duke@1 2976 } else {
mgronlun@34666 2977 _methods = MetadataFactory::new_array<Method*>(_loader_data,
mgronlun@34666 2978 length,
mgronlun@34666 2979 NULL,
mgronlun@34666 2980 CHECK);
coleenp@13728 2981
duke@1 2982 for (int index = 0; index < length; index++) {
mgronlun@34666 2983 Method* method = parse_method(cfs,
mgronlun@34666 2984 is_interface,
mgronlun@34666 2985 _cp,
mgronlun@34666 2986 promoted_flags,
mgronlun@34666 2987 CHECK);
coleenp@13728 2988
duke@1 2989 if (method->is_final()) {
duke@1 2990 *has_final_method = true;
duke@1 2991 }
dholmes@41669 2992 // declares_nonstatic_concrete_methods: declares concrete instance methods, any access flags
acorn@27402 2993 // used for interface initialization, and default method inheritance analysis
dholmes@41669 2994 if (is_interface && !(*declares_nonstatic_concrete_methods)
acorn@27402 2995 && !method->is_abstract() && !method->is_static()) {
dholmes@41669 2996 *declares_nonstatic_concrete_methods = true;
kamg@14385 2997 }
mgronlun@34666 2998 _methods->at_put(index, method);
duke@1 2999 }
stefank@15097 3000
duke@1 3001 if (_need_verify && length > 1) {
duke@1 3002 // Check duplicated methods
duke@1 3003 ResourceMark rm(THREAD);
duke@1 3004 NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
duke@1 3005 THREAD, NameSigHash*, HASH_ROW_SIZE);
duke@1 3006 initialize_hashtable(names_and_sigs);
duke@1 3007 bool dup = false;
shshahma@46301 3008 const Symbol* name = NULL;
shshahma@46301 3009 const Symbol* sig = NULL;
duke@1 3010 {
david@35492 3011 debug_only(NoSafepointVerifier nsv;)
duke@1 3012 for (int i = 0; i < length; i++) {
mgronlun@34666 3013 const Method* const m = _methods->at(i);
shshahma@46301 3014 name = m->name();
shshahma@46301 3015 sig = m->signature();
duke@1 3016 // If no duplicates, add name/signature in hashtable names_and_sigs.
shshahma@46301 3017 if (!put_after_lookup(name, sig, names_and_sigs)) {
duke@1 3018 dup = true;
duke@1 3019 break;
duke@1 3020 }
duke@1 3021 }
duke@1 3022 }
duke@1 3023 if (dup) {
shshahma@46301 3024 classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s",
shshahma@46301 3025 name->as_C_string(), sig->as_klass_external_name(), CHECK);
duke@1 3026 }
duke@1 3027 }
duke@1 3028 }
duke@1 3029 }
duke@1 3030
mgronlun@34666 3031 static const intArray* sort_methods(Array<Method*>* methods) {
mgronlun@34666 3032 const int length = methods->length();
coleenp@9172 3033 // If JVMTI original method ordering or sharing is enabled we have to
duke@1 3034 // remember the original class file ordering.
coleenp@13728 3035 // We temporarily use the vtable_index field in the Method* to store the
duke@1 3036 // class file index, so we can read in after calling qsort.
coleenp@9172 3037 // Put the method ordering in the shared archive.
coleenp@9172 3038 if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
duke@1 3039 for (int index = 0; index < length; index++) {
mgronlun@34666 3040 Method* const m = methods->at(index);
duke@1 3041 assert(!m->valid_vtable_index(), "vtable index should not be set");
duke@1 3042 m->set_vtable_index(index);
duke@1 3043 }
duke@1 3044 }
duke@1 3045 // Sort method array by ascending method name (for faster lookups & vtable construction)
coleenp@8076 3046 // Note that the ordering is not alphabetical, see Symbol::fast_compare
coleenp@15601 3047 Method::sort_methods(methods);
duke@1 3048
coleenp@15935 3049 intArray* method_ordering = NULL;
coleenp@9172 3050 // If JVMTI original method ordering or sharing is enabled construct int
coleenp@9172 3051 // array remembering the original ordering
coleenp@9172 3052 if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
fzhinkin@38031 3053 method_ordering = new intArray(length, length, -1);
duke@1 3054 for (int index = 0; index < length; index++) {
mgronlun@34666 3055 Method* const m = methods->at(index);
mgronlun@34666 3056 const int old_index = m->vtable_index();
duke@1 3057 assert(old_index >= 0 && old_index < length, "invalid method index");
coleenp@13728 3058 method_ordering->at_put(index, old_index);
coleenp@13728 3059 m->set_vtable_index(Method::invalid_vtable_index);
duke@1 3060 }
duke@1 3061 }
coleenp@15935 3062 return method_ordering;
duke@1 3063 }
duke@1 3064
acorn@25507 3065 // Parse generic_signature attribute for methods and fields
mgronlun@34666 3066 u2 ClassFileParser::parse_generic_signature_attribute(const ClassFileStream* const cfs,
mgronlun@34666 3067 TRAPS) {
mgronlun@34666 3068 assert(cfs != NULL, "invariant");
mgronlun@34666 3069
acorn@25507 3070 cfs->guarantee_more(2, CHECK_0); // generic_signature_index
mgronlun@34666 3071 const u2 generic_signature_index = cfs->get_u2_fast();
acorn@25507 3072 check_property(
acorn@25507 3073 valid_symbol_at(generic_signature_index),
acorn@25507 3074 "Invalid Signature attribute at constant pool index %u in class file %s",
acorn@25507 3075 generic_signature_index, CHECK_0);
acorn@25507 3076 return generic_signature_index;
acorn@25507 3077 }
duke@1 3078
mgronlun@34666 3079 void ClassFileParser::parse_classfile_sourcefile_attribute(const ClassFileStream* const cfs,
mgronlun@34666 3080 TRAPS) {
mgronlun@34666 3081
mgronlun@34666 3082 assert(cfs != NULL, "invariant");
mgronlun@34666 3083
duke@1 3084 cfs->guarantee_more(2, CHECK); // sourcefile_index
mgronlun@34666 3085 const u2 sourcefile_index = cfs->get_u2_fast();
duke@1 3086 check_property(
coleenp@15935 3087 valid_symbol_at(sourcefile_index),
duke@1 3088 "Invalid SourceFile attribute at constant pool index %u in class file %s",
duke@1 3089 sourcefile_index, CHECK);
jiangli@19326 3090 set_class_sourcefile_index(sourcefile_index);
duke@1 3091 }
duke@1 3092
mgronlun@34666 3093 void ClassFileParser::parse_classfile_source_debug_extension_attribute(const ClassFileStream* const cfs,
mgronlun@34666 3094 int length,
mgronlun@34666 3095 TRAPS) {
mgronlun@34666 3096 assert(cfs != NULL, "invariant");
mgronlun@34666 3097
mikael@46504 3098 const u1* const sde_buffer = cfs->current();
duke@1 3099 assert(sde_buffer != NULL, "null sde buffer");
duke@1 3100
duke@1 3101 // Don't bother storing it if there is no way to retrieve it
duke@1 3102 if (JvmtiExport::can_get_source_debug_extension()) {
kvn@13295 3103 assert((length+1) > length, "Overflow checking");
mgronlun@34666 3104 u1* const sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1);
kvn@13295 3105 for (int i = 0; i < length; i++) {
kvn@13295 3106 sde[i] = sde_buffer[i];
kvn@13295 3107 }
kvn@13295 3108 sde[length] = '\0';
mgronlun@34666 3109 set_class_sde_buffer((const char*)sde, length);
duke@1 3110 }
duke@1 3111 // Got utf8 string, set stream position forward
duke@1 3112 cfs->skip_u1(length, CHECK);
duke@1 3113 }
duke@1 3114
duke@1 3115
duke@1 3116 // Inner classes can be static, private or protected (classic VM does this)
mgronlun@34666 3117 #define RECOGNIZED_INNER_CLASS_MODIFIERS ( JVM_RECOGNIZED_CLASS_MODIFIERS | \
mgronlun@34666 3118 JVM_ACC_PRIVATE | \
mgronlun@34666 3119 JVM_ACC_PROTECTED | \
mgronlun@34666 3120 JVM_ACC_STATIC \
mgronlun@34666 3121 )
duke@1 3122
duke@1 3123 // Return number of classes in the inner classes attribute table
mgronlun@34666 3124 u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStream* const cfs,
mgronlun@34666 3125 const u1* const inner_classes_attribute_start,
jiangli@12231 3126 bool parsed_enclosingmethod_attribute,
jiangli@12231 3127 u2 enclosing_method_class_index,
jiangli@12231 3128 u2 enclosing_method_method_index,
jrose@13291 3129 TRAPS) {
mgronlun@34666 3130 const u1* const current_mark = cfs->current();
jiangli@12231 3131 u2 length = 0;
jiangli@12231 3132 if (inner_classes_attribute_start != NULL) {
jiangli@12231 3133 cfs->set_current(inner_classes_attribute_start);
jiangli@12231 3134 cfs->guarantee_more(2, CHECK_0); // length
jiangli@12231 3135 length = cfs->get_u2_fast();
jiangli@12231 3136 }
jiangli@12231 3137
jiangli@12231 3138 // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
jiangli@12231 3139 // method data:
jiangli@12231 3140 // [inner_class_info_index,
jiangli@12231 3141 // outer_class_info_index,
jiangli@12231 3142 // inner_name_index,
jiangli@12231 3143 // inner_class_access_flags,
jiangli@12231 3144 // ...
jiangli@12231 3145 // enclosing_method_class_index,
jiangli@12231 3146 // enclosing_method_method_index]
mgronlun@34666 3147 const int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
mgronlun@34666 3148 Array<u2>* const inner_classes = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
coleenp@15935 3149 _inner_classes = inner_classes;
coleenp@15935 3150
duke@1 3151 int index = 0;
duke@1 3152 cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2
duke@1 3153 for (int n = 0; n < length; n++) {
duke@1 3154 // Inner class index
mgronlun@34666 3155 const u2 inner_class_info_index = cfs->get_u2_fast();
duke@1 3156 check_property(
hseigel@31776 3157 valid_klass_reference_at(inner_class_info_index),
duke@1 3158 "inner_class_info_index %u has bad constant type in class file %s",
duke@1 3159 inner_class_info_index, CHECK_0);
duke@1 3160 // Outer class index
mgronlun@34666 3161 const u2 outer_class_info_index = cfs->get_u2_fast();
duke@1 3162 check_property(
duke@1 3163 outer_class_info_index == 0 ||
coleenp@15935 3164 valid_klass_reference_at(outer_class_info_index),
duke@1 3165 "outer_class_info_index %u has bad constant type in class file %s",
duke@1 3166 outer_class_info_index, CHECK_0);
duke@1 3167 // Inner class name
mgronlun@34666 3168 const u2 inner_name_index = cfs->get_u2_fast();
duke@1 3169 check_property(
coleenp@15935 3170 inner_name_index == 0 || valid_symbol_at(inner_name_index),
duke@1 3171 "inner_name_index %u has bad constant type in class file %s",
duke@1 3172 inner_name_index, CHECK_0);
duke@1 3173 if (_need_verify) {
duke@1 3174 guarantee_property(inner_class_info_index != outer_class_info_index,