Skip to content

Commit 64e0649

Browse files
authored
Update (2023.12.27)
33161: LA port of 8320368: Per-CPU optimization of Klass range reservation 33160: LA port of 8261837: SIGSEGV in ciVirtualCallTypeData::translate_from 33159: LA port of 8318776: Require supports_cx8 to always be true
1 parent cf24236 commit 64e0649

File tree

6 files changed

+127
-19
lines changed

6 files changed

+127
-19
lines changed

src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,7 +1507,6 @@ void LIR_Assembler::casl(Register addr, Register newval, Register cmpval, Regist
15071507
}
15081508

15091509
void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
1510-
assert(VM_Version::supports_cx8(), "wrong machine");
15111510
Register addr;
15121511
if (op->addr()->is_register()) {
15131512
addr = as_reg(op->addr());
@@ -2977,7 +2976,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
29772976
__ verify_oop(obj);
29782977

29792978
if (tmp != obj) {
2979+
assert_different_registers(obj, tmp, SCR1, SCR2, mdo_addr.base(), mdo_addr.index());
29802980
__ move(tmp, obj);
2981+
} else {
2982+
assert_different_registers(obj, SCR1, SCR2, mdo_addr.base(), mdo_addr.index());
29812983
}
29822984
if (do_null) {
29832985
__ bnez(tmp, update);
@@ -3036,10 +3038,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
30363038
__ beqz(SCR2, none);
30373039
__ li(SCR1, (u1)TypeEntries::null_seen);
30383040
__ beq(SCR2, SCR1, none);
3039-
// There is a chance that the checks above (re-reading profiling
3040-
// data from memory) fail if another thread has just set the
3041+
// There is a chance that the checks above
3042+
// fail if another thread has just set the
30413043
// profiling to this obj's klass
30423044
membar_acquire();
3045+
__ XOR(tmp, tmp, SCR2); // get back original value before XOR
30433046
__ ld_d(SCR2, mdo_addr);
30443047
__ XOR(tmp, tmp, SCR2);
30453048
assert(TypeEntries::type_klass_mask == -4, "must be");
@@ -3066,6 +3069,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
30663069
__ bind(none);
30673070
// first time here. Set profile type.
30683071
__ st_d(tmp, mdo_addr);
3072+
#ifdef ASSERT
3073+
assert(TypeEntries::type_mask == -2, "must be");
3074+
__ bstrpick_d(tmp, tmp, 63, 1);
3075+
__ verify_klass_ptr(tmp);
3076+
#endif
30693077
}
30703078
} else {
30713079
// There's a single possible klass at this profile point
@@ -3099,6 +3107,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
30993107
#endif
31003108
// first time here. Set profile type.
31013109
__ st_d(tmp, mdo_addr);
3110+
#ifdef ASSERT
3111+
assert(TypeEntries::type_mask == -2, "must be");
3112+
__ bstrpick_d(tmp, tmp, 63, 1);
3113+
__ verify_klass_ptr(tmp);
3114+
#endif
31023115
} else {
31033116
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
31043117
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (c) 2023, Red Hat, Inc. All rights reserved.
3+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2023, Loongson Technology. All rights reserved.
5+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6+
*
7+
* This code is free software; you can redistribute it and/or modify it
8+
* under the terms of the GNU General Public License version 2 only, as
9+
* published by the Free Software Foundation.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*
25+
*/
26+
27+
#include "precompiled.hpp"
28+
#include "oops/compressedKlass.hpp"
29+
#include "utilities/globalDefinitions.hpp"
30+
31+
char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) {
32+
33+
char* result = nullptr;
34+
35+
// LoongArch loads a 64-bit immediate in up to four separate steps, splitting it into four different sections
36+
// (two 32-bit sections, each split into two subsections of 20/12 bits).
37+
//
38+
// 63 ....... 52 51 ... 32 31 ....... 12 11 ... 0
39+
// D C B A
40+
//
41+
// A "good" base is, in this order:
42+
// 1) only bits in A; this would be an address < 4KB, which is unrealistic on normal Linux boxes since
43+
// the typical default for vm.mmap_min_address is 64KB. We ignore that.
44+
// 2) only bits in B: a 12-bit-aligned address below 4GB. 12 bit = 4KB, but since mmap reserves at
45+
// page boundaries, we can ignore the alignment.
46+
// 3) only bits in C: a 4GB-aligned address that is lower than 4PB.
47+
// 4) only bits in D: a 4PB-aligned address.
48+
49+
// First, attempt to allocate < 4GB. We do this unconditionally:
50+
// - if can_optimize_for_zero_base, a <4GB mapping start would allow us to run unscaled (base = 0, shift = 0)
51+
// - if !can_optimize_for_zero_base, a <4GB mapping start is still good, the resulting immediate can be encoded
52+
// with one instruction (2)
53+
result = reserve_address_space_for_unscaled_encoding(size, aslr);
54+
55+
// Failing that, attempt to reserve for base=zero shift>0
56+
if (result == nullptr && optimize_for_zero_base) {
57+
result = reserve_address_space_for_zerobased_encoding(size, aslr);
58+
}
59+
60+
// Failing that, optimize for case (3) - a base with only bits set between [33-52)
61+
if (result == nullptr) {
62+
const uintptr_t from = nth_bit(32 + (optimize_for_zero_base ? LogKlassAlignmentInBytes : 0));
63+
constexpr uintptr_t to = nth_bit(52);
64+
constexpr size_t alignment = nth_bit(32);
65+
result = reserve_address_space_X(from, to, size, alignment, aslr);
66+
}
67+
68+
// Failing that, optimize for case (4) - a base with only bits set between [52-64)
69+
if (result == nullptr) {
70+
constexpr uintptr_t from = nth_bit(52);
71+
constexpr uintptr_t to = UINT64_MAX;
72+
constexpr size_t alignment = nth_bit(52);
73+
result = reserve_address_space_X(from, to, size, alignment, aslr);
74+
}
75+
76+
return result;
77+
}

src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,7 @@ void InterpreterMacroAssembler::narrow(Register result) {
15001500

15011501

15021502
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
1503+
assert_different_registers(obj, AT, T5, mdo_addr.base(), mdo_addr.index());
15031504
Label update, next, none;
15041505

15051506
verify_oop(obj);
@@ -1538,25 +1539,21 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
15381539
xorr(obj, obj, AT);
15391540

15401541
assert(TypeEntries::type_klass_mask == -4, "must be");
1541-
bstrpick_d(AT, obj, 63, 2);
1542-
beqz(AT, next);
1542+
bstrpick_d(T5, obj, 63, 2);
1543+
beqz(T5, next);
15431544

1544-
andi(AT, obj, TypeEntries::type_unknown);
1545-
bnez(AT, next);
1545+
andi(T5, obj, TypeEntries::type_unknown);
1546+
bnez(T5, next);
15461547

1547-
if (mdo_addr.index() == noreg) {
1548-
ld_d(AT, mdo_addr);
1549-
} else {
1550-
ld_d(AT, T0, mdo_addr.disp());
1551-
}
15521548
beqz(AT, none);
15531549

1554-
addi_d(AT, AT, -(TypeEntries::null_seen));
1555-
beqz(AT, none);
1550+
addi_d(T5, AT, -(TypeEntries::null_seen));
1551+
beqz(T5, none);
15561552

1557-
// There is a chance that the checks above (re-reading profiling
1558-
// data from memory) fail if another thread has just set the
1553+
// There is a chance that the checks above
1554+
// fail if another thread has just set the
15591555
// profiling to this obj's klass
1556+
xorr(obj, obj, AT); // get back original value before XOR
15601557
if (mdo_addr.index() == noreg) {
15611558
ld_d(AT, mdo_addr);
15621559
} else {
@@ -1588,6 +1585,11 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
15881585
} else {
15891586
st_d(obj, T0, mdo_addr.disp());
15901587
}
1588+
#ifdef ASSERT
1589+
assert(TypeEntries::type_mask == -2, "must be");
1590+
bstrpick_d(obj, obj, 63, 1);
1591+
verify_klass_ptr(obj);
1592+
#endif
15911593

15921594
bind(next);
15931595
if (mdo_addr.index() != noreg) {

src/hotspot/cpu/loongarch/loongarch_64.ad

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11823,7 +11823,6 @@ instruct compareAndSwapI(mRegI res, memory_exclusive mem_ptr, mRegI oldval, mReg
1182311823
%}
1182411824

1182511825
instruct compareAndSwapL(mRegI res, memory_exclusive mem_ptr, mRegL oldval, mRegL newval) %{
11826-
predicate(VM_Version::supports_cx8());
1182711826
match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
1182811827
effect(TEMP_DEF res);
1182911828
ins_cost(3 * MEMORY_REF_COST);

src/hotspot/cpu/loongarch/vm_version_loongarch.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ void VM_Version::get_processor_features() {
160160
get_cpu_info_stub(&_cpuid_info);
161161
_features |= get_feature_flags_by_cpucfg();
162162

163-
_supports_cx8 = true;
164-
165163
if (UseG1GC && FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
166164
FLAG_SET_DEFAULT(MaxGCPauseMillis, 150);
167165
}

test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
* questions.
2222
*/
2323

24+
/*
25+
* This file has been modified by Loongson Technology in 2023, These
26+
* modifications are Copyright (c) 2023 Loongson Technology, and are made
27+
* available on the same license terms set forth above.
28+
*/
29+
2430
/*
2531
* @test
2632
* @summary Test the various CPU-specific reservation schemes
@@ -94,6 +100,19 @@ private static void do_test(boolean CDS) throws IOException {
94100
}
95101
// bits 44..64
96102
output.shouldContain("reserve_between (range [0x0000100000000000-0xffffffffffffffff)");
103+
} else if (Platform.isLoongArch64()) {
104+
output.shouldContain(tryReserveForUnscaled); // unconditionally
105+
if (CDS) {
106+
output.shouldNotContain(tryReserveForZeroBased);
107+
// bits 32..52
108+
output.shouldContain("reserve_between (range [0x0000000100000000-0x0010000000000000)");
109+
} else {
110+
output.shouldContain(tryReserveForZeroBased);
111+
// bits 32..52, but not lower than zero-based limit
112+
output.shouldContain("reserve_between (range [0x0000000800000000-0x0010000000000000)");
113+
}
114+
// bits 52..64
115+
output.shouldContain("reserve_between (range [0x0010000000000000-0xffffffffffffffff)");
97116
} else if (Platform.isS390x()) {
98117
output.shouldContain(tryReserveForUnscaled); // unconditionally
99118
if (CDS) {

0 commit comments

Comments
 (0)