11/*
2- * Copyright (c) 2014, 2023 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2014, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2626#define SHARE_MEMORY_GUARDEDMEMORY_HPP
2727
2828#include " memory/allocation.hpp"
29+ #include " runtime/os.hpp"
2930#include " utilities/globalDefinitions.hpp"
3031
3132/* *
4142 * |Offset | Content | Description |
4243 * |------------------------------------------------------------
4344 * |base_addr | 0xABABABABABABABAB | Head guard |
44- * |+16 | <size_t:user_size> | User data size |
45- * |+sizeof(uintptr_t) | <tag> | Tag word |
45+ * |+GUARD_SIZE | <size_t:user_size> | User data size |
46+ * |+sizeof(size_t) | <tag> | Tag word |
47+ * |+sizeof(void*) | <tag2> | Tag word |
48+ * |+sizeof(void*) | <pad bytes> | Padding |
4649 * |+sizeof(void*) | 0xF1 <user_data> ( | User data |
4750 * |+user_size | 0xABABABABABABABAB | Tail guard |
4851 * -------------------------------------------------------------
4952 *
5053 * Where:
5154 * - guard padding uses "badResourceValue" (0xAB)
52- * - tag word is general purpose
55+ * - tag word and tag2 word are general purpose
56+ * - padding is inserted as-needed by the compiler to ensure
57+ * the user data is aligned on a 16-byte boundary
5358 * - user data
5459 * -- initially padded with "uninitBlockPad" (0xF1),
5560 * -- to "freeBlockPad" (0xBA), when freed
@@ -111,6 +116,10 @@ class GuardedMemory : StackObj { // Wrapper on stack
111116 }
112117
113118 bool verify () const {
119+ // We may not be able to dereference directly.
120+ if (!os::is_readable_range ((const void *) _guard, (const void *) (_guard + GUARD_SIZE))) {
121+ return false ;
122+ }
114123 u_char* c = (u_char*) _guard;
115124 u_char* end = c + GUARD_SIZE;
116125 while (c < end) {
@@ -126,24 +135,30 @@ class GuardedMemory : StackObj { // Wrapper on stack
126135
127136 /* *
128137 * Header guard and size
138+ *
139+ * NB: the size and placement of the GuardHeader must be such that the
140+ * user-ptr is maximally aligned i.e. 16-byte alignment for x86 ABI for
141+ * stack alignment and use of vector (xmm) instructions. We use alignas
142+ * to achieve this.
129143 */
130- class GuardHeader : Guard {
144+ class alignas ( 16 ) GuardHeader : Guard {
131145 friend class GuardedMemory ;
132146 protected:
133- // Take care in modifying fields here, will effect alignment
134- // e.g. x86 ABI 16 byte stack alignment
135147 union {
136148 uintptr_t __unused_full_word1;
137149 size_t _user_size;
138150 };
139151 void * _tag;
152+ void * _tag2;
140153 public:
141154 void set_user_size (const size_t usz) { _user_size = usz; }
142155 size_t get_user_size () const { return _user_size; }
143156
144157 void set_tag (const void * tag) { _tag = (void *) tag; }
145158 void * get_tag () const { return _tag; }
146159
160+ void set_tag2 (const void * tag2) { _tag2 = (void *) tag2; }
161+ void * get_tag2 () const { return _tag2; }
147162 }; // GuardedMemory::GuardHeader
148163
149164 // Guarded Memory...
@@ -162,9 +177,11 @@ class GuardedMemory : StackObj { // Wrapper on stack
162177 * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
163178 * @param user_size the size of the user data to be wrapped.
164179 * @param tag optional general purpose tag.
180+ * @param tag2 optional second general purpose tag.
165181 */
166- GuardedMemory (void * base_ptr, const size_t user_size, const void * tag = nullptr ) {
167- wrap_with_guards (base_ptr, user_size, tag);
182+ GuardedMemory (void * base_ptr, const size_t user_size,
183+ const void * tag = nullptr , const void * tag2 = nullptr ) {
184+ wrap_with_guards (base_ptr, user_size, tag, tag2);
168185 }
169186
170187 /* *
@@ -189,16 +206,19 @@ class GuardedMemory : StackObj { // Wrapper on stack
189206 * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
190207 * @param user_size the size of the user data to be wrapped.
191208 * @param tag optional general purpose tag.
209+ * @param tag2 optional second general purpose tag.
192210 *
193211 * @return user data pointer (inner pointer to supplied "base_ptr").
194212 */
195- void * wrap_with_guards (void * base_ptr, size_t user_size, const void * tag = nullptr ) {
213+ void * wrap_with_guards (void * base_ptr, size_t user_size,
214+ const void * tag = nullptr , const void * tag2 = nullptr ) {
196215 assert (base_ptr != nullptr , " Attempt to wrap null with memory guard" );
197216 _base_addr = (u_char*)base_ptr;
198217 get_head_guard ()->build ();
199218 get_head_guard ()->set_user_size (user_size);
200219 get_tail_guard ()->build ();
201220 set_tag (tag);
221+ set_tag2 (tag2);
202222 set_user_bytes (uninitBlockPad);
203223 assert (verify_guards (), " Expected valid memory guards" );
204224 return get_user_ptr ();
@@ -230,6 +250,20 @@ class GuardedMemory : StackObj { // Wrapper on stack
230250 */
231251 void * get_tag () const { return get_head_guard ()->get_tag (); }
232252
253+ /* *
254+ * Set the second general purpose tag.
255+ *
256+ * @param tag general purpose tag.
257+ */
258+ void set_tag2 (const void * tag) { get_head_guard ()->set_tag2 (tag); }
259+
260+ /* *
261+ * Return the second general purpose tag.
262+ *
263+ * @return the second general purpose tag, defaults to null.
264+ */
265+ void * get_tag2 () const { return get_head_guard ()->get_tag2 (); }
266+
233267 /* *
234268 * Return the size of the user data.
235269 *
@@ -302,10 +336,12 @@ class GuardedMemory : StackObj { // Wrapper on stack
302336 * @param ptr the memory to be copied
303337 * @param len the length of the copy
304338 * @param tag optional general purpose tag (see GuardedMemory::get_tag())
339+ * @param tag2 optional general purpose tag (see GuardedMemory::get_tag2())
305340 *
306341 * @return guarded wrapped memory pointer to the user area, or null if OOM.
307342 */
308- static void * wrap_copy (const void * p, const size_t len, const void * tag = nullptr );
343+ static void * wrap_copy (const void * p, const size_t len,
344+ const void * tag = nullptr , const void * tag2 = nullptr );
309345
310346 /* *
311347 * Free wrapped copy.
0 commit comments