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() |