comparison src/share/vm/runtime/relocator.cpp @ 1877:a4c7fe54bf3f

6991315: RedefineClasses fails with java.lang.VerifyError Summary: Repair stackmap table attribute when relocating bytecode Reviewed-by: acorn, never
author kamg
date Thu, 21 Oct 2010 10:10:23 -0400
parents c18cbe5936b8
children f95d63e2154a
comparison
equal deleted inserted replaced
1874:75ab0162aa84 1877:a4c7fe54bf3f
433 } 433 }
434 } 434 }
435 } 435 }
436 } 436 }
437 437
438 // Create a new array, copying the src array but adding a hole at
439 // the specified location
440 static typeArrayOop insert_hole_at(
441 size_t where, int hole_sz, typeArrayOop src) {
442 Thread* THREAD = Thread::current();
443 Handle src_hnd(THREAD, src);
444 typeArrayOop dst =
445 oopFactory::new_permanent_byteArray(src->length() + hole_sz, CHECK_NULL);
446 src = (typeArrayOop)src_hnd();
447
448 address src_addr = (address)src->byte_at_addr(0);
449 address dst_addr = (address)dst->byte_at_addr(0);
450
451 memcpy(dst_addr, src_addr, where);
452 memcpy(dst_addr + where + hole_sz,
453 src_addr + where, src->length() - where);
454 return dst;
455 }
456
457 // The width of instruction at "bci" is changing by "delta". Adjust the stack
458 // map frames.
459 void Relocator::adjust_stack_map_table(int bci, int delta) {
460 if (method()->has_stackmap_table()) {
461 typeArrayOop data = method()->stackmap_data();
462 // The data in the array is a classfile representation of the stackmap
463 // table attribute, less the initial u2 tag and u4 attribute_length fields.
464 stack_map_table_attribute* attr = stack_map_table_attribute::at(
465 (address)data->byte_at_addr(0) - (sizeof(u2) + sizeof(u4)));
466
467 int count = attr->number_of_entries();
468 stack_map_frame* frame = attr->entries();
469 int bci_iter = -1;
470 bool offset_adjusted = false; // only need to adjust one offset
471
472 for (int i = 0; i < count; ++i) {
473 int offset_delta = frame->offset_delta();
474 bci_iter += offset_delta;
475
476 if (!offset_adjusted && bci_iter > bci) {
477 int new_offset_delta = offset_delta + delta;
478
479 if (frame->is_valid_offset(new_offset_delta)) {
480 frame->set_offset_delta(new_offset_delta);
481 } else {
482 assert(frame->is_same_frame() ||
483 frame->is_same_frame_1_stack_item_frame(),
484 "Frame must be one of the compressed forms");
485 // The new delta exceeds the capacity of the 'same_frame' or
486 // 'same_frame_1_stack_item_frame' frame types. We need to
487 // convert these frames to the extended versions, but the extended
488 // version is bigger and requires more room. So we allocate a
489 // new array and copy the data, being sure to leave u2-sized hole
490 // right after the 'frame_type' for the new offset field.
491 //
492 // We can safely ignore the reverse situation as a small delta
493 // can still be used in an extended version of the frame.
494
495 size_t frame_offset = (address)frame - (address)data->byte_at_addr(0);
496
497 data = insert_hole_at(frame_offset + 1, 2, data);
498 if (data == NULL) {
499 return; // out-of-memory?
500 }
501
502 address frame_addr = (address)(data->byte_at_addr(0) + frame_offset);
503 frame = stack_map_frame::at(frame_addr);
504
505
506 // Now convert the frames in place
507 if (frame->is_same_frame()) {
508 same_frame_extended::create_at(frame_addr, new_offset_delta);
509 } else {
510 same_frame_1_stack_item_extended::create_at(
511 frame_addr, new_offset_delta, NULL);
512 // the verification_info_type should already be at the right spot
513 }
514 }
515 offset_adjusted = true; // needs to be done only once, since subsequent
516 // values are offsets from the current
517 }
518
519 // The stack map frame may contain verification types, if so we need to
520 // check and update any Uninitialized type's bci (no matter where it is).
521 int number_of_types = frame->number_of_types();
522 verification_type_info* types = frame->types();
523
524 for (int i = 0; i < number_of_types; ++i) {
525 if (types->is_uninitialized() && types->bci() > bci) {
526 types->set_bci(types->bci() + delta);
527 }
528 types = types->next();
529 }
530
531 // Full frame has stack values too
532 full_frame* ff = frame->as_full_frame();
533 if (ff != NULL) {
534 address eol = (address)types;
535 number_of_types = ff->stack_slots(eol);
536 types = ff->stack(eol);
537 for (int i = 0; i < number_of_types; ++i) {
538 if (types->is_uninitialized() && types->bci() > bci) {
539 types->set_bci(types->bci() + delta);
540 }
541 types = types->next();
542 }
543 }
544
545 frame = frame->next();
546 }
547
548 method()->set_stackmap_data(data); // in case it has changed
549 }
550 }
551
438 552
439 bool Relocator::expand_code_array(int delta) { 553 bool Relocator::expand_code_array(int delta) {
440 int length = MAX2(code_length() + delta, code_length() * (100+code_slop_pct()) / 100); 554 int length = MAX2(code_length() + delta, code_length() * (100+code_slop_pct()) / 100);
441 555
442 if (length > MAX_METHOD_LENGTH) { 556 if (length > MAX_METHOD_LENGTH) {
496 adjust_exception_table(bci, delta); 610 adjust_exception_table(bci, delta);
497 // Line number tables... 611 // Line number tables...
498 adjust_line_no_table(bci, delta); 612 adjust_line_no_table(bci, delta);
499 // And local variable table... 613 // And local variable table...
500 adjust_local_var_table(bci, delta); 614 adjust_local_var_table(bci, delta);
615
616 // Adjust stack maps
617 adjust_stack_map_table(bci, delta);
501 618
502 // Relocate the pending change stack... 619 // Relocate the pending change stack...
503 for (int j = 0; j < _changes->length(); j++) { 620 for (int j = 0; j < _changes->length(); j++) {
504 ChangeItem* ci = _changes->at(j); 621 ChangeItem* ci = _changes->at(j);
505 ci->relocate(bci, delta); 622 ci->relocate(bci, delta);
639 assert(pad_delta > 0, "check"); 756 assert(pad_delta > 0, "check");
640 // Move the expanded instruction up. 757 // Move the expanded instruction up.
641 memmove(addr_at(bci +1 + new_pad), 758 memmove(addr_at(bci +1 + new_pad),
642 addr_at(bci +1 + old_pad), 759 addr_at(bci +1 + old_pad),
643 len * 4); 760 len * 4);
761 memset(addr_at(bci + 1), 0, new_pad); // pad must be 0
644 } 762 }
645 } 763 }
646 return true; 764 return true;
647 } 765 }