38
38
#include " logging/log.hpp"
39
39
#include " logging/logStream.hpp"
40
40
#include " memory/allocation.inline.hpp"
41
- #include " memory/guardedMemory.hpp"
42
41
#include " memory/resourceArea.hpp"
43
42
#include " memory/universe.hpp"
44
43
#include " oops/compressedOops.inline.hpp"
@@ -83,13 +82,6 @@ int os::_processor_count = 0;
83
82
int os::_initial_active_processor_count = 0 ;
84
83
os::PageSizes os::_page_sizes;
85
84
86
- #ifndef PRODUCT
87
- julong os::num_mallocs = 0 ; // # of calls to malloc/realloc
88
- julong os::alloc_bytes = 0 ; // # of bytes allocated
89
- julong os::num_frees = 0 ; // # of calls to free
90
- julong os::free_bytes = 0 ; // # of bytes freed
91
- #endif
92
-
93
85
static size_t cur_malloc_words = 0 ; // current size for MallocMaxTestWords
94
86
95
87
DEBUG_ONLY (bool os::_mutex_init_done = false ;)
@@ -603,30 +595,11 @@ char* os::strdup_check_oom(const char* str, MEMFLAGS flags) {
603
595
return p;
604
596
}
605
597
606
-
607
- #define paranoid 0 /* only set to 1 if you suspect checking code has bug */
608
-
609
- #ifdef ASSERT
610
-
611
- static void verify_memory (void * ptr) {
612
- GuardedMemory guarded (ptr);
613
- if (!guarded.verify_guards ()) {
614
- LogTarget (Warning, malloc, free) lt;
615
- ResourceMark rm;
616
- LogStream ls (lt);
617
- ls.print_cr (" ## nof_mallocs = " UINT64_FORMAT " , nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
618
- ls.print_cr (" ## memory stomp:" );
619
- guarded.print_on (&ls);
620
- fatal (" memory stomping error" );
621
- }
622
- }
623
-
624
- #endif
625
-
626
598
//
627
599
// This function supports testing of the malloc out of memory
628
600
// condition without really running the system out of memory.
629
601
//
602
+
630
603
static bool has_reached_max_malloc_test_peak (size_t alloc_size) {
631
604
if (MallocMaxTestWords > 0 ) {
632
605
size_t words = (alloc_size / BytesPerWord);
@@ -639,13 +612,24 @@ static bool has_reached_max_malloc_test_peak(size_t alloc_size) {
639
612
return false ;
640
613
}
641
614
615
+ #ifdef ASSERT
616
+ static void check_crash_protection () {
617
+ assert (!os::ThreadCrashProtection::is_crash_protected (Thread::current_or_null ()),
618
+ " not allowed when crash protection is set" );
619
+ }
620
+ static void break_if_ptr_caught (void * ptr) {
621
+ if (p2i (ptr) == (intptr_t )MallocCatchPtr) {
622
+ log_warning (malloc, free)(" ptr caught: " PTR_FORMAT, p2i (ptr));
623
+ breakpoint ();
624
+ }
625
+ }
626
+ #endif // ASSERT
627
+
642
628
void * os::malloc (size_t size, MEMFLAGS flags) {
643
629
return os::malloc (size, flags, CALLER_PC);
644
630
}
645
631
646
632
void * os::malloc (size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
647
- NOT_PRODUCT (inc_stat_counter (&num_mallocs, 1 ));
648
- NOT_PRODUCT (inc_stat_counter (&alloc_bytes, size));
649
633
650
634
#if INCLUDE_NMT
651
635
{
@@ -656,58 +640,35 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
656
640
}
657
641
#endif
658
642
659
- // Since os::malloc can be called when the libjvm.{dll,so} is
660
- // first loaded and we don't have a thread yet we must accept NULL also here.
661
- assert (!os::ThreadCrashProtection::is_crash_protected (Thread::current_or_null ()),
662
- " malloc() not allowed when crash protection is set" );
643
+ DEBUG_ONLY (check_crash_protection ());
663
644
664
- if (size == 0 ) {
665
- // return a valid pointer if size is zero
666
- // if NULL is returned the calling functions assume out of memory.
667
- size = 1 ;
668
- }
669
-
670
- // NMT support
671
- NMT_TrackingLevel level = MemTracker::tracking_level ();
672
- const size_t nmt_overhead =
673
- MemTracker::malloc_header_size (level) + MemTracker::malloc_footer_size (level);
674
-
675
- #ifndef ASSERT
676
- const size_t alloc_size = size + nmt_overhead;
677
- #else
678
- const size_t alloc_size = GuardedMemory::get_total_size (size + nmt_overhead);
679
- if (size + nmt_overhead > alloc_size) { // Check for rollover.
680
- return NULL ;
681
- }
682
- #endif
645
+ // On malloc(0), implementators of malloc(3) have the choice to return either
646
+ // NULL or a unique non-NULL pointer. To unify libc behavior across our platforms
647
+ // we chose the latter.
648
+ size = MAX2 ((size_t )1 , size);
683
649
684
650
// For the test flag -XX:MallocMaxTestWords
685
651
if (has_reached_max_malloc_test_peak (size)) {
686
652
return NULL ;
687
653
}
688
654
689
- u_char* ptr;
690
- ptr = (u_char*)::malloc (alloc_size);
655
+ const NMT_TrackingLevel level = MemTracker::tracking_level ();
656
+ const size_t nmt_overhead =
657
+ MemTracker::malloc_header_size (level) + MemTracker::malloc_footer_size (level);
658
+
659
+ const size_t outer_size = size + nmt_overhead;
691
660
692
- # ifdef ASSERT
693
- if (ptr == NULL ) {
661
+ void * const outer_ptr = (u_char*):: malloc (outer_size);
662
+ if (outer_ptr == NULL ) {
694
663
return NULL ;
695
664
}
696
- // Wrap memory with guard
697
- GuardedMemory guarded (ptr, size + nmt_overhead);
698
- ptr = guarded.get_user_ptr ();
699
665
700
- if ((intptr_t )ptr == (intptr_t )MallocCatchPtr) {
701
- log_warning (malloc, free)(" os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, p2i (ptr));
702
- breakpoint ();
703
- }
704
- if (paranoid) {
705
- verify_memory (ptr);
706
- }
707
- #endif
666
+ void * inner_ptr = MemTracker::record_malloc ((address)outer_ptr, size, memflags, stack, level);
708
667
709
- // we do not track guard memory
710
- return MemTracker::record_malloc ((address)ptr, size, memflags, stack, level);
668
+ DEBUG_ONLY (::memset (inner_ptr, uninitBlockPad, size);)
669
+ DEBUG_ONLY (break_if_ptr_caught (inner_ptr);)
670
+
671
+ return inner_ptr;
711
672
}
712
673
713
674
void * os::realloc (void *memblock, size_t size, MEMFLAGS flags) {
@@ -725,59 +686,41 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCa
725
686
}
726
687
#endif
727
688
689
+ if (memblock == NULL ) {
690
+ return os::malloc (size, memflags, stack);
691
+ }
692
+
693
+ DEBUG_ONLY (check_crash_protection ());
694
+
695
+ // On realloc(p, 0), implementators of realloc(3) have the choice to return either
696
+ // NULL or a unique non-NULL pointer. To unify libc behavior across our platforms
697
+ // we chose the latter.
698
+ size = MAX2 ((size_t )1 , size);
699
+
728
700
// For the test flag -XX:MallocMaxTestWords
729
701
if (has_reached_max_malloc_test_peak (size)) {
730
702
return NULL ;
731
703
}
732
704
733
- if (size == 0 ) {
734
- // return a valid pointer if size is zero
735
- // if NULL is returned the calling functions assume out of memory.
736
- size = 1 ;
737
- }
738
-
739
- #ifndef ASSERT
740
- NOT_PRODUCT (inc_stat_counter (&num_mallocs, 1 ));
741
- NOT_PRODUCT (inc_stat_counter (&alloc_bytes, size));
742
- // NMT support
743
- NMT_TrackingLevel level = MemTracker::tracking_level ();
744
- void * membase = MemTracker::record_free (memblock, level);
705
+ const NMT_TrackingLevel level = MemTracker::tracking_level ();
745
706
const size_t nmt_overhead =
746
707
MemTracker::malloc_header_size (level) + MemTracker::malloc_footer_size (level);
747
- void * ptr = ::realloc (membase, size + nmt_overhead);
748
- return MemTracker::record_malloc (ptr, size, memflags, stack, level);
749
- #else
750
- if (memblock == NULL ) {
751
- return os::malloc (size, memflags, stack);
752
- }
753
- if ((intptr_t )memblock == (intptr_t )MallocCatchPtr) {
754
- log_warning (malloc, free)(" os::realloc caught " PTR_FORMAT, p2i (memblock));
755
- breakpoint ();
756
- }
757
- // NMT support
758
- void * membase = MemTracker::malloc_base (memblock);
759
- verify_memory (membase);
760
- // always move the block
761
- void * ptr = os::malloc (size, memflags, stack);
762
- // Copy to new memory if malloc didn't fail
763
- if (ptr != NULL ) {
764
- GuardedMemory guarded (MemTracker::malloc_base (memblock));
765
- // Guard's user data contains NMT header
766
- NMT_TrackingLevel level = MemTracker::tracking_level ();
767
- const size_t nmt_overhead =
768
- MemTracker::malloc_header_size (level) + MemTracker::malloc_footer_size (level);
769
- size_t memblock_size = guarded.get_user_size () - nmt_overhead;
770
- memcpy (ptr, memblock, MIN2 (size, memblock_size));
771
- if (paranoid) {
772
- verify_memory (MemTracker::malloc_base (ptr));
773
- }
774
- os::free (memblock);
775
- }
776
- return ptr;
777
- #endif
708
+
709
+ const size_t new_outer_size = size + nmt_overhead;
710
+
711
+ // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block.
712
+ void * const old_outer_ptr = MemTracker::record_free (memblock, level);
713
+
714
+ void * const new_outer_ptr = ::realloc (old_outer_ptr, new_outer_size);
715
+
716
+ // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block.
717
+ void * const new_inner_ptr = MemTracker::record_malloc (new_outer_ptr, size, memflags, stack, level);
718
+
719
+ DEBUG_ONLY (break_if_ptr_caught (new_inner_ptr);)
720
+
721
+ return new_inner_ptr;
778
722
}
779
723
780
- // handles NULL pointers
781
724
void os::free (void *memblock) {
782
725
783
726
#if INCLUDE_NMT
@@ -786,25 +729,17 @@ void os::free(void *memblock) {
786
729
}
787
730
#endif
788
731
789
- NOT_PRODUCT (inc_stat_counter (&num_frees, 1 ));
790
- #ifdef ASSERT
791
- if (memblock == NULL ) return ;
792
- if ((intptr_t )memblock == (intptr_t )MallocCatchPtr) {
793
- log_warning (malloc, free)(" os::free caught " PTR_FORMAT, p2i (memblock));
794
- breakpoint ();
732
+ if (memblock == NULL ) {
733
+ return ;
795
734
}
796
- void * membase = MemTracker::record_free (memblock, MemTracker::tracking_level ());
797
- verify_memory (membase);
798
735
799
- GuardedMemory guarded (membase);
800
- size_t size = guarded.get_user_size ();
801
- inc_stat_counter (&free_bytes, size);
802
- membase = guarded.release_for_freeing ();
803
- ::free (membase);
804
- #else
805
- void * membase = MemTracker::record_free (memblock, MemTracker::tracking_level ());
806
- ::free (membase);
807
- #endif
736
+ DEBUG_ONLY (break_if_ptr_caught (memblock);)
737
+
738
+ const NMT_TrackingLevel level = MemTracker::tracking_level ();
739
+
740
+ // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block.
741
+ void * const old_outer_ptr = MemTracker::record_free (memblock, level);
742
+ ::free (old_outer_ptr);
808
743
}
809
744
810
745
void os::init_random (unsigned int initval) {
0 commit comments