From 10eafdc62e8216e6ef69773fe491a21346c8682d Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Thu, 22 Feb 2024 09:14:20 +0000 Subject: [PATCH] 8325870: Zap end padding bits for ArrayOops in non-release builds Reviewed-by: stefank, ayang --- src/hotspot/share/gc/shared/memAllocator.cpp | 22 +++++++++++++- src/hotspot/share/gc/shared/memAllocator.hpp | 4 ++- src/hotspot/share/gc/z/zObjArrayAllocator.cpp | 4 ++- .../share/utilities/globalDefinitions.hpp | 29 ++++++++++--------- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/shared/memAllocator.cpp b/src/hotspot/share/gc/shared/memAllocator.cpp index e4b91413537..dc94b83c139 100644 --- a/src/hotspot/share/gc/shared/memAllocator.cpp +++ b/src/hotspot/share/gc/shared/memAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/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 @@ -41,6 +41,7 @@ #include "services/lowMemoryDetector.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" +#include "utilities/globalDefinitions.hpp" class MemAllocator::Allocation: StackObj { friend class MemAllocator; @@ -408,11 +409,30 @@ oop ObjArrayAllocator::initialize(HeapWord* mem) const { assert(_length >= 0, "length should be non-negative"); if (_do_zero) { mem_clear(mem); + mem_zap_end_padding(mem); } arrayOopDesc::set_length(mem, _length); return finish(mem); } +#ifndef PRODUCT +void ObjArrayAllocator::mem_zap_end_padding(HeapWord* mem) const { + const size_t length_in_bytes = static_cast(_length) << ArrayKlass::cast(_klass)->log2_element_size(); + const BasicType element_type = ArrayKlass::cast(_klass)->element_type(); + const size_t base_offset_in_bytes = arrayOopDesc::base_offset_in_bytes(element_type); + const size_t size_in_bytes = _word_size * BytesPerWord; + + const address obj_end = reinterpret_cast
(mem) + size_in_bytes; + const address base = reinterpret_cast
(mem) + base_offset_in_bytes; + const address elements_end = base + length_in_bytes; + assert(elements_end <= obj_end, "payload must fit in object"); + if (elements_end < obj_end) { + const size_t padding_in_bytes = obj_end - elements_end; + Copy::fill_to_bytes(elements_end, padding_in_bytes, heapPaddingByteVal); + } +} +#endif + oop ClassAllocator::initialize(HeapWord* mem) const { // Set oop_size field before setting the _klass field because a // non-null _klass field indicates that the object is parsable by diff --git a/src/hotspot/share/gc/shared/memAllocator.hpp b/src/hotspot/share/gc/shared/memAllocator.hpp index 93ed10dce05..bd4ae04babf 100644 --- a/src/hotspot/share/gc/shared/memAllocator.hpp +++ b/src/hotspot/share/gc/shared/memAllocator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/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 @@ -98,6 +98,8 @@ protected: const int _length; const bool _do_zero; + void mem_zap_end_padding(HeapWord* mem) const PRODUCT_RETURN; + public: ObjArrayAllocator(Klass* klass, size_t word_size, int length, bool do_zero, Thread* thread = Thread::current()) diff --git a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp index c65f0d613d0..faa1290f37e 100644 --- a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp +++ b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, 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. * * This code is free software; you can redistribute it and/or modify it @@ -132,6 +132,8 @@ oop ZObjArrayAllocator::initialize(HeapWord* mem) const { assert(result, "Array initialization should always succeed the second time"); } + mem_zap_end_padding(mem); + ZThreadLocalData::clear_invisible_root(_thread); // Signal to the ZIterator that this is no longer an invisible root diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index c0f5b719666..ce94629c84b 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -1028,19 +1028,20 @@ enum LockingMode { //---------------------------------------------------------------------------------------------------- // Special constants for debugging -const jint badInt = -3; // generic "bad int" value -const intptr_t badAddressVal = -2; // generic "bad address" value -const intptr_t badOopVal = -1; // generic "bad oop" value -const intptr_t badHeapOopVal = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC -const int badStackSegVal = 0xCA; // value used to zap stack segments -const int badHandleValue = 0xBC; // value used to zap vm handle area -const int badResourceValue = 0xAB; // value used to zap resource area -const int freeBlockPad = 0xBA; // value used to pad freed blocks. -const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks. -const juint uninitMetaWordVal= 0xf7f7f7f7; // value used to zap newly allocated metachunk -const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC -const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC -const int badCodeHeapNewVal= 0xCC; // value used to zap Code heap at allocation +const jint badInt = -3; // generic "bad int" value +const intptr_t badAddressVal = -2; // generic "bad address" value +const intptr_t badOopVal = -1; // generic "bad oop" value +const intptr_t badHeapOopVal = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC +const int badStackSegVal = 0xCA; // value used to zap stack segments +const int badHandleValue = 0xBC; // value used to zap vm handle area +const int badResourceValue = 0xAB; // value used to zap resource area +const int freeBlockPad = 0xBA; // value used to pad freed blocks. +const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks. +const juint uninitMetaWordVal = 0xf7f7f7f7; // value used to zap newly allocated metachunk +const jubyte heapPaddingByteVal = 0xBD; // value used to zap object padding in the heap +const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC +const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC +const int badCodeHeapNewVal = 0xCC; // value used to zap Code heap at allocation const int badCodeHeapFreeVal = 0xDD; // value used to zap Code heap at deallocation const intptr_t badDispHeaderDeopt = 0xDE0BD000; // value to fill unused displaced header during deoptimization const intptr_t badDispHeaderOSR = 0xDEAD05A0; // value to fill unused displaced header during OSR