8068317: No_Safepoint_Verifier is not necessary in Rewriter::scan_method

Remove NSV, Method* can't move or be redefined while being rewritten

Reviewed-by: shade, jiangli
This commit is contained in:
Coleen Phillimore 2017-08-09 19:00:54 -04:00
parent 1453d9cb23
commit 7c1aeeeae9

View File

@ -355,131 +355,124 @@ void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_err
int nof_jsrs = 0; int nof_jsrs = 0;
bool has_monitor_bytecodes = false; bool has_monitor_bytecodes = false;
Bytecodes::Code c;
{ // Bytecodes and their length
// We cannot tolerate a GC in this block, because we've const address code_base = method->code_base();
// cached the bytecodes in 'code_base'. If the Method* const int code_length = method->code_size();
// moves, the bytecodes will also move.
NoSafepointVerifier nsv;
Bytecodes::Code c;
// Bytecodes and their length int bc_length;
const address code_base = method->code_base(); for (int bci = 0; bci < code_length; bci += bc_length) {
const int code_length = method->code_size(); address bcp = code_base + bci;
int prefix_length = 0;
c = (Bytecodes::Code)(*bcp);
int bc_length; // Since we have the code, see if we can get the length
for (int bci = 0; bci < code_length; bci += bc_length) { // directly. Some more complicated bytecodes will report
address bcp = code_base + bci; // a length of zero, meaning we need to make another method
int prefix_length = 0; // call to calculate the length.
c = (Bytecodes::Code)(*bcp); bc_length = Bytecodes::length_for(c);
if (bc_length == 0) {
bc_length = Bytecodes::length_at(method, bcp);
// Since we have the code, see if we can get the length // length_at will put us at the bytecode after the one modified
// directly. Some more complicated bytecodes will report // by 'wide'. We don't currently examine any of the bytecodes
// a length of zero, meaning we need to make another method // modified by wide, but in case we do in the future...
// call to calculate the length. if (c == Bytecodes::_wide) {
bc_length = Bytecodes::length_for(c); prefix_length = 1;
if (bc_length == 0) { c = (Bytecodes::Code)bcp[1];
bc_length = Bytecodes::length_at(method, bcp); }
}
// length_at will put us at the bytecode after the one modified assert(bc_length != 0, "impossible bytecode length");
// by 'wide'. We don't currently examine any of the bytecodes
// modified by wide, but in case we do in the future... switch (c) {
if (c == Bytecodes::_wide) { case Bytecodes::_lookupswitch : {
prefix_length = 1; #ifndef CC_INTERP
c = (Bytecodes::Code)bcp[1]; Bytecode_lookupswitch bc(method, bcp);
} (*bcp) = (
bc.number_of_pairs() < BinarySwitchThreshold
? Bytecodes::_fast_linearswitch
: Bytecodes::_fast_binaryswitch
);
#endif
break;
}
case Bytecodes::_fast_linearswitch:
case Bytecodes::_fast_binaryswitch: {
#ifndef CC_INTERP
(*bcp) = Bytecodes::_lookupswitch;
#endif
break;
} }
assert(bc_length != 0, "impossible bytecode length"); case Bytecodes::_invokespecial : {
rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);
break;
}
switch (c) { case Bytecodes::_putstatic :
case Bytecodes::_lookupswitch : { case Bytecodes::_putfield : {
#ifndef CC_INTERP if (!reverse) {
Bytecode_lookupswitch bc(method, bcp); // Check if any final field of the class given as parameter is modified
(*bcp) = ( // outside of initializer methods of the class. Fields that are modified
bc.number_of_pairs() < BinarySwitchThreshold // are marked with a flag. For marked fields, the compilers do not perform
? Bytecodes::_fast_linearswitch // constant folding (as the field can be changed after initialization).
: Bytecodes::_fast_binaryswitch //
); // The check is performed after verification and only if verification has
#endif // succeeded. Therefore, the class is guaranteed to be well-formed.
break; InstanceKlass* klass = method->method_holder();
} u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
case Bytecodes::_fast_linearswitch: constantPoolHandle cp(method->constants());
case Bytecodes::_fast_binaryswitch: { Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
#ifndef CC_INTERP
(*bcp) = Bytecodes::_lookupswitch;
#endif
break;
}
case Bytecodes::_invokespecial : { if (klass->name() == ref_class_name) {
rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error); Symbol* field_name = cp->name_ref_at(bc_index);
break; Symbol* field_sig = cp->signature_ref_at(bc_index);
}
case Bytecodes::_putstatic : fieldDescriptor fd;
case Bytecodes::_putfield : { if (klass->find_field(field_name, field_sig, &fd) != NULL) {
if (!reverse) { if (fd.access_flags().is_final()) {
// Check if any final field of the class given as parameter is modified if (fd.access_flags().is_static()) {
// outside of initializer methods of the class. Fields that are modified if (!method->is_static_initializer()) {
// are marked with a flag. For marked fields, the compilers do not perform fd.set_has_initialized_final_update(true);
// constant folding (as the field can be changed after initialization). }
// } else {
// The check is performed after verification and only if verification has if (!method->is_object_initializer()) {
// succeeded. Therefore, the class is guaranteed to be well-formed. fd.set_has_initialized_final_update(true);
InstanceKlass* klass = method->method_holder();
u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
constantPoolHandle cp(method->constants());
Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
if (klass->name() == ref_class_name) {
Symbol* field_name = cp->name_ref_at(bc_index);
Symbol* field_sig = cp->signature_ref_at(bc_index);
fieldDescriptor fd;
if (klass->find_field(field_name, field_sig, &fd) != NULL) {
if (fd.access_flags().is_final()) {
if (fd.access_flags().is_static()) {
if (!method->is_static_initializer()) {
fd.set_has_initialized_final_update(true);
}
} else {
if (!method->is_object_initializer()) {
fd.set_has_initialized_final_update(true);
}
} }
} }
} }
} }
} }
} }
// fall through
case Bytecodes::_getstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_invokevirtual : // fall through
case Bytecodes::_invokestatic :
case Bytecodes::_invokeinterface:
case Bytecodes::_invokehandle : // if reverse=true
rewrite_member_reference(bcp, prefix_length+1, reverse);
break;
case Bytecodes::_invokedynamic:
rewrite_invokedynamic(bcp, prefix_length+1, reverse);
break;
case Bytecodes::_ldc:
case Bytecodes::_fast_aldc: // if reverse=true
maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
break;
case Bytecodes::_ldc_w:
case Bytecodes::_fast_aldc_w: // if reverse=true
maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
break;
case Bytecodes::_jsr : // fall through
case Bytecodes::_jsr_w : nof_jsrs++; break;
case Bytecodes::_monitorenter : // fall through
case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break;
default: break;
} }
// fall through
case Bytecodes::_getstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_invokevirtual : // fall through
case Bytecodes::_invokestatic :
case Bytecodes::_invokeinterface:
case Bytecodes::_invokehandle : // if reverse=true
rewrite_member_reference(bcp, prefix_length+1, reverse);
break;
case Bytecodes::_invokedynamic:
rewrite_invokedynamic(bcp, prefix_length+1, reverse);
break;
case Bytecodes::_ldc:
case Bytecodes::_fast_aldc: // if reverse=true
maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
break;
case Bytecodes::_ldc_w:
case Bytecodes::_fast_aldc_w: // if reverse=true
maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
break;
case Bytecodes::_jsr : // fall through
case Bytecodes::_jsr_w : nof_jsrs++; break;
case Bytecodes::_monitorenter : // fall through
case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break;
default: break;
} }
} }