Mercurial > hg > truffle
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 |