comparison src/share/vm/runtime/os.cpp @ 2250:f7de3327c683

7017124: Fix some VM stats to avoid 32-bit overflow Summary: Added new method inc_stat_counter() to increment long statistic values and use atomic long load and store. Reviewed-by: dholmes, jrose, phh, never
author kvn
date Mon, 07 Feb 2011 10:34:39 -0800
parents 3582bf76420e
children a2babfb34c24 f767174aac14
comparison
equal deleted inserted replaced
2249:3763ca6579b7 2250:f7de3327c683
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
70 long os::_rand_seed = 1; 70 long os::_rand_seed = 1;
71 int os::_processor_count = 0; 71 int os::_processor_count = 0;
72 size_t os::_page_sizes[os::page_sizes_max]; 72 size_t os::_page_sizes[os::page_sizes_max];
73 73
74 #ifndef PRODUCT 74 #ifndef PRODUCT
75 int os::num_mallocs = 0; // # of calls to malloc/realloc 75 julong os::num_mallocs = 0; // # of calls to malloc/realloc
76 size_t os::alloc_bytes = 0; // # of bytes allocated 76 julong os::alloc_bytes = 0; // # of bytes allocated
77 int os::num_frees = 0; // # of calls to free 77 julong os::num_frees = 0; // # of calls to free
78 julong os::free_bytes = 0; // # of bytes freed
78 #endif 79 #endif
79 80
80 // Fill in buffer with current local time as an ISO-8601 string. 81 // Fill in buffer with current local time as an ISO-8601 string.
81 // E.g., yyyy-mm-ddThh:mm:ss-zzzz. 82 // E.g., yyyy-mm-ddThh:mm:ss-zzzz.
82 // Returns buffer, or NULL if it failed. 83 // Returns buffer, or NULL if it failed.
488 size = *size_addr_from_base(start_of_prev_block); 489 size = *size_addr_from_base(start_of_prev_block);
489 obj = start_of_prev_block + space_before; 490 obj = start_of_prev_block + space_before;
490 } 491 }
491 492
492 if (start_of_prev_block + space_before + size + space_after == start_of_this_block) { 493 if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
493 tty->print_cr("### previous object: %p (%ld bytes)", obj, size); 494 tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
494 } else { 495 } else {
495 tty->print_cr("### previous object (not sure if correct): %p (%ld bytes)", obj, size); 496 tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
496 } 497 }
497 498
498 // now find successor block 499 // now find successor block
499 u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after; 500 u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
500 start_of_next_block = find_cushion_forwards(start_of_next_block); 501 start_of_next_block = find_cushion_forwards(start_of_next_block);
502 ptrdiff_t next_size = *size_addr_from_base(start_of_next_block); 503 ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
503 if (start_of_next_block[0] == badResourceValue && 504 if (start_of_next_block[0] == badResourceValue &&
504 start_of_next_block[1] == badResourceValue && 505 start_of_next_block[1] == badResourceValue &&
505 start_of_next_block[2] == badResourceValue && 506 start_of_next_block[2] == badResourceValue &&
506 start_of_next_block[3] == badResourceValue) { 507 start_of_next_block[3] == badResourceValue) {
507 tty->print_cr("### next object: %p (%ld bytes)", next_obj, next_size); 508 tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
508 } else { 509 } else {
509 tty->print_cr("### next object (not sure if correct): %p (%ld bytes)", next_obj, next_size); 510 tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
510 } 511 }
511 } 512 }
512 513
513 514
514 void report_heap_error(void* memblock, void* bad, const char* where) { 515 void report_heap_error(void* memblock, void* bad, const char* where) {
515 tty->print_cr("## nof_mallocs = %d, nof_frees = %d", os::num_mallocs, os::num_frees); 516 tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
516 tty->print_cr("## memory stomp: byte at %p %s object %p", bad, where, memblock); 517 tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
517 print_neighbor_blocks(memblock); 518 print_neighbor_blocks(memblock);
518 fatal("memory stomping error"); 519 fatal("memory stomping error");
519 } 520 }
520 521
521 void verify_block(void* memblock) { 522 void verify_block(void* memblock) {
536 } 537 }
537 } 538 }
538 #endif 539 #endif
539 540
540 void* os::malloc(size_t size) { 541 void* os::malloc(size_t size) {
541 NOT_PRODUCT(num_mallocs++); 542 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
542 NOT_PRODUCT(alloc_bytes += size); 543 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
543 544
544 if (size == 0) { 545 if (size == 0) {
545 // return a valid pointer if size is zero 546 // return a valid pointer if size is zero
546 // if NULL is returned the calling functions assume out of memory. 547 // if NULL is returned the calling functions assume out of memory.
547 size = 1; 548 size = 1;
560 // put size just before data 561 // put size just before data
561 *size_addr_from_base(ptr) = size; 562 *size_addr_from_base(ptr) = size;
562 #endif 563 #endif
563 u_char* memblock = ptr + space_before; 564 u_char* memblock = ptr + space_before;
564 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { 565 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
565 tty->print_cr("os::malloc caught, %lu bytes --> %p", size, memblock); 566 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
566 breakpoint(); 567 breakpoint();
567 } 568 }
568 debug_only(if (paranoid) verify_block(memblock)); 569 debug_only(if (paranoid) verify_block(memblock));
569 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc %lu bytes --> %p", size, memblock); 570 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
570 return memblock; 571 return memblock;
571 } 572 }
572 573
573 574
574 void* os::realloc(void *memblock, size_t size) { 575 void* os::realloc(void *memblock, size_t size) {
575 NOT_PRODUCT(num_mallocs++);
576 NOT_PRODUCT(alloc_bytes += size);
577 #ifndef ASSERT 576 #ifndef ASSERT
577 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
578 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
578 return ::realloc(memblock, size); 579 return ::realloc(memblock, size);
579 #else 580 #else
580 if (memblock == NULL) { 581 if (memblock == NULL) {
581 return os::malloc(size); 582 return malloc(size);
582 } 583 }
583 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { 584 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
584 tty->print_cr("os::realloc caught %p", memblock); 585 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
585 breakpoint(); 586 breakpoint();
586 } 587 }
587 verify_block(memblock); 588 verify_block(memblock);
588 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); 589 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
589 if (size == 0) return NULL; 590 if (size == 0) return NULL;
590 // always move the block 591 // always move the block
591 void* ptr = malloc(size); 592 void* ptr = malloc(size);
592 if (PrintMalloc) tty->print_cr("os::remalloc %lu bytes, %p --> %p", size, memblock, ptr); 593 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
593 // Copy to new memory if malloc didn't fail 594 // Copy to new memory if malloc didn't fail
594 if ( ptr != NULL ) { 595 if ( ptr != NULL ) {
595 memcpy(ptr, memblock, MIN2(size, get_size(memblock))); 596 memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
596 if (paranoid) verify_block(ptr); 597 if (paranoid) verify_block(ptr);
597 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { 598 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
598 tty->print_cr("os::realloc caught, %lu bytes --> %p", size, ptr); 599 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
599 breakpoint(); 600 breakpoint();
600 } 601 }
601 free(memblock); 602 free(memblock);
602 } 603 }
603 return ptr; 604 return ptr;
604 #endif 605 #endif
605 } 606 }
606 607
607 608
608 void os::free(void *memblock) { 609 void os::free(void *memblock) {
609 NOT_PRODUCT(num_frees++); 610 NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
610 #ifdef ASSERT 611 #ifdef ASSERT
611 if (memblock == NULL) return; 612 if (memblock == NULL) return;
612 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { 613 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
613 if (tty != NULL) tty->print_cr("os::free caught %p", memblock); 614 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
614 breakpoint(); 615 breakpoint();
615 } 616 }
616 verify_block(memblock); 617 verify_block(memblock);
617 if (PrintMalloc && tty != NULL)
618 // tty->print_cr("os::free %p", memblock);
619 fprintf(stderr, "os::free %p\n", memblock);
620 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); 618 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
621 // Added by detlefs. 619 // Added by detlefs.
622 if (MallocCushion) { 620 if (MallocCushion) {
623 u_char* ptr = (u_char*)memblock - space_before; 621 u_char* ptr = (u_char*)memblock - space_before;
624 for (u_char* p = ptr; p < ptr + MallocCushion; p++) { 622 for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
625 guarantee(*p == badResourceValue, 623 guarantee(*p == badResourceValue,
626 "Thing freed should be malloc result."); 624 "Thing freed should be malloc result.");
627 *p = (u_char)freeBlockPad; 625 *p = (u_char)freeBlockPad;
628 } 626 }
629 size_t size = get_size(memblock); 627 size_t size = get_size(memblock);
628 inc_stat_counter(&free_bytes, size);
630 u_char* end = ptr + space_before + size; 629 u_char* end = ptr + space_before + size;
631 for (u_char* q = end; q < end + MallocCushion; q++) { 630 for (u_char* q = end; q < end + MallocCushion; q++) {
632 guarantee(*q == badResourceValue, 631 guarantee(*q == badResourceValue,
633 "Thing freed should be malloc result."); 632 "Thing freed should be malloc result.");
634 *q = (u_char)freeBlockPad; 633 *q = (u_char)freeBlockPad;
635 } 634 }
635 if (PrintMalloc && tty != NULL)
636 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, memblock);
637 } else if (PrintMalloc && tty != NULL) {
638 // tty->print_cr("os::free %p", memblock);
639 fprintf(stderr, "os::free " PTR_FORMAT "\n", memblock);
636 } 640 }
637 #endif 641 #endif
638 ::free((char*)memblock - space_before); 642 ::free((char*)memblock - space_before);
639 } 643 }
640 644