8369187: Add wrapper for <new> that forbids use of global allocation and deallocation functions

Reviewed-by: stefank, erikj, jrose
This commit is contained in:
Kim Barrett 2025-11-19 20:56:21 +00:00
parent 6f1c5733ed
commit f5bc6ee90d
15 changed files with 187 additions and 20 deletions

View File

@ -95,6 +95,7 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBJVM, \
EXTRA_OBJECT_FILES := $(BUILD_LIBJVM_ALL_OBJS), \
DEFAULT_CFLAGS := false, \
CFLAGS := $(JVM_CFLAGS) \
-DHOTSPOT_GTEST \
-I$(GTEST_FRAMEWORK_SRC)/googletest/include \
-I$(GTEST_FRAMEWORK_SRC)/googlemock/include \
$(addprefix -I, $(GTEST_TEST_SRC)), \

View File

@ -26,6 +26,7 @@
#include "code/compiledIC.hpp"
#include "code/nmethod.hpp"
#include "code/relocInfo.hpp"
#include "cppstdlib/new.hpp"
#include "cppstdlib/type_traits.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
@ -37,8 +38,6 @@
#include "utilities/checkedCast.hpp"
#include "utilities/copy.hpp"
#include <new>
const RelocationHolder RelocationHolder::none; // its type is relocInfo::none

View File

@ -25,6 +25,7 @@
#ifndef SHARE_CODE_RELOCINFO_HPP
#define SHARE_CODE_RELOCINFO_HPP
#include "cppstdlib/new.hpp"
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/osInfo.hpp"
@ -32,8 +33,6 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include <new>
class CodeBlob;
class Metadata;
class NativeMovConstReg;

View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2022, 2025, 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
* 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.
*
*/
#ifndef SHARE_CPPSTDLIB_NEW_HPP
#define SHARE_CPPSTDLIB_NEW_HPP
#include "utilities/compilerWarnings.hpp"
// HotSpot usage:
// Only the following may be used:
// * std::nothrow_t, std::nothrow
// * std::align_val_t
// * The non-allocating forms of `operator new` and `operator new[]` are
// implicitly used by the corresponding `new` and `new[]` expressions.
// - operator new(size_t, void*) noexcept
// - operator new[](size_t, void*) noexcept
// Note that the non-allocating forms of `operator delete` and `operator
// delete[]` are not used, since they are only invoked by a placement new
// expression that fails by throwing an exception. But they might still
// end up being referenced in such a situation.
BEGIN_ALLOW_FORBIDDEN_FUNCTIONS
#include "utilities/vmassert_uninstall.hpp"
#include <new>
#include "utilities/vmassert_reinstall.hpp" // don't reorder
END_ALLOW_FORBIDDEN_FUNCTIONS
// Deprecation declarations to forbid use of the default global allocator.
// See C++17 21.6.1 Header <new> synopsis.
namespace std {
#if 0
// We could deprecate exception types, for completeness, but don't bother. We
// already have exceptions disabled, and run into compiler bugs when we try.
//
// gcc -Wattributes => type attributes ignored after type is already defined
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122167
//
// clang -Wignored-attributes => attribute declaration must precede definition
// The clang warning is https://github.com/llvm/llvm-project/issues/135481,
// which should be fixed in clang 21.
class [[deprecated]] bad_alloc;
class [[deprecated]] bad_array_new_length;
#endif // #if 0
// Forbid new_handler manipulation by HotSpot code, leaving it untouched for
// use by application code.
[[deprecated]] new_handler get_new_handler() noexcept;
[[deprecated]] new_handler set_new_handler(new_handler) noexcept;
// Prefer HotSpot mechanisms for padding.
//
// The syntax for redeclaring these for deprecation is tricky, and not
// supported by some versions of some compilers. Dispatch on compiler and
// version to decide whether to redeclare deprecated.
#if defined(__clang__)
#if __clang_major__ >= 19
// clang18 and earlier may accept the declaration but go wrong with uses.
// Different warnings and link-time failures are both possible.
#define CAN_DEPRECATE_HARDWARE_INTERFERENCE_SIZES 1
#endif // restrict clang version
#elif defined(__GNUC__)
#if (__GNUC__ > 13) || (__GNUC__ == 13 && __GNUC_MINOR__ >= 2)
// g++11.5 accepts the declaration and reports deprecation for uses, but also
// has link-time failure for uses. Haven't tested intermediate versions.
#define CAN_DEPRECATE_HARDWARE_INTERFERENCE_SIZES 1
#endif // restrict gcc version
#elif defined(_MSVC)
// VS2022-17.13.2 => error C2370: '...': redefinition; different storage class
#endif // Compiler dispatch
// Redeclare deprecated if such is supported.
#ifdef CAN_DEPRECATE_HARDWARE_INTERFERENCE_SIZES
[[deprecated]] extern const size_t hardware_destructive_interference_size;
[[deprecated]] extern const size_t hardware_constructive_interference_size;
#undef CAN_DEPRECATE_HARDWARE_INTERFERENCE_SIZES
#endif // CAN_DEPRECATE_HARDWARE_INTERFERENCE_SIZES
} // namespace std
// Forbid using the global allocator by HotSpot code.
// This doesn't provide complete coverage. Some global allocation and
// deallocation functions are implicitly declared in all translation units,
// without needing to include <new>; see C++17 6.7.4. So this doesn't remove
// the need for the link-time verification that these functions aren't used.
//
// But don't poison them when compiling gtests. The gtest framework, the
// HotSpot wrapper around it (gtestMain.cpp), and even some tests, all have
// new/new[] and delete/delete[] expressions that use the default global
// allocator. We also don't apply the link-time check for gtests, for the
// same reason.
#ifndef HOTSPOT_GTEST
[[deprecated]] void* operator new(std::size_t);
[[deprecated]] void* operator new(std::size_t, std::align_val_t);
[[deprecated]] void* operator new(std::size_t, const std::nothrow_t&) noexcept;
[[deprecated]] void* operator new(std::size_t, std::align_val_t,
const std::nothrow_t&) noexcept;
[[deprecated]] void operator delete(void*) noexcept;
[[deprecated]] void operator delete(void*, std::size_t) noexcept;
[[deprecated]] void operator delete(void*, std::align_val_t) noexcept;
[[deprecated]] void operator delete(void*, std::size_t, std::align_val_t) noexcept;
[[deprecated]] void operator delete(void*, const std::nothrow_t&) noexcept;
[[deprecated]] void operator delete(void*, std::align_val_t,
const std::nothrow_t&) noexcept;
[[deprecated]] void* operator new[](std::size_t);
[[deprecated]] void* operator new[](std::size_t, std::align_val_t);
[[deprecated]] void* operator new[](std::size_t, const std::nothrow_t&) noexcept;
[[deprecated]] void* operator new[](std::size_t, std::align_val_t,
const std::nothrow_t&) noexcept;
[[deprecated]] void operator delete[](void*) noexcept;
[[deprecated]] void operator delete[](void*, std::size_t) noexcept;
[[deprecated]] void operator delete[](void*, std::align_val_t) noexcept;
[[deprecated]] void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
[[deprecated]] void operator delete[](void*, const std::nothrow_t&) noexcept;
[[deprecated]] void operator delete[](void*, std::align_val_t,
const std::nothrow_t&) noexcept;
#endif // HOTSPOT_GTEST
// Allow (don't poison) the non-allocating forms from [new.delete.placement].
#endif // SHARE_CPPSTDLIB_NEW_HPP

View File

@ -22,12 +22,11 @@
*
*/
#include "cppstdlib/new.hpp"
#include "gc/shared/bufferNode.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/debug.hpp"
#include <new>
BufferNode::AllocatorConfig::AllocatorConfig(size_t size)
: _buffer_capacity(size)
{

View File

@ -22,6 +22,7 @@
*
*/
#include "cppstdlib/new.hpp"
#include "gc/shared/partialArrayState.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/arena.hpp"
@ -33,8 +34,6 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include <new>
PartialArrayState::PartialArrayState(oop src, oop dst,
size_t index, size_t length,
size_t initial_refcount)

View File

@ -27,10 +27,9 @@
#include "gc/z/zDeferredConstructed.hpp"
#include "cppstdlib/new.hpp"
#include "cppstdlib/type_traits.hpp"
#include <new>
template <typename T>
inline ZDeferredConstructed<T>::ZDeferredConstructed()
DEBUG_ONLY(: _initialized(false)) {

View File

@ -25,14 +25,13 @@
#ifndef SHARE_MEMORY_ALLOCATION_HPP
#define SHARE_MEMORY_ALLOCATION_HPP
#include "cppstdlib/new.hpp"
#include "memory/allStatic.hpp"
#include "nmt/memTag.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include <new>
class outputStream;
class Thread;
class JavaThread;

View File

@ -24,6 +24,7 @@
*/
#include "compiler/compilationMemoryStatistic.hpp"
#include "cppstdlib/new.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/arena.hpp"
#include "memory/resourceArea.hpp"

View File

@ -31,8 +31,6 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/powerOfTwo.hpp"
#include <new>
// The byte alignment to be used by Arena::Amalloc.
#define ARENA_AMALLOC_ALIGNMENT BytesPerLong
#define ARENA_ALIGN(x) (align_up((x), ARENA_AMALLOC_ALIGNMENT))

View File

@ -29,6 +29,7 @@
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "cppstdlib/new.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm.h"
@ -63,7 +64,6 @@
#include "utilities/unsigned5.hpp"
#include "utilities/vmError.hpp"
#include <new>
#include <stdarg.h>
#include <stdio.h>

View File

@ -25,11 +25,10 @@
#ifndef SHARE_UTILITIES_DEFERREDSTATIC_HPP
#define SHARE_UTILITIES_DEFERREDSTATIC_HPP
#include "cppstdlib/new.hpp"
#include "cppstdlib/type_traits.hpp"
#include "utilities/globalDefinitions.hpp"
#include <new>
// The purpose of this class is to provide control over the initialization
// time for an object of type T with static storage duration. An instance of
// this class provides storage for an object, sized and aligned for T. The

View File

@ -25,6 +25,7 @@
#if !defined(_WINDOWS) && !defined(__APPLE__)
#include "cppstdlib/new.hpp"
#include "jvm_io.h"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
@ -37,7 +38,6 @@
#include "utilities/ostream.hpp"
#include <limits.h>
#include <new>
#include <stdio.h>
#include <string.h>

View File

@ -1386,4 +1386,25 @@ template<typename T> inline constexpr bool DependentAlwaysFalse = false;
// handled.
bool IEEE_subnormal_handling_OK();
//----------------------------------------------------------------------------------------------------
// Forbid using the global allocator by HotSpot code.
//
// This is a subset of allocator and deallocator functions. These are
// implicitly declared in all translation units, without needing to include
// <new>; see C++17 6.7.4. This isn't even the full set of those; implicit
// declarations involving std::align_val_t are not covered here, since that
// type is defined in <new>. A translation unit that doesn't include <new> is
// still likely to include this file. See cppstdlib/new.hpp for more details.
#ifndef HOTSPOT_GTEST
[[deprecated]] void* operator new(std::size_t);
[[deprecated]] void operator delete(void*) noexcept;
[[deprecated]] void operator delete(void*, std::size_t) noexcept;
[[deprecated]] void* operator new[](std::size_t);
[[deprecated]] void operator delete[](void*) noexcept;
[[deprecated]] void operator delete[](void*, std::size_t) noexcept;
#endif // HOTSPOT_GTEST
#endif // SHARE_UTILITIES_GLOBALDEFINITIONS_HPP

View File

@ -21,6 +21,7 @@
* questions.
*/
#include "cppstdlib/new.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/globalDefinitions.hpp"
@ -28,8 +29,6 @@
#include "threadHelper.inline.hpp"
#include "unittest.hpp"
#include <new>
class LockFreeStackTestElement {
typedef LockFreeStackTestElement Element;