8074345: Enable RewriteBytecodes when VM runs with CDS

Enable bytecode rewriting when CDS turned on.

Co-authored-by: Ioi Lam <ioi.lam@oracle.com>
Reviewed-by: coleenp, iklam
This commit is contained in:
Yumin Qi 2015-03-25 15:18:37 -07:00
parent c08ffb03e4
commit 3e6cf09c39
13 changed files with 202 additions and 97 deletions

View file

@ -386,7 +386,6 @@ void TemplateTable::fast_aldc(bool wide) {
__ verify_oop(Otos_i); __ verify_oop(Otos_i);
} }
void TemplateTable::ldc2_w() { void TemplateTable::ldc2_w() {
transition(vtos, vtos); transition(vtos, vtos);
Label Long, exit; Label Long, exit;
@ -431,22 +430,28 @@ void TemplateTable::ldc2_w() {
__ bind(exit); __ bind(exit);
} }
void TemplateTable::locals_index(Register reg, int offset) { void TemplateTable::locals_index(Register reg, int offset) {
__ ldub( at_bcp(offset), reg ); __ ldub( at_bcp(offset), reg );
} }
void TemplateTable::locals_index_wide(Register reg) { void TemplateTable::locals_index_wide(Register reg) {
// offset is 2, not 1, because Lbcp points to wide prefix code // offset is 2, not 1, because Lbcp points to wide prefix code
__ get_2_byte_integer_at_bcp(2, G4_scratch, reg, InterpreterMacroAssembler::Unsigned); __ get_2_byte_integer_at_bcp(2, G4_scratch, reg, InterpreterMacroAssembler::Unsigned);
} }
void TemplateTable::iload() { void TemplateTable::iload() {
iload_internal();
}
void TemplateTable::nofast_iload() {
iload_internal(may_not_rewrite);
}
void TemplateTable::iload_internal(RewriteControl rc) {
transition(vtos, itos); transition(vtos, itos);
// Rewrite iload,iload pair into fast_iload2 // Rewrite iload,iload pair into fast_iload2
// iload,caload pair into fast_icaload // iload,caload pair into fast_icaload
if (RewriteFrequentPairs) { if (RewriteFrequentPairs && rc == may_rewrite) {
Label rewrite, done; Label rewrite, done;
// get next byte // get next byte
@ -673,8 +678,15 @@ void TemplateTable::aload(int n) {
__ ld_ptr( Llocals, Interpreter::local_offset_in_bytes(n), Otos_i ); __ ld_ptr( Llocals, Interpreter::local_offset_in_bytes(n), Otos_i );
} }
void TemplateTable::aload_0() { void TemplateTable::aload_0() {
aload_0_internal();
}
void TemplateTable::nofast_aload_0() {
aload_0_internal(may_not_rewrite);
}
void TemplateTable::aload_0_internal(RewriteControl rc) {
transition(vtos, atos); transition(vtos, atos);
// According to bytecode histograms, the pairs: // According to bytecode histograms, the pairs:
@ -688,7 +700,7 @@ void TemplateTable::aload_0() {
// bytecode into a pair bytecode; otherwise it rewrites the current // bytecode into a pair bytecode; otherwise it rewrites the current
// bytecode into _fast_aload_0 that doesn't do the pair check anymore. // bytecode into _fast_aload_0 that doesn't do the pair check anymore.
// //
if (RewriteFrequentPairs) { if (RewriteFrequentPairs && rc == may_rewrite) {
Label rewrite, done; Label rewrite, done;
// get next byte // get next byte
@ -732,7 +744,6 @@ void TemplateTable::aload_0() {
} }
} }
void TemplateTable::istore() { void TemplateTable::istore() {
transition(itos, vtos); transition(itos, vtos);
locals_index(G3_scratch); locals_index(G3_scratch);
@ -2046,16 +2057,23 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
Register index, Register index,
size_t index_size) { size_t index_size) {
// Depends on cpCacheOop layout! // Depends on cpCacheOop layout!
Label resolved; Label resolved;
Bytecodes::Code code = bytecode();
switch (code) {
case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
}
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
__ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size); __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
__ cmp(Lbyte_code, (int) bytecode()); // have we resolved this bytecode? __ cmp(Lbyte_code, code); // have we resolved this bytecode?
__ br(Assembler::equal, false, Assembler::pt, resolved); __ br(Assembler::equal, false, Assembler::pt, resolved);
__ delayed()->set((int)bytecode(), O1); __ delayed()->set(code, O1);
address entry; address entry;
switch (bytecode()) {
switch (code) {
case Bytecodes::_getstatic : // fall through case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through case Bytecodes::_getfield : // fall through
@ -2067,7 +2085,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break; case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
default: default:
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode()))); fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
break; break;
} }
// first time invocation - must resolve first // first time invocation - must resolve first
@ -2184,7 +2202,7 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
} }
} }
void TemplateTable::getfield_or_static(int byte_no, bool is_static) { void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos); transition(vtos, vtos);
Register Rcache = G3_scratch; Register Rcache = G3_scratch;
@ -2232,7 +2250,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ load_heap_oop(Rclass, Roffset, Otos_i); __ load_heap_oop(Rclass, Roffset, Otos_i);
__ verify_oop(Otos_i); __ verify_oop(Otos_i);
__ push(atos); __ push(atos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2247,7 +2265,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// itos // itos
__ ld(Rclass, Roffset, Otos_i); __ ld(Rclass, Roffset, Otos_i);
__ push(itos); __ push(itos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2263,7 +2281,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// load must be atomic // load must be atomic
__ ld_long(Rclass, Roffset, Otos_l); __ ld_long(Rclass, Roffset, Otos_l);
__ push(ltos); __ push(ltos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2278,7 +2296,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// btos // btos
__ ldsb(Rclass, Roffset, Otos_i); __ ldsb(Rclass, Roffset, Otos_i);
__ push(itos); __ push(itos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2293,7 +2311,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// ctos // ctos
__ lduh(Rclass, Roffset, Otos_i); __ lduh(Rclass, Roffset, Otos_i);
__ push(itos); __ push(itos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2308,7 +2326,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// stos // stos
__ ldsh(Rclass, Roffset, Otos_i); __ ldsh(Rclass, Roffset, Otos_i);
__ push(itos); __ push(itos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2324,7 +2342,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// ftos // ftos
__ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f); __ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f);
__ push(ftos); __ push(ftos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2336,7 +2354,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// dtos // dtos
__ ldf(FloatRegisterImpl::D, Rclass, Roffset, Ftos_d); __ ldf(FloatRegisterImpl::D, Rclass, Roffset, Ftos_d);
__ push(dtos); __ push(dtos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_dgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_dgetfield, G3_scratch, G4_scratch);
} }
@ -2351,16 +2369,18 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ bind(exit); __ bind(exit);
} }
void TemplateTable::getfield(int byte_no) { void TemplateTable::getfield(int byte_no) {
getfield_or_static(byte_no, false); getfield_or_static(byte_no, false);
} }
void TemplateTable::nofast_getfield(int byte_no) {
getfield_or_static(byte_no, false, may_not_rewrite);
}
void TemplateTable::getstatic(int byte_no) { void TemplateTable::getstatic(int byte_no) {
getfield_or_static(byte_no, true); getfield_or_static(byte_no, true);
} }
void TemplateTable::fast_accessfield(TosState state) { void TemplateTable::fast_accessfield(TosState state) {
transition(atos, state); transition(atos, state);
Register Rcache = G3_scratch; Register Rcache = G3_scratch;
@ -2545,7 +2565,7 @@ void TemplateTable::pop_and_check_object(Register r) {
__ verify_oop(r); __ verify_oop(r);
} }
void TemplateTable::putfield_or_static(int byte_no, bool is_static) { void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos); transition(vtos, vtos);
Register Rcache = G3_scratch; Register Rcache = G3_scratch;
Register index = G4_scratch; Register index = G4_scratch;
@ -2621,7 +2641,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_i(); __ pop_i();
pop_and_check_object(Rclass); pop_and_check_object(Rclass);
__ st(Otos_i, Rclass, Roffset); __ st(Otos_i, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no); if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
} }
@ -2637,7 +2657,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
pop_and_check_object(Rclass); pop_and_check_object(Rclass);
__ verify_oop(Otos_i); __ verify_oop(Otos_i);
do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no); if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
} }
@ -2654,7 +2674,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_i(); __ pop_i();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ stb(Otos_i, Rclass, Roffset); __ stb(Otos_i, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2671,7 +2691,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_l(); __ pop_l();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ st_long(Otos_l, Rclass, Roffset); __ st_long(Otos_l, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2688,7 +2708,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_i(); __ pop_i();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset); __ sth(Otos_i, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2705,7 +2725,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_i(); __ pop_i();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset); __ sth(Otos_i, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2722,7 +2742,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_f(); __ pop_f();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no);
} }
__ ba(checkVolatile); __ ba(checkVolatile);
@ -2736,7 +2756,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop_d(); __ pop_d();
if (!is_static) pop_and_check_object(Rclass); if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no); patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no);
} }
} }
@ -2810,16 +2830,18 @@ void TemplateTable::fast_storefield(TosState state) {
} }
} }
void TemplateTable::putfield(int byte_no) { void TemplateTable::putfield(int byte_no) {
putfield_or_static(byte_no, false); putfield_or_static(byte_no, false);
} }
void TemplateTable::nofast_putfield(int byte_no) {
putfield_or_static(byte_no, false, may_not_rewrite);
}
void TemplateTable::putstatic(int byte_no) { void TemplateTable::putstatic(int byte_no) {
putfield_or_static(byte_no, true); putfield_or_static(byte_no, true);
} }
void TemplateTable::fast_xaccess(TosState state) { void TemplateTable::fast_xaccess(TosState state) {
transition(vtos, state); transition(vtos, state);
Register Rcache = G3_scratch; Register Rcache = G3_scratch;
@ -2972,7 +2994,9 @@ void TemplateTable::invokevirtual(int byte_no) {
__ br(Assembler::zero, false, Assembler::pt, notFinal); __ br(Assembler::zero, false, Assembler::pt, notFinal);
__ delayed()->and3(Rret, 0xFF, G4_scratch); // gets number of parameters __ delayed()->and3(Rret, 0xFF, G4_scratch); // gets number of parameters
if (RewriteBytecodes && !UseSharedSpaces) {
patch_bytecode(Bytecodes::_fast_invokevfinal, Rscratch, Rtemp); patch_bytecode(Bytecodes::_fast_invokevfinal, Rscratch, Rtemp);
}
invokevfinal_helper(Rscratch, Rret); invokevfinal_helper(Rscratch, Rret);

View file

@ -544,8 +544,16 @@ void TemplateTable::locals_index(Register reg, int offset) {
} }
void TemplateTable::iload() { void TemplateTable::iload() {
iload_internal();
}
void TemplateTable::nofast_iload() {
iload_internal(may_not_rewrite);
}
void TemplateTable::iload_internal(RewriteControl rc) {
transition(vtos, itos); transition(vtos, itos);
if (RewriteFrequentPairs) { if (RewriteFrequentPairs && rc == may_rewrite) {
Label rewrite, done; Label rewrite, done;
const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx); const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
LP64_ONLY(assert(rbx != bc, "register damaged")); LP64_ONLY(assert(rbx != bc, "register damaged"));
@ -816,6 +824,14 @@ void TemplateTable::aload(int n) {
} }
void TemplateTable::aload_0() { void TemplateTable::aload_0() {
aload_0_internal();
}
void TemplateTable::nofast_aload_0() {
aload_0_internal(may_not_rewrite);
}
void TemplateTable::aload_0_internal(RewriteControl rc) {
transition(vtos, atos); transition(vtos, atos);
// According to bytecode histograms, the pairs: // According to bytecode histograms, the pairs:
// //
@ -838,7 +854,7 @@ void TemplateTable::aload_0() {
// aload_0, iload_1 // aload_0, iload_1
// These bytecodes with a small amount of code are most profitable // These bytecodes with a small amount of code are most profitable
// to rewrite // to rewrite
if (RewriteFrequentPairs) { if (RewriteFrequentPairs && rc == may_rewrite) {
Label rewrite, done; Label rewrite, done;
const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx); const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
@ -2492,14 +2508,21 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
assert_different_registers(Rcache, index, temp); assert_different_registers(Rcache, index, temp);
Label resolved; Label resolved;
Bytecodes::Code code = bytecode();
switch (code) {
case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
}
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
__ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size); __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
__ cmpl(temp, (int) bytecode()); // have we resolved this bytecode? __ cmpl(temp, code); // have we resolved this bytecode?
__ jcc(Assembler::equal, resolved); __ jcc(Assembler::equal, resolved);
// resolve first time through // resolve first time through
address entry; address entry;
switch (bytecode()) { switch (code) {
case Bytecodes::_getstatic : // fall through case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through case Bytecodes::_getfield : // fall through
@ -2511,10 +2534,10 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break; case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
default: default:
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode()))); fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
break; break;
} }
__ movl(temp, (int)bytecode()); __ movl(temp, code);
__ call_VM(noreg, entry, temp); __ call_VM(noreg, entry, temp);
// Update registers with resolved info // Update registers with resolved info
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
@ -2629,7 +2652,7 @@ void TemplateTable::pop_and_check_object(Register r) {
__ verify_oop(r); __ verify_oop(r);
} }
void TemplateTable::getfield_or_static(int byte_no, bool is_static) { void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos); transition(vtos, vtos);
const Register cache = rcx; const Register cache = rcx;
@ -2661,7 +2684,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ load_signed_byte(rax, field); __ load_signed_byte(rax, field);
__ push(btos); __ push(btos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2672,7 +2695,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
// atos // atos
__ load_heap_oop(rax, field); __ load_heap_oop(rax, field);
__ push(atos); __ push(atos);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2684,7 +2707,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ movl(rax, field); __ movl(rax, field);
__ push(itos); __ push(itos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_igetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_igetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2696,7 +2719,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ load_unsigned_short(rax, field); __ load_unsigned_short(rax, field);
__ push(ctos); __ push(ctos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2708,7 +2731,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ load_signed_short(rax, field); __ load_signed_short(rax, field);
__ push(stos); __ push(stos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2732,7 +2755,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ push(ltos); __ push(ltos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
LP64_ONLY(if (!is_static) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx)); LP64_ONLY(if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx));
__ jmp(Done); __ jmp(Done);
__ bind(notLong); __ bind(notLong);
@ -2744,7 +2767,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
NOT_LP64(__ fld_s(field)); NOT_LP64(__ fld_s(field));
__ push(ftos); __ push(ftos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_fgetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_fgetfield, bc, rbx);
} }
__ jmp(Done); __ jmp(Done);
@ -2759,7 +2782,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
NOT_LP64(__ fld_d(field)); NOT_LP64(__ fld_d(field));
__ push(dtos); __ push(dtos);
// Rewrite bytecode to be faster // Rewrite bytecode to be faster
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_dgetfield, bc, rbx); patch_bytecode(Bytecodes::_fast_dgetfield, bc, rbx);
} }
#ifdef ASSERT #ifdef ASSERT
@ -2780,6 +2803,10 @@ void TemplateTable::getfield(int byte_no) {
getfield_or_static(byte_no, false); getfield_or_static(byte_no, false);
} }
void TemplateTable::nofast_getfield(int byte_no) {
getfield_or_static(byte_no, false, may_not_rewrite);
}
void TemplateTable::getstatic(int byte_no) { void TemplateTable::getstatic(int byte_no) {
getfield_or_static(byte_no, true); getfield_or_static(byte_no, true);
} }
@ -2871,7 +2898,7 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is
} }
} }
void TemplateTable::putfield_or_static(int byte_no, bool is_static) { void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos); transition(vtos, vtos);
const Register cache = rcx; const Register cache = rcx;
@ -2912,7 +2939,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop(btos); __ pop(btos);
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
__ movb(field, rax); __ movb(field, rax);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -2928,7 +2955,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
// Store into the field // Store into the field
do_oop_store(_masm, field, rax, _bs->kind(), false); do_oop_store(_masm, field, rax, _bs->kind(), false);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -2943,7 +2970,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop(itos); __ pop(itos);
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
__ movl(field, rax); __ movl(field, rax);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -2958,7 +2985,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop(ctos); __ pop(ctos);
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
__ movw(field, rax); __ movw(field, rax);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -2973,7 +3000,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop(stos); __ pop(stos);
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
__ movw(field, rax); __ movw(field, rax);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -2989,7 +3016,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ pop(ltos); __ pop(ltos);
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
__ movq(field, rax); __ movq(field, rax);
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -3036,7 +3063,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
NOT_LP64( __ fstp_s(field);) NOT_LP64( __ fstp_s(field);)
LP64_ONLY( __ movflt(field, xmm0);) LP64_ONLY( __ movflt(field, xmm0);)
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
} }
__ jmp(Done); __ jmp(Done);
@ -3054,7 +3081,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
NOT_LP64( __ fstp_d(field);) NOT_LP64( __ fstp_d(field);)
LP64_ONLY( __ movdbl(field, xmm0);) LP64_ONLY( __ movdbl(field, xmm0);)
if (!is_static) { if (!is_static && rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no); patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
} }
} }
@ -3080,6 +3107,10 @@ void TemplateTable::putfield(int byte_no) {
putfield_or_static(byte_no, false); putfield_or_static(byte_no, false);
} }
void TemplateTable::nofast_putfield(int byte_no) {
putfield_or_static(byte_no, false, may_not_rewrite);
}
void TemplateTable::putstatic(int byte_no) { void TemplateTable::putstatic(int byte_no) {
putfield_or_static(byte_no, true); putfield_or_static(byte_no, true);
} }

View file

@ -578,8 +578,8 @@ BytecodeInterpreter::run(interpreterState istate) {
/* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer, /* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer,
/* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default, /* 0xE8 */ &&opc_invokehandle,&&opc_nofast_getfield,&&opc_nofast_putfield, &&opc_nofast_aload_0,
/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xEC */ &&opc_nofast_iload,&&opc_default, &&opc_default, &&opc_default,
/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,

View file

@ -525,6 +525,12 @@ void Bytecodes::initialize() {
def(_fast_aldc , "fast_aldc" , "bj" , NULL , T_OBJECT, 1, true, _ldc ); def(_fast_aldc , "fast_aldc" , "bj" , NULL , T_OBJECT, 1, true, _ldc );
def(_fast_aldc_w , "fast_aldc_w" , "bJJ" , NULL , T_OBJECT, 1, true, _ldc_w ); def(_fast_aldc_w , "fast_aldc_w" , "bJJ" , NULL , T_OBJECT, 1, true, _ldc_w );
def(_nofast_getfield , "nofast_getfield" , "bJJ" , NULL , T_ILLEGAL, 0, true, _getfield );
def(_nofast_putfield , "nofast_putfield" , "bJJ" , NULL , T_ILLEGAL, -2, true , _putfield );
def(_nofast_aload_0 , "nofast_aload_0" , "b" , NULL , T_ILLEGAL, 1, true , _aload_0 );
def(_nofast_iload , "nofast_iload" , "bi" , NULL , T_ILLEGAL, 1, false, _iload );
def(_shouldnotreachhere , "_shouldnotreachhere" , "b" , NULL , T_VOID , 0, false); def(_shouldnotreachhere , "_shouldnotreachhere" , "b" , NULL , T_VOID , 0, false);
// compare can_trap information for each bytecode with the // compare can_trap information for each bytecode with the

View file

@ -285,7 +285,20 @@ class Bytecodes: AllStatic {
// special handling of signature-polymorphic methods: // special handling of signature-polymorphic methods:
_invokehandle , _invokehandle ,
_shouldnotreachhere, // For debugging // These bytecodes are rewritten at CDS dump time, so that we can prevent them from being
// rewritten at run time. This way, the ConstMethods can be placed in the CDS ReadOnly
// section, and RewriteByteCodes/RewriteFrequentPairs can rewrite non-CDS bytecodes
// at run time.
//
// Rewritten at CDS dump time to | Original bytecode
// _invoke_virtual rewritten on sparc, will be disabled if UseSharedSpaces turned on.
// ------------------------------+------------------
_nofast_getfield , // <- _getfield
_nofast_putfield , // <- _putfield
_nofast_aload_0 , // <- _aload_0
_nofast_iload , // <- _iload
_shouldnotreachhere , // For debugging
number_of_codes number_of_codes

View file

@ -541,7 +541,8 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
// resolve field // resolve field
fieldDescriptor info; fieldDescriptor info;
constantPoolHandle pool(thread, method(thread)->constants()); constantPoolHandle pool(thread, method(thread)->constants());
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield ||
bytecode == Bytecodes::_putstatic);
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{ {

View file

@ -777,11 +777,11 @@ void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass
TRAPS) { TRAPS) {
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield || byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
(byte == Bytecodes::_nop && !check_access), "bad field access bytecode"); (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic); bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
// Check if there's a resolved klass containing the field // Check if there's a resolved klass containing the field
if (resolved_klass.is_null()) { if (resolved_klass.is_null()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);

View file

@ -26,6 +26,7 @@
#include "interpreter/bytecodes.hpp" #include "interpreter/bytecodes.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "interpreter/rewriter.hpp" #include "interpreter/rewriter.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/gcLocker.hpp" #include "memory/gcLocker.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/generateOopMap.hpp" #include "oops/generateOopMap.hpp"
@ -500,12 +501,14 @@ void Rewriter::rewrite_bytecodes(TRAPS) {
} }
void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) {
if (!DumpSharedSpaces) {
assert(!MetaspaceShared::is_in_shared_space(klass()), "archive methods must not be rewritten at run time");
}
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Rewriter rw(klass, klass->constants(), klass->methods(), CHECK); Rewriter rw(klass, klass->constants(), klass->methods(), CHECK);
// (That's all, folks.) // (That's all, folks.)
} }
Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS)
: _klass(klass), : _klass(klass),
_pool(cpool), _pool(cpool),

View file

@ -517,6 +517,12 @@ void TemplateTable::initialize() {
def(Bytecodes::_invokehandle , ubcp|disp|clvm|____, vtos, vtos, invokehandle , f1_byte ); def(Bytecodes::_invokehandle , ubcp|disp|clvm|____, vtos, vtos, invokehandle , f1_byte );
def(Bytecodes::_nofast_getfield , ubcp|____|clvm|____, vtos, vtos, nofast_getfield , f1_byte );
def(Bytecodes::_nofast_putfield , ubcp|____|clvm|____, vtos, vtos, nofast_putfield , f2_byte );
def(Bytecodes::_nofast_aload_0 , ____|____|clvm|____, vtos, atos, nofast_aload_0 , _ );
def(Bytecodes::_nofast_iload , ubcp|____|clvm|____, vtos, itos, nofast_iload , _ );
def(Bytecodes::_shouldnotreachhere , ____|____|____|____, vtos, vtos, shouldnotreachhere , _ ); def(Bytecodes::_shouldnotreachhere , ____|____|____|____, vtos, vtos, shouldnotreachhere , _ );
// platform specific bytecodes // platform specific bytecodes
pd_initialize(); pd_initialize();

View file

@ -82,6 +82,7 @@ class TemplateTable: AllStatic {
enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr }; enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr };
enum Condition { equal, not_equal, less, less_equal, greater, greater_equal }; enum Condition { equal, not_equal, less, less_equal, greater, greater_equal };
enum CacheByte { f1_byte = 1, f2_byte = 2 }; // byte_no codes enum CacheByte { f1_byte = 1, f2_byte = 2 }; // byte_no codes
enum RewriteControl { may_rewrite, may_not_rewrite }; // control for fast code under CDS
private: private:
static bool _is_initialized; // true if TemplateTable has been initialized static bool _is_initialized; // true if TemplateTable has been initialized
@ -165,6 +166,10 @@ class TemplateTable: AllStatic {
static void dload(int n); static void dload(int n);
static void aload(int n); static void aload(int n);
static void aload_0(); static void aload_0();
static void nofast_aload_0();
static void nofast_iload();
static void iload_internal(RewriteControl rc = may_rewrite);
static void aload_0_internal(RewriteControl rc = may_rewrite);
static void istore(); static void istore();
static void lstore(); static void lstore();
@ -279,10 +284,13 @@ class TemplateTable: AllStatic {
static void invokehandle(int byte_no); static void invokehandle(int byte_no);
static void fast_invokevfinal(int byte_no); static void fast_invokevfinal(int byte_no);
static void getfield_or_static(int byte_no, bool is_static); static void getfield_or_static(int byte_no, bool is_static, RewriteControl rc = may_rewrite);
static void putfield_or_static(int byte_no, bool is_static); static void putfield_or_static(int byte_no, bool is_static, RewriteControl rc = may_rewrite);
static void getfield(int byte_no); static void getfield(int byte_no);
static void putfield(int byte_no); static void putfield(int byte_no);
static void nofast_getfield(int byte_no);
static void nofast_putfield(int byte_no);
static void getstatic(int byte_no); static void getstatic(int byte_no);
static void putstatic(int byte_no); static void putstatic(int byte_no);
static void pop_and_check_object(Register obj); static void pop_and_check_object(Register obj);

View file

@ -30,6 +30,8 @@
#include "classfile/symbolTable.hpp" #include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp" #include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp" #include "code/codeCache.hpp"
#include "interpreter/bytecodes.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "memory/filemap.hpp" #include "memory/filemap.hpp"
#include "memory/gcLocker.hpp" #include "memory/gcLocker.hpp"
#include "memory/metaspace.hpp" #include "memory/metaspace.hpp"
@ -104,15 +106,33 @@ static void remove_unshareable_in_classes() {
} }
} }
// Walk all methods in the class list and assign a fingerprint. static void rewrite_nofast_bytecode(Method* method) {
// so that this part of the ConstMethod* is read only. RawBytecodeStream bcs(method);
static void calculate_fingerprints() { while (!bcs.is_last_bytecode()) {
Bytecodes::Code opcode = bcs.raw_next();
switch (opcode) {
case Bytecodes::_getfield: *bcs.bcp() = Bytecodes::_nofast_getfield; break;
case Bytecodes::_putfield: *bcs.bcp() = Bytecodes::_nofast_putfield; break;
case Bytecodes::_aload_0: *bcs.bcp() = Bytecodes::_nofast_aload_0; break;
case Bytecodes::_iload: *bcs.bcp() = Bytecodes::_nofast_iload; break;
default: break;
}
}
}
// Walk all methods in the class list to ensure that they won't be modified at
// run time. This includes:
// [1] Rewrite all bytecodes as needed, so that the ConstMethod* will not be modified
// at run time by RewriteBytecodes/RewriteFrequentPairs
// [2] Assign a fingerprint, so one doesn't need to be assigned at run-time.
static void rewrite_nofast_bytecodes_and_calculate_fingerprints() {
for (int i = 0; i < _global_klass_objects->length(); i++) { for (int i = 0; i < _global_klass_objects->length(); i++) {
Klass* k = _global_klass_objects->at(i); Klass* k = _global_klass_objects->at(i);
if (k->oop_is_instance()) { if (k->oop_is_instance()) {
InstanceKlass* ik = InstanceKlass::cast(k); InstanceKlass* ik = InstanceKlass::cast(k);
for (int i = 0; i < ik->methods()->length(); i++) { for (int i = 0; i < ik->methods()->length(); i++) {
Method* m = ik->methods()->at(i); Method* m = ik->methods()->at(i);
rewrite_nofast_bytecode(m);
Fingerprinter fp(m); Fingerprinter fp(m);
// The side effect of this call sets method's fingerprint field. // The side effect of this call sets method's fingerprint field.
fp.fingerprint(); fp.fingerprint();
@ -476,9 +496,10 @@ void VM_PopulateDumpSharedSpace::doit() {
tty->print_cr(" type array classes = %5d", num_type_array); tty->print_cr(" type array classes = %5d", num_type_array);
} }
// Update all the fingerprints in the shared methods.
tty->print("Calculating fingerprints ... "); // Ensure the ConstMethods won't be modified at run-time
calculate_fingerprints(); tty->print("Updating ConstMethods ... ");
rewrite_nofast_bytecodes_and_calculate_fingerprints();
tty->print_cr("done. "); tty->print_cr("done. ");
// Remove all references outside the metadata // Remove all references outside the metadata

View file

@ -32,7 +32,6 @@
// processes in a read-only section with Class Data Sharing (CDS). It's important // processes in a read-only section with Class Data Sharing (CDS). It's important
// that this class doesn't have virtual functions because the vptr cannot be shared // that this class doesn't have virtual functions because the vptr cannot be shared
// with CDS. // with CDS.
// (*)RewriteByteCodes and RewriteFrequentPairs is an exception but turned off in CDS
// //
// Note that most applications load thousands of methods, so keeping the size of this // Note that most applications load thousands of methods, so keeping the size of this
// structure small has a big impact on footprint. // structure small has a big impact on footprint.

View file

@ -1848,15 +1848,8 @@ void Arguments::set_heap_size() {
} }
} }
// This must be called after ergonomics because we want bytecode rewriting // This must be called after ergonomics.
// if the server compiler is used, or if UseSharedSpaces is disabled.
void Arguments::set_bytecode_flags() { void Arguments::set_bytecode_flags() {
// Better not attempt to store into a read-only space.
if (UseSharedSpaces) {
FLAG_SET_DEFAULT(RewriteBytecodes, false);
FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
}
if (!RewriteBytecodes) { if (!RewriteBytecodes) {
FLAG_SET_DEFAULT(RewriteFrequentPairs, false); FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
} }