8139457: Relax alignment of array elements
Co-authored-by: Fei Yang <fyang@openjdk.org> Co-authored-by: Thomas Stuefe <stuefe@openjdk.org> Reviewed-by: stuefe, stefank, shade, coleenp, kdnilsen, aboldtch
This commit is contained in:
parent
cb809f8e04
commit
336bbbe389
@ -1209,7 +1209,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
len,
|
len,
|
||||||
tmp1,
|
tmp1,
|
||||||
tmp2,
|
tmp2,
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
array_element_size(op->type()),
|
array_element_size(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -188,6 +188,12 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||||||
|
|
||||||
if (len->is_valid()) {
|
if (len->is_valid()) {
|
||||||
strw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
|
strw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
|
||||||
|
int base_offset = arrayOopDesc::length_offset_in_bytes() + BytesPerInt;
|
||||||
|
if (!is_aligned(base_offset, BytesPerWord)) {
|
||||||
|
assert(is_aligned(base_offset, BytesPerInt), "must be 4-byte aligned");
|
||||||
|
// Clear gap/first 4 bytes following the length field.
|
||||||
|
strw(zr, Address(obj, base_offset));
|
||||||
|
}
|
||||||
} else if (UseCompressedClassPointers) {
|
} else if (UseCompressedClassPointers) {
|
||||||
store_klass_gap(obj, zr);
|
store_klass_gap(obj, zr);
|
||||||
}
|
}
|
||||||
@ -266,7 +272,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
|
|||||||
|
|
||||||
verify_oop(obj);
|
verify_oop(obj);
|
||||||
}
|
}
|
||||||
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, int f, Register klass, Label& slow_case) {
|
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int base_offset_in_bytes, int f, Register klass, Label& slow_case) {
|
||||||
assert_different_registers(obj, len, t1, t2, klass);
|
assert_different_registers(obj, len, t1, t2, klass);
|
||||||
|
|
||||||
// determine alignment mask
|
// determine alignment mask
|
||||||
@ -279,7 +285,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
|
|||||||
|
|
||||||
const Register arr_size = t2; // okay to be the same
|
const Register arr_size = t2; // okay to be the same
|
||||||
// align object end
|
// align object end
|
||||||
mov(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask);
|
mov(arr_size, (int32_t)base_offset_in_bytes + MinObjAlignmentInBytesMask);
|
||||||
add(arr_size, arr_size, len, ext::uxtw, f);
|
add(arr_size, arr_size, len, ext::uxtw, f);
|
||||||
andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
|
andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
|
||||||
|
|
||||||
@ -287,8 +293,11 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
|
|||||||
|
|
||||||
initialize_header(obj, klass, len, t1, t2);
|
initialize_header(obj, klass, len, t1, t2);
|
||||||
|
|
||||||
|
// Align-up to word boundary, because we clear the 4 bytes potentially
|
||||||
|
// following the length field in initialize_header().
|
||||||
|
int base_offset = align_up(base_offset_in_bytes, BytesPerWord);
|
||||||
// clear rest of allocated space
|
// clear rest of allocated space
|
||||||
initialize_body(obj, arr_size, header_size * BytesPerWord, t1, t2);
|
initialize_body(obj, arr_size, base_offset, t1, t2);
|
||||||
if (Compilation::current()->bailed_out()) {
|
if (Compilation::current()->bailed_out()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -100,7 +100,7 @@ using MacroAssembler::null_check;
|
|||||||
// header_size: size of object header in words
|
// header_size: size of object header in words
|
||||||
// f : element scale factor
|
// f : element scale factor
|
||||||
// slow_case : exit to slow case implementation if fast allocation fails
|
// slow_case : exit to slow case implementation if fast allocation fails
|
||||||
void allocate_array(Register obj, Register len, Register t, Register t2, int header_size, int f, Register klass, Label& slow_case);
|
void allocate_array(Register obj, Register len, Register t, Register t2, int base_offset_in_bytes, int f, Register klass, Label& slow_case);
|
||||||
|
|
||||||
int rsp_offset() const { return _rsp_offset; }
|
int rsp_offset() const { return _rsp_offset; }
|
||||||
void set_rsp_offset(int n) { _rsp_offset = n; }
|
void set_rsp_offset(int n) { _rsp_offset = n; }
|
||||||
|
@ -968,7 +968,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
op->tmp1()->as_register(),
|
op->tmp1()->as_register(),
|
||||||
op->tmp2()->as_register(),
|
op->tmp2()->as_register(),
|
||||||
op->tmp3()->as_register(),
|
op->tmp3()->as_register(),
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
type2aelembytes(op->type()),
|
type2aelembytes(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -2298,7 +2298,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
op->tmp1()->as_register(),
|
op->tmp1()->as_register(),
|
||||||
op->tmp2()->as_register(),
|
op->tmp2()->as_register(),
|
||||||
op->tmp3()->as_register(),
|
op->tmp3()->as_register(),
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
type2aelembytes(op->type()),
|
type2aelembytes(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -310,7 +310,7 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
Register t1, // temp register
|
Register t1, // temp register
|
||||||
Register t2, // temp register
|
Register t2, // temp register
|
||||||
Register t3, // temp register
|
Register t3, // temp register
|
||||||
int hdr_size, // object header size in words
|
int base_offset_in_bytes, // elements offset in bytes
|
||||||
int elt_size, // element size in bytes
|
int elt_size, // element size in bytes
|
||||||
Register klass, // object klass
|
Register klass, // object klass
|
||||||
Label& slow_case // continuation point if fast allocation fails
|
Label& slow_case // continuation point if fast allocation fails
|
||||||
@ -342,7 +342,7 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
sldi(t1, len, log2_elt_size);
|
sldi(t1, len, log2_elt_size);
|
||||||
arr_len_in_bytes = t1;
|
arr_len_in_bytes = t1;
|
||||||
}
|
}
|
||||||
addi(arr_size, arr_len_in_bytes, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment.
|
addi(arr_size, arr_len_in_bytes, base_offset_in_bytes + MinObjAlignmentInBytesMask); // Add space for header & alignment.
|
||||||
clrrdi(arr_size, arr_size, LogMinObjAlignmentInBytes); // Align array size.
|
clrrdi(arr_size, arr_size, LogMinObjAlignmentInBytes); // Align array size.
|
||||||
|
|
||||||
// Allocate space & initialize header.
|
// Allocate space & initialize header.
|
||||||
@ -352,8 +352,18 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
// Initialize body.
|
// Initialize body.
|
||||||
const Register base = t2;
|
const Register base = t2;
|
||||||
const Register index = t3;
|
const Register index = t3;
|
||||||
addi(base, obj, hdr_size * wordSize); // compute address of first element
|
addi(base, obj, base_offset_in_bytes); // compute address of first element
|
||||||
addi(index, arr_size, -(hdr_size * wordSize)); // compute index = number of bytes to clear
|
addi(index, arr_size, -(base_offset_in_bytes)); // compute index = number of bytes to clear
|
||||||
|
|
||||||
|
// Zero first 4 bytes, if start offset is not word aligned.
|
||||||
|
if (!is_aligned(base_offset_in_bytes, BytesPerWord)) {
|
||||||
|
assert(is_aligned(base_offset_in_bytes, BytesPerInt), "must be 4-byte aligned");
|
||||||
|
li(t1, 0);
|
||||||
|
stw(t1, 0, base);
|
||||||
|
addi(base, base, BytesPerInt);
|
||||||
|
// Note: initialize_body will align index down, no need to correct it here.
|
||||||
|
}
|
||||||
|
|
||||||
initialize_body(base, index);
|
initialize_body(base, index);
|
||||||
|
|
||||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -80,7 +80,7 @@
|
|||||||
Register t1, // temp register
|
Register t1, // temp register
|
||||||
Register t2, // temp register
|
Register t2, // temp register
|
||||||
Register t3, // temp register
|
Register t3, // temp register
|
||||||
int hdr_size, // object header size in words
|
int base_offset_in_bytes, // elements offset in bytes
|
||||||
int elt_size, // element size in bytes
|
int elt_size, // element size in bytes
|
||||||
Register klass, // object klass
|
Register klass, // object klass
|
||||||
Label& slow_case // continuation point if fast allocation fails
|
Label& slow_case // continuation point if fast allocation fails
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
@ -1020,7 +1020,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
len,
|
len,
|
||||||
tmp1,
|
tmp1,
|
||||||
tmp2,
|
tmp2,
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
array_element_size(op->type()),
|
array_element_size(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
@ -280,7 +280,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
|
|||||||
verify_oop(obj);
|
verify_oop(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int header_size, int f, Register klass, Label& slow_case) {
|
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int base_offset_in_bytes, int f, Register klass, Label& slow_case) {
|
||||||
assert_different_registers(obj, len, tmp1, tmp2, klass);
|
assert_different_registers(obj, len, tmp1, tmp2, klass);
|
||||||
|
|
||||||
// determine alignment mask
|
// determine alignment mask
|
||||||
@ -292,7 +292,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1
|
|||||||
|
|
||||||
const Register arr_size = tmp2; // okay to be the same
|
const Register arr_size = tmp2; // okay to be the same
|
||||||
// align object end
|
// align object end
|
||||||
mv(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask);
|
mv(arr_size, (int32_t)base_offset_in_bytes + MinObjAlignmentInBytesMask);
|
||||||
shadd(arr_size, len, arr_size, t0, f);
|
shadd(arr_size, len, arr_size, t0, f);
|
||||||
andi(arr_size, arr_size, ~(uint)MinObjAlignmentInBytesMask);
|
andi(arr_size, arr_size, ~(uint)MinObjAlignmentInBytesMask);
|
||||||
|
|
||||||
@ -300,9 +300,20 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1
|
|||||||
|
|
||||||
initialize_header(obj, klass, len, tmp1, tmp2);
|
initialize_header(obj, klass, len, tmp1, tmp2);
|
||||||
|
|
||||||
|
// Clear leading 4 bytes, if necessary.
|
||||||
|
// TODO: This could perhaps go into initialize_body() and also clear the leading 4 bytes
|
||||||
|
// for non-array objects, thereby replacing the klass-gap clearing code in initialize_header().
|
||||||
|
int base_offset = base_offset_in_bytes;
|
||||||
|
if (!is_aligned(base_offset, BytesPerWord)) {
|
||||||
|
assert(is_aligned(base_offset, BytesPerInt), "must be 4-byte aligned");
|
||||||
|
sw(zr, Address(obj, base_offset));
|
||||||
|
base_offset += BytesPerInt;
|
||||||
|
}
|
||||||
|
assert(is_aligned(base_offset, BytesPerWord), "must be word-aligned");
|
||||||
|
|
||||||
// clear rest of allocated space
|
// clear rest of allocated space
|
||||||
const Register len_zero = len;
|
const Register len_zero = len;
|
||||||
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
|
initialize_body(obj, arr_size, base_offset, len_zero);
|
||||||
|
|
||||||
membar(MacroAssembler::StoreStore);
|
membar(MacroAssembler::StoreStore);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
||||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
@ -101,7 +101,7 @@ using MacroAssembler::null_check;
|
|||||||
// header_size: size of object header in words
|
// header_size: size of object header in words
|
||||||
// f : element scale factor
|
// f : element scale factor
|
||||||
// slow_case : exit to slow case implementation if fast allocation fails
|
// slow_case : exit to slow case implementation if fast allocation fails
|
||||||
void allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int header_size, int f, Register klass, Label& slow_case);
|
void allocate_array(Register obj, Register len, Register tmp1, Register tmp2, int base_offset_in_bytes, int f, Register klass, Label& slow_case);
|
||||||
|
|
||||||
int rsp_offset() const { return _rsp_offset; }
|
int rsp_offset() const { return _rsp_offset; }
|
||||||
|
|
||||||
|
@ -2382,7 +2382,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
op->len()->as_register(),
|
op->len()->as_register(),
|
||||||
op->tmp1()->as_register(),
|
op->tmp1()->as_register(),
|
||||||
op->tmp2()->as_register(),
|
op->tmp2()->as_register(),
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
type2aelembytes(op->type()),
|
type2aelembytes(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -271,7 +271,7 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
Register len, // array length
|
Register len, // array length
|
||||||
Register t1, // temp register
|
Register t1, // temp register
|
||||||
Register t2, // temp register
|
Register t2, // temp register
|
||||||
int hdr_size, // object header size in words
|
int base_offset_in_bytes, // elements offset in bytes
|
||||||
int elt_size, // element size in bytes
|
int elt_size, // element size in bytes
|
||||||
Register klass, // object klass
|
Register klass, // object klass
|
||||||
Label& slow_case // Continuation point if fast allocation fails.
|
Label& slow_case // Continuation point if fast allocation fails.
|
||||||
@ -297,7 +297,7 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
case 8: z_sllg(arr_size, len, 3); break;
|
case 8: z_sllg(arr_size, len, 3); break;
|
||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
add2reg(arr_size, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment.
|
add2reg(arr_size, base_offset_in_bytes + MinObjAlignmentInBytesMask); // Add space for header & alignment.
|
||||||
z_nill(arr_size, (~MinObjAlignmentInBytesMask) & 0xffff); // Align array size.
|
z_nill(arr_size, (~MinObjAlignmentInBytesMask) & 0xffff); // Align array size.
|
||||||
|
|
||||||
try_allocate(obj, arr_size, 0, t1, slow_case);
|
try_allocate(obj, arr_size, 0, t1, slow_case);
|
||||||
@ -308,9 +308,9 @@ void C1_MacroAssembler::allocate_array(
|
|||||||
Label done;
|
Label done;
|
||||||
Register object_fields = t1;
|
Register object_fields = t1;
|
||||||
Register Rzero = Z_R1_scratch;
|
Register Rzero = Z_R1_scratch;
|
||||||
z_aghi(arr_size, -(hdr_size * BytesPerWord));
|
z_aghi(arr_size, -base_offset_in_bytes);
|
||||||
z_bre(done); // Jump if size of fields is zero.
|
z_bre(done); // Jump if size of fields is zero.
|
||||||
z_la(object_fields, hdr_size * BytesPerWord, obj);
|
z_la(object_fields, base_offset_in_bytes, obj);
|
||||||
z_xgr(Rzero, Rzero);
|
z_xgr(Rzero, Rzero);
|
||||||
initialize_body(object_fields, arr_size, Rzero);
|
initialize_body(object_fields, arr_size, Rzero);
|
||||||
bind(done);
|
bind(done);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -86,7 +86,7 @@
|
|||||||
Register len, // array length
|
Register len, // array length
|
||||||
Register t1, // temp register
|
Register t1, // temp register
|
||||||
Register t2, // temp register
|
Register t2, // temp register
|
||||||
int hdr_size, // object header size in words
|
int base_offset_in_bytes, // elements offset in bytes
|
||||||
int elt_size, // element size in bytes
|
int elt_size, // element size in bytes
|
||||||
Register klass, // object klass
|
Register klass, // object klass
|
||||||
Label& slow_case // Continuation point if fast allocation fails.
|
Label& slow_case // Continuation point if fast allocation fails.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1618,7 +1618,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
|||||||
len,
|
len,
|
||||||
tmp1,
|
tmp1,
|
||||||
tmp2,
|
tmp2,
|
||||||
arrayOopDesc::header_size(op->type()),
|
arrayOopDesc::base_offset_in_bytes(op->type()),
|
||||||
array_element_size(op->type()),
|
array_element_size(op->type()),
|
||||||
op->klass()->as_register(),
|
op->klass()->as_register(),
|
||||||
*op->stub()->entry());
|
*op->stub()->entry());
|
||||||
|
@ -186,6 +186,15 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||||||
|
|
||||||
if (len->is_valid()) {
|
if (len->is_valid()) {
|
||||||
movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
|
movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
|
||||||
|
#ifdef _LP64
|
||||||
|
int base_offset = arrayOopDesc::length_offset_in_bytes() + BytesPerInt;
|
||||||
|
if (!is_aligned(base_offset, BytesPerWord)) {
|
||||||
|
assert(is_aligned(base_offset, BytesPerInt), "must be 4-byte aligned");
|
||||||
|
// Clear gap/first 4 bytes following the length field.
|
||||||
|
xorl(t1, t1);
|
||||||
|
movl(Address(obj, base_offset), t1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
else if (UseCompressedClassPointers) {
|
else if (UseCompressedClassPointers) {
|
||||||
@ -269,7 +278,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
|
|||||||
verify_oop(obj);
|
verify_oop(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, Address::ScaleFactor f, Register klass, Label& slow_case) {
|
void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int base_offset_in_bytes, Address::ScaleFactor f, Register klass, Label& slow_case) {
|
||||||
assert(obj == rax, "obj must be in rax, for cmpxchg");
|
assert(obj == rax, "obj must be in rax, for cmpxchg");
|
||||||
assert_different_registers(obj, len, t1, t2, klass);
|
assert_different_registers(obj, len, t1, t2, klass);
|
||||||
|
|
||||||
@ -282,7 +291,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
|
|||||||
|
|
||||||
const Register arr_size = t2; // okay to be the same
|
const Register arr_size = t2; // okay to be the same
|
||||||
// align object end
|
// align object end
|
||||||
movptr(arr_size, header_size * BytesPerWord + MinObjAlignmentInBytesMask);
|
movptr(arr_size, base_offset_in_bytes + MinObjAlignmentInBytesMask);
|
||||||
lea(arr_size, Address(arr_size, len, f));
|
lea(arr_size, Address(arr_size, len, f));
|
||||||
andptr(arr_size, ~MinObjAlignmentInBytesMask);
|
andptr(arr_size, ~MinObjAlignmentInBytesMask);
|
||||||
|
|
||||||
@ -292,7 +301,10 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
|
|||||||
|
|
||||||
// clear rest of allocated space
|
// clear rest of allocated space
|
||||||
const Register len_zero = len;
|
const Register len_zero = len;
|
||||||
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
|
// Align-up to word boundary, because we clear the 4 bytes potentially
|
||||||
|
// following the length field in initialize_header().
|
||||||
|
int base_offset = align_up(base_offset_in_bytes, BytesPerWord);
|
||||||
|
initialize_body(obj, arr_size, base_offset, len_zero);
|
||||||
|
|
||||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||||
assert(obj == rax, "must be");
|
assert(obj == rax, "must be");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -89,7 +89,7 @@
|
|||||||
// header_size: size of object header in words
|
// header_size: size of object header in words
|
||||||
// f : element scale factor
|
// f : element scale factor
|
||||||
// slow_case : exit to slow case implementation if fast allocation fails
|
// slow_case : exit to slow case implementation if fast allocation fails
|
||||||
void allocate_array(Register obj, Register len, Register t, Register t2, int header_size, Address::ScaleFactor f, Register klass, Label& slow_case);
|
void allocate_array(Register obj, Register len, Register t, Register t2, int base_offset_in_bytes, Address::ScaleFactor f, Register klass, Label& slow_case);
|
||||||
|
|
||||||
int rsp_offset() const { return _rsp_offset; }
|
int rsp_offset() const { return _rsp_offset; }
|
||||||
void set_rsp_offset(int n) { _rsp_offset = n; }
|
void set_rsp_offset(int n) { _rsp_offset = n; }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -402,6 +402,13 @@ void CollectedHeap::set_gc_cause(GCCause::Cause v) {
|
|||||||
_gc_cause = v;
|
_gc_cause = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the header size in words aligned to the requirements of the
|
||||||
|
// array object type.
|
||||||
|
static int int_array_header_size() {
|
||||||
|
size_t typesize_in_bytes = arrayOopDesc::header_size_in_bytes();
|
||||||
|
return (int)align_up(typesize_in_bytes, HeapWordSize)/HeapWordSize;
|
||||||
|
}
|
||||||
|
|
||||||
size_t CollectedHeap::max_tlab_size() const {
|
size_t CollectedHeap::max_tlab_size() const {
|
||||||
// TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
|
// TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
|
||||||
// This restriction could be removed by enabling filling with multiple arrays.
|
// This restriction could be removed by enabling filling with multiple arrays.
|
||||||
@ -411,14 +418,14 @@ size_t CollectedHeap::max_tlab_size() const {
|
|||||||
// We actually lose a little by dividing first,
|
// We actually lose a little by dividing first,
|
||||||
// but that just makes the TLAB somewhat smaller than the biggest array,
|
// but that just makes the TLAB somewhat smaller than the biggest array,
|
||||||
// which is fine, since we'll be able to fill that.
|
// which is fine, since we'll be able to fill that.
|
||||||
size_t max_int_size = typeArrayOopDesc::header_size(T_INT) +
|
size_t max_int_size = int_array_header_size() +
|
||||||
sizeof(jint) *
|
sizeof(jint) *
|
||||||
((juint) max_jint / (size_t) HeapWordSize);
|
((juint) max_jint / (size_t) HeapWordSize);
|
||||||
return align_down(max_int_size, MinObjAlignment);
|
return align_down(max_int_size, MinObjAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CollectedHeap::filler_array_hdr_size() {
|
size_t CollectedHeap::filler_array_hdr_size() {
|
||||||
return align_object_offset(arrayOopDesc::header_size(T_INT)); // align to Long
|
return align_object_offset(int_array_header_size()); // align to Long
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CollectedHeap::filler_array_min_size() {
|
size_t CollectedHeap::filler_array_min_size() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -50,7 +50,17 @@ oop XObjArrayAllocator::initialize(HeapWord* mem) const {
|
|||||||
// time and time-to-safepoint
|
// time and time-to-safepoint
|
||||||
const size_t segment_max = XUtils::bytes_to_words(64 * K);
|
const size_t segment_max = XUtils::bytes_to_words(64 * K);
|
||||||
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
|
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
|
||||||
const size_t header = arrayOopDesc::header_size(element_type);
|
|
||||||
|
// Clear leading 32 bits, if necessary.
|
||||||
|
int base_offset = arrayOopDesc::base_offset_in_bytes(element_type);
|
||||||
|
if (!is_aligned(base_offset, HeapWordSize)) {
|
||||||
|
assert(is_aligned(base_offset, BytesPerInt), "array base must be 32 bit aligned");
|
||||||
|
*reinterpret_cast<jint*>(reinterpret_cast<char*>(mem) + base_offset) = 0;
|
||||||
|
base_offset += BytesPerInt;
|
||||||
|
}
|
||||||
|
assert(is_aligned(base_offset, HeapWordSize), "remaining array base must be 64 bit aligned");
|
||||||
|
|
||||||
|
const size_t header = heap_word_size(base_offset);
|
||||||
const size_t payload_size = _word_size - header;
|
const size_t payload_size = _word_size - header;
|
||||||
|
|
||||||
if (payload_size <= segment_max) {
|
if (payload_size <= segment_max) {
|
||||||
|
@ -50,7 +50,17 @@ oop ZObjArrayAllocator::initialize(HeapWord* mem) const {
|
|||||||
// time and time-to-safepoint
|
// time and time-to-safepoint
|
||||||
const size_t segment_max = ZUtils::bytes_to_words(64 * K);
|
const size_t segment_max = ZUtils::bytes_to_words(64 * K);
|
||||||
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
|
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
|
||||||
const size_t header = arrayOopDesc::header_size(element_type);
|
|
||||||
|
// Clear leading 32 bits, if necessary.
|
||||||
|
int base_offset = arrayOopDesc::base_offset_in_bytes(element_type);
|
||||||
|
if (!is_aligned(base_offset, HeapWordSize)) {
|
||||||
|
assert(is_aligned(base_offset, BytesPerInt), "array base must be 32 bit aligned");
|
||||||
|
*reinterpret_cast<jint*>(reinterpret_cast<char*>(mem) + base_offset) = 0;
|
||||||
|
base_offset += BytesPerInt;
|
||||||
|
}
|
||||||
|
assert(is_aligned(base_offset, HeapWordSize), "remaining array base must be 64 bit aligned");
|
||||||
|
|
||||||
|
const size_t header = heap_word_size(base_offset);
|
||||||
const size_t payload_size = _word_size - header;
|
const size_t payload_size = _word_size - header;
|
||||||
|
|
||||||
if (payload_size <= segment_max) {
|
if (payload_size <= segment_max) {
|
||||||
|
@ -2442,7 +2442,7 @@ C2V_END
|
|||||||
|
|
||||||
C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jchar type_char))
|
C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jchar type_char))
|
||||||
BasicType type = JVMCIENV->typeCharToBasicType(type_char, JVMCI_CHECK_0);
|
BasicType type = JVMCIENV->typeCharToBasicType(type_char, JVMCI_CHECK_0);
|
||||||
return arrayOopDesc::header_size(type) * HeapWordSize;
|
return arrayOopDesc::base_offset_in_bytes(type);
|
||||||
C2V_END
|
C2V_END
|
||||||
|
|
||||||
C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jchar type_char))
|
C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jchar type_char))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "oops/oop.hpp"
|
#include "oops/oop.hpp"
|
||||||
#include "utilities/align.hpp"
|
#include "utilities/align.hpp"
|
||||||
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
// arrayOopDesc is the abstract baseclass for all arrays. It doesn't
|
// arrayOopDesc is the abstract baseclass for all arrays. It doesn't
|
||||||
// declare pure virtual to enforce this because that would allocate a vtbl
|
// declare pure virtual to enforce this because that would allocate a vtbl
|
||||||
@ -45,13 +46,29 @@ class arrayOopDesc : public oopDesc {
|
|||||||
|
|
||||||
// Interpreter/Compiler offsets
|
// Interpreter/Compiler offsets
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Returns the address of the length "field". See length_offset_in_bytes().
|
||||||
|
static int* length_addr_impl(void* obj_ptr) {
|
||||||
|
char* ptr = static_cast<char*>(obj_ptr);
|
||||||
|
return reinterpret_cast<int*>(ptr + length_offset_in_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a type, return true if elements of that type must be aligned to 64-bit.
|
||||||
|
static bool element_type_should_be_aligned(BasicType type) {
|
||||||
|
#ifdef _LP64
|
||||||
|
if (type == T_OBJECT || type == T_ARRAY) {
|
||||||
|
return !UseCompressedOops;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return type == T_DOUBLE || type == T_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
// Header size computation.
|
// Header size computation.
|
||||||
// The header is considered the oop part of this type plus the length.
|
// The header is considered the oop part of this type plus the length.
|
||||||
// Returns the aligned header_size_in_bytes. This is not equivalent to
|
// This is not equivalent to sizeof(arrayOopDesc) which should not appear in the code.
|
||||||
// sizeof(arrayOopDesc) which should not appear in the code.
|
|
||||||
static int header_size_in_bytes() {
|
static int header_size_in_bytes() {
|
||||||
size_t hs = align_up(length_offset_in_bytes() + sizeof(int),
|
size_t hs = length_offset_in_bytes() + sizeof(int);
|
||||||
HeapWordSize);
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// make sure it isn't called before UseCompressedOops is initialized.
|
// make sure it isn't called before UseCompressedOops is initialized.
|
||||||
static size_t arrayoopdesc_hs = 0;
|
static size_t arrayoopdesc_hs = 0;
|
||||||
@ -61,20 +78,6 @@ class arrayOopDesc : public oopDesc {
|
|||||||
return (int)hs;
|
return (int)hs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the address of the length "field". See length_offset_in_bytes().
|
|
||||||
static int* length_addr_impl(void* obj_ptr) {
|
|
||||||
char* ptr = static_cast<char*>(obj_ptr);
|
|
||||||
return reinterpret_cast<int*>(ptr + length_offset_in_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether an element of a typeArrayOop with the given type must be
|
|
||||||
// aligned 0 mod 8. The typeArrayOop itself must be aligned at least this
|
|
||||||
// strongly.
|
|
||||||
static bool element_type_should_be_aligned(BasicType type) {
|
|
||||||
return type == T_DOUBLE || type == T_LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// The _length field is not declared in C++. It is allocated after the
|
// The _length field is not declared in C++. It is allocated after the
|
||||||
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise
|
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise
|
||||||
// it occupies the second half of the _klass field in oopDesc.
|
// it occupies the second half of the _klass field in oopDesc.
|
||||||
@ -85,7 +88,8 @@ class arrayOopDesc : public oopDesc {
|
|||||||
|
|
||||||
// Returns the offset of the first element.
|
// Returns the offset of the first element.
|
||||||
static int base_offset_in_bytes(BasicType type) {
|
static int base_offset_in_bytes(BasicType type) {
|
||||||
return header_size(type) * HeapWordSize;
|
size_t hs = header_size_in_bytes();
|
||||||
|
return (int)(element_type_should_be_aligned(type) ? align_up(hs, BytesPerLong) : hs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the address of the first element. The elements in the array will not
|
// Returns the address of the first element. The elements in the array will not
|
||||||
@ -122,18 +126,7 @@ class arrayOopDesc : public oopDesc {
|
|||||||
*length_addr_impl(mem) = length;
|
*length_addr_impl(mem) = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should only be called with constants as argument
|
// Return the maximum length of an array of BasicType. The length can be passed
|
||||||
// (will not constant fold otherwise)
|
|
||||||
// Returns the header size in words aligned to the requirements of the
|
|
||||||
// array object type.
|
|
||||||
static int header_size(BasicType type) {
|
|
||||||
size_t typesize_in_bytes = header_size_in_bytes();
|
|
||||||
return (int)(element_type_should_be_aligned(type)
|
|
||||||
? align_object_offset(typesize_in_bytes/HeapWordSize)
|
|
||||||
: typesize_in_bytes/HeapWordSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the maximum length of an array of BasicType. The length can passed
|
|
||||||
// to typeArrayOop::object_size(scale, length, header_size) without causing an
|
// to typeArrayOop::object_size(scale, length, header_size) without causing an
|
||||||
// overflow. We also need to make sure that this will not overflow a size_t on
|
// overflow. We also need to make sure that this will not overflow a size_t on
|
||||||
// 32 bit platforms when we convert it to a byte size.
|
// 32 bit platforms when we convert it to a byte size.
|
||||||
@ -141,8 +134,12 @@ class arrayOopDesc : public oopDesc {
|
|||||||
assert(type < T_CONFLICT, "wrong type");
|
assert(type < T_CONFLICT, "wrong type");
|
||||||
assert(type2aelembytes(type) != 0, "wrong type");
|
assert(type2aelembytes(type) != 0, "wrong type");
|
||||||
|
|
||||||
|
size_t hdr_size_in_bytes = base_offset_in_bytes(type);
|
||||||
|
// This is rounded-up and may overlap with the first array elements.
|
||||||
|
size_t hdr_size_in_words = align_up(hdr_size_in_bytes, HeapWordSize) / HeapWordSize;
|
||||||
|
|
||||||
const size_t max_element_words_per_size_t =
|
const size_t max_element_words_per_size_t =
|
||||||
align_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
|
align_down((SIZE_MAX/HeapWordSize - hdr_size_in_words), MinObjAlignment);
|
||||||
const size_t max_elements_per_size_t =
|
const size_t max_elements_per_size_t =
|
||||||
HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
|
HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
|
||||||
if ((size_t)max_jint < max_elements_per_size_t) {
|
if ((size_t)max_jint < max_elements_per_size_t) {
|
||||||
@ -150,7 +147,7 @@ class arrayOopDesc : public oopDesc {
|
|||||||
// (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
|
// (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
|
||||||
// passing around the size (in words) of an object. So, we need to avoid
|
// passing around the size (in words) of an object. So, we need to avoid
|
||||||
// overflowing an int when we add the header. See CRs 4718400 and 7110613.
|
// overflowing an int when we add the header. See CRs 4718400 and 7110613.
|
||||||
return align_down(max_jint - header_size(type), MinObjAlignment);
|
return align_down(max_jint - hdr_size_in_words, MinObjAlignment);
|
||||||
}
|
}
|
||||||
return (int32_t)max_elements_per_size_t;
|
return (int32_t)max_elements_per_size_t;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -51,32 +51,6 @@ class objArrayOopDesc : public arrayOopDesc {
|
|||||||
return base_offset_in_bytes() + sizeof(T) * index;
|
return base_offset_in_bytes() + sizeof(T) * index;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
// Give size of objArrayOop in HeapWords minus the header
|
|
||||||
static int array_size(int length) {
|
|
||||||
const uint OopsPerHeapWord = HeapWordSize/heapOopSize;
|
|
||||||
assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
|
|
||||||
"Else the following (new) computation would be in error");
|
|
||||||
uint res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
|
|
||||||
#ifdef ASSERT
|
|
||||||
// The old code is left in for sanity-checking; it'll
|
|
||||||
// go away pretty soon. XXX
|
|
||||||
// Without UseCompressedOops, this is simply:
|
|
||||||
// oop->length() * HeapWordsPerOop;
|
|
||||||
// With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
|
|
||||||
// The oop elements are aligned up to wordSize
|
|
||||||
const uint HeapWordsPerOop = heapOopSize/HeapWordSize;
|
|
||||||
uint old_res;
|
|
||||||
if (HeapWordsPerOop > 0) {
|
|
||||||
old_res = length * HeapWordsPerOop;
|
|
||||||
} else {
|
|
||||||
old_res = align_up((uint)length, OopsPerHeapWord)/OopsPerHeapWord;
|
|
||||||
}
|
|
||||||
assert(res == old_res, "Inconsistency between old and new.");
|
|
||||||
#endif // ASSERT
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns the offset of the first element.
|
// Returns the offset of the first element.
|
||||||
static int base_offset_in_bytes() {
|
static int base_offset_in_bytes() {
|
||||||
@ -94,16 +68,15 @@ private:
|
|||||||
oop replace_if_null(int index, oop exchange_value);
|
oop replace_if_null(int index, oop exchange_value);
|
||||||
|
|
||||||
// Sizing
|
// Sizing
|
||||||
static int header_size() { return arrayOopDesc::header_size(T_OBJECT); }
|
|
||||||
size_t object_size() { return object_size(length()); }
|
size_t object_size() { return object_size(length()); }
|
||||||
|
|
||||||
static size_t object_size(int length) {
|
static size_t object_size(int length) {
|
||||||
// This returns the object size in HeapWords.
|
// This returns the object size in HeapWords.
|
||||||
uint asz = array_size(length);
|
size_t asz = (size_t)length * heapOopSize;
|
||||||
uint osz = align_object_size(header_size() + asz);
|
size_t size_words = heap_word_size(base_offset_in_bytes() + asz);
|
||||||
assert(osz >= asz, "no overflow");
|
size_t osz = align_object_size(size_words);
|
||||||
assert((int)osz > 0, "no overflow");
|
assert(osz < max_jint, "no overflow");
|
||||||
return (size_t)osz;
|
return osz;
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* element_klass();
|
Klass* element_klass();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -319,14 +319,17 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len
|
|||||||
// Zero array here if the caller is deoptimized.
|
// Zero array here if the caller is deoptimized.
|
||||||
const size_t size = TypeArrayKlass::cast(array_type)->oop_size(result);
|
const size_t size = TypeArrayKlass::cast(array_type)->oop_size(result);
|
||||||
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
|
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
|
||||||
const size_t hs = arrayOopDesc::header_size(elem_type);
|
size_t hs_bytes = arrayOopDesc::base_offset_in_bytes(elem_type);
|
||||||
// Align to next 8 bytes to avoid trashing arrays's length.
|
assert(is_aligned(hs_bytes, BytesPerInt), "must be 4 byte aligned");
|
||||||
const size_t aligned_hs = align_object_offset(hs);
|
|
||||||
HeapWord* obj = cast_from_oop<HeapWord*>(result);
|
HeapWord* obj = cast_from_oop<HeapWord*>(result);
|
||||||
if (aligned_hs > hs) {
|
if (!is_aligned(hs_bytes, BytesPerLong)) {
|
||||||
Copy::zero_to_words(obj+hs, aligned_hs-hs);
|
*reinterpret_cast<jint*>(reinterpret_cast<char*>(obj) + hs_bytes) = 0;
|
||||||
|
hs_bytes += BytesPerInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimized zeroing.
|
// Optimized zeroing.
|
||||||
|
assert(is_aligned(hs_bytes, BytesPerLong), "must be 8-byte aligned");
|
||||||
|
const size_t aligned_hs = hs_bytes / BytesPerLong;
|
||||||
Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs);
|
Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -5169,18 +5169,17 @@ void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( _offset != 0 ) {
|
if( _offset != 0 ) {
|
||||||
int header_size = objArrayOopDesc::header_size() * wordSize;
|
BasicType basic_elem_type = elem()->basic_type();
|
||||||
|
int header_size = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
|
||||||
if( _offset == OffsetTop ) st->print("+undefined");
|
if( _offset == OffsetTop ) st->print("+undefined");
|
||||||
else if( _offset == OffsetBot ) st->print("+any");
|
else if( _offset == OffsetBot ) st->print("+any");
|
||||||
else if( _offset < header_size ) st->print("+%d", _offset);
|
else if( _offset < header_size ) st->print("+%d", _offset);
|
||||||
else {
|
else {
|
||||||
BasicType basic_elem_type = elem()->basic_type();
|
|
||||||
if (basic_elem_type == T_ILLEGAL) {
|
if (basic_elem_type == T_ILLEGAL) {
|
||||||
st->print("+any");
|
st->print("+any");
|
||||||
} else {
|
} else {
|
||||||
int array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
|
|
||||||
int elem_size = type2aelembytes(basic_elem_type);
|
int elem_size = type2aelembytes(basic_elem_type);
|
||||||
st->print("[%d]", (_offset - array_base)/elem_size);
|
st->print("[%d]", (_offset - header_size)/elem_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define MAX_OBJECT_SIZE \
|
#define MAX_OBJECT_SIZE \
|
||||||
( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
|
( arrayOopDesc::base_offset_in_bytes(T_DOUBLE) \
|
||||||
+ ((julong)max_jint * sizeof(double)) )
|
+ ((julong)max_jint * sizeof(double)) )
|
||||||
|
|
||||||
#define UNSAFE_ENTRY(result_type, header) \
|
#define UNSAFE_ENTRY(result_type, header) \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -116,13 +116,6 @@ public class Universe {
|
|||||||
heap().printOn(tty);
|
heap().printOn(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether an element of a typeArrayOop with the given type must be
|
|
||||||
// aligned 0 mod 8. The typeArrayOop itself must be aligned at least this
|
|
||||||
// strongly.
|
|
||||||
public static boolean elementTypeShouldBeAligned(BasicType type) {
|
|
||||||
return type == BasicType.T_DOUBLE || type == BasicType.T_LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether an object field (static/non-static) of the given type must be
|
// Check whether an object field (static/non-static) of the given type must be
|
||||||
// aligned 0 mod 8.
|
// aligned 0 mod 8.
|
||||||
public static boolean fieldTypeShouldBeAligned(BasicType type) {
|
public static boolean fieldTypeShouldBeAligned(BasicType type) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -57,28 +57,27 @@ public class Array extends Oop {
|
|||||||
private static long lengthOffsetInBytes=0;
|
private static long lengthOffsetInBytes=0;
|
||||||
private static long typeSize;
|
private static long typeSize;
|
||||||
|
|
||||||
|
// Check whether an element of a arrayOop with the given type must be
|
||||||
|
// aligned 0 mod 8. The arrayOop itself must be aligned at least this
|
||||||
|
// strongly.
|
||||||
|
private static boolean elementTypeShouldBeAligned(BasicType type) {
|
||||||
|
if (VM.getVM().isLP64()) {
|
||||||
|
if (type == BasicType.T_OBJECT || type == BasicType.T_ARRAY) {
|
||||||
|
return !VM.getVM().isCompressedOopsEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type == BasicType.T_DOUBLE || type == BasicType.T_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
private static long headerSizeInBytes() {
|
private static long headerSizeInBytes() {
|
||||||
if (headerSize != 0) {
|
if (headerSize != 0) {
|
||||||
return headerSize;
|
return headerSize;
|
||||||
}
|
}
|
||||||
if (VM.getVM().isCompressedKlassPointersEnabled()) {
|
headerSize = lengthOffsetInBytes() + VM.getVM().getIntSize();
|
||||||
headerSize = typeSize;
|
|
||||||
} else {
|
|
||||||
headerSize = VM.getVM().alignUp(typeSize + VM.getVM().getIntSize(),
|
|
||||||
VM.getVM().getHeapWordSize());
|
|
||||||
}
|
|
||||||
return headerSize;
|
return headerSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long headerSize(BasicType type) {
|
private static long lengthOffsetInBytes() {
|
||||||
if (Universe.elementTypeShouldBeAligned(type)) {
|
|
||||||
return alignObjectSize(headerSizeInBytes())/VM.getVM().getHeapWordSize();
|
|
||||||
} else {
|
|
||||||
return headerSizeInBytes()/VM.getVM().getHeapWordSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long lengthOffsetInBytes() {
|
|
||||||
if (lengthOffsetInBytes != 0) {
|
if (lengthOffsetInBytes != 0) {
|
||||||
return lengthOffsetInBytes;
|
return lengthOffsetInBytes;
|
||||||
}
|
}
|
||||||
@ -108,7 +107,13 @@ public class Array extends Oop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long baseOffsetInBytes(BasicType type) {
|
public static long baseOffsetInBytes(BasicType type) {
|
||||||
return headerSize(type) * VM.getVM().getHeapWordSize();
|
long typeSizeInBytes = headerSizeInBytes();
|
||||||
|
if (elementTypeShouldBeAligned(type)) {
|
||||||
|
VM vm = VM.getVM();
|
||||||
|
return vm.alignUp(typeSizeInBytes, vm.getVM().getHeapWordSize());
|
||||||
|
} else {
|
||||||
|
return typeSizeInBytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArray() { return true; }
|
public boolean isArray() { return true; }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,19 +27,11 @@
|
|||||||
#include "unittest.hpp"
|
#include "unittest.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
class arrayOopDescTest {
|
|
||||||
public:
|
|
||||||
|
|
||||||
static int header_size_in_bytes() {
|
|
||||||
return arrayOopDesc::header_size_in_bytes();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool check_max_length_overflow(BasicType type) {
|
static bool check_max_length_overflow(BasicType type) {
|
||||||
julong length = arrayOopDesc::max_array_length(type);
|
julong length = arrayOopDesc::max_array_length(type);
|
||||||
julong bytes_per_element = type2aelembytes(type);
|
julong bytes_per_element = type2aelembytes(type);
|
||||||
julong bytes = length * bytes_per_element
|
julong bytes = length * bytes_per_element
|
||||||
+ arrayOopDescTest::header_size_in_bytes();
|
+ arrayOopDesc::base_offset_in_bytes(type);
|
||||||
return (julong) (size_t) bytes == bytes;
|
return (julong) (size_t) bytes == bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,3 +79,47 @@ TEST_VM(arrayOopDesc, narrowOop) {
|
|||||||
ASSERT_PRED1(check_max_length_overflow, T_NARROWOOP);
|
ASSERT_PRED1(check_max_length_overflow, T_NARROWOOP);
|
||||||
}
|
}
|
||||||
// T_VOID and T_ADDRESS are not supported by max_array_length()
|
// T_VOID and T_ADDRESS are not supported by max_array_length()
|
||||||
|
|
||||||
|
TEST_VM(arrayOopDesc, base_offset) {
|
||||||
|
#ifdef _LP64
|
||||||
|
if (UseCompressedClassPointers) {
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BOOLEAN), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BYTE), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_SHORT), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_CHAR), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_INT), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_LONG), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_OBJECT), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_ARRAY), 16);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BOOLEAN), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BYTE), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_SHORT), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_CHAR), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_INT), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_LONG), 24);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 24);
|
||||||
|
if (UseCompressedOops) {
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_OBJECT), 20);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_ARRAY), 20);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_OBJECT), 24);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_ARRAY), 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BOOLEAN), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_BYTE), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_SHORT), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_CHAR), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_INT), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_LONG), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 16);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_OBJECT), 12);
|
||||||
|
EXPECT_EQ(arrayOopDesc::base_offset_in_bytes(T_ARRAY), 12);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
57
test/hotspot/gtest/oops/test_objArrayOop.cpp
Normal file
57
test/hotspot/gtest/oops/test_objArrayOop.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "oops/objArrayOop.hpp"
|
||||||
|
#include "unittest.hpp"
|
||||||
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
|
TEST_VM(objArrayOop, osize) {
|
||||||
|
static const struct {
|
||||||
|
int objal; bool ccp; bool coops; int result;
|
||||||
|
} x[] = {
|
||||||
|
// ObjAligInB, UseCCP, UseCoops, object size in heap words
|
||||||
|
#ifdef _LP64
|
||||||
|
{ 8, false, false, 4 }, // 20 byte header, 8 byte oops
|
||||||
|
{ 8, false, true, 3 }, // 20 byte header, 4 byte oops
|
||||||
|
{ 8, true, false, 3 }, // 16 byte header, 8 byte oops
|
||||||
|
{ 8, true, true, 3 }, // 16 byte header, 4 byte oops
|
||||||
|
{ 16, false, false, 4 }, // 20 byte header, 8 byte oops, 16-byte align
|
||||||
|
{ 16, false, true, 4 }, // 20 byte header, 4 byte oops, 16-byte align
|
||||||
|
{ 16, true, false, 4 }, // 16 byte header, 8 byte oops, 16-byte align
|
||||||
|
{ 16, true, true, 4 }, // 16 byte header, 4 byte oops, 16-byte align
|
||||||
|
{ 256, false, false, 32 }, // 20 byte header, 8 byte oops, 256-byte align
|
||||||
|
{ 256, false, true, 32 }, // 20 byte header, 4 byte oops, 256-byte align
|
||||||
|
{ 256, true, false, 32 }, // 16 byte header, 8 byte oops, 256-byte align
|
||||||
|
{ 256, true, true, 32 }, // 16 byte header, 4 byte oops, 256-byte align
|
||||||
|
#else
|
||||||
|
{ 8, false, false, 4 }, // 12 byte header, 4 byte oops, wordsize 4
|
||||||
|
#endif
|
||||||
|
{ -1, false, false, -1 }
|
||||||
|
};
|
||||||
|
for (int i = 0; x[i].result != -1; i++) {
|
||||||
|
if (x[i].objal == (int)ObjectAlignmentInBytes && x[i].ccp == UseCompressedClassPointers && x[i].coops == UseCompressedOops) {
|
||||||
|
EXPECT_EQ(objArrayOopDesc::object_size(1), (size_t)x[i].result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
test/hotspot/jtreg/gtest/ArrayTests.java
Normal file
56
test/hotspot/jtreg/gtest/ArrayTests.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This tests object array sizes by running gtests with different settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @test id=with-coops-with-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=arrayOop -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=with-coops-no-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=arrayOop -XX:-UseCompressedClassPointers -XX:+UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-with-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=arrayOop -XX:+UseCompressedClassPointers -XX:-UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-no-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=arrayOop -XX:-UseCompressedClassPointers -XX:-UseCompressedOops
|
||||||
|
*/
|
85
test/hotspot/jtreg/gtest/ObjArrayTests.java
Normal file
85
test/hotspot/jtreg/gtest/ObjArrayTests.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This tests object array sizes by running gtests with different settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @test id=with-coops-with-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=with-coops-no-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:-UseCompressedClassPointers -XX:+UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-with-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:+UseCompressedClassPointers -XX:-UseCompressedOops
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-no-ccp
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:-UseCompressedClassPointers -XX:-UseCompressedOops
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @test id=with-coops-with-ccp-large-align
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:ObjAlignmentInBytes=256
|
||||||
|
*/
|
||||||
|
/* @test id=with-coops-no-ccp-large-align
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:-UseCompressedClassPointers -XX:+UseCompressedOops -XX:ObjAlignmentInBytes=256
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-with-ccp-large-align
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:+UseCompressedClassPointers -XX:-UseCompressedOops -XX:ObjAlignmentInBytes=256
|
||||||
|
*/
|
||||||
|
/* @test id=no-coops-no-ccp-large-align
|
||||||
|
* @summary Run object array size tests with compressed oops and compressed class pointers
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.xml
|
||||||
|
* @run main/native GTestWrapper --gtest_filter=objArrayOop -XX:-UseCompressedClassPointers -XX:-UseCompressedOops -XX:ObjAlignmentInBytes=256
|
||||||
|
*/
|
113
test/hotspot/jtreg/runtime/FieldLayout/ArrayBaseOffsets.java
Normal file
113
test/hotspot/jtreg/runtime/FieldLayout/ArrayBaseOffsets.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test id=with-coops-no-ccp
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.bits == "64"
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @run main/othervm -XX:+UseCompressedOops -XX:-UseCompressedClassPointers ArrayBaseOffsets
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @test id=with-coops-with-ccp
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.bits == "64"
|
||||||
|
* @requires vm.opt.UseCompressedClassPointers != false
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @run main/othervm -XX:+UseCompressedOops -XX:+UseCompressedClassPointers ArrayBaseOffsets
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @test id=no-coops-no-ccp
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.bits == "64"
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @run main/othervm -XX:-UseCompressedOops -XX:-UseCompressedClassPointers ArrayBaseOffsets
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @test id=no-coops-with-ccp
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.bits == "64"
|
||||||
|
* @requires vm.opt.UseCompressedClassPointers != false
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @run main/othervm -XX:-UseCompressedOops -XX:+UseCompressedClassPointers ArrayBaseOffsets
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @test id=32bit
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.bits == "32"
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @run main/othervm ArrayBaseOffsets
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import jdk.test.lib.Platform;
|
||||||
|
|
||||||
|
public class ArrayBaseOffsets {
|
||||||
|
|
||||||
|
private static final boolean COOP;
|
||||||
|
private static final boolean CCP;
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (Platform.is64bit()) {
|
||||||
|
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||||
|
List<String> vmargs = runtime.getInputArguments();
|
||||||
|
CCP = !vmargs.contains("-XX:-UseCompressedClassPointers");
|
||||||
|
COOP = System.getProperty("java.vm.compressedOopsMode") != null;
|
||||||
|
} else {
|
||||||
|
COOP = CCP = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main(String[] args) {
|
||||||
|
Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
int intOffset, longOffset;
|
||||||
|
if (Platform.is64bit()) {
|
||||||
|
if (CCP) {
|
||||||
|
intOffset = 16;
|
||||||
|
longOffset = 16;
|
||||||
|
} else {
|
||||||
|
intOffset = 20;
|
||||||
|
longOffset = 24;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intOffset = 12;
|
||||||
|
longOffset = 16;
|
||||||
|
}
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(boolean[].class), intOffset, "Misplaced boolean array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(byte[].class), intOffset, "Misplaced byte array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(char[].class), intOffset, "Misplaced char array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(short[].class), intOffset, "Misplaced short array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(int[].class), intOffset, "Misplaced int array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(long[].class), longOffset, "Misplaced long array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(float[].class), intOffset, "Misplaced float array base");
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(double[].class), longOffset, "Misplaced double array base");
|
||||||
|
int expectedObjArrayOffset = (COOP || !Platform.is64bit()) ? intOffset : longOffset;
|
||||||
|
Asserts.assertEquals(unsafe.arrayBaseOffset(Object[].class), expectedObjArrayOffset, "Misplaced object array base");
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2022, Red Hat, Inc. All rights reserved.
|
* Copyright (c) 2020, 2024, Red Hat, Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -313,6 +313,9 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
static final int LARGE_INT_ARRAY_SIZE = 1024*1024*1024 + 1024;
|
static final int LARGE_INT_ARRAY_SIZE = 1024*1024*1024 + 1024;
|
||||||
static final int LARGE_OBJ_ARRAY_SIZE = (4096/(int)REF_SIZE)*1024*1024 + 1024;
|
static final int LARGE_OBJ_ARRAY_SIZE = (4096/(int)REF_SIZE)*1024*1024 + 1024;
|
||||||
|
|
||||||
|
static final boolean CCP = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedClassPointers");
|
||||||
|
static final int ARRAY_HEADER_SIZE = CCP ? 16 : (Platform.is64bit() ? 20 : 16);
|
||||||
|
|
||||||
final String mode;
|
final String mode;
|
||||||
|
|
||||||
public GetObjectSizeIntrinsicsTest(String name, String mode) {
|
public GetObjectSizeIntrinsicsTest(String name, String mode) {
|
||||||
@ -396,7 +399,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void testSize_newSmallIntArray() {
|
private void testSize_newSmallIntArray() {
|
||||||
long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(4L*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(new int[SMALL_ARRAY_SIZE]));
|
assertEquals(expected, fInst.getObjectSize(new int[SMALL_ARRAY_SIZE]));
|
||||||
}
|
}
|
||||||
@ -404,7 +407,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
|
|
||||||
private void testSize_localSmallIntArray() {
|
private void testSize_localSmallIntArray() {
|
||||||
int[] arr = new int[SMALL_ARRAY_SIZE];
|
int[] arr = new int[SMALL_ARRAY_SIZE];
|
||||||
long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(4L*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(arr));
|
assertEquals(expected, fInst.getObjectSize(arr));
|
||||||
}
|
}
|
||||||
@ -413,14 +416,14 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
static int[] smallArr = new int[SMALL_ARRAY_SIZE];
|
static int[] smallArr = new int[SMALL_ARRAY_SIZE];
|
||||||
|
|
||||||
private void testSize_fieldSmallIntArray() {
|
private void testSize_fieldSmallIntArray() {
|
||||||
long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(4L*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(smallArr));
|
assertEquals(expected, fInst.getObjectSize(smallArr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testSize_newSmallObjArray() {
|
private void testSize_newSmallObjArray() {
|
||||||
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(new Object[SMALL_ARRAY_SIZE]));
|
assertEquals(expected, fInst.getObjectSize(new Object[SMALL_ARRAY_SIZE]));
|
||||||
}
|
}
|
||||||
@ -428,7 +431,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
|
|
||||||
private void testSize_localSmallObjArray() {
|
private void testSize_localSmallObjArray() {
|
||||||
Object[] arr = new Object[SMALL_ARRAY_SIZE];
|
Object[] arr = new Object[SMALL_ARRAY_SIZE];
|
||||||
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(arr));
|
assertEquals(expected, fInst.getObjectSize(arr));
|
||||||
}
|
}
|
||||||
@ -437,7 +440,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
static Object[] smallObjArr = new Object[SMALL_ARRAY_SIZE];
|
static Object[] smallObjArr = new Object[SMALL_ARRAY_SIZE];
|
||||||
|
|
||||||
private void testSize_fieldSmallObjArray() {
|
private void testSize_fieldSmallObjArray() {
|
||||||
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(smallObjArr));
|
assertEquals(expected, fInst.getObjectSize(smallObjArr));
|
||||||
}
|
}
|
||||||
@ -445,7 +448,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
|
|
||||||
private void testSize_localLargeIntArray() {
|
private void testSize_localLargeIntArray() {
|
||||||
int[] arr = new int[LARGE_INT_ARRAY_SIZE];
|
int[] arr = new int[LARGE_INT_ARRAY_SIZE];
|
||||||
long expected = roundUp(4L*LARGE_INT_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(4L*LARGE_INT_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(arr));
|
assertEquals(expected, fInst.getObjectSize(arr));
|
||||||
}
|
}
|
||||||
@ -453,7 +456,7 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase
|
|||||||
|
|
||||||
private void testSize_localLargeObjArray() {
|
private void testSize_localLargeObjArray() {
|
||||||
Object[] arr = new Object[LARGE_OBJ_ARRAY_SIZE];
|
Object[] arr = new Object[LARGE_OBJ_ARRAY_SIZE];
|
||||||
long expected = roundUp(REF_SIZE*LARGE_OBJ_ARRAY_SIZE + 16, OBJ_ALIGN);
|
long expected = roundUp(REF_SIZE*LARGE_OBJ_ARRAY_SIZE + ARRAY_HEADER_SIZE, OBJ_ALIGN);
|
||||||
for (int c = 0; c < ITERS; c++) {
|
for (int c = 0; c < ITERS; c++) {
|
||||||
assertEquals(expected, fInst.getObjectSize(arr));
|
assertEquals(expected, fInst.getObjectSize(arr));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user