Skip to content
This repository was archived by the owner on Jul 17, 2024. It is now read-only.

Commit 5eb11e5

Browse files
offamitkumarRealLucy
authored andcommitted
8310513: [s390x] Intrinsify recursive ObjectMonitor locking
Reviewed-by: lucy Backport-of: 47df14590c003ccb1607ec0edfe999fcf2aebd86
1 parent 0f4bc65 commit 5eb11e5

File tree

1 file changed

+65
-47
lines changed

1 file changed

+65
-47
lines changed

src/hotspot/cpu/s390/macroAssembler_s390.cpp

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
2+
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. 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
@@ -3150,28 +3150,32 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
31503150
Register temp = temp2;
31513151
NearLabel done, object_has_monitor;
31523152

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

31553159
// Load markWord from oop into mark.
3156-
z_lg(displacedHeader, 0, oop);
3160+
z_lg(displacedHeader, hdr_offset, oop);
31573161

31583162
if (DiagnoseSyncOnValueBasedClasses != 0) {
3159-
load_klass(Z_R1_scratch, oop);
3160-
z_l(Z_R1_scratch, Address(Z_R1_scratch, Klass::access_flags_offset()));
3163+
load_klass(temp, oop);
3164+
z_l(temp, Address(temp, Klass::access_flags_offset()));
31613165
assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction");
3162-
z_nilh(Z_R1_scratch, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
3166+
z_nilh(temp, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
31633167
z_brne(done);
31643168
}
31653169

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

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

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

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

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

32053210
z_bru(done);
@@ -3209,28 +3214,34 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
32093214
z_bru(done);
32103215
}
32113216

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

32363247
BLOCK_COMMENT("} compiler_fast_lock_object");
@@ -3243,11 +3254,12 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
32433254
Register displacedHeader = temp1;
32443255
Register currentHeader = temp2;
32453256
Register temp = temp1;
3246-
Register monitor = temp2;
32473257

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

3250-
Label done, object_has_monitor;
3260+
assert_different_registers(temp1, temp2, oop, box);
3261+
3262+
Label done, object_has_monitor, not_recursive;
32513263

32523264
BLOCK_COMMENT("compiler_fast_unlock_object {");
32533265

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

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

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

@@ -3294,11 +3301,22 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
32943301

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

0 commit comments

Comments
 (0)