Skip to content

Commit b0ac857

Browse files
authored
Address review comments (#15)
* Address review comments
1 parent f81aaa9 commit b0ac857

File tree

9 files changed

+159
-23
lines changed

9 files changed

+159
-23
lines changed

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5965,7 +5965,7 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned,
59655965
orl(value, rtmp);
59665966
}
59675967

5968-
cmpl(count, 2<<shift); // Short arrays (< 8 bytes) fill by element
5968+
cmpptr(count, 2<<shift); // Short arrays (< 8 bytes) fill by element
59695969
jcc(Assembler::below, L_fill_4_bytes); // use unsigned cmp
59705970
if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
59715971
Label L_skip_align2;
@@ -6042,7 +6042,7 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned,
60426042
Label L_fill_64_bytes_loop_avx3, L_check_fill_64_bytes_avx2;
60436043

60446044
// If number of bytes to fill < VM_Version::avx3_threshold(), perform fill using AVX2
6045-
cmpl(count, VM_Version::avx3_threshold());
6045+
cmpptr(count, VM_Version::avx3_threshold());
60466046
jccb(Assembler::below, L_check_fill_64_bytes_avx2);
60476047

60486048
vpbroadcastd(xtmp, xtmp, Assembler::AVX_512bit);

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,11 @@ void StubGenerator::generate_initial_stubs() {
40134013
UnsafeCopyMemory::create_table(16);
40144014
}
40154015

4016+
// Initialize table for unsafe set memeory check.
4017+
if (UnsafeSetMemory::_table == nullptr) {
4018+
UnsafeSetMemory::create_table(16);
4019+
}
4020+
40164021
// entry points that exist in all platforms Note: This is code
40174022
// that could be shared among different platforms - however the
40184023
// benefit seems to be smaller than the disadvantage of having a

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ address StubGenerator::generate_disjoint_copy_avx3_masked(address* entry, const
732732
__ ret(0);
733733

734734
if (MaxVectorSize == 64) {
735+
UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, false, ucme_exit_pc);
735736
__ BIND(L_copy_large);
736737
arraycopy_avx3_large(to, from, temp1, temp2, temp3, temp4, count, xmm1, xmm2, xmm3, xmm4, shift);
737738
__ jmp(L_finish);
@@ -2547,6 +2548,7 @@ address StubGenerator::generate_unsafe_setmemory(const char *name,
25472548
// Fill words
25482549
{
25492550
Label L_wordsTail, L_wordsLoop, L_wordsTailLoop;
2551+
UnsafeSetMemoryMark usmm(this, true, true);
25502552
////// Set words
25512553
__ leaq(rScratch2, Address(size, 1));
25522554
__ movq(rScratch1, rScratch2);
@@ -2584,14 +2586,15 @@ address StubGenerator::generate_unsafe_setmemory(const char *name,
25842586
__ incrementq(rScratch1);
25852587
__ cmpq(size, rScratch1);
25862588
__ jccb(Assembler::notEqual, L_wordsTailLoop);
2587-
__ jmp(L_exit);
25882589
}
2590+
__ jmp(L_exit);
25892591

25902592
__ BIND(L_fillQuadwords);
25912593

25922594
// Fill QUADWORDs
25932595
{
25942596
Label L_qwordLoop, L_qwordsTail, L_qwordsTailLoop;
2597+
UnsafeSetMemoryMark usmm(this, true, true);
25952598

25962599
__ leaq(rScratch2, Address(size, 7));
25972600
__ movq(rScratch1, rScratch2);
@@ -2628,14 +2631,18 @@ address StubGenerator::generate_unsafe_setmemory(const char *name,
26282631
__ incrementq(rScratch1);
26292632
__ cmpq(size, rScratch1);
26302633
__ jccb(Assembler::notEqual, L_qwordsTailLoop);
2631-
__ jmp(L_exit);
26322634
}
2635+
__ BIND(L_exit);
2636+
2637+
restore_arg_regs();
2638+
__ ret(0);
26332639

26342640
__ BIND(L_fillDwords);
26352641

26362642
// Fill DWORDs
26372643
{
26382644
Label L_dwordLoop, L_dwordsTail, L_dwordsTailLoop;
2645+
UnsafeSetMemoryMark usmm(this, true, true);
26392646

26402647
__ leaq(rScratch2, Address(size, 3));
26412648
__ movq(rScratch1, rScratch2);
@@ -2675,13 +2682,14 @@ address StubGenerator::generate_unsafe_setmemory(const char *name,
26752682
__ incrementq(rScratch1);
26762683
__ cmpq(size, rScratch1);
26772684
__ jccb(Assembler::notEqual, L_dwordsTailLoop);
2678-
__ jmpb(L_exit);
26792685
}
2686+
__ jmpb(L_exit);
26802687

26812688
__ BIND(L_fillBytes);
26822689
#ifdef MUSL_LIBC
26832690
{
26842691
Label L_byteLoop, L_longByteLoop, L_byteTail, L_byteTailLoop;
2692+
UnsafeSetMemoryMark usmm(this, true, true);
26852693

26862694
#undef wide_value
26872695
#define savedSize rax
@@ -2738,13 +2746,22 @@ address StubGenerator::generate_unsafe_setmemory(const char *name,
27382746
__ movq(c_rarg2, rax);
27392747

27402748
__ xchgq(c_rarg1, c_rarg2);
2741-
__ jump(RuntimeAddress(byte_fill_entry));
2749+
// generate_unsafe_fill(T_BYTE, false, "unsafe_set_memory");
2750+
__ mov(r11, c_rarg2);
2751+
2752+
__ enter(); // required for proper stackwalking of RuntimeStub frame
2753+
2754+
{
2755+
UnsafeSetMemoryMark usmm(this, true, true);
2756+
2757+
__ generate_fill(T_BYTE, false, c_rarg0, c_rarg1, r11, rax, xmm0);
2758+
}
2759+
2760+
__ vzeroupper();
2761+
__ leave(); // required for proper stackwalking of RuntimeStub frame
2762+
__ ret(0);
27422763
}
27432764
#endif // MUSL_LIBC
2744-
__ BIND(L_exit);
2745-
2746-
restore_arg_regs();
2747-
__ ret(0);
27482765

27492766
#undef dest
27502767
#undef size

src/hotspot/os/windows/os_windows.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2788,12 +2788,16 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
27882788
}
27892789

27902790
bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
2791-
if (((in_vm || in_native || is_unsafe_arraycopy) && thread->doing_unsafe_access()) ||
2791+
bool is_unsafe_setmemory = (in_native || in_java) && UnsafeSetMemory::contains_pc(pc);
2792+
if (((in_vm || in_native || is_unsafe_arraycopy || is_unsafe_setmemory) && thread->doing_unsafe_access()) ||
27922793
(nm != nullptr && nm->has_unsafe_access())) {
27932794
address next_pc = Assembler::locate_next_instruction(pc);
27942795
if (is_unsafe_arraycopy) {
27952796
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
27962797
}
2798+
if (is_unsafe_setmemory) {
2799+
next_pc = UnsafeSetMemory::page_error_continue_pc(pc);
2800+
}
27972801
return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
27982802
}
27992803
}

src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,18 +442,21 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
442442
CodeBlob* cb = CodeCache::find_blob(pc);
443443
CompiledMethod* nm = (cb != nullptr) ? cb->as_compiled_method_or_null() : nullptr;
444444
bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
445-
if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
445+
bool is_unsafe_setmemory = thread->doing_unsafe_access() && UnsafeSetMemory::contains_pc(pc);
446+
if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy ||
447+
is_unsafe_setmemory) {
446448
address next_pc = Assembler::locate_next_instruction(pc);
447449
if (is_unsafe_arraycopy) {
448450
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
449451
}
452+
if (is_unsafe_setmemory) {
453+
next_pc = UnsafeSetMemory::page_error_continue_pc(pc);
454+
}
450455
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
451456
}
452-
}
453-
else
454-
457+
} else
455458
#ifdef AMD64
456-
if (sig == SIGFPE &&
459+
if (sig == SIGFPE &&
457460
(info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV
458461
// Workaround for macOS ARM incorrectly reporting FPE_FLTINV for "div by 0"
459462
// instead of the expected FPE_FLTDIV when running x86_64 binary under Rosetta emulation
@@ -526,6 +529,9 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
526529
if (UnsafeCopyMemory::contains_pc(pc)) {
527530
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
528531
}
532+
if (UnsafeSetMemory::contains_pc(pc)) {
533+
next_pc = UnsafeSetMemory::page_error_continue_pc(pc);
534+
}
529535
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
530536
}
531537

src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,18 +261,21 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
261261
CodeBlob* cb = CodeCache::find_blob(pc);
262262
CompiledMethod* nm = (cb != nullptr) ? cb->as_compiled_method_or_null() : nullptr;
263263
bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
264-
if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
264+
bool is_unsafe_setmemory = thread->doing_unsafe_access() && UnsafeSetMemory::contains_pc(pc);
265+
if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy ||
266+
is_unsafe_setmemory) {
265267
address next_pc = Assembler::locate_next_instruction(pc);
266268
if (is_unsafe_arraycopy) {
267269
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
268270
}
271+
if (is_unsafe_setmemory) {
272+
next_pc = UnsafeSetMemory::page_error_continue_pc(pc);
273+
}
269274
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
270275
}
271-
}
272-
else
273-
276+
} else
274277
#ifdef AMD64
275-
if (sig == SIGFPE &&
278+
if (sig == SIGFPE &&
276279
(info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) {
277280
stub =
278281
SharedRuntime::
@@ -320,6 +323,9 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
320323
if (UnsafeCopyMemory::contains_pc(pc)) {
321324
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
322325
}
326+
if (UnsafeSetMemory::contains_pc(pc)) {
327+
next_pc = UnsafeSetMemory::page_error_continue_pc(pc);
328+
}
323329
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
324330
}
325331

src/hotspot/share/opto/library_call.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4951,9 +4951,9 @@ bool LibraryCallKit::inline_unsafe_setMemory() {
49514951
null_check_receiver(); // null-check receiver
49524952
if (stopped()) return true;
49534953

4954-
C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
4954+
if (StubRoutines::unsafe_setmemory() == nullptr) return false;
49554955

4956-
// printf("In inline_unsafe_setMemory\n");
4956+
C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
49574957

49584958
Node* dst_base = argument(1); // type: oop
49594959
Node* dst_off = ConvL2X(argument(2)); // type: long

src/hotspot/share/runtime/stubRoutines.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ int UnsafeCopyMemory::_table_length = 0;
4545
int UnsafeCopyMemory::_table_max_length = 0;
4646
address UnsafeCopyMemory::_common_exit_stub_pc = nullptr;
4747

48+
UnsafeSetMemory* UnsafeSetMemory::_table = nullptr;
49+
int UnsafeSetMemory::_table_length = 0;
50+
int UnsafeSetMemory::_table_max_length = 0;
51+
address UnsafeSetMemory::_common_exit_stub_pc = nullptr;
52+
4853
// Implementation of StubRoutines - for a description
4954
// of how to extend it, see the header file.
5055

@@ -226,6 +231,31 @@ address UnsafeCopyMemory::page_error_continue_pc(address pc) {
226231
return nullptr;
227232
}
228233

234+
void UnsafeSetMemory::create_table(int max_size) {
235+
UnsafeSetMemory::_table = new UnsafeSetMemory[max_size];
236+
UnsafeSetMemory::_table_max_length = max_size;
237+
}
238+
239+
bool UnsafeSetMemory::contains_pc(address pc) {
240+
for (int i = 0; i < UnsafeSetMemory::_table_length; i++) {
241+
UnsafeSetMemory* entry = &UnsafeSetMemory::_table[i];
242+
if (pc >= entry->start_pc() && pc < entry->end_pc()) {
243+
return true;
244+
}
245+
}
246+
return false;
247+
}
248+
249+
address UnsafeSetMemory::page_error_continue_pc(address pc) {
250+
for (int i = 0; i < UnsafeSetMemory::_table_length; i++) {
251+
UnsafeSetMemory* entry = &UnsafeSetMemory::_table[i];
252+
if (pc >= entry->start_pc() && pc < entry->end_pc()) {
253+
return entry->error_exit_pc();
254+
}
255+
}
256+
return nullptr;
257+
}
258+
229259

230260
static BufferBlob* initialize_stubs(StubCodeGenerator::StubsKind kind,
231261
int code_size, int max_aligned_stubs,
@@ -539,3 +569,25 @@ UnsafeCopyMemoryMark::~UnsafeCopyMemoryMark() {
539569
}
540570
}
541571
}
572+
573+
UnsafeSetMemoryMark::UnsafeSetMemoryMark(StubCodeGenerator* cgen, bool add_entry, bool continue_at_scope_end, address error_exit_pc) {
574+
_cgen = cgen;
575+
_ucm_entry = nullptr;
576+
if (add_entry) {
577+
address err_exit_pc = nullptr;
578+
if (!continue_at_scope_end) {
579+
err_exit_pc = error_exit_pc != nullptr ? error_exit_pc : UnsafeSetMemory::common_exit_stub_pc();
580+
}
581+
assert(err_exit_pc != nullptr || continue_at_scope_end, "error exit not set");
582+
_ucm_entry = UnsafeSetMemory::add_to_table(_cgen->assembler()->pc(), nullptr, err_exit_pc);
583+
}
584+
}
585+
586+
UnsafeSetMemoryMark::~UnsafeSetMemoryMark() {
587+
if (_ucm_entry != nullptr) {
588+
_ucm_entry->set_end_pc(_cgen->assembler()->pc());
589+
if (_ucm_entry->error_exit_pc() == nullptr) {
590+
_ucm_entry->set_error_exit_pc(_cgen->assembler()->pc());
591+
}
592+
}
593+
}

src/hotspot/share/runtime/stubRoutines.hpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,52 @@ class UnsafeCopyMemoryMark : public StackObj {
122122
~UnsafeCopyMemoryMark();
123123
};
124124

125+
class UnsafeSetMemory : public CHeapObj<mtCode> {
126+
private:
127+
address _start_pc;
128+
address _end_pc;
129+
address _error_exit_pc;
130+
public:
131+
static address _common_exit_stub_pc;
132+
static UnsafeSetMemory* _table;
133+
static int _table_length;
134+
static int _table_max_length;
135+
UnsafeSetMemory() : _start_pc(nullptr), _end_pc(nullptr), _error_exit_pc(nullptr) {}
136+
void set_start_pc(address pc) { _start_pc = pc; }
137+
void set_end_pc(address pc) { _end_pc = pc; }
138+
void set_error_exit_pc(address pc) { _error_exit_pc = pc; }
139+
address start_pc() const { return _start_pc; }
140+
address end_pc() const { return _end_pc; }
141+
address error_exit_pc() const { return _error_exit_pc; }
142+
143+
static void set_common_exit_stub_pc(address pc) { _common_exit_stub_pc = pc; }
144+
static address common_exit_stub_pc() { return _common_exit_stub_pc; }
145+
146+
static UnsafeSetMemory* add_to_table(address start_pc, address end_pc, address error_exit_pc) {
147+
guarantee(_table_length < _table_max_length, "Incorrect UnsafeSetMemory::_table_max_length");
148+
UnsafeSetMemory* entry = &_table[_table_length];
149+
entry->set_start_pc(start_pc);
150+
entry->set_end_pc(end_pc);
151+
entry->set_error_exit_pc(error_exit_pc);
152+
153+
_table_length++;
154+
return entry;
155+
}
156+
157+
static bool contains_pc(address pc);
158+
static address page_error_continue_pc(address pc);
159+
static void create_table(int max_size);
160+
};
161+
162+
class UnsafeSetMemoryMark : public StackObj {
163+
private:
164+
UnsafeSetMemory* _ucm_entry;
165+
StubCodeGenerator* _cgen;
166+
public:
167+
UnsafeSetMemoryMark(StubCodeGenerator* cgen, bool add_entry, bool continue_at_scope_end, address error_exit_pc = nullptr);
168+
~UnsafeSetMemoryMark();
169+
};
170+
125171
class StubRoutines: AllStatic {
126172

127173
public:

0 commit comments

Comments
 (0)