提交 30abf54d 编写于 作者: S sspitsyn

8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds

Summary: Need a support for invokedynamic entry kinds when new and old constant pools are merged.
Reviewed-by: coleenp, twisti
Contributed-by: serguei.spitsyn@oracle.com
上级 a3031899
...@@ -278,76 +278,23 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp, ...@@ -278,76 +278,23 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
case JVM_CONSTANT_NameAndType: case JVM_CONSTANT_NameAndType:
{ {
int name_ref_i = scratch_cp->name_ref_index_at(scratch_i); int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
int new_name_ref_i = 0; int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p,
bool match = (name_ref_i < *merge_cp_length_p) && merge_cp_length_p, THREAD);
scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
THREAD);
if (!match) {
// forward reference in *merge_cp_p or not a direct match
int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
THREAD);
if (found_i != 0) {
guarantee(found_i != name_ref_i,
"compare_entry_to() and find_matching_entry() do not agree");
// Found a matching entry somewhere else in *merge_cp_p so
// just need a mapping entry.
new_name_ref_i = found_i;
map_index(scratch_cp, name_ref_i, found_i);
} else {
// no match found so we have to append this entry to *merge_cp_p
append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
THREAD);
// The above call to append_entry() can only append one entry
// so the post call query of *merge_cp_length_p is only for
// the sake of consistency.
new_name_ref_i = *merge_cp_length_p - 1;
}
}
int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i); int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
int new_signature_ref_i = 0; int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i,
match = (signature_ref_i < *merge_cp_length_p) && merge_cp_p, merge_cp_length_p,
scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p, THREAD);
signature_ref_i, THREAD);
if (!match) {
// forward reference in *merge_cp_p or not a direct match
int found_i = scratch_cp->find_matching_entry(signature_ref_i,
*merge_cp_p, THREAD);
if (found_i != 0) {
guarantee(found_i != signature_ref_i,
"compare_entry_to() and find_matching_entry() do not agree");
// Found a matching entry somewhere else in *merge_cp_p so
// just need a mapping entry.
new_signature_ref_i = found_i;
map_index(scratch_cp, signature_ref_i, found_i);
} else {
// no match found so we have to append this entry to *merge_cp_p
append_entry(scratch_cp, signature_ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
// The above call to append_entry() can only append one entry
// so the post call query of *merge_cp_length_p is only for
// the sake of consistency.
new_signature_ref_i = *merge_cp_length_p - 1;
}
}
// If the referenced entries already exist in *merge_cp_p, then // If the referenced entries already exist in *merge_cp_p, then
// both new_name_ref_i and new_signature_ref_i will both be 0. // both new_name_ref_i and new_signature_ref_i will both be 0.
// In that case, all we are appending is the current entry. // In that case, all we are appending is the current entry.
if (new_name_ref_i == 0) { if (new_name_ref_i != name_ref_i) {
new_name_ref_i = name_ref_i;
} else {
RC_TRACE(0x00080000, RC_TRACE(0x00080000,
("NameAndType entry@%d name_ref_index change: %d to %d", ("NameAndType entry@%d name_ref_index change: %d to %d",
*merge_cp_length_p, name_ref_i, new_name_ref_i)); *merge_cp_length_p, name_ref_i, new_name_ref_i));
} }
if (new_signature_ref_i == 0) { if (new_signature_ref_i != signature_ref_i) {
new_signature_ref_i = signature_ref_i;
} else {
RC_TRACE(0x00080000, RC_TRACE(0x00080000,
("NameAndType entry@%d signature_ref_index change: %d to %d", ("NameAndType entry@%d signature_ref_index change: %d to %d",
*merge_cp_length_p, signature_ref_i, new_signature_ref_i)); *merge_cp_length_p, signature_ref_i, new_signature_ref_i));
...@@ -369,76 +316,12 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp, ...@@ -369,76 +316,12 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
case JVM_CONSTANT_Methodref: case JVM_CONSTANT_Methodref:
{ {
int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i); int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
int new_klass_ref_i = 0; int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i,
bool match = (klass_ref_i < *merge_cp_length_p) && merge_cp_p, merge_cp_length_p, THREAD);
scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
THREAD);
if (!match) {
// forward reference in *merge_cp_p or not a direct match
int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p,
THREAD);
if (found_i != 0) {
guarantee(found_i != klass_ref_i,
"compare_entry_to() and find_matching_entry() do not agree");
// Found a matching entry somewhere else in *merge_cp_p so
// just need a mapping entry.
new_klass_ref_i = found_i;
map_index(scratch_cp, klass_ref_i, found_i);
} else {
// no match found so we have to append this entry to *merge_cp_p
append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p,
THREAD);
// The above call to append_entry() can only append one entry
// so the post call query of *merge_cp_length_p is only for
// the sake of consistency. Without the optimization where we
// use JVM_CONSTANT_UnresolvedClass, then up to two entries
// could be appended.
new_klass_ref_i = *merge_cp_length_p - 1;
}
}
int name_and_type_ref_i =
scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
int new_name_and_type_ref_i = 0;
match = (name_and_type_ref_i < *merge_cp_length_p) &&
scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p,
name_and_type_ref_i, THREAD);
if (!match) {
// forward reference in *merge_cp_p or not a direct match
int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i,
*merge_cp_p, THREAD);
if (found_i != 0) {
guarantee(found_i != name_and_type_ref_i,
"compare_entry_to() and find_matching_entry() do not agree");
// Found a matching entry somewhere else in *merge_cp_p so
// just need a mapping entry.
new_name_and_type_ref_i = found_i;
map_index(scratch_cp, name_and_type_ref_i, found_i);
} else {
// no match found so we have to append this entry to *merge_cp_p
append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
// The above call to append_entry() can append more than
// one entry so the post call query of *merge_cp_length_p
// is required in order to get the right index for the
// JVM_CONSTANT_NameAndType entry.
new_name_and_type_ref_i = *merge_cp_length_p - 1;
}
}
// If the referenced entries already exist in *merge_cp_p, then int name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
// both new_klass_ref_i and new_name_and_type_ref_i will both be int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i,
// 0. In that case, all we are appending is the current entry. merge_cp_p, merge_cp_length_p, THREAD);
if (new_klass_ref_i == 0) {
new_klass_ref_i = klass_ref_i;
}
if (new_name_and_type_ref_i == 0) {
new_name_and_type_ref_i = name_and_type_ref_i;
}
const char *entry_name; const char *entry_name;
switch (scratch_cp->tag_at(scratch_i).value()) { switch (scratch_cp->tag_at(scratch_i).value()) {
...@@ -481,6 +364,72 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp, ...@@ -481,6 +364,72 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
(*merge_cp_length_p)++; (*merge_cp_length_p)++;
} break; } break;
// this is an indirect CP entry so it needs special handling
case JVM_CONSTANT_MethodType:
{
int ref_i = scratch_cp->method_type_index_at(scratch_i);
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != ref_i) {
RC_TRACE(0x00080000,
("MethodType entry@%d ref_index change: %d to %d",
*merge_cp_length_p, ref_i, new_ref_i));
}
(*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i);
if (scratch_i != *merge_cp_length_p) {
// The new entry in *merge_cp_p is at a different index than
// the new entry in scratch_cp so we need to map the index values.
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
}
(*merge_cp_length_p)++;
} break;
// this is an indirect CP entry so it needs special handling
case JVM_CONSTANT_MethodHandle:
{
int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i);
int ref_i = scratch_cp->method_handle_index_at(scratch_i);
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != ref_i) {
RC_TRACE(0x00080000,
("MethodHandle entry@%d ref_index change: %d to %d",
*merge_cp_length_p, ref_i, new_ref_i));
}
(*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i);
if (scratch_i != *merge_cp_length_p) {
// The new entry in *merge_cp_p is at a different index than
// the new entry in scratch_cp so we need to map the index values.
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
}
(*merge_cp_length_p)++;
} break;
// this is an indirect CP entry so it needs special handling
case JVM_CONSTANT_InvokeDynamic:
{
// TBD: cross-checks and possible extra appends into CP and bsm operands
// are needed as well. This issue is tracked by a separate bug 8007037.
int bss_idx = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
int ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != ref_i) {
RC_TRACE(0x00080000,
("InvokeDynamic entry@%d name_and_type ref_index change: %d to %d",
*merge_cp_length_p, ref_i, new_ref_i));
}
(*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, bss_idx, new_ref_i);
if (scratch_i != *merge_cp_length_p) {
// The new entry in *merge_cp_p is at a different index than
// the new entry in scratch_cp so we need to map the index values.
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
}
(*merge_cp_length_p)++;
} break;
// At this stage, Class or UnresolvedClass could be here, but not // At this stage, Class or UnresolvedClass could be here, but not
// ClassIndex // ClassIndex
case JVM_CONSTANT_ClassIndex: // fall through case JVM_CONSTANT_ClassIndex: // fall through
...@@ -507,6 +456,35 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp, ...@@ -507,6 +456,35 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
} // end append_entry() } // end append_entry()
int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp,
int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
int new_ref_i = ref_i;
bool match = (ref_i < *merge_cp_length_p) &&
scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD);
if (!match) {
// forward reference in *merge_cp_p or not a direct match
int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD);
if (found_i != 0) {
guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree");
// Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry.
new_ref_i = found_i;
map_index(scratch_cp, ref_i, found_i);
} else {
// no match found so we have to append this entry to *merge_cp_p
append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD);
// The above call to append_entry() can only append one entry
// so the post call query of *merge_cp_length_p is only for
// the sake of consistency.
new_ref_i = *merge_cp_length_p - 1;
}
}
return new_ref_i;
} // end find_or_append_indirect_entry()
void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) { void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) {
AnnotationArray* save; AnnotationArray* save;
......
...@@ -421,10 +421,11 @@ class VM_RedefineClasses: public VM_Operation { ...@@ -421,10 +421,11 @@ class VM_RedefineClasses: public VM_Operation {
// and in all direct and indirect subclasses. // and in all direct and indirect subclasses.
void increment_class_counter(InstanceKlass *ik, TRAPS); void increment_class_counter(InstanceKlass *ik, TRAPS);
// Support for constant pool merging (these routines are in alpha // Support for constant pool merging (these routines are in alpha order):
// order):
void append_entry(constantPoolHandle scratch_cp, int scratch_i, void append_entry(constantPoolHandle scratch_cp, int scratch_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS); constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
int find_new_index(int old_index); int find_new_index(int old_index);
bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1, bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
constantPoolHandle cp2, int index2); constantPoolHandle cp2, int index2);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册