1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef SHARE_MEMORY_METASPACE_ALLOCATION_GUARD_HPP 27 #define SHARE_MEMORY_METASPACE_ALLOCATION_GUARD_HPP 28 29 #include "memory/allocation.hpp" 30 #include "memory/metaspace/chunkLevel.hpp" 31 #include "utilities/debug.hpp" 32 #include "utilities/globalDefinitions.hpp" 33 34 // In Debug builds, Metadata in Metaspace can be optionally guarded - enclosed in canaries - 35 // to detect memory overwriters. 36 // 37 // These canaries are periodically checked, e.g. when the Metaspace is purged in a context 38 // of a GC. 39 40 // The canaries precede any allocated block... 41 // 42 // +---------------+ 43 // | 'METAMETA' | 44 // +---------------+ 45 // | block size | 46 // +---------------+ 47 // | block... | 48 // . . 49 // . . 50 // . . 51 // | | 52 // +---------------+ 53 // . <padding> . 54 // +---------------+ 55 // | 'METAMETA' | 56 // +---------------+ 57 // | block size | 58 // +---------------+ 59 // | block... | 60 61 // ... and since the blocks are allocated via pointer bump and closely follow each other, 62 // one block's prefix is its predecessor's suffix, so apart from the last block all 63 // blocks have an overwriter canary on both ends. 64 // 65 66 // Note: this feature is only available in debug, and is activated using 67 // -XX:+MetaspaceGuardAllocations. When active, it disables deallocation handling - since 68 // freeblock handling in the freeblock lists would get too complex - so one may run leaks 69 // in deallocation-heavvy scenarios (e.g. lots of class redefinitions). 70 // 71 72 73 namespace metaspace { 74 75 #ifdef ASSERT 76 77 struct prefix_t { 78 uintx mark; 79 size_t word_size; // raw word size including prefix 80 // MetaWord payload [0]; // varsized (but unfortunately not all our compilers understand that) 81 }; 82 83 // The prefix structure must be aligned to MetaWord size. 84 STATIC_ASSERT((sizeof(prefix_t) & WordAlignmentMask) == 0); 85 86 inline prefix_t* prefix_from_payload(MetaWord* p) { 87 return (prefix_t*)((address)p - sizeof(prefix_t)); 88 } 89 90 inline MetaWord* payload_from_prefix(prefix_t* pp) { 91 // return pp->payload; 92 return (MetaWord*)((address)pp + sizeof(prefix_t)); 93 } 94 95 inline size_t prefix_size() { 96 return sizeof(prefix_t); 97 } 98 99 #define EYECATCHER NOT_LP64(0x77698465) LP64_ONLY(0x7769846577698465ULL) // "META" resp "METAMETA" 100 101 // Given a pointer to a memory area, establish the prefix at the start of that area and 102 // return the starting pointer to the payload. 103 inline MetaWord* establish_prefix(MetaWord* p_raw, size_t raw_word_size) { 104 prefix_t* pp = (prefix_t*)p_raw; 105 pp->mark = EYECATCHER; 106 pp->word_size = raw_word_size; 107 return payload_from_prefix(pp); 108 } 109 110 inline void check_prefix(const prefix_t* pp) { 111 assert(pp->mark == EYECATCHER, "corrupt block at " PTR_FORMAT ".", p2i(pp)); 112 assert(pp->word_size > 0 && pp->word_size < chunklevel::MAX_CHUNK_WORD_SIZE, 113 "Invalid size " SIZE_FORMAT " in block at " PTR_FORMAT ".", pp->word_size, p2i(pp)); 114 } 115 116 #endif 117 118 } // namespace metaspace 119 120 #endif // SHARE_MEMORY_METASPACE_ALLOCATION_GUARD_HPP