2235 } |
2258 } |
2236 } |
2259 } |
2237 |
2260 |
2238 return true; |
2261 return true; |
2239 } // end rewrite_cp_refs_in_methods_default_annotations() |
2262 } // end rewrite_cp_refs_in_methods_default_annotations() |
|
2263 |
|
2264 |
|
2265 // Rewrite constant pool references in a class_type_annotations field. |
|
2266 bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations( |
|
2267 instanceKlassHandle scratch_class, TRAPS) { |
|
2268 |
|
2269 AnnotationArray* class_type_annotations = scratch_class->class_type_annotations(); |
|
2270 if (class_type_annotations == NULL || class_type_annotations->length() == 0) { |
|
2271 // no class_type_annotations so nothing to do |
|
2272 return true; |
|
2273 } |
|
2274 |
|
2275 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2276 ("class_type_annotations length=%d", class_type_annotations->length())); |
|
2277 |
|
2278 int byte_i = 0; // byte index into class_type_annotations |
|
2279 return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, |
|
2280 byte_i, "ClassFile", THREAD); |
|
2281 } // end rewrite_cp_refs_in_class_type_annotations() |
|
2282 |
|
2283 |
|
2284 // Rewrite constant pool references in a fields_type_annotations field. |
|
2285 bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations( |
|
2286 instanceKlassHandle scratch_class, TRAPS) { |
|
2287 |
|
2288 Array<AnnotationArray*>* fields_type_annotations = scratch_class->fields_type_annotations(); |
|
2289 if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { |
|
2290 // no fields_type_annotations so nothing to do |
|
2291 return true; |
|
2292 } |
|
2293 |
|
2294 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2295 ("fields_type_annotations length=%d", fields_type_annotations->length())); |
|
2296 |
|
2297 for (int i = 0; i < fields_type_annotations->length(); i++) { |
|
2298 AnnotationArray* field_type_annotations = fields_type_annotations->at(i); |
|
2299 if (field_type_annotations == NULL || field_type_annotations->length() == 0) { |
|
2300 // this field does not have any annotations so skip it |
|
2301 continue; |
|
2302 } |
|
2303 |
|
2304 int byte_i = 0; // byte index into field_type_annotations |
|
2305 if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, |
|
2306 byte_i, "field_info", THREAD)) { |
|
2307 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2308 ("bad field_type_annotations at %d", i)); |
|
2309 // propagate failure back to caller |
|
2310 return false; |
|
2311 } |
|
2312 } |
|
2313 |
|
2314 return true; |
|
2315 } // end rewrite_cp_refs_in_fields_type_annotations() |
|
2316 |
|
2317 |
|
2318 // Rewrite constant pool references in a methods_type_annotations field. |
|
2319 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations( |
|
2320 instanceKlassHandle scratch_class, TRAPS) { |
|
2321 |
|
2322 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
|
2323 Method* m = scratch_class->methods()->at(i); |
|
2324 AnnotationArray* method_type_annotations = m->constMethod()->type_annotations(); |
|
2325 |
|
2326 if (method_type_annotations == NULL || method_type_annotations->length() == 0) { |
|
2327 // this method does not have any annotations so skip it |
|
2328 continue; |
|
2329 } |
|
2330 |
|
2331 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2332 ("methods type_annotations length=%d", method_type_annotations->length())); |
|
2333 |
|
2334 int byte_i = 0; // byte index into method_type_annotations |
|
2335 if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, |
|
2336 byte_i, "method_info", THREAD)) { |
|
2337 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2338 ("bad method_type_annotations at %d", i)); |
|
2339 // propagate failure back to caller |
|
2340 return false; |
|
2341 } |
|
2342 } |
|
2343 |
|
2344 return true; |
|
2345 } // end rewrite_cp_refs_in_methods_type_annotations() |
|
2346 |
|
2347 |
|
2348 // Rewrite constant pool references in a type_annotations |
|
2349 // field. This "structure" is adapted from the |
|
2350 // RuntimeVisibleTypeAnnotations_attribute described in |
|
2351 // section 4.7.20 of the Java SE 8 Edition of the VM spec: |
|
2352 // |
|
2353 // type_annotations_typeArray { |
|
2354 // u2 num_annotations; |
|
2355 // type_annotation annotations[num_annotations]; |
|
2356 // } |
|
2357 // |
|
2358 bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray( |
|
2359 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
|
2360 const char * location_mesg, TRAPS) { |
|
2361 |
|
2362 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2363 // not enough room for num_annotations field |
|
2364 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2365 ("length() is too small for num_annotations field")); |
|
2366 return false; |
|
2367 } |
|
2368 |
|
2369 u2 num_annotations = Bytes::get_Java_u2((address) |
|
2370 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2371 byte_i_ref += 2; |
|
2372 |
|
2373 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2374 ("num_type_annotations=%d", num_annotations)); |
|
2375 |
|
2376 int calc_num_annotations = 0; |
|
2377 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { |
|
2378 if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, |
|
2379 byte_i_ref, location_mesg, THREAD)) { |
|
2380 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2381 ("bad type_annotation_struct at %d", calc_num_annotations)); |
|
2382 // propagate failure back to caller |
|
2383 return false; |
|
2384 } |
|
2385 } |
|
2386 assert(num_annotations == calc_num_annotations, "sanity check"); |
|
2387 |
|
2388 if (byte_i_ref != type_annotations_typeArray->length()) { |
|
2389 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2390 ("read wrong amount of bytes at end of processing " |
|
2391 "type_annotations_typeArray (%d of %d bytes were read)", |
|
2392 byte_i_ref, type_annotations_typeArray->length())); |
|
2393 return false; |
|
2394 } |
|
2395 |
|
2396 return true; |
|
2397 } // end rewrite_cp_refs_in_type_annotations_typeArray() |
|
2398 |
|
2399 |
|
2400 // Rewrite constant pool references in a type_annotation |
|
2401 // field. This "structure" is adapted from the |
|
2402 // RuntimeVisibleTypeAnnotations_attribute described in |
|
2403 // section 4.7.20 of the Java SE 8 Edition of the VM spec: |
|
2404 // |
|
2405 // type_annotation { |
|
2406 // u1 target_type; |
|
2407 // union { |
|
2408 // type_parameter_target; |
|
2409 // supertype_target; |
|
2410 // type_parameter_bound_target; |
|
2411 // empty_target; |
|
2412 // method_formal_parameter_target; |
|
2413 // throws_target; |
|
2414 // localvar_target; |
|
2415 // catch_target; |
|
2416 // offset_target; |
|
2417 // type_argument_target; |
|
2418 // } target_info; |
|
2419 // type_path target_path; |
|
2420 // annotation anno; |
|
2421 // } |
|
2422 // |
|
2423 bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct( |
|
2424 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
|
2425 const char * location_mesg, TRAPS) { |
|
2426 |
|
2427 if (!skip_type_annotation_target(type_annotations_typeArray, |
|
2428 byte_i_ref, location_mesg, THREAD)) { |
|
2429 return false; |
|
2430 } |
|
2431 |
|
2432 if (!skip_type_annotation_type_path(type_annotations_typeArray, |
|
2433 byte_i_ref, THREAD)) { |
|
2434 return false; |
|
2435 } |
|
2436 |
|
2437 if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray, |
|
2438 byte_i_ref, THREAD)) { |
|
2439 return false; |
|
2440 } |
|
2441 |
|
2442 return true; |
|
2443 } // end rewrite_cp_refs_in_type_annotation_struct() |
|
2444 |
|
2445 |
|
2446 // Read, verify and skip over the target_type and target_info part |
|
2447 // so that rewriting can continue in the later parts of the struct. |
|
2448 // |
|
2449 // u1 target_type; |
|
2450 // union { |
|
2451 // type_parameter_target; |
|
2452 // supertype_target; |
|
2453 // type_parameter_bound_target; |
|
2454 // empty_target; |
|
2455 // method_formal_parameter_target; |
|
2456 // throws_target; |
|
2457 // localvar_target; |
|
2458 // catch_target; |
|
2459 // offset_target; |
|
2460 // type_argument_target; |
|
2461 // } target_info; |
|
2462 // |
|
2463 bool VM_RedefineClasses::skip_type_annotation_target( |
|
2464 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
|
2465 const char * location_mesg, TRAPS) { |
|
2466 |
|
2467 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
|
2468 // not enough room for a target_type let alone the rest of a type_annotation |
|
2469 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2470 ("length() is too small for a target_type")); |
|
2471 return false; |
|
2472 } |
|
2473 |
|
2474 u1 target_type = type_annotations_typeArray->at(byte_i_ref); |
|
2475 byte_i_ref += 1; |
|
2476 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type)); |
|
2477 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg)); |
|
2478 |
|
2479 // Skip over target_info |
|
2480 switch (target_type) { |
|
2481 case 0x00: |
|
2482 // kind: type parameter declaration of generic class or interface |
|
2483 // location: ClassFile |
|
2484 case 0x01: |
|
2485 // kind: type parameter declaration of generic method or constructor |
|
2486 // location: method_info |
|
2487 |
|
2488 { |
|
2489 // struct: |
|
2490 // type_parameter_target { |
|
2491 // u1 type_parameter_index; |
|
2492 // } |
|
2493 // |
|
2494 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
|
2495 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2496 ("length() is too small for a type_parameter_target")); |
|
2497 return false; |
|
2498 } |
|
2499 |
|
2500 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
|
2501 byte_i_ref += 1; |
|
2502 |
|
2503 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2504 ("type_parameter_target: type_parameter_index=%d", |
|
2505 type_parameter_index)); |
|
2506 } break; |
|
2507 |
|
2508 case 0x10: |
|
2509 // kind: type in extends clause of class or interface declaration |
|
2510 // (including the direct superclass of an anonymous class declaration), |
|
2511 // or in implements clause of interface declaration |
|
2512 // location: ClassFile |
|
2513 |
|
2514 { |
|
2515 // struct: |
|
2516 // supertype_target { |
|
2517 // u2 supertype_index; |
|
2518 // } |
|
2519 // |
|
2520 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2521 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2522 ("length() is too small for a supertype_target")); |
|
2523 return false; |
|
2524 } |
|
2525 |
|
2526 u2 supertype_index = Bytes::get_Java_u2((address) |
|
2527 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2528 byte_i_ref += 2; |
|
2529 |
|
2530 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2531 ("supertype_target: supertype_index=%d", supertype_index)); |
|
2532 } break; |
|
2533 |
|
2534 case 0x11: |
|
2535 // kind: type in bound of type parameter declaration of generic class or interface |
|
2536 // location: ClassFile |
|
2537 case 0x12: |
|
2538 // kind: type in bound of type parameter declaration of generic method or constructor |
|
2539 // location: method_info |
|
2540 |
|
2541 { |
|
2542 // struct: |
|
2543 // type_parameter_bound_target { |
|
2544 // u1 type_parameter_index; |
|
2545 // u1 bound_index; |
|
2546 // } |
|
2547 // |
|
2548 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2549 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2550 ("length() is too small for a type_parameter_bound_target")); |
|
2551 return false; |
|
2552 } |
|
2553 |
|
2554 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
|
2555 byte_i_ref += 1; |
|
2556 u1 bound_index = type_annotations_typeArray->at(byte_i_ref); |
|
2557 byte_i_ref += 1; |
|
2558 |
|
2559 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2560 ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", |
|
2561 type_parameter_index, bound_index)); |
|
2562 } break; |
|
2563 |
|
2564 case 0x13: |
|
2565 // kind: type in field declaration |
|
2566 // location: field_info |
|
2567 case 0x14: |
|
2568 // kind: return type of method, or type of newly constructed object |
|
2569 // location: method_info |
|
2570 case 0x15: |
|
2571 // kind: receiver type of method or constructor |
|
2572 // location: method_info |
|
2573 |
|
2574 { |
|
2575 // struct: |
|
2576 // empty_target { |
|
2577 // } |
|
2578 // |
|
2579 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2580 ("empty_target")); |
|
2581 } break; |
|
2582 |
|
2583 case 0x16: |
|
2584 // kind: type in formal parameter declaration of method, constructor, or lambda expression |
|
2585 // location: method_info |
|
2586 |
|
2587 { |
|
2588 // struct: |
|
2589 // formal_parameter_target { |
|
2590 // u1 formal_parameter_index; |
|
2591 // } |
|
2592 // |
|
2593 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
|
2594 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2595 ("length() is too small for a formal_parameter_target")); |
|
2596 return false; |
|
2597 } |
|
2598 |
|
2599 u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
|
2600 byte_i_ref += 1; |
|
2601 |
|
2602 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2603 ("formal_parameter_target: formal_parameter_index=%d", |
|
2604 formal_parameter_index)); |
|
2605 } break; |
|
2606 |
|
2607 case 0x17: |
|
2608 // kind: type in throws clause of method or constructor |
|
2609 // location: method_info |
|
2610 |
|
2611 { |
|
2612 // struct: |
|
2613 // throws_target { |
|
2614 // u2 throws_type_index |
|
2615 // } |
|
2616 // |
|
2617 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2618 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2619 ("length() is too small for a throws_target")); |
|
2620 return false; |
|
2621 } |
|
2622 |
|
2623 u2 throws_type_index = Bytes::get_Java_u2((address) |
|
2624 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2625 byte_i_ref += 2; |
|
2626 |
|
2627 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2628 ("throws_target: throws_type_index=%d", throws_type_index)); |
|
2629 } break; |
|
2630 |
|
2631 case 0x40: |
|
2632 // kind: type in local variable declaration |
|
2633 // location: Code |
|
2634 case 0x41: |
|
2635 // kind: type in resource variable declaration |
|
2636 // location: Code |
|
2637 |
|
2638 { |
|
2639 // struct: |
|
2640 // localvar_target { |
|
2641 // u2 table_length; |
|
2642 // struct { |
|
2643 // u2 start_pc; |
|
2644 // u2 length; |
|
2645 // u2 index; |
|
2646 // } table[table_length]; |
|
2647 // } |
|
2648 // |
|
2649 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2650 // not enough room for a table_length let alone the rest of a localvar_target |
|
2651 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2652 ("length() is too small for a localvar_target table_length")); |
|
2653 return false; |
|
2654 } |
|
2655 |
|
2656 u2 table_length = Bytes::get_Java_u2((address) |
|
2657 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2658 byte_i_ref += 2; |
|
2659 |
|
2660 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2661 ("localvar_target: table_length=%d", table_length)); |
|
2662 |
|
2663 int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry |
|
2664 int table_size = table_length * table_struct_size; |
|
2665 |
|
2666 if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { |
|
2667 // not enough room for a table |
|
2668 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2669 ("length() is too small for a table array of length %d", table_length)); |
|
2670 return false; |
|
2671 } |
|
2672 |
|
2673 // Skip over table |
|
2674 byte_i_ref += table_size; |
|
2675 } break; |
|
2676 |
|
2677 case 0x42: |
|
2678 // kind: type in exception parameter declaration |
|
2679 // location: Code |
|
2680 |
|
2681 { |
|
2682 // struct: |
|
2683 // catch_target { |
|
2684 // u2 exception_table_index; |
|
2685 // } |
|
2686 // |
|
2687 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2688 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2689 ("length() is too small for a catch_target")); |
|
2690 return false; |
|
2691 } |
|
2692 |
|
2693 u2 exception_table_index = Bytes::get_Java_u2((address) |
|
2694 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2695 byte_i_ref += 2; |
|
2696 |
|
2697 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2698 ("catch_target: exception_table_index=%d", exception_table_index)); |
|
2699 } break; |
|
2700 |
|
2701 case 0x43: |
|
2702 // kind: type in instanceof expression |
|
2703 // location: Code |
|
2704 case 0x44: |
|
2705 // kind: type in new expression |
|
2706 // location: Code |
|
2707 case 0x45: |
|
2708 // kind: type in method reference expression using ::new |
|
2709 // location: Code |
|
2710 case 0x46: |
|
2711 // kind: type in method reference expression using ::Identifier |
|
2712 // location: Code |
|
2713 |
|
2714 { |
|
2715 // struct: |
|
2716 // offset_target { |
|
2717 // u2 offset; |
|
2718 // } |
|
2719 // |
|
2720 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
|
2721 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2722 ("length() is too small for a offset_target")); |
|
2723 return false; |
|
2724 } |
|
2725 |
|
2726 u2 offset = Bytes::get_Java_u2((address) |
|
2727 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2728 byte_i_ref += 2; |
|
2729 |
|
2730 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2731 ("offset_target: offset=%d", offset)); |
|
2732 } break; |
|
2733 |
|
2734 case 0x47: |
|
2735 // kind: type in cast expression |
|
2736 // location: Code |
|
2737 case 0x48: |
|
2738 // kind: type argument for generic constructor in new expression or |
|
2739 // explicit constructor invocation statement |
|
2740 // location: Code |
|
2741 case 0x49: |
|
2742 // kind: type argument for generic method in method invocation expression |
|
2743 // location: Code |
|
2744 case 0x4A: |
|
2745 // kind: type argument for generic constructor in method reference expression using ::new |
|
2746 // location: Code |
|
2747 case 0x4B: |
|
2748 // kind: type argument for generic method in method reference expression using ::Identifier |
|
2749 // location: Code |
|
2750 |
|
2751 { |
|
2752 // struct: |
|
2753 // type_argument_target { |
|
2754 // u2 offset; |
|
2755 // u1 type_argument_index; |
|
2756 // } |
|
2757 // |
|
2758 if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { |
|
2759 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2760 ("length() is too small for a type_argument_target")); |
|
2761 return false; |
|
2762 } |
|
2763 |
|
2764 u2 offset = Bytes::get_Java_u2((address) |
|
2765 type_annotations_typeArray->adr_at(byte_i_ref)); |
|
2766 byte_i_ref += 2; |
|
2767 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
|
2768 byte_i_ref += 1; |
|
2769 |
|
2770 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2771 ("type_argument_target: offset=%d, type_argument_index=%d", |
|
2772 offset, type_argument_index)); |
|
2773 } break; |
|
2774 |
|
2775 default: |
|
2776 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2777 ("unknown target_type")); |
|
2778 #ifdef ASSERT |
|
2779 ShouldNotReachHere(); |
|
2780 #endif |
|
2781 return false; |
|
2782 } |
|
2783 |
|
2784 return true; |
|
2785 } // end skip_type_annotation_target() |
|
2786 |
|
2787 |
|
2788 // Read, verify and skip over the type_path part so that rewriting |
|
2789 // can continue in the later parts of the struct. |
|
2790 // |
|
2791 // type_path { |
|
2792 // u1 path_length; |
|
2793 // { |
|
2794 // u1 type_path_kind; |
|
2795 // u1 type_argument_index; |
|
2796 // } path[path_length]; |
|
2797 // } |
|
2798 // |
|
2799 bool VM_RedefineClasses::skip_type_annotation_type_path( |
|
2800 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { |
|
2801 |
|
2802 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
|
2803 // not enough room for a path_length let alone the rest of the type_path |
|
2804 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2805 ("length() is too small for a type_path")); |
|
2806 return false; |
|
2807 } |
|
2808 |
|
2809 u1 path_length = type_annotations_typeArray->at(byte_i_ref); |
|
2810 byte_i_ref += 1; |
|
2811 |
|
2812 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2813 ("type_path: path_length=%d", path_length)); |
|
2814 |
|
2815 int calc_path_length = 0; |
|
2816 for (; calc_path_length < path_length; calc_path_length++) { |
|
2817 if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { |
|
2818 // not enough room for a path |
|
2819 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2820 ("length() is too small for path entry %d of %d", |
|
2821 calc_path_length, path_length)); |
|
2822 return false; |
|
2823 } |
|
2824 |
|
2825 u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); |
|
2826 byte_i_ref += 1; |
|
2827 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
|
2828 byte_i_ref += 1; |
|
2829 |
|
2830 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2831 ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", |
|
2832 calc_path_length, type_path_kind, type_argument_index)); |
|
2833 |
|
2834 if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { |
|
2835 // not enough room for a path |
|
2836 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
|
2837 ("inconsistent type_path values")); |
|
2838 return false; |
|
2839 } |
|
2840 } |
|
2841 assert(path_length == calc_path_length, "sanity check"); |
|
2842 |
|
2843 return true; |
|
2844 } // end skip_type_annotation_type_path() |
2240 |
2845 |
2241 |
2846 |
2242 // Rewrite constant pool references in the method's stackmap table. |
2847 // Rewrite constant pool references in the method's stackmap table. |
2243 // These "structures" are adapted from the StackMapTable_attribute that |
2848 // These "structures" are adapted from the StackMapTable_attribute that |
2244 // is described in section 4.8.4 of the 6.0 version of the VM spec |
2849 // is described in section 4.8.4 of the 6.0 version of the VM spec |