Skip to content

Commit 200784d

Browse files
coleenpRoland Westerlinvnkozlovrose00
committed
8132051: Better byte behavior
Co-authored-by: Roland Westerlin <[email protected]> Co-authored-by: Vladimir Kozlov <[email protected]> Co-authored-by: John Rose <[email protected]> Reviewed-by: bdelsart, roland, kvn, jrose, ahgross
1 parent ed18f94 commit 200784d

40 files changed

+513
-87
lines changed

hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
344344
length.set_instruction(x->length());
345345
length.load_item();
346346
}
347-
if (needs_store_check) {
347+
if (needs_store_check || x->check_boolean()) {
348348
value.load_item();
349349
} else {
350350
value.load_for_store(x->elt_type());
@@ -389,7 +389,8 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
389389
pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
390390
true /* do_load */, false /* patch */, NULL);
391391
}
392-
__ move(value.result(), array_addr, null_check_info);
392+
LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
393+
__ move(result, array_addr, null_check_info);
393394
if (obj_store) {
394395
// Precise card mark
395396
post_barrier(LIR_OprFact::address(array_addr), value.result());

hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
208208
case atos: ld_ptr(oop_addr, Otos_l);
209209
st_ptr(G0, oop_addr); break;
210210
case btos: // fall through
211+
case ztos: // fall through
211212
case ctos: // fall through
212213
case stos: // fall through
213214
case itos: ld(val_addr, Otos_l1); break;
@@ -452,9 +453,10 @@ void InterpreterMacroAssembler::push(TosState state) {
452453
interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
453454
switch (state) {
454455
case atos: push_ptr(); break;
455-
case btos: push_i(); break;
456-
case ctos:
457-
case stos: push_i(); break;
456+
case btos: // fall through
457+
case ztos: // fall through
458+
case ctos: // fall through
459+
case stos: // fall through
458460
case itos: push_i(); break;
459461
case ltos: push_l(); break;
460462
case ftos: push_f(); break;
@@ -468,9 +470,10 @@ void InterpreterMacroAssembler::push(TosState state) {
468470
void InterpreterMacroAssembler::pop(TosState state) {
469471
switch (state) {
470472
case atos: pop_ptr(); break;
471-
case btos: pop_i(); break;
472-
case ctos:
473-
case stos: pop_i(); break;
473+
case btos: // fall through
474+
case ztos: // fall through
475+
case ctos: // fall through
476+
case stos: // fall through
474477
case itos: pop_i(); break;
475478
case ltos: pop_l(); break;
476479
case ftos: pop_f(); break;
@@ -1103,6 +1106,49 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
11031106
interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
11041107
}
11051108

1109+
void InterpreterMacroAssembler::narrow(Register result) {
1110+
1111+
ld_ptr(Address(Lmethod, Method::const_offset()), G3_scratch);
1112+
ldub(G3_scratch, in_bytes(ConstMethod::result_type_offset()), G3_scratch);
1113+
1114+
Label notBool, notByte, notChar, done;
1115+
1116+
// common case first
1117+
cmp(G3_scratch, T_INT);
1118+
br(Assembler::equal, true, pn, done);
1119+
delayed()->nop();
1120+
1121+
cmp(G3_scratch, T_BOOLEAN);
1122+
br(Assembler::notEqual, true, pn, notBool);
1123+
delayed()->cmp(G3_scratch, T_BYTE);
1124+
and3(result, 1, result);
1125+
ba(done);
1126+
delayed()->nop();
1127+
1128+
bind(notBool);
1129+
// cmp(G3_scratch, T_BYTE);
1130+
br(Assembler::notEqual, true, pn, notByte);
1131+
delayed()->cmp(G3_scratch, T_CHAR);
1132+
sll(result, 24, result);
1133+
sra(result, 24, result);
1134+
ba(done);
1135+
delayed()->nop();
1136+
1137+
bind(notByte);
1138+
// cmp(G3_scratch, T_CHAR);
1139+
sll(result, 16, result);
1140+
br(Assembler::notEqual, true, pn, done);
1141+
delayed()->sra(result, 16, result);
1142+
// sll(result, 16, result);
1143+
srl(result, 16, result);
1144+
1145+
// bind(notChar);
1146+
// must be short, instructions already executed in delay slot
1147+
// sll(result, 16, result);
1148+
// sra(result, 16, result);
1149+
1150+
bind(done);
1151+
}
11061152

11071153
// remove activation
11081154
//
@@ -1151,6 +1197,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
11511197
case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1
11521198
#endif
11531199
case btos: // fall through
1200+
case ztos: // fall through
11541201
case ctos:
11551202
case stos: // fall through
11561203
case atos: // fall through

hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
103103
void dispatch_via (TosState state, address* table);
104104

105105

106+
void narrow(Register result);
107+
106108
// Removes the current activation (incl. unlocking of monitors).
107109
// Additionally this code is used for earlyReturn in which case we
108110
// want to skip throwing an exception and installing an exception.

hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
165165
switch (bc) {
166166
case Bytecodes::_fast_aputfield:
167167
case Bytecodes::_fast_bputfield:
168+
case Bytecodes::_fast_zputfield:
168169
case Bytecodes::_fast_cputfield:
169170
case Bytecodes::_fast_dputfield:
170171
case Bytecodes::_fast_fputfield:
@@ -922,8 +923,20 @@ void TemplateTable::bastore() {
922923
transition(itos, vtos);
923924
__ pop_i(O2); // index
924925
// Otos_i: val
926+
// O2: index
925927
// O3: array
926928
__ index_check(O3, O2, 0, G3_scratch, O2);
929+
// Need to check whether array is boolean or byte
930+
// since both types share the bastore bytecode.
931+
__ load_klass(O3, G4_scratch);
932+
__ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
933+
__ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
934+
__ andcc(G3_scratch, G4_scratch, G0);
935+
Label L_skip;
936+
__ br(Assembler::zero, false, Assembler::pn, L_skip);
937+
__ delayed()->nop();
938+
__ and3(Otos_i, 1, Otos_i); // if it is a T_BOOLEAN array, mask the stored value to 0/1
939+
__ bind(L_skip);
927940
__ stb(Otos_i, O2, arrayOopDesc::base_offset_in_bytes(T_BYTE));
928941
}
929942

@@ -2008,6 +2021,12 @@ void TemplateTable::_return(TosState state) {
20082021
__ bind(skip_register_finalizer);
20092022
}
20102023

2024+
// Narrow result if state is itos but result type is smaller.
2025+
// Need to narrow in the return bytecode rather than in generate_return_entry
2026+
// since compiled code callers expect the result to already be narrowed.
2027+
if (state == itos) {
2028+
__ narrow(Otos_i);
2029+
}
20112030
__ remove_activation(state, /* throw_monitor_exception */ true);
20122031

20132032
// The caller's SP was adjusted upon method entry to accomodate
@@ -2218,7 +2237,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
22182237
Label checkVolatile;
22192238

22202239
// compute field type
2221-
Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj;
2240+
Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj;
22222241
__ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
22232242
// Make sure we don't need to mask Rflags after the above shift
22242243
ConstantPoolCacheEntry::verify_tos_state_shift();
@@ -2273,7 +2292,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
22732292

22742293
// cmp(Rflags, btos);
22752294
__ br(Assembler::notEqual, false, Assembler::pt, notByte);
2276-
__ delayed() ->cmp(Rflags, ctos);
2295+
__ delayed() ->cmp(Rflags, ztos);
22772296

22782297
// btos
22792298
__ ldsb(Rclass, Roffset, Otos_i);
@@ -2286,6 +2305,22 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
22862305

22872306
__ bind(notByte);
22882307

2308+
// cmp(Rflags, ztos);
2309+
__ br(Assembler::notEqual, false, Assembler::pt, notBool);
2310+
__ delayed() ->cmp(Rflags, ctos);
2311+
2312+
// ztos
2313+
__ ldsb(Rclass, Roffset, Otos_i);
2314+
__ push(itos);
2315+
if (!is_static && rc == may_rewrite) {
2316+
// use btos rewriting, no truncating to t/f bit is needed for getfield.
2317+
patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
2318+
}
2319+
__ ba(checkVolatile);
2320+
__ delayed()->tst(Lscratch);
2321+
2322+
__ bind(notBool);
2323+
22892324
// cmp(Rflags, ctos);
22902325
__ br(Assembler::notEqual, false, Assembler::pt, notChar);
22912326
__ delayed() ->cmp(Rflags, stos);
@@ -2449,6 +2484,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
24492484
switch (bytecode()) { // save tos values before call_VM() clobbers them
24502485
case Bytecodes::_fast_aputfield: __ push_ptr(Otos_i); break;
24512486
case Bytecodes::_fast_bputfield: // fall through
2487+
case Bytecodes::_fast_zputfield: // fall through
24522488
case Bytecodes::_fast_sputfield: // fall through
24532489
case Bytecodes::_fast_cputfield: // fall through
24542490
case Bytecodes::_fast_iputfield: __ push_i(Otos_i); break;
@@ -2466,6 +2502,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
24662502
switch (bytecode()) { // restore tos values
24672503
case Bytecodes::_fast_aputfield: __ pop_ptr(Otos_i); break;
24682504
case Bytecodes::_fast_bputfield: // fall through
2505+
case Bytecodes::_fast_zputfield: // fall through
24692506
case Bytecodes::_fast_sputfield: // fall through
24702507
case Bytecodes::_fast_cputfield: // fall through
24712508
case Bytecodes::_fast_iputfield: __ pop_i(Otos_i); break;
@@ -2581,7 +2618,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
25812618
ConstantPoolCacheEntry::verify_tos_state_shift();
25822619

25832620
// compute field type
2584-
Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat;
2621+
Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
25852622

25862623
if (is_static) {
25872624
// putstatic with object type most likely, check that first
@@ -2649,7 +2686,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
26492686

26502687
// cmp(Rflags, btos);
26512688
__ br(Assembler::notEqual, false, Assembler::pt, notByte);
2652-
__ delayed()->cmp(Rflags, ltos);
2689+
__ delayed()->cmp(Rflags, ztos);
26532690

26542691
// btos
26552692
{
@@ -2664,6 +2701,25 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
26642701
}
26652702

26662703
__ bind(notByte);
2704+
2705+
// cmp(Rflags, btos);
2706+
__ br(Assembler::notEqual, false, Assembler::pt, notBool);
2707+
__ delayed()->cmp(Rflags, ltos);
2708+
2709+
// ztos
2710+
{
2711+
__ pop_i();
2712+
if (!is_static) pop_and_check_object(Rclass);
2713+
__ and3(Otos_i, 1, Otos_i);
2714+
__ stb(Otos_i, Rclass, Roffset);
2715+
if (!is_static && rc == may_rewrite) {
2716+
patch_bytecode(Bytecodes::_fast_zputfield, G3_scratch, G4_scratch, true, byte_no);
2717+
}
2718+
__ ba(checkVolatile);
2719+
__ delayed()->tst(Lscratch);
2720+
}
2721+
2722+
__ bind(notBool);
26672723
// cmp(Rflags, ltos);
26682724
__ br(Assembler::notEqual, false, Assembler::pt, notLong);
26692725
__ delayed()->cmp(Rflags, ctos);
@@ -2787,6 +2843,7 @@ void TemplateTable::fast_storefield(TosState state) {
27872843
pop_and_check_object(Rclass);
27882844

27892845
switch (bytecode()) {
2846+
case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield
27902847
case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
27912848
case Bytecodes::_fast_cputfield: /* fall through */
27922849
case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;

hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
284284
length.load_item();
285285

286286
}
287-
if (needs_store_check) {
287+
if (needs_store_check || x->check_boolean()) {
288288
value.load_item();
289289
} else {
290290
value.load_for_store(x->elt_type());
@@ -332,7 +332,8 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
332332
// Seems to be a precise
333333
post_barrier(LIR_OprFact::address(array_addr), value.result());
334334
} else {
335-
__ move(value.result(), array_addr, null_check_info);
335+
LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
336+
__ move(result, array_addr, null_check_info);
336337
}
337338
}
338339

hotspot/src/cpu/x86/vm/interp_masm_x86.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
349349
verify_oop(rax, state); break;
350350
case ltos: movptr(rax, val_addr); break;
351351
case btos: // fall through
352+
case ztos: // fall through
352353
case ctos: // fall through
353354
case stos: // fall through
354355
case itos: movl(rax, val_addr); break;
@@ -370,6 +371,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
370371
case ltos:
371372
movl(rdx, val_addr1); // fall through
372373
case btos: // fall through
374+
case ztos: // fall through
373375
case ctos: // fall through
374376
case stos: // fall through
375377
case itos: movl(rax, val_addr); break;
@@ -616,6 +618,7 @@ void InterpreterMacroAssembler::pop(TosState state) {
616618
switch (state) {
617619
case atos: pop_ptr(); break;
618620
case btos:
621+
case ztos:
619622
case ctos:
620623
case stos:
621624
case itos: pop_i(); break;
@@ -633,6 +636,7 @@ void InterpreterMacroAssembler::push(TosState state) {
633636
switch (state) {
634637
case atos: push_ptr(); break;
635638
case btos:
639+
case ztos:
636640
case ctos:
637641
case stos:
638642
case itos: push_i(); break;
@@ -668,6 +672,7 @@ void InterpreterMacroAssembler::pop(TosState state) {
668672
switch (state) {
669673
case atos: pop_ptr(rax); break;
670674
case btos: // fall through
675+
case ztos: // fall through
671676
case ctos: // fall through
672677
case stos: // fall through
673678
case itos: pop_i(rax); break;
@@ -716,6 +721,7 @@ void InterpreterMacroAssembler::push(TosState state) {
716721
switch (state) {
717722
case atos: push_ptr(rax); break;
718723
case btos: // fall through
724+
case ztos: // fall through
719725
case ctos: // fall through
720726
case stos: // fall through
721727
case itos: push_i(rax); break;
@@ -849,6 +855,51 @@ void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
849855
dispatch_base(state, table);
850856
}
851857

858+
void InterpreterMacroAssembler::narrow(Register result) {
859+
860+
// Get method->_constMethod->_result_type
861+
movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
862+
movptr(rcx, Address(rcx, Method::const_offset()));
863+
load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
864+
865+
Label done, notBool, notByte, notChar;
866+
867+
// common case first
868+
cmpl(rcx, T_INT);
869+
jcc(Assembler::equal, done);
870+
871+
// mask integer result to narrower return type.
872+
cmpl(rcx, T_BOOLEAN);
873+
jcc(Assembler::notEqual, notBool);
874+
andl(result, 0x1);
875+
jmp(done);
876+
877+
bind(notBool);
878+
cmpl(rcx, T_BYTE);
879+
jcc(Assembler::notEqual, notByte);
880+
LP64_ONLY(movsbl(result, result);)
881+
NOT_LP64(shll(result, 24);) // truncate upper 24 bits
882+
NOT_LP64(sarl(result, 24);) // and sign-extend byte
883+
jmp(done);
884+
885+
bind(notByte);
886+
cmpl(rcx, T_CHAR);
887+
jcc(Assembler::notEqual, notChar);
888+
LP64_ONLY(movzwl(result, result);)
889+
NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits
890+
jmp(done);
891+
892+
bind(notChar);
893+
// cmpl(rcx, T_SHORT); // all that's left
894+
// jcc(Assembler::notEqual, done);
895+
LP64_ONLY(movswl(result, result);)
896+
NOT_LP64(shll(result, 16);) // truncate upper 16 bits
897+
NOT_LP64(sarl(result, 16);) // and sign-extend short
898+
899+
// Nothing to do for T_INT
900+
bind(done);
901+
}
902+
852903
// remove activation
853904
//
854905
// Unlock the receiver if this is a synchronized method.

0 commit comments

Comments
 (0)