Skip to content

Commit 9159882

Browse files
offamitkumarshipilev
authored andcommitted
8310513: [s390x] Intrinsify recursive ObjectMonitor locking
Reviewed-by: lucy Backport-of: 47df14590c003ccb1607ec0edfe999fcf2aebd86
1 parent 3ff5359 commit 9159882

File tree

1 file changed

+64
-46
lines changed

1 file changed

+64
-46
lines changed

src/hotspot/cpu/s390/macroAssembler_s390.cpp

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
3+
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -3149,28 +3149,32 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
31493149
Register temp = temp2;
31503150
NearLabel done, object_has_monitor;
31513151

3152+
const int hdr_offset = oopDesc::mark_offset_in_bytes();
3153+
3154+
assert_different_registers(temp1, temp2, oop, box);
3155+
31523156
BLOCK_COMMENT("compiler_fast_lock_object {");
31533157

31543158
// Load markWord from oop into mark.
3155-
z_lg(displacedHeader, 0, oop);
3159+
z_lg(displacedHeader, hdr_offset, oop);
31563160

31573161
if (DiagnoseSyncOnValueBasedClasses != 0) {
3158-
load_klass(Z_R1_scratch, oop);
3159-
z_l(Z_R1_scratch, Address(Z_R1_scratch, Klass::access_flags_offset()));
3162+
load_klass(temp, oop);
3163+
z_l(temp, Address(temp, Klass::access_flags_offset()));
31603164
assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction");
3161-
z_nilh(Z_R1_scratch, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
3165+
z_nilh(temp, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
31623166
z_brne(done);
31633167
}
31643168

31653169
// Handle existing monitor.
31663170
// The object has an existing monitor iff (mark & monitor_value) != 0.
31673171
guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word");
3168-
z_lgr(temp, displacedHeader);
3169-
z_nill(temp, markWord::monitor_value);
3170-
z_brne(object_has_monitor);
3172+
z_tmll(displacedHeader, markWord::monitor_value);
3173+
z_brnaz(object_has_monitor);
31713174

31723175
if (LockingMode == LM_MONITOR) {
31733176
// Set NE to indicate 'failure' -> take slow-path
3177+
// From loading the markWord, we know that oop != nullptr
31743178
z_ltgr(oop, oop);
31753179
z_bru(done);
31763180
} else if (LockingMode == LM_LEGACY) {
@@ -3182,23 +3186,24 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
31823186
// Initialize the box (must happen before we update the object mark).
31833187
z_stg(displacedHeader, BasicLock::displaced_header_offset_in_bytes(), box);
31843188

3185-
// Memory Fence (in cmpxchgd)
3186-
// Compare object markWord with mark and if equal exchange scratch1 with object markWord.
3187-
3188-
// If the compare-and-swap succeeded, then we found an unlocked object and we
3189-
// have now locked it.
3190-
z_csg(displacedHeader, box, 0, oop);
3189+
// Compare object markWord with mark and if equal, exchange box with object markWork.
3190+
// If the compare-and-swap succeeds, then we found an unlocked object and have now locked it.
3191+
z_csg(displacedHeader, box, hdr_offset, oop);
31913192
assert(currentHeader == displacedHeader, "must be same register"); // Identified two registers from z/Architecture.
31923193
z_bre(done);
31933194

3194-
// We did not see an unlocked object so try the fast recursive case.
3195-
3195+
// We did not see an unlocked object
3196+
// currentHeader contains what is currently stored in the oop's markWord.
3197+
// We might have a recursive case. Verify by checking if the owner is self.
3198+
// To do so, compare the value in the markWord (currentHeader) with the stack pointer.
31963199
z_sgr(currentHeader, Z_SP);
31973200
load_const_optimized(temp, (~(os::vm_page_size() - 1) | markWord::lock_mask_in_place));
31983201

31993202
z_ngr(currentHeader, temp);
3200-
// z_brne(done);
3201-
// z_release();
3203+
3204+
// result zero: owner is self -> recursive lock. Indicate that by storing 0 in the box.
3205+
// result not-zero: attempt failed. We don't hold the lock -> go for slow case.
3206+
32023207
z_stg(currentHeader/*==0 or not 0*/, BasicLock::displaced_header_offset_in_bytes(), box);
32033208

32043209
z_bru(done);
@@ -3208,28 +3213,34 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
32083213
z_bru(done);
32093214
}
32103215

3216+
bind(object_has_monitor);
3217+
32113218
Register zero = temp;
32123219
Register monitor_tagged = displacedHeader; // Tagged with markWord::monitor_value.
3213-
bind(object_has_monitor);
32143220
// The object's monitor m is unlocked iff m->owner is null,
32153221
// otherwise m->owner may contain a thread or a stack address.
3216-
//
3222+
32173223
// Try to CAS m->owner from null to current thread.
3218-
z_lghi(zero, 0);
32193224
// If m->owner is null, then csg succeeds and sets m->owner=THREAD and CR=EQ.
3225+
// Otherwise, register zero is filled with the current owner.
3226+
z_lghi(zero, 0);
32203227
z_csg(zero, Z_thread, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), monitor_tagged);
32213228
if (LockingMode != LM_LIGHTWEIGHT) {
32223229
// Store a non-null value into the box.
32233230
z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box);
32243231
}
3225-
#ifdef ASSERT
3226-
z_brne(done);
3227-
// We've acquired the monitor, check some invariants.
3228-
// Invariant 1: _recursions should be 0.
3229-
asm_assert_mem8_is_zero(OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions), monitor_tagged,
3230-
"monitor->_recursions should be 0", -1);
3231-
z_ltgr(zero, zero); // Set CR=EQ.
3232-
#endif
3232+
3233+
z_bre(done); // acquired the lock for the first time.
3234+
3235+
BLOCK_COMMENT("fast_path_recursive_lock {");
3236+
// Check if we are already the owner (recursive lock)
3237+
z_cgr(Z_thread, zero); // owner is stored in zero by "z_csg" above
3238+
z_brne(done); // not a recursive lock
3239+
3240+
// Current thread already owns the lock. Just increment recursion count.
3241+
z_agsi(Address(monitor_tagged, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), 1ll);
3242+
z_cgr(zero, zero); // set the CC to EQUAL
3243+
BLOCK_COMMENT("} fast_path_recursive_lock");
32333244
bind(done);
32343245

32353246
BLOCK_COMMENT("} compiler_fast_lock_object");
@@ -3242,11 +3253,12 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
32423253
Register displacedHeader = temp1;
32433254
Register currentHeader = temp2;
32443255
Register temp = temp1;
3245-
Register monitor = temp2;
32463256

32473257
const int hdr_offset = oopDesc::mark_offset_in_bytes();
32483258

3249-
Label done, object_has_monitor;
3259+
assert_different_registers(temp1, temp2, oop, box);
3260+
3261+
Label done, object_has_monitor, not_recursive;
32503262

32513263
BLOCK_COMMENT("compiler_fast_unlock_object {");
32523264

@@ -3261,30 +3273,25 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
32613273
// The object has an existing monitor iff (mark & monitor_value) != 0.
32623274
z_lg(currentHeader, hdr_offset, oop);
32633275
guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word");
3264-
if (LockingMode == LM_LIGHTWEIGHT) {
3265-
z_lgr(temp, currentHeader);
3266-
}
3267-
z_nill(currentHeader, markWord::monitor_value);
3268-
z_brne(object_has_monitor);
3276+
3277+
z_tmll(currentHeader, markWord::monitor_value);
3278+
z_brnaz(object_has_monitor);
32693279

32703280
if (LockingMode == LM_MONITOR) {
32713281
// Set NE to indicate 'failure' -> take slow-path
32723282
z_ltgr(oop, oop);
32733283
z_bru(done);
32743284
} else if (LockingMode == LM_LEGACY) {
3275-
// Check if it is still a light weight lock, this is true if we see
3285+
// Check if it is still a lightweight lock, this is true if we see
32763286
// the stack address of the basicLock in the markWord of the object
32773287
// copy box to currentHeader such that csg does not kill it.
32783288
z_lgr(currentHeader, box);
3279-
z_csg(currentHeader, displacedHeader, 0, oop);
3289+
z_csg(currentHeader, displacedHeader, hdr_offset, oop);
32803290
z_bru(done); // csg sets CR as desired.
32813291
} else {
32823292
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
32833293

3284-
// don't load currentHead again from stack-top after monitor check, as it is possible
3285-
// some other thread modified it.
3286-
// currentHeader is altered, but it's contents are copied in temp as well
3287-
lightweight_unlock(oop, temp, currentHeader, done);
3294+
lightweight_unlock(oop, currentHeader, displacedHeader, done);
32883295
z_bru(done);
32893296
}
32903297

@@ -3293,11 +3300,22 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
32933300

32943301
// Handle existing monitor.
32953302
bind(object_has_monitor);
3296-
z_lg(currentHeader, hdr_offset, oop); // CurrentHeader is tagged with monitor_value set.
3297-
load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
3298-
z_brne(done);
3299-
load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
3303+
3304+
z_cg(Z_thread, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
33003305
z_brne(done);
3306+
3307+
BLOCK_COMMENT("fast_path_recursive_unlock {");
3308+
load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
3309+
z_bre(not_recursive); // if 0 then jump, it's not recursive locking
3310+
3311+
// Recursive inflated unlock
3312+
z_agsi(Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), -1ll);
3313+
z_cgr(currentHeader, currentHeader); // set the CC to EQUAL
3314+
BLOCK_COMMENT("} fast_path_recursive_unlock");
3315+
z_bru(done);
3316+
3317+
bind(not_recursive);
3318+
33013319
load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
33023320
z_brne(done);
33033321
load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));

0 commit comments

Comments
 (0)