src/share/vm/prims/jvmtiRedefineClasses.cpp

Print this page




1379 // Merge constant pools between the_class and scratch_class and
1380 // potentially rewrite bytecodes in scratch_class to use the merged
1381 // constant pool.
1382 jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
1383              instanceKlassHandle the_class, instanceKlassHandle scratch_class,
1384              TRAPS) {
1385   // worst case merged constant pool length is old and new combined
1386   int merge_cp_length = the_class->constants()->length()
1387         + scratch_class->constants()->length();
1388 
1389   // Constant pools are not easily reused so we allocate a new one
1390   // each time.
1391   // merge_cp is created unsafe for concurrent GC processing.  It
1392   // should be marked safe before discarding it. Even though
1393   // garbage,  if it crosses a card boundary, it may be scanned
1394   // in order to find the start of the first complete object on the card.
1395   ClassLoaderData* loader_data = the_class->class_loader_data();
1396   ConstantPool* merge_cp_oop =
1397     ConstantPool::allocate(loader_data,
1398                                   merge_cp_length,
1399                                   THREAD);
1400   MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop);
1401 
1402   HandleMark hm(THREAD);  // make sure handles are cleared before
1403                           // MergeCPCleaner clears out merge_cp_oop
1404   constantPoolHandle merge_cp(THREAD, merge_cp_oop);
1405 
1406   // Get constants() from the old class because it could have been rewritten
1407   // while we were at a safepoint allocating a new constant pool.
1408   constantPoolHandle old_cp(THREAD, the_class->constants());
1409   constantPoolHandle scratch_cp(THREAD, scratch_class->constants());
1410 
1411   // If the length changed, the class was redefined out from under us. Return
1412   // an error.
1413   if (merge_cp_length != the_class->constants()->length()
1414          + scratch_class->constants()->length()) {
1415     return JVMTI_ERROR_INTERNAL;
1416   }
1417 
1418   // Update the version number of the constant pool
1419   merge_cp->increment_and_save_version(old_cp->version());


1455       // class.
1456 
1457       // toss the merged constant pool at return
1458     } else if (old_cp->length() < scratch_cp->length()) {
1459       // The old constant pool has fewer entries than the new constant
1460       // pool and the index map is empty. This means the new constant
1461       // pool is a superset of the old constant pool. However, the old
1462       // class bytecodes have already gone through constant pool cache
1463       // rewriting so we can't use the new constant pool with the old
1464       // class.
1465 
1466       // toss the merged constant pool at return
1467     } else {
1468       // The old constant pool has more entries than the new constant
1469       // pool and the index map is empty. This means that both the old
1470       // and merged constant pools are supersets of the new constant
1471       // pool.
1472 
1473       // Replace the new constant pool with a shrunken copy of the
1474       // merged constant pool
1475       set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD);

1476       // The new constant pool replaces scratch_cp so have cleaner clean it up.
1477       // It can't be cleaned up while there are handles to it.
1478       cp_cleaner.add_scratch_cp(scratch_cp());
1479     }
1480   } else {
1481     if (RC_TRACE_ENABLED(0x00040000)) {
1482       // don't want to loop unless we are tracing
1483       int count = 0;
1484       for (int i = 1; i < _index_map_p->length(); i++) {
1485         int value = _index_map_p->at(i);
1486 
1487         if (value != -1) {
1488           RC_TRACE_WITH_THREAD(0x00040000, THREAD,
1489             ("index_map[%d]: old=%d new=%d", count, i, value));
1490           count++;
1491         }
1492       }
1493     }
1494 
1495     // We have entries mapped between the new and merged constant pools
1496     // so we have to rewrite some constant pool references.
1497     if (!rewrite_cp_refs(scratch_class, THREAD)) {
1498       return JVMTI_ERROR_INTERNAL;
1499     }
1500 
1501     // Replace the new constant pool with a shrunken copy of the
1502     // merged constant pool so now the rewritten bytecodes have
1503     // valid references; the previous new constant pool will get
1504     // GCed.
1505     set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD);

1506     // The new constant pool replaces scratch_cp so have cleaner clean it up.
1507     // It can't be cleaned up while there are handles to it.
1508     cp_cleaner.add_scratch_cp(scratch_cp());
1509   }
1510 
1511   return JVMTI_ERROR_NONE;
1512 } // end merge_cp_and_rewrite()
1513 
1514 
1515 // Rewrite constant pool references in klass scratch_class.
1516 bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class,
1517        TRAPS) {
1518 
1519   // rewrite constant pool references in the methods:
1520   if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
1521     // propagate failure back to caller
1522     return false;
1523   }
1524 
1525   // rewrite constant pool references in the class_annotations:


2470       ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag));
2471     ShouldNotReachHere();
2472     break;
2473   } // end switch (tag)
2474 } // end rewrite_cp_refs_in_verification_type_info()
2475 
2476 
2477 // Change the constant pool associated with klass scratch_class to
2478 // scratch_cp. If shrink is true, then scratch_cp_length elements
2479 // are copied from scratch_cp to a smaller constant pool and the
2480 // smaller constant pool is associated with scratch_class.
2481 void VM_RedefineClasses::set_new_constant_pool(
2482        ClassLoaderData* loader_data,
2483        instanceKlassHandle scratch_class, constantPoolHandle scratch_cp,
2484        int scratch_cp_length, TRAPS) {
2485   assert(scratch_cp->length() >= scratch_cp_length, "sanity check");
2486 
2487   // scratch_cp is a merged constant pool and has enough space for a
2488   // worst case merge situation. We want to associate the minimum
2489   // sized constant pool with the klass to save space.
2490   constantPoolHandle smaller_cp(THREAD,
2491           ConstantPool::allocate(loader_data, scratch_cp_length, THREAD));
2492 
2493   // preserve version() value in the smaller copy
2494   int version = scratch_cp->version();
2495   assert(version != 0, "sanity check");
2496   smaller_cp->set_version(version);
2497 
2498   // attach klass to new constant pool
2499   // reference to the cp holder is needed for copy_operands()
2500   smaller_cp->set_pool_holder(scratch_class());
2501 
2502   scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);





2503   scratch_cp = smaller_cp;
2504 
2505   // attach new constant pool to klass
2506   scratch_class->set_constants(scratch_cp());
2507 
2508   int i;  // for portability
2509 
2510   // update each field in klass to use new constant pool indices as needed
2511   for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) {
2512     jshort cur_index = fs.name_index();
2513     jshort new_index = find_new_index(cur_index);
2514     if (new_index != 0) {
2515       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
2516         ("field-name_index change: %d to %d", cur_index, new_index));
2517       fs.set_name_index(new_index);
2518     }
2519     cur_index = fs.signature_index();
2520     new_index = find_new_index(cur_index);
2521     if (new_index != 0) {
2522       RC_TRACE_WITH_THREAD(0x00080000, THREAD,




1379 // Merge constant pools between the_class and scratch_class and
1380 // potentially rewrite bytecodes in scratch_class to use the merged
1381 // constant pool.
1382 jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
1383              instanceKlassHandle the_class, instanceKlassHandle scratch_class,
1384              TRAPS) {
1385   // worst case merged constant pool length is old and new combined
1386   int merge_cp_length = the_class->constants()->length()
1387         + scratch_class->constants()->length();
1388 
1389   // Constant pools are not easily reused so we allocate a new one
1390   // each time.
1391   // merge_cp is created unsafe for concurrent GC processing.  It
1392   // should be marked safe before discarding it. Even though
1393   // garbage,  if it crosses a card boundary, it may be scanned
1394   // in order to find the start of the first complete object on the card.
1395   ClassLoaderData* loader_data = the_class->class_loader_data();
1396   ConstantPool* merge_cp_oop =
1397     ConstantPool::allocate(loader_data,
1398                            merge_cp_length,
1399                            CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
1400   MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop);
1401 
1402   HandleMark hm(THREAD);  // make sure handles are cleared before
1403                           // MergeCPCleaner clears out merge_cp_oop
1404   constantPoolHandle merge_cp(THREAD, merge_cp_oop);
1405 
1406   // Get constants() from the old class because it could have been rewritten
1407   // while we were at a safepoint allocating a new constant pool.
1408   constantPoolHandle old_cp(THREAD, the_class->constants());
1409   constantPoolHandle scratch_cp(THREAD, scratch_class->constants());
1410 
1411   // If the length changed, the class was redefined out from under us. Return
1412   // an error.
1413   if (merge_cp_length != the_class->constants()->length()
1414          + scratch_class->constants()->length()) {
1415     return JVMTI_ERROR_INTERNAL;
1416   }
1417 
1418   // Update the version number of the constant pool
1419   merge_cp->increment_and_save_version(old_cp->version());


1455       // class.
1456 
1457       // toss the merged constant pool at return
1458     } else if (old_cp->length() < scratch_cp->length()) {
1459       // The old constant pool has fewer entries than the new constant
1460       // pool and the index map is empty. This means the new constant
1461       // pool is a superset of the old constant pool. However, the old
1462       // class bytecodes have already gone through constant pool cache
1463       // rewriting so we can't use the new constant pool with the old
1464       // class.
1465 
1466       // toss the merged constant pool at return
1467     } else {
1468       // The old constant pool has more entries than the new constant
1469       // pool and the index map is empty. This means that both the old
1470       // and merged constant pools are supersets of the new constant
1471       // pool.
1472 
1473       // Replace the new constant pool with a shrunken copy of the
1474       // merged constant pool
1475       set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
1476                             CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
1477       // The new constant pool replaces scratch_cp so have cleaner clean it up.
1478       // It can't be cleaned up while there are handles to it.
1479       cp_cleaner.add_scratch_cp(scratch_cp());
1480     }
1481   } else {
1482     if (RC_TRACE_ENABLED(0x00040000)) {
1483       // don't want to loop unless we are tracing
1484       int count = 0;
1485       for (int i = 1; i < _index_map_p->length(); i++) {
1486         int value = _index_map_p->at(i);
1487 
1488         if (value != -1) {
1489           RC_TRACE_WITH_THREAD(0x00040000, THREAD,
1490             ("index_map[%d]: old=%d new=%d", count, i, value));
1491           count++;
1492         }
1493       }
1494     }
1495 
1496     // We have entries mapped between the new and merged constant pools
1497     // so we have to rewrite some constant pool references.
1498     if (!rewrite_cp_refs(scratch_class, THREAD)) {
1499       return JVMTI_ERROR_INTERNAL;
1500     }
1501 
1502     // Replace the new constant pool with a shrunken copy of the
1503     // merged constant pool so now the rewritten bytecodes have
1504     // valid references; the previous new constant pool will get
1505     // GCed.
1506     set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
1507                           CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
1508     // The new constant pool replaces scratch_cp so have cleaner clean it up.
1509     // It can't be cleaned up while there are handles to it.
1510     cp_cleaner.add_scratch_cp(scratch_cp());
1511   }
1512 
1513   return JVMTI_ERROR_NONE;
1514 } // end merge_cp_and_rewrite()
1515 
1516 
1517 // Rewrite constant pool references in klass scratch_class.
1518 bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class,
1519        TRAPS) {
1520 
1521   // rewrite constant pool references in the methods:
1522   if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
1523     // propagate failure back to caller
1524     return false;
1525   }
1526 
1527   // rewrite constant pool references in the class_annotations:


2472       ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag));
2473     ShouldNotReachHere();
2474     break;
2475   } // end switch (tag)
2476 } // end rewrite_cp_refs_in_verification_type_info()
2477 
2478 
2479 // Change the constant pool associated with klass scratch_class to
2480 // scratch_cp. If shrink is true, then scratch_cp_length elements
2481 // are copied from scratch_cp to a smaller constant pool and the
2482 // smaller constant pool is associated with scratch_class.
2483 void VM_RedefineClasses::set_new_constant_pool(
2484        ClassLoaderData* loader_data,
2485        instanceKlassHandle scratch_class, constantPoolHandle scratch_cp,
2486        int scratch_cp_length, TRAPS) {
2487   assert(scratch_cp->length() >= scratch_cp_length, "sanity check");
2488 
2489   // scratch_cp is a merged constant pool and has enough space for a
2490   // worst case merge situation. We want to associate the minimum
2491   // sized constant pool with the klass to save space.
2492   ConstantPool* cp = ConstantPool::allocate(loader_data, scratch_cp_length, CHECK);
2493   constantPoolHandle smaller_cp(THREAD, cp);
2494 
2495   // preserve version() value in the smaller copy
2496   int version = scratch_cp->version();
2497   assert(version != 0, "sanity check");
2498   smaller_cp->set_version(version);
2499 
2500   // attach klass to new constant pool
2501   // reference to the cp holder is needed for copy_operands()
2502   smaller_cp->set_pool_holder(scratch_class());
2503 
2504   scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
2505   if (HAS_PENDING_EXCEPTION) {
2506     // Exception is handled in the caller
2507     loader_data->add_to_deallocate_list(smaller_cp());
2508     return;
2509   }
2510   scratch_cp = smaller_cp;
2511 
2512   // attach new constant pool to klass
2513   scratch_class->set_constants(scratch_cp());
2514 
2515   int i;  // for portability
2516 
2517   // update each field in klass to use new constant pool indices as needed
2518   for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) {
2519     jshort cur_index = fs.name_index();
2520     jshort new_index = find_new_index(cur_index);
2521     if (new_index != 0) {
2522       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
2523         ("field-name_index change: %d to %d", cur_index, new_index));
2524       fs.set_name_index(new_index);
2525     }
2526     cur_index = fs.signature_index();
2527     new_index = find_new_index(cur_index);
2528     if (new_index != 0) {
2529       RC_TRACE_WITH_THREAD(0x00080000, THREAD,