hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
changeset 17077 8607f7c33310
parent 17029 9ff8d7c0ed79
child 17357 98206e5df09e
equal deleted inserted replaced
17076:cf842e58f030 17077:8607f7c33310
   413     } break;
   413     } break;
   414 
   414 
   415     // this is an indirect CP entry so it needs special handling
   415     // this is an indirect CP entry so it needs special handling
   416     case JVM_CONSTANT_InvokeDynamic:
   416     case JVM_CONSTANT_InvokeDynamic:
   417     {
   417     {
   418       // TBD: cross-checks and possible extra appends into CP and bsm operands
   418       // Index of the bootstrap specifier in the operands array
   419       // are needed as well. This issue is tracked by a separate bug 8007037.
   419       int old_bs_i = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
   420       int bss_idx = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
   420       int new_bs_i = find_or_append_operand(scratch_cp, old_bs_i, merge_cp_p,
   421 
   421                                             merge_cp_length_p, THREAD);
   422       int ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
   422       // The bootstrap method NameAndType_info index
   423       int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
   423       int old_ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
       
   424       int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
   424                                                     merge_cp_length_p, THREAD);
   425                                                     merge_cp_length_p, THREAD);
   425       if (new_ref_i != ref_i) {
   426       if (new_bs_i != old_bs_i) {
   426         RC_TRACE(0x00080000,
   427         RC_TRACE(0x00080000,
   427                  ("InvokeDynamic entry@%d name_and_type ref_index change: %d to %d",
   428                  ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d",
   428                   *merge_cp_length_p, ref_i, new_ref_i));
   429                   *merge_cp_length_p, old_bs_i, new_bs_i));
   429       }
   430       }
   430 
   431       if (new_ref_i != old_ref_i) {
   431       (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, bss_idx, new_ref_i);
   432         RC_TRACE(0x00080000,
       
   433                  ("InvokeDynamic entry@%d name_and_type_index change: %d to %d",
       
   434                   *merge_cp_length_p, old_ref_i, new_ref_i));
       
   435       }
       
   436 
       
   437       (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i);
   432       if (scratch_i != *merge_cp_length_p) {
   438       if (scratch_i != *merge_cp_length_p) {
   433         // The new entry in *merge_cp_p is at a different index than
   439         // The new entry in *merge_cp_p is at a different index than
   434         // the new entry in scratch_cp so we need to map the index values.
   440         // the new entry in scratch_cp so we need to map the index values.
   435         map_index(scratch_cp, scratch_i, *merge_cp_length_p);
   441         map_index(scratch_cp, scratch_i, *merge_cp_length_p);
   436       }
   442       }
   488     }
   494     }
   489   }
   495   }
   490 
   496 
   491   return new_ref_i;
   497   return new_ref_i;
   492 } // end find_or_append_indirect_entry()
   498 } // end find_or_append_indirect_entry()
       
   499 
       
   500 
       
   501 // Append a bootstrap specifier into the merge_cp operands that is semantically equal
       
   502 // to the scratch_cp operands bootstrap specifier passed by the old_bs_i index.
       
   503 // Recursively append new merge_cp entries referenced by the new bootstrap specifier.
       
   504 void VM_RedefineClasses::append_operand(constantPoolHandle scratch_cp, int old_bs_i,
       
   505        constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
       
   506 
       
   507   int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i);
       
   508   int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
       
   509                                                 merge_cp_length_p, THREAD);
       
   510   if (new_ref_i != old_ref_i) {
       
   511     RC_TRACE(0x00080000,
       
   512              ("operands entry@%d bootstrap method ref_index change: %d to %d",
       
   513               _operands_cur_length, old_ref_i, new_ref_i));
       
   514   }
       
   515 
       
   516   Array<u2>* merge_ops = (*merge_cp_p)->operands();
       
   517   int new_bs_i = _operands_cur_length;
       
   518   // We have _operands_cur_length == 0 when the merge_cp operands is empty yet.
       
   519   // However, the operand_offset_at(0) was set in the extend_operands() call.
       
   520   int new_base = (new_bs_i == 0) ? (*merge_cp_p)->operand_offset_at(0)
       
   521                                  : (*merge_cp_p)->operand_next_offset_at(new_bs_i - 1);
       
   522   int argc     = scratch_cp->operand_argument_count_at(old_bs_i);
       
   523 
       
   524   ConstantPool::operand_offset_at_put(merge_ops, _operands_cur_length, new_base);
       
   525   merge_ops->at_put(new_base++, new_ref_i);
       
   526   merge_ops->at_put(new_base++, argc);
       
   527 
       
   528   for (int i = 0; i < argc; i++) {
       
   529     int old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i);
       
   530     int new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p,
       
   531                                                       merge_cp_length_p, THREAD);
       
   532     merge_ops->at_put(new_base++, new_arg_ref_i);
       
   533     if (new_arg_ref_i != old_arg_ref_i) {
       
   534       RC_TRACE(0x00080000,
       
   535                ("operands entry@%d bootstrap method argument ref_index change: %d to %d",
       
   536                 _operands_cur_length, old_arg_ref_i, new_arg_ref_i));
       
   537     }
       
   538   }
       
   539   if (old_bs_i != _operands_cur_length) {
       
   540     // The bootstrap specifier in *merge_cp_p is at a different index than
       
   541     // that in scratch_cp so we need to map the index values.
       
   542     map_operand_index(old_bs_i, new_bs_i);
       
   543   }
       
   544   _operands_cur_length++;
       
   545 } // end append_operand()
       
   546 
       
   547 
       
   548 int VM_RedefineClasses::find_or_append_operand(constantPoolHandle scratch_cp,
       
   549       int old_bs_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
       
   550 
       
   551   int new_bs_i = old_bs_i; // bootstrap specifier index
       
   552   bool match = (old_bs_i < _operands_cur_length) &&
       
   553                scratch_cp->compare_operand_to(old_bs_i, *merge_cp_p, old_bs_i, THREAD);
       
   554 
       
   555   if (!match) {
       
   556     // forward reference in *merge_cp_p or not a direct match
       
   557     int found_i = scratch_cp->find_matching_operand(old_bs_i, *merge_cp_p,
       
   558                                                     _operands_cur_length, THREAD);
       
   559     if (found_i != -1) {
       
   560       guarantee(found_i != old_bs_i, "compare_operand_to() and find_matching_operand() disagree");
       
   561       // found a matching operand somewhere else in *merge_cp_p so just need a mapping
       
   562       new_bs_i = found_i;
       
   563       map_operand_index(old_bs_i, found_i);
       
   564     } else {
       
   565       // no match found so we have to append this bootstrap specifier to *merge_cp_p
       
   566       append_operand(scratch_cp, old_bs_i, merge_cp_p, merge_cp_length_p, THREAD);
       
   567       new_bs_i = _operands_cur_length - 1;
       
   568     }
       
   569   }
       
   570   return new_bs_i;
       
   571 } // end find_or_append_operand()
       
   572 
       
   573 
       
   574 void VM_RedefineClasses::finalize_operands_merge(constantPoolHandle merge_cp, TRAPS) {
       
   575   if (merge_cp->operands() == NULL) {
       
   576     return;
       
   577   }
       
   578   // Shrink the merge_cp operands
       
   579   merge_cp->shrink_operands(_operands_cur_length, CHECK);
       
   580 
       
   581   if (RC_TRACE_ENABLED(0x00040000)) {
       
   582     // don't want to loop unless we are tracing
       
   583     int count = 0;
       
   584     for (int i = 1; i < _operands_index_map_p->length(); i++) {
       
   585       int value = _operands_index_map_p->at(i);
       
   586       if (value != -1) {
       
   587         RC_TRACE_WITH_THREAD(0x00040000, THREAD,
       
   588           ("operands_index_map[%d]: old=%d new=%d", count, i, value));
       
   589         count++;
       
   590       }
       
   591     }
       
   592   }
       
   593   // Clean-up
       
   594   _operands_index_map_p = NULL;
       
   595   _operands_cur_length = 0;
       
   596   _operands_index_map_count = 0;
       
   597 } // end finalize_operands_merge()
   493 
   598 
   494 
   599 
   495 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
   600 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
   496              instanceKlassHandle the_class,
   601              instanceKlassHandle the_class,
   497              instanceKlassHandle scratch_class) {
   602              instanceKlassHandle scratch_class) {
   763 
   868 
   764   return value;
   869   return value;
   765 } // end find_new_index()
   870 } // end find_new_index()
   766 
   871 
   767 
   872 
       
   873 // Find new bootstrap specifier index value for old bootstrap specifier index
       
   874 // value by seaching the index map. Returns unused index (-1) if there is
       
   875 // no mapped value for the old bootstrap specifier index.
       
   876 int VM_RedefineClasses::find_new_operand_index(int old_index) {
       
   877   if (_operands_index_map_count == 0) {
       
   878     // map is empty so nothing can be found
       
   879     return -1;
       
   880   }
       
   881 
       
   882   if (old_index == -1 || old_index >= _operands_index_map_p->length()) {
       
   883     // The old_index is out of range so it is not mapped.
       
   884     // This should not happen in regular constant pool merging use.
       
   885     return -1;
       
   886   }
       
   887 
       
   888   int value = _operands_index_map_p->at(old_index);
       
   889   if (value == -1) {
       
   890     // the old_index is not mapped
       
   891     return -1;
       
   892   }
       
   893 
       
   894   return value;
       
   895 } // end find_new_operand_index()
       
   896 
       
   897 
   768 // Returns true if the current mismatch is due to a resolved/unresolved
   898 // Returns true if the current mismatch is due to a resolved/unresolved
   769 // class pair. Otherwise, returns false.
   899 // class pair. Otherwise, returns false.
   770 bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
   900 bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
   771        int index1, constantPoolHandle cp2, int index2) {
   901        int index1, constantPoolHandle cp2, int index2) {
   772 
   902 
  1012   RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d",
  1142   RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d",
  1013     scratch_cp->tag_at(old_index).value(), old_index, new_index));
  1143     scratch_cp->tag_at(old_index).value(), old_index, new_index));
  1014 } // end map_index()
  1144 } // end map_index()
  1015 
  1145 
  1016 
  1146 
       
  1147 // Map old_index to new_index as needed.
       
  1148 void VM_RedefineClasses::map_operand_index(int old_index, int new_index) {
       
  1149   if (find_new_operand_index(old_index) != -1) {
       
  1150     // old_index is already mapped
       
  1151     return;
       
  1152   }
       
  1153 
       
  1154   if (old_index == new_index) {
       
  1155     // no mapping is needed
       
  1156     return;
       
  1157   }
       
  1158 
       
  1159   _operands_index_map_p->at_put(old_index, new_index);
       
  1160   _operands_index_map_count++;
       
  1161 
       
  1162   RC_TRACE(0x00040000, ("mapped bootstrap specifier at index %d to %d", old_index, new_index));
       
  1163 } // end map_index()
       
  1164 
       
  1165 
  1017 // Merge old_cp and scratch_cp and return the results of the merge via
  1166 // Merge old_cp and scratch_cp and return the results of the merge via
  1018 // merge_cp_p. The number of entries in *merge_cp_p is returned via
  1167 // merge_cp_p. The number of entries in *merge_cp_p is returned via
  1019 // merge_cp_length_p. The entries in old_cp occupy the same locations
  1168 // merge_cp_length_p. The entries in old_cp occupy the same locations
  1020 // in *merge_cp_p. Also creates a map of indices from entries in
  1169 // in *merge_cp_p. Also creates a map of indices from entries in
  1021 // scratch_cp to the corresponding entry in *merge_cp_p. Index map
  1170 // scratch_cp to the corresponding entry in *merge_cp_p. Index map
  1084         break;
  1233         break;
  1085       }
  1234       }
  1086     } // end for each old_cp entry
  1235     } // end for each old_cp entry
  1087 
  1236 
  1088     ConstantPool::copy_operands(old_cp, *merge_cp_p, CHECK_0);
  1237     ConstantPool::copy_operands(old_cp, *merge_cp_p, CHECK_0);
       
  1238     (*merge_cp_p)->extend_operands(scratch_cp, CHECK_0);
  1089 
  1239 
  1090     // We don't need to sanity check that *merge_cp_length_p is within
  1240     // We don't need to sanity check that *merge_cp_length_p is within
  1091     // *merge_cp_p bounds since we have the minimum on-entry check above.
  1241     // *merge_cp_p bounds since we have the minimum on-entry check above.
  1092     (*merge_cp_length_p) = old_i;
  1242     (*merge_cp_length_p) = old_i;
  1093   }
  1243   }
  1196       // referenced entries to *merge_cp_p.
  1346       // referenced entries to *merge_cp_p.
  1197       append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
  1347       append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
  1198         CHECK_0);
  1348         CHECK_0);
  1199     }
  1349     }
  1200 
  1350 
       
  1351     finalize_operands_merge(*merge_cp_p, THREAD);
       
  1352 
  1201     RC_TRACE_WITH_THREAD(0x00020000, THREAD,
  1353     RC_TRACE_WITH_THREAD(0x00020000, THREAD,
  1202       ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
  1354       ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
  1203       *merge_cp_length_p, scratch_i, _index_map_count));
  1355       *merge_cp_length_p, scratch_i, _index_map_count));
  1204   }
  1356   }
  1205 
  1357 
  1268 
  1420 
  1269   ResourceMark rm(THREAD);
  1421   ResourceMark rm(THREAD);
  1270   _index_map_count = 0;
  1422   _index_map_count = 0;
  1271   _index_map_p = new intArray(scratch_cp->length(), -1);
  1423   _index_map_p = new intArray(scratch_cp->length(), -1);
  1272 
  1424 
       
  1425   _operands_cur_length = ConstantPool::operand_array_length(old_cp->operands());
       
  1426   _operands_index_map_count = 0;
       
  1427   _operands_index_map_p = new intArray(
       
  1428     ConstantPool::operand_array_length(scratch_cp->operands()), -1);
       
  1429 
  1273   // reference to the cp holder is needed for copy_operands()
  1430   // reference to the cp holder is needed for copy_operands()
  1274   merge_cp->set_pool_holder(scratch_class());
  1431   merge_cp->set_pool_holder(scratch_class());
  1275   bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
  1432   bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
  1276                   &merge_cp_length, THREAD);
  1433                   &merge_cp_length, THREAD);
  1277   merge_cp->set_pool_holder(NULL);
  1434   merge_cp->set_pool_holder(NULL);
  1397     return false;
  1554     return false;
  1398   }
  1555   }
  1399 
  1556 
  1400   return true;
  1557   return true;
  1401 } // end rewrite_cp_refs()
  1558 } // end rewrite_cp_refs()
  1402 
       
  1403 
  1559 
  1404 // Rewrite constant pool references in the methods.
  1560 // Rewrite constant pool references in the methods.
  1405 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
  1561 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
  1406        instanceKlassHandle scratch_class, TRAPS) {
  1562        instanceKlassHandle scratch_class, TRAPS) {
  1407 
  1563