1.1 --- a/src/share/vm/runtime/os.cpp Mon Aug 04 10:48:10 2014 -0700 1.2 +++ b/src/share/vm/runtime/os.cpp Thu Aug 14 15:16:07 2014 +0200 1.3 @@ -32,6 +32,9 @@ 1.4 #include "gc_implementation/shared/vmGCOperations.hpp" 1.5 #include "interpreter/interpreter.hpp" 1.6 #include "memory/allocation.inline.hpp" 1.7 +#ifdef ASSERT 1.8 +#include "memory/guardedMemory.hpp" 1.9 +#endif 1.10 #include "oops/oop.inline.hpp" 1.11 #include "prims/jvm.h" 1.12 #include "prims/jvm_misc.hpp" 1.13 @@ -524,118 +527,16 @@ 1.14 1.15 1.16 1.17 -#ifdef ASSERT 1.18 -#define space_before (MallocCushion + sizeof(double)) 1.19 -#define space_after MallocCushion 1.20 -#define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t)) 1.21 -#define size_addr_from_obj(p) ((size_t*)p - 1) 1.22 -// MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly 1.23 -// NB: cannot be debug variable, because these aren't set from the command line until 1.24 -// *after* the first few allocs already happened 1.25 -#define MallocCushion 16 1.26 -#else 1.27 -#define space_before 0 1.28 -#define space_after 0 1.29 -#define size_addr_from_base(p) should not use w/o ASSERT 1.30 -#define size_addr_from_obj(p) should not use w/o ASSERT 1.31 -#define MallocCushion 0 1.32 -#endif 1.33 #define paranoid 0 /* only set to 1 if you suspect checking code has bug */ 1.34 1.35 #ifdef ASSERT 1.36 -inline size_t get_size(void* obj) { 1.37 - size_t size = *size_addr_from_obj(obj); 1.38 - if (size < 0) { 1.39 - fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten (" 1.40 - SIZE_FORMAT ")", obj, size)); 1.41 - } 1.42 - return size; 1.43 -} 1.44 - 1.45 -u_char* find_cushion_backwards(u_char* start) { 1.46 - u_char* p = start; 1.47 - while (p[ 0] != badResourceValue || p[-1] != badResourceValue || 1.48 - p[-2] != badResourceValue || p[-3] != badResourceValue) p--; 1.49 - // ok, we have four consecutive marker bytes; find start 1.50 - u_char* q = p - 4; 1.51 - while (*q == badResourceValue) q--; 1.52 - return q + 1; 1.53 -} 1.54 - 1.55 -u_char* find_cushion_forwards(u_char* start) { 1.56 - u_char* p = start; 1.57 - while (p[0] != badResourceValue || p[1] != badResourceValue || 1.58 - p[2] != badResourceValue || p[3] != badResourceValue) p++; 1.59 - // ok, we have four consecutive marker bytes; find end of cushion 1.60 - u_char* q = p + 4; 1.61 - while (*q == badResourceValue) q++; 1.62 - return q - MallocCushion; 1.63 -} 1.64 - 1.65 -void print_neighbor_blocks(void* ptr) { 1.66 - // find block allocated before ptr (not entirely crash-proof) 1.67 - if (MallocCushion < 4) { 1.68 - tty->print_cr("### cannot find previous block (MallocCushion < 4)"); 1.69 - return; 1.70 - } 1.71 - u_char* start_of_this_block = (u_char*)ptr - space_before; 1.72 - u_char* end_of_prev_block_data = start_of_this_block - space_after -1; 1.73 - // look for cushion in front of prev. block 1.74 - u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data); 1.75 - ptrdiff_t size = *size_addr_from_base(start_of_prev_block); 1.76 - u_char* obj = start_of_prev_block + space_before; 1.77 - if (size <= 0 ) { 1.78 - // start is bad; mayhave been confused by OS data inbetween objects 1.79 - // search one more backwards 1.80 - start_of_prev_block = find_cushion_backwards(start_of_prev_block); 1.81 - size = *size_addr_from_base(start_of_prev_block); 1.82 - obj = start_of_prev_block + space_before; 1.83 - } 1.84 - 1.85 - if (start_of_prev_block + space_before + size + space_after == start_of_this_block) { 1.86 - tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size); 1.87 - } else { 1.88 - tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size); 1.89 - } 1.90 - 1.91 - // now find successor block 1.92 - u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after; 1.93 - start_of_next_block = find_cushion_forwards(start_of_next_block); 1.94 - u_char* next_obj = start_of_next_block + space_before; 1.95 - ptrdiff_t next_size = *size_addr_from_base(start_of_next_block); 1.96 - if (start_of_next_block[0] == badResourceValue && 1.97 - start_of_next_block[1] == badResourceValue && 1.98 - start_of_next_block[2] == badResourceValue && 1.99 - start_of_next_block[3] == badResourceValue) { 1.100 - tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size); 1.101 - } else { 1.102 - tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size); 1.103 - } 1.104 -} 1.105 - 1.106 - 1.107 -void report_heap_error(void* memblock, void* bad, const char* where) { 1.108 - tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees); 1.109 - tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock); 1.110 - print_neighbor_blocks(memblock); 1.111 - fatal("memory stomping error"); 1.112 -} 1.113 - 1.114 -void verify_block(void* memblock) { 1.115 - size_t size = get_size(memblock); 1.116 - if (MallocCushion) { 1.117 - u_char* ptr = (u_char*)memblock - space_before; 1.118 - for (int i = 0; i < MallocCushion; i++) { 1.119 - if (ptr[i] != badResourceValue) { 1.120 - report_heap_error(memblock, ptr+i, "in front of"); 1.121 - } 1.122 - } 1.123 - u_char* end = (u_char*)memblock + size + space_after; 1.124 - for (int j = -MallocCushion; j < 0; j++) { 1.125 - if (end[j] != badResourceValue) { 1.126 - report_heap_error(memblock, end+j, "after"); 1.127 - } 1.128 - } 1.129 +static void verify_memory(void* ptr) { 1.130 + GuardedMemory guarded(ptr); 1.131 + if (!guarded.verify_guards()) { 1.132 + tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees); 1.133 + tty->print_cr("## memory stomp:"); 1.134 + guarded.print_on(tty); 1.135 + fatal("memory stomping error"); 1.136 } 1.137 } 1.138 #endif 1.139 @@ -686,16 +587,18 @@ 1.140 size = 1; 1.141 } 1.142 1.143 - const size_t alloc_size = size + space_before + space_after; 1.144 - 1.145 +#ifndef ASSERT 1.146 + const size_t alloc_size = size; 1.147 +#else 1.148 + const size_t alloc_size = GuardedMemory::get_total_size(size); 1.149 if (size > alloc_size) { // Check for rollover. 1.150 return NULL; 1.151 } 1.152 +#endif 1.153 1.154 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); 1.155 1.156 u_char* ptr; 1.157 - 1.158 if (MallocMaxTestWords > 0) { 1.159 ptr = testMalloc(alloc_size); 1.160 } else { 1.161 @@ -703,28 +606,26 @@ 1.162 } 1.163 1.164 #ifdef ASSERT 1.165 - if (ptr == NULL) return NULL; 1.166 - if (MallocCushion) { 1.167 - for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue; 1.168 - u_char* end = ptr + space_before + size; 1.169 - for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad; 1.170 - for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue; 1.171 + if (ptr == NULL) { 1.172 + return NULL; 1.173 } 1.174 - // put size just before data 1.175 - *size_addr_from_base(ptr) = size; 1.176 + // Wrap memory with guard 1.177 + GuardedMemory guarded(ptr, size); 1.178 + ptr = guarded.get_user_ptr(); 1.179 #endif 1.180 - u_char* memblock = ptr + space_before; 1.181 - if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { 1.182 - tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); 1.183 + if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { 1.184 + tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); 1.185 breakpoint(); 1.186 } 1.187 - debug_only(if (paranoid) verify_block(memblock)); 1.188 - if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); 1.189 + debug_only(if (paranoid) verify_memory(ptr)); 1.190 + if (PrintMalloc && tty != NULL) { 1.191 + tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); 1.192 + } 1.193 1.194 - // we do not track MallocCushion memory 1.195 - MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller); 1.196 + // we do not track guard memory 1.197 + MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller); 1.198 1.199 - return memblock; 1.200 + return ptr; 1.201 } 1.202 1.203 1.204 @@ -743,27 +644,32 @@ 1.205 return ptr; 1.206 #else 1.207 if (memblock == NULL) { 1.208 - return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller)); 1.209 + return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller)); 1.210 } 1.211 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { 1.212 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); 1.213 breakpoint(); 1.214 } 1.215 - verify_block(memblock); 1.216 + verify_memory(memblock); 1.217 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); 1.218 - if (size == 0) return NULL; 1.219 + if (size == 0) { 1.220 + return NULL; 1.221 + } 1.222 // always move the block 1.223 - void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller); 1.224 - if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); 1.225 + void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller); 1.226 + if (PrintMalloc) { 1.227 + tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); 1.228 + } 1.229 // Copy to new memory if malloc didn't fail 1.230 if ( ptr != NULL ) { 1.231 - memcpy(ptr, memblock, MIN2(size, get_size(memblock))); 1.232 - if (paranoid) verify_block(ptr); 1.233 + GuardedMemory guarded(memblock); 1.234 + memcpy(ptr, memblock, MIN2(size, guarded.get_user_size())); 1.235 + if (paranoid) verify_memory(ptr); 1.236 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { 1.237 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); 1.238 breakpoint(); 1.239 } 1.240 - free(memblock); 1.241 + os::free(memblock); 1.242 } 1.243 return ptr; 1.244 #endif 1.245 @@ -771,6 +677,7 @@ 1.246 1.247 1.248 void os::free(void *memblock, MEMFLAGS memflags) { 1.249 + address trackp = (address) memblock; 1.250 NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); 1.251 #ifdef ASSERT 1.252 if (memblock == NULL) return; 1.253 @@ -778,34 +685,20 @@ 1.254 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); 1.255 breakpoint(); 1.256 } 1.257 - verify_block(memblock); 1.258 + verify_memory(memblock); 1.259 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); 1.260 - // Added by detlefs. 1.261 - if (MallocCushion) { 1.262 - u_char* ptr = (u_char*)memblock - space_before; 1.263 - for (u_char* p = ptr; p < ptr + MallocCushion; p++) { 1.264 - guarantee(*p == badResourceValue, 1.265 - "Thing freed should be malloc result."); 1.266 - *p = (u_char)freeBlockPad; 1.267 - } 1.268 - size_t size = get_size(memblock); 1.269 - inc_stat_counter(&free_bytes, size); 1.270 - u_char* end = ptr + space_before + size; 1.271 - for (u_char* q = end; q < end + MallocCushion; q++) { 1.272 - guarantee(*q == badResourceValue, 1.273 - "Thing freed should be malloc result."); 1.274 - *q = (u_char)freeBlockPad; 1.275 - } 1.276 - if (PrintMalloc && tty != NULL) 1.277 + 1.278 + GuardedMemory guarded(memblock); 1.279 + size_t size = guarded.get_user_size(); 1.280 + inc_stat_counter(&free_bytes, size); 1.281 + memblock = guarded.release_for_freeing(); 1.282 + if (PrintMalloc && tty != NULL) { 1.283 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock); 1.284 - } else if (PrintMalloc && tty != NULL) { 1.285 - // tty->print_cr("os::free %p", memblock); 1.286 - fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock); 1.287 } 1.288 #endif 1.289 - MemTracker::record_free((address)memblock, memflags); 1.290 + MemTracker::record_free(trackp, memflags); 1.291 1.292 - ::free((char*)memblock - space_before); 1.293 + ::free(memblock); 1.294 } 1.295 1.296 void os::init_random(long initval) {