src/share/vm/services/mallocTracker.hpp

changeset 7344
787c9c28311f
parent 7267
417e3b8d04c5
child 7356
ec2c6fdd1ce6
equal deleted inserted replaced
7343:09259e52a610 7344:787c9c28311f
237 * which ensures 8-bytes alignment on 32-bit systems and 16-bytes on 64-bit systems (Product build). 237 * which ensures 8-bytes alignment on 32-bit systems and 16-bytes on 64-bit systems (Product build).
238 */ 238 */
239 239
240 class MallocHeader VALUE_OBJ_CLASS_SPEC { 240 class MallocHeader VALUE_OBJ_CLASS_SPEC {
241 #ifdef _LP64 241 #ifdef _LP64
242 size_t _size : 62; 242 size_t _size : 64;
243 size_t _level : 2;
244 size_t _flags : 8; 243 size_t _flags : 8;
245 size_t _pos_idx : 16; 244 size_t _pos_idx : 16;
246 size_t _bucket_idx: 40; 245 size_t _bucket_idx: 40;
247 #define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40) 246 #define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40)
248 #define MAX_BUCKET_LENGTH ((size_t)(1 << 16)) 247 #define MAX_BUCKET_LENGTH ((size_t)(1 << 16))
249 #define MAX_MALLOC_SIZE (((size_t)1 << 62) - 1)
250 #else 248 #else
251 size_t _size : 30; 249 size_t _size : 32;
252 size_t _level : 2;
253 size_t _flags : 8; 250 size_t _flags : 8;
254 size_t _pos_idx : 8; 251 size_t _pos_idx : 8;
255 size_t _bucket_idx: 16; 252 size_t _bucket_idx: 16;
256 #define MAX_MALLOCSITE_TABLE_SIZE ((size_t)(1 << 16)) 253 #define MAX_MALLOCSITE_TABLE_SIZE ((size_t)(1 << 16))
257 #define MAX_BUCKET_LENGTH ((size_t)(1 << 8)) 254 #define MAX_BUCKET_LENGTH ((size_t)(1 << 8))
258 // Max malloc size = 1GB - 1 on 32 bit system, such has total 4GB memory
259 #define MAX_MALLOC_SIZE ((size_t)(1 << 30) - 1)
260 #endif // _LP64 255 #endif // _LP64
261 256
262 public: 257 public:
263 // Summary tracking header 258 MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) {
264 MallocHeader(size_t size, MEMFLAGS flags) {
265 assert(sizeof(MallocHeader) == sizeof(void*) * 2, 259 assert(sizeof(MallocHeader) == sizeof(void*) * 2,
266 "Wrong header size"); 260 "Wrong header size");
267 261
268 _level = NMT_summary; 262 if (level == NMT_minimal) {
263 return;
264 }
265
269 _flags = flags; 266 _flags = flags;
270 set_size(size); 267 set_size(size);
268 if (level == NMT_detail) {
269 size_t bucket_idx;
270 size_t pos_idx;
271 if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
272 assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
273 assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
274 _bucket_idx = bucket_idx;
275 _pos_idx = pos_idx;
276 }
277 }
278
271 MallocMemorySummary::record_malloc(size, flags); 279 MallocMemorySummary::record_malloc(size, flags);
272 MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader)); 280 MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
273 }
274 // Detail tracking header
275 MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack) {
276 assert(sizeof(MallocHeader) == sizeof(void*) * 2,
277 "Wrong header size");
278
279 _level = NMT_detail;
280 _flags = flags;
281 set_size(size);
282 size_t bucket_idx;
283 size_t pos_idx;
284 if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
285 assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
286 assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
287 _bucket_idx = bucket_idx;
288 _pos_idx = pos_idx;
289 }
290 MallocMemorySummary::record_malloc(size, flags);
291 MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
292 }
293 // Minimal tracking header
294 MallocHeader() {
295 assert(sizeof(MallocHeader) == sizeof(void*) * 2,
296 "Wrong header size");
297
298 _level = (unsigned short)NMT_minimal;
299 }
300
301 inline NMT_TrackingLevel tracking_level() const {
302 return (NMT_TrackingLevel)_level;
303 } 281 }
304 282
305 inline size_t size() const { return _size; } 283 inline size_t size() const { return _size; }
306 inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; } 284 inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
307 bool get_stack(NativeCallStack& stack) const; 285 bool get_stack(NativeCallStack& stack) const;
309 // Cleanup tracking information before the memory is released. 287 // Cleanup tracking information before the memory is released.
310 void release() const; 288 void release() const;
311 289
312 private: 290 private:
313 inline void set_size(size_t size) { 291 inline void set_size(size_t size) {
314 assert(size <= MAX_MALLOC_SIZE, "Malloc size too large, should use virtual memory?");
315 _size = size; 292 _size = size;
316 } 293 }
317 bool record_malloc_site(const NativeCallStack& stack, size_t size, 294 bool record_malloc_site(const NativeCallStack& stack, size_t size,
318 size_t* bucket_idx, size_t* pos_idx) const; 295 size_t* bucket_idx, size_t* pos_idx) const;
319 }; 296 };
345 const NativeCallStack& stack, NMT_TrackingLevel level); 322 const NativeCallStack& stack, NMT_TrackingLevel level);
346 323
347 // Record free on specified memory block 324 // Record free on specified memory block
348 static void* record_free(void* memblock); 325 static void* record_free(void* memblock);
349 326
350 // Get tracking level of specified memory block
351 static inline NMT_TrackingLevel get_memory_tracking_level(void* memblock);
352
353
354 // Offset memory address to header address 327 // Offset memory address to header address
355 static inline void* get_base(void* memblock); 328 static inline void* get_base(void* memblock);
356 static inline void* get_base(void* memblock, NMT_TrackingLevel level) { 329 static inline void* get_base(void* memblock, NMT_TrackingLevel level) {
357 if (memblock == NULL || level == NMT_off) return memblock; 330 if (memblock == NULL || level == NMT_off) return memblock;
358 return (char*)memblock - malloc_header_size(level); 331 return (char*)memblock - malloc_header_size(level);
359 } 332 }
360 333
361 // Get memory size 334 // Get memory size
362 static inline size_t get_size(void* memblock) { 335 static inline size_t get_size(void* memblock) {
363 MallocHeader* header = malloc_header(memblock); 336 MallocHeader* header = malloc_header(memblock);
364 assert(header->tracking_level() >= NMT_summary,
365 "Wrong tracking level");
366 return header->size(); 337 return header->size();
367 } 338 }
368 339
369 // Get memory type 340 // Get memory type
370 static inline MEMFLAGS get_flags(void* memblock) { 341 static inline MEMFLAGS get_flags(void* memblock) {
371 MallocHeader* header = malloc_header(memblock); 342 MallocHeader* header = malloc_header(memblock);
372 assert(header->tracking_level() >= NMT_summary,
373 "Wrong tracking level");
374 return header->flags(); 343 return header->flags();
375 } 344 }
376 345
377 // Get header size 346 // Get header size
378 static inline size_t get_header_size(void* memblock) { 347 static inline size_t get_header_size(void* memblock) {
392 } 361 }
393 private: 362 private:
394 static inline MallocHeader* malloc_header(void *memblock) { 363 static inline MallocHeader* malloc_header(void *memblock) {
395 assert(memblock != NULL, "NULL pointer"); 364 assert(memblock != NULL, "NULL pointer");
396 MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader)); 365 MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader));
397 assert(header->tracking_level() >= NMT_minimal, "Bad header");
398 return header; 366 return header;
399 } 367 }
400 }; 368 };
401 369
402 #endif // INCLUDE_NMT 370 #endif // INCLUDE_NMT

mercurial