comparison src/share/vm/classfile/classFileParser.cpp @ 1922:5caa30ea147b

Merge
author iveresov
date Mon, 08 Nov 2010 14:33:48 -0800
parents 6412b3805cd6 3b2dea75431e
children f95d63e2154a
comparison
equal deleted inserted replaced
1892:4ac698856c43 1922:5caa30ea147b
1 /* 1 /*
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
71 int lengths[SymbolTable::symbol_alloc_batch_size]; 71 int lengths[SymbolTable::symbol_alloc_batch_size];
72 int indices[SymbolTable::symbol_alloc_batch_size]; 72 int indices[SymbolTable::symbol_alloc_batch_size];
73 unsigned int hashValues[SymbolTable::symbol_alloc_batch_size]; 73 unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
74 int names_count = 0; 74 int names_count = 0;
75 75
76 // Side buffer for operands of variable-sized (InvokeDynamic) entries.
77 GrowableArray<int>* operands = NULL;
78 #ifdef ASSERT
79 GrowableArray<int>* indy_instructions = new GrowableArray<int>(THREAD, 10);
80 #endif
81
76 // parsing Index 0 is unused 82 // parsing Index 0 is unused
77 for (int index = 1; index < length; index++) { 83 for (int index = 1; index < length; index++) {
78 // Each of the following case guarantees one more byte in the stream 84 // Each of the following case guarantees one more byte in the stream
79 // for the following tag or the access_flags following constant pool, 85 // for the following tag or the access_flags following constant pool,
80 // so we don't need bounds-check for reading tag. 86 // so we don't need bounds-check for reading tag.
139 cp->method_type_index_at_put(index, signature_index); 145 cp->method_type_index_at_put(index, signature_index);
140 } else { 146 } else {
141 ShouldNotReachHere(); 147 ShouldNotReachHere();
142 } 148 }
143 break; 149 break;
150 case JVM_CONSTANT_InvokeDynamicTrans : // this tag appears only in old classfiles
144 case JVM_CONSTANT_InvokeDynamic : 151 case JVM_CONSTANT_InvokeDynamic :
145 { 152 {
146 if (!EnableInvokeDynamic || 153 if (!EnableInvokeDynamic ||
147 _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { 154 _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
148 classfile_parse_error( 155 classfile_parse_error(
149 (!EnableInvokeDynamic ? 156 (!EnableInvokeDynamic ?
150 "This JVM does not support constant tag %u in class file %s" : 157 "This JVM does not support constant tag %u in class file %s" :
151 "Class file version does not support constant tag %u in class file %s"), 158 "Class file version does not support constant tag %u in class file %s"),
152 tag, CHECK); 159 tag, CHECK);
153 } 160 }
154 cfs->guarantee_more(5, CHECK); // bsm_index, name_and_type_index, tag/access_flags 161 if (!AllowTransitionalJSR292 && tag == JVM_CONSTANT_InvokeDynamicTrans) {
162 classfile_parse_error(
163 "This JVM does not support transitional InvokeDynamic tag %u in class file %s",
164 tag, CHECK);
165 }
166 bool trans_no_argc = AllowTransitionalJSR292 && (tag == JVM_CONSTANT_InvokeDynamicTrans);
167 cfs->guarantee_more(7, CHECK); // bsm_index, nt, argc, ..., tag/access_flags
155 u2 bootstrap_method_index = cfs->get_u2_fast(); 168 u2 bootstrap_method_index = cfs->get_u2_fast();
156 u2 name_and_type_index = cfs->get_u2_fast(); 169 u2 name_and_type_index = cfs->get_u2_fast();
157 cp->invoke_dynamic_at_put(index, bootstrap_method_index, name_and_type_index); 170 int argument_count = trans_no_argc ? 0 : cfs->get_u2_fast();
171 cfs->guarantee_more(2*argument_count + 1, CHECK); // argv[argc]..., tag/access_flags
172 int argv_offset = constantPoolOopDesc::_indy_argv_offset;
173 int op_count = argv_offset + argument_count; // bsm, nt, argc, argv[]...
174 int op_base = start_operand_group(operands, op_count, CHECK);
175 assert(argv_offset == 3, "else adjust next 3 assignments");
176 operands->at_put(op_base + constantPoolOopDesc::_indy_bsm_offset, bootstrap_method_index);
177 operands->at_put(op_base + constantPoolOopDesc::_indy_nt_offset, name_and_type_index);
178 operands->at_put(op_base + constantPoolOopDesc::_indy_argc_offset, argument_count);
179 for (int arg_i = 0; arg_i < argument_count; arg_i++) {
180 int arg = cfs->get_u2_fast();
181 operands->at_put(op_base + constantPoolOopDesc::_indy_argv_offset + arg_i, arg);
182 }
183 cp->invoke_dynamic_at_put(index, op_base, op_count);
184 #ifdef ASSERT
185 // Record the steps just taken for later checking.
186 indy_instructions->append(index);
187 indy_instructions->append(bootstrap_method_index);
188 indy_instructions->append(name_and_type_index);
189 indy_instructions->append(argument_count);
190 #endif //ASSERT
158 } 191 }
159 break; 192 break;
160 case JVM_CONSTANT_Integer : 193 case JVM_CONSTANT_Integer :
161 { 194 {
162 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags 195 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags
255 // Allocate the remaining symbols 288 // Allocate the remaining symbols
256 if (names_count > 0) { 289 if (names_count > 0) {
257 oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); 290 oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
258 } 291 }
259 292
293 if (operands != NULL && operands->length() > 0) {
294 store_operand_array(operands, cp, CHECK);
295 }
296 #ifdef ASSERT
297 // Re-assert the indy structures, now that assertion checking can work.
298 for (int indy_i = 0; indy_i < indy_instructions->length(); ) {
299 int index = indy_instructions->at(indy_i++);
300 int bootstrap_method_index = indy_instructions->at(indy_i++);
301 int name_and_type_index = indy_instructions->at(indy_i++);
302 int argument_count = indy_instructions->at(indy_i++);
303 assert(cp->check_invoke_dynamic_at(index,
304 bootstrap_method_index, name_and_type_index,
305 argument_count),
306 "indy structure is OK");
307 }
308 #endif //ASSERT
309
260 // Copy _current pointer of local copy back to stream(). 310 // Copy _current pointer of local copy back to stream().
261 #ifdef ASSERT 311 #ifdef ASSERT
262 assert(cfs0->current() == old_current, "non-exclusive use of stream()"); 312 assert(cfs0->current() == old_current, "non-exclusive use of stream()");
263 #endif 313 #endif
264 cfs0->set_current(cfs1.current()); 314 cfs0->set_current(cfs1.current());
265 } 315 }
316
317 int ClassFileParser::start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS) {
318 if (operands == NULL) {
319 operands = new GrowableArray<int>(THREAD, 100);
320 int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
321 while (operands->length() <= fillp_offset)
322 operands->append(0); // force op_base > 0, for an error check
323 DEBUG_ONLY(operands->at_put(fillp_offset, (int)badHeapWordVal));
324 }
325 int cnt_pos = operands->append(op_count);
326 int arg_pos = operands->length();
327 operands->at_grow(arg_pos + op_count - 1); // grow to include the operands
328 assert(operands->length() == arg_pos + op_count, "");
329 int op_base = cnt_pos - constantPoolOopDesc::_multi_operand_count_offset;
330 return op_base;
331 }
332
333 void ClassFileParser::store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS) {
334 // Collect the buffer of operands from variable-sized entries into a permanent array.
335 int arraylen = operands->length();
336 int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
337 assert(operands->at(fillp_offset) == (int)badHeapWordVal, "value unused so far");
338 operands->at_put(fillp_offset, arraylen);
339 cp->multi_operand_buffer_grow(arraylen, CHECK);
340 typeArrayOop operands_oop = cp->operands();
341 assert(operands_oop->length() == arraylen, "");
342 for (int i = 0; i < arraylen; i++) {
343 operands_oop->int_at_put(i, operands->at(i));
344 }
345 cp->set_operands(operands_oop);
346 // The fill_pointer is used only by constantPoolOop::copy_entry_to and friends,
347 // when constant pools need to be merged. Make sure it is sane now.
348 assert(cp->multi_operand_buffer_fill_pointer() == arraylen, "");
349 }
350
266 351
267 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } 352 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
268 353
269 constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { 354 constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
270 ClassFileStream* cfs = stream(); 355 ClassFileStream* cfs = stream();
429 EnableMethodHandles, 514 EnableMethodHandles,
430 "Invalid constant pool index %u in class file %s", 515 "Invalid constant pool index %u in class file %s",
431 ref_index, CHECK_(nullHandle)); 516 ref_index, CHECK_(nullHandle));
432 } 517 }
433 break; 518 break;
519 case JVM_CONSTANT_InvokeDynamicTrans :
520 ShouldNotReachHere(); // this tag does not appear in the heap
434 case JVM_CONSTANT_InvokeDynamic : 521 case JVM_CONSTANT_InvokeDynamic :
435 { 522 {
436 int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index); 523 int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
437 int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); 524 int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
438 check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292) 525 check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292)
439 || 526 ||
440 (valid_cp_range(bootstrap_method_ref_index, length) && 527 (valid_cp_range(bootstrap_method_ref_index, length) &&
441 cp->tag_at(bootstrap_method_ref_index).is_method_handle()), 528 (cp->tag_at(bootstrap_method_ref_index).is_method_handle())),
442 "Invalid constant pool index %u in class file %s", 529 "Invalid constant pool index %u in class file %s",
443 bootstrap_method_ref_index, 530 bootstrap_method_ref_index,
444 CHECK_(nullHandle)); 531 CHECK_(nullHandle));
445 check_property(valid_cp_range(name_and_type_ref_index, length) && 532 check_property(valid_cp_range(name_and_type_ref_index, length) &&
446 cp->tag_at(name_and_type_ref_index).is_name_and_type(), 533 cp->tag_at(name_and_type_ref_index).is_name_and_type(),
447 "Invalid constant pool index %u in class file %s", 534 "Invalid constant pool index %u in class file %s",
448 name_and_type_ref_index, 535 name_and_type_ref_index,
449 CHECK_(nullHandle)); 536 CHECK_(nullHandle));
537 int argc = cp->invoke_dynamic_argument_count_at(index);
538 for (int arg_i = 0; arg_i < argc; arg_i++) {
539 int arg = cp->invoke_dynamic_argument_index_at(index, arg_i);
540 check_property(valid_cp_range(arg, length) &&
541 cp->tag_at(arg).is_loadable_constant() ||
542 // temporary early forms of string and class:
543 cp->tag_at(arg).is_klass_index() ||
544 cp->tag_at(arg).is_string_index(),
545 "Invalid constant pool index %u in class file %s",
546 arg,
547 CHECK_(nullHandle));
548 }
450 break; 549 break;
451 } 550 }
452 default: 551 default:
453 fatal(err_msg("bad constant pool tag value %u", 552 fatal(err_msg("bad constant pool tag value %u",
454 cp->tag_at(index).value())); 553 cp->tag_at(index).value()));
2514 // 2613 //
2515 // Check the fields in java.lang.ref.Reference for the "discovered" 2614 // Check the fields in java.lang.ref.Reference for the "discovered"
2516 // field. If it is not present, artifically create a field for it. 2615 // field. If it is not present, artifically create a field for it.
2517 // This allows this VM to run on early JDK where the field is not 2616 // This allows this VM to run on early JDK where the field is not
2518 // present. 2617 // present.
2519
2520 //
2521 // Increment fac.nonstatic_oop_count so that the start of the
2522 // next type of non-static oops leaves room for the fake oop.
2523 // Do not increment next_nonstatic_oop_offset so that the
2524 // fake oop is place after the java.lang.ref.Reference oop
2525 // fields.
2526 //
2527 // Check the fields in java.lang.ref.Reference for the "discovered"
2528 // field. If it is not present, artifically create a field for it.
2529 // This allows this VM to run on early JDK where the field is not
2530 // present.
2531 int reference_sig_index = 0; 2618 int reference_sig_index = 0;
2532 int reference_name_index = 0; 2619 int reference_name_index = 0;
2533 int reference_index = 0; 2620 int reference_index = 0;
2534 int extra = java_lang_ref_Reference::number_of_fake_oop_fields; 2621 int extra = java_lang_ref_Reference::number_of_fake_oop_fields;
2535 const int n = (*fields_ptr)()->length(); 2622 const int n = (*fields_ptr)()->length();
2661 2748
2662 2749
2663 // Force MethodHandle.vmentry to be an unmanaged pointer. 2750 // Force MethodHandle.vmentry to be an unmanaged pointer.
2664 // There is no way for a classfile to express this, so we must help it. 2751 // There is no way for a classfile to express this, so we must help it.
2665 void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, 2752 void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
2666 typeArrayHandle* fields_ptr, 2753 typeArrayHandle fields,
2667 FieldAllocationCount *fac_ptr, 2754 FieldAllocationCount *fac_ptr,
2668 TRAPS) { 2755 TRAPS) {
2669 // Add fake fields for java.dyn.MethodHandle instances 2756 // Add fake fields for java.dyn.MethodHandle instances
2670 // 2757 //
2671 // This is not particularly nice, but since there is no way to express 2758 // This is not particularly nice, but since there is no way to express
2685 2772
2686 if (word_sig_index == 0) 2773 if (word_sig_index == 0)
2687 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 2774 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2688 "missing I or J signature (for vmentry) in java.dyn.MethodHandle"); 2775 "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
2689 2776
2777 // Find vmentry field and change the signature.
2690 bool found_vmentry = false; 2778 bool found_vmentry = false;
2691 2779 for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) {
2692 const int n = (*fields_ptr)()->length(); 2780 int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
2693 for (int i = 0; i < n; i += instanceKlass::next_offset) { 2781 int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
2694 int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset); 2782 int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset);
2695 int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset);
2696 int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset);
2697 symbolOop f_name = cp->symbol_at(name_index); 2783 symbolOop f_name = cp->symbol_at(name_index);
2698 symbolOop f_sig = cp->symbol_at(sig_index); 2784 symbolOop f_sig = cp->symbol_at(sig_index);
2699 if (f_sig == vmSymbols::byte_signature() && 2785
2700 f_name == vmSymbols::vmentry_name() && 2786 if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) {
2701 (acc_flags & JVM_ACC_STATIC) == 0) { 2787 if (f_sig == vmSymbols::machine_word_signature()) {
2702 // Adjust the field type from byte to an unmanaged pointer. 2788 // If the signature of vmentry is already changed, we're done.
2703 assert(fac_ptr->nonstatic_byte_count > 0, ""); 2789 found_vmentry = true;
2704 fac_ptr->nonstatic_byte_count -= 1; 2790 break;
2705 2791 }
2706 (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); 2792 else if (f_sig == vmSymbols::byte_signature()) {
2707 assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); 2793 // Adjust the field type from byte to an unmanaged pointer.
2708 if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; 2794 assert(fac_ptr->nonstatic_byte_count > 0, "");
2709 else fac_ptr->nonstatic_word_count += 1; 2795 fac_ptr->nonstatic_byte_count -= 1;
2710 2796
2711 FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset); 2797 fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
2712 assert(atype == NONSTATIC_BYTE, ""); 2798 assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
2713 FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; 2799 if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1;
2714 (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype); 2800 else fac_ptr->nonstatic_word_count += 1;
2715 2801
2716 found_vmentry = true; 2802 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
2717 break; 2803 assert(atype == NONSTATIC_BYTE, "");
2804 FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
2805 fields->ushort_at_put(i + instanceKlass::low_offset, new_atype);
2806
2807 found_vmentry = true;
2808 break;
2809 }
2718 } 2810 }
2719 } 2811 }
2720 2812
2721 if (!found_vmentry) 2813 if (!found_vmentry)
2722 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 2814 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2723 "missing vmentry byte field in java.dyn.MethodHandle"); 2815 "missing vmentry byte field in java.dyn.MethodHandle");
2724
2725 } 2816 }
2726 2817
2727 2818
2728 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, 2819 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
2729 Handle class_loader, 2820 Handle class_loader,
3080 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); 3171 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
3081 } 3172 }
3082 3173
3083 // adjust the vmentry field declaration in java.dyn.MethodHandle 3174 // adjust the vmentry field declaration in java.dyn.MethodHandle
3084 if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { 3175 if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
3085 java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle)); 3176 java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
3086 } 3177 }
3087 3178
3088 // Add a fake "discovered" field if it is not present 3179 // Add a fake "discovered" field if it is not present
3089 // for compatibility with earlier jdk's. 3180 // for compatibility with earlier jdk's.
3090 if (class_name() == vmSymbols::java_lang_ref_Reference() 3181 if (class_name() == vmSymbols::java_lang_ref_Reference()