hotspot/src/share/vm/runtime/os.cpp
changeset 25056 5ad92b0d1beb
parent 24457 0e20b36df5c4
child 25351 7c198a690050
equal deleted inserted replaced
25055:b8579a44691b 25056:5ad92b0d1beb
    30 #include "code/icBuffer.hpp"
    30 #include "code/icBuffer.hpp"
    31 #include "code/vtableStubs.hpp"
    31 #include "code/vtableStubs.hpp"
    32 #include "gc_implementation/shared/vmGCOperations.hpp"
    32 #include "gc_implementation/shared/vmGCOperations.hpp"
    33 #include "interpreter/interpreter.hpp"
    33 #include "interpreter/interpreter.hpp"
    34 #include "memory/allocation.inline.hpp"
    34 #include "memory/allocation.inline.hpp"
       
    35 #ifdef ASSERT
       
    36 #include "memory/guardedMemory.hpp"
       
    37 #endif
    35 #include "oops/oop.inline.hpp"
    38 #include "oops/oop.inline.hpp"
    36 #include "prims/jvm.h"
    39 #include "prims/jvm.h"
    37 #include "prims/jvm_misc.hpp"
    40 #include "prims/jvm_misc.hpp"
    38 #include "prims/privilegedStack.hpp"
    41 #include "prims/privilegedStack.hpp"
    39 #include "runtime/arguments.hpp"
    42 #include "runtime/arguments.hpp"
   521   strcpy(dup_str, str);
   524   strcpy(dup_str, str);
   522   return dup_str;
   525   return dup_str;
   523 }
   526 }
   524 
   527 
   525 
   528 
       
   529 #define paranoid                 0  /* only set to 1 if you suspect checking code has bug */
   526 
   530 
   527 #ifdef ASSERT
   531 #ifdef ASSERT
   528 #define space_before             (MallocCushion + sizeof(double))
   532 
   529 #define space_after              MallocCushion
   533 static void verify_memory(void* ptr) {
   530 #define size_addr_from_base(p)   (size_t*)(p + space_before - sizeof(size_t))
   534   GuardedMemory guarded(ptr);
   531 #define size_addr_from_obj(p)    ((size_t*)p - 1)
   535   if (!guarded.verify_guards()) {
   532 // MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly
   536     tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
   533 // NB: cannot be debug variable, because these aren't set from the command line until
   537     tty->print_cr("## memory stomp:");
   534 // *after* the first few allocs already happened
   538     guarded.print_on(tty);
   535 #define MallocCushion            16
   539     fatal("memory stomping error");
   536 #else
   540   }
   537 #define space_before             0
   541 }
   538 #define space_after              0
   542 
   539 #define size_addr_from_base(p)   should not use w/o ASSERT
       
   540 #define size_addr_from_obj(p)    should not use w/o ASSERT
       
   541 #define MallocCushion            0
       
   542 #endif
       
   543 #define paranoid                 0  /* only set to 1 if you suspect checking code has bug */
       
   544 
       
   545 #ifdef ASSERT
       
   546 inline size_t get_size(void* obj) {
       
   547   size_t size = *size_addr_from_obj(obj);
       
   548   if (size < 0) {
       
   549     fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten ("
       
   550                   SIZE_FORMAT ")", obj, size));
       
   551   }
       
   552   return size;
       
   553 }
       
   554 
       
   555 u_char* find_cushion_backwards(u_char* start) {
       
   556   u_char* p = start;
       
   557   while (p[ 0] != badResourceValue || p[-1] != badResourceValue ||
       
   558          p[-2] != badResourceValue || p[-3] != badResourceValue) p--;
       
   559   // ok, we have four consecutive marker bytes; find start
       
   560   u_char* q = p - 4;
       
   561   while (*q == badResourceValue) q--;
       
   562   return q + 1;
       
   563 }
       
   564 
       
   565 u_char* find_cushion_forwards(u_char* start) {
       
   566   u_char* p = start;
       
   567   while (p[0] != badResourceValue || p[1] != badResourceValue ||
       
   568          p[2] != badResourceValue || p[3] != badResourceValue) p++;
       
   569   // ok, we have four consecutive marker bytes; find end of cushion
       
   570   u_char* q = p + 4;
       
   571   while (*q == badResourceValue) q++;
       
   572   return q - MallocCushion;
       
   573 }
       
   574 
       
   575 void print_neighbor_blocks(void* ptr) {
       
   576   // find block allocated before ptr (not entirely crash-proof)
       
   577   if (MallocCushion < 4) {
       
   578     tty->print_cr("### cannot find previous block (MallocCushion < 4)");
       
   579     return;
       
   580   }
       
   581   u_char* start_of_this_block = (u_char*)ptr - space_before;
       
   582   u_char* end_of_prev_block_data = start_of_this_block - space_after -1;
       
   583   // look for cushion in front of prev. block
       
   584   u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data);
       
   585   ptrdiff_t size = *size_addr_from_base(start_of_prev_block);
       
   586   u_char* obj = start_of_prev_block + space_before;
       
   587   if (size <= 0 ) {
       
   588     // start is bad; may have been confused by OS data in between objects
       
   589     // search one more backwards
       
   590     start_of_prev_block = find_cushion_backwards(start_of_prev_block);
       
   591     size = *size_addr_from_base(start_of_prev_block);
       
   592     obj = start_of_prev_block + space_before;
       
   593   }
       
   594 
       
   595   if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
       
   596     tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
       
   597   } else {
       
   598     tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
       
   599   }
       
   600 
       
   601   // now find successor block
       
   602   u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
       
   603   start_of_next_block = find_cushion_forwards(start_of_next_block);
       
   604   u_char* next_obj = start_of_next_block + space_before;
       
   605   ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
       
   606   if (start_of_next_block[0] == badResourceValue &&
       
   607       start_of_next_block[1] == badResourceValue &&
       
   608       start_of_next_block[2] == badResourceValue &&
       
   609       start_of_next_block[3] == badResourceValue) {
       
   610     tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
       
   611   } else {
       
   612     tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
       
   613   }
       
   614 }
       
   615 
       
   616 
       
   617 void report_heap_error(void* memblock, void* bad, const char* where) {
       
   618   tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
       
   619   tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
       
   620   print_neighbor_blocks(memblock);
       
   621   fatal("memory stomping error");
       
   622 }
       
   623 
       
   624 void verify_block(void* memblock) {
       
   625   size_t size = get_size(memblock);
       
   626   if (MallocCushion) {
       
   627     u_char* ptr = (u_char*)memblock - space_before;
       
   628     for (int i = 0; i < MallocCushion; i++) {
       
   629       if (ptr[i] != badResourceValue) {
       
   630         report_heap_error(memblock, ptr+i, "in front of");
       
   631       }
       
   632     }
       
   633     u_char* end = (u_char*)memblock + size + space_after;
       
   634     for (int j = -MallocCushion; j < 0; j++) {
       
   635       if (end[j] != badResourceValue) {
       
   636         report_heap_error(memblock, end+j, "after");
       
   637       }
       
   638     }
       
   639   }
       
   640 }
       
   641 #endif
   543 #endif
   642 
   544 
   643 //
   545 //
   644 // This function supports testing of the malloc out of memory
   546 // This function supports testing of the malloc out of memory
   645 // condition without really running the system out of memory.
   547 // condition without really running the system out of memory.
   684     // return a valid pointer if size is zero
   586     // return a valid pointer if size is zero
   685     // if NULL is returned the calling functions assume out of memory.
   587     // if NULL is returned the calling functions assume out of memory.
   686     size = 1;
   588     size = 1;
   687   }
   589   }
   688 
   590 
   689   const size_t alloc_size = size + space_before + space_after;
   591 #ifndef ASSERT
   690 
   592   const size_t alloc_size = size;
       
   593 #else
       
   594   const size_t alloc_size = GuardedMemory::get_total_size(size);
   691   if (size > alloc_size) { // Check for rollover.
   595   if (size > alloc_size) { // Check for rollover.
   692     return NULL;
   596     return NULL;
   693   }
   597   }
       
   598 #endif
   694 
   599 
   695   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   600   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   696 
   601 
   697   u_char* ptr;
   602   u_char* ptr;
   698 
       
   699   if (MallocMaxTestWords > 0) {
   603   if (MallocMaxTestWords > 0) {
   700     ptr = testMalloc(alloc_size);
   604     ptr = testMalloc(alloc_size);
   701   } else {
   605   } else {
   702     ptr = (u_char*)::malloc(alloc_size);
   606     ptr = (u_char*)::malloc(alloc_size);
   703   }
   607   }
   704 
   608 
   705 #ifdef ASSERT
   609 #ifdef ASSERT
   706   if (ptr == NULL) return NULL;
   610   if (ptr == NULL) {
   707   if (MallocCushion) {
   611     return NULL;
   708     for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue;
   612   }
   709     u_char* end = ptr + space_before + size;
   613   // Wrap memory with guard
   710     for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad;
   614   GuardedMemory guarded(ptr, size);
   711     for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue;
   615   ptr = guarded.get_user_ptr();
   712   }
   616 #endif
   713   // put size just before data
   617   if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
   714   *size_addr_from_base(ptr) = size;
   618     tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
   715 #endif
       
   716   u_char* memblock = ptr + space_before;
       
   717   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
       
   718     tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
       
   719     breakpoint();
   619     breakpoint();
   720   }
   620   }
   721   debug_only(if (paranoid) verify_block(memblock));
   621   debug_only(if (paranoid) verify_memory(ptr));
   722   if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
   622   if (PrintMalloc && tty != NULL) {
   723 
   623     tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
   724   // we do not track MallocCushion memory
   624   }
   725     MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
   625 
   726 
   626   // we do not track guard memory
   727   return memblock;
   627   MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller);
       
   628 
       
   629   return ptr;
   728 }
   630 }
   729 
   631 
   730 
   632 
   731 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
   633 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
   732 #ifndef ASSERT
   634 #ifndef ASSERT
   741     tkr.discard();
   643     tkr.discard();
   742   }
   644   }
   743   return ptr;
   645   return ptr;
   744 #else
   646 #else
   745   if (memblock == NULL) {
   647   if (memblock == NULL) {
   746     return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
   648     return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
   747   }
   649   }
   748   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
   650   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
   749     tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
   651     tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
   750     breakpoint();
   652     breakpoint();
   751   }
   653   }
   752   verify_block(memblock);
   654   verify_memory(memblock);
   753   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   655   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   754   if (size == 0) return NULL;
   656   if (size == 0) {
       
   657     return NULL;
       
   658   }
   755   // always move the block
   659   // always move the block
   756   void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
   660   void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
   757   if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
   661   if (PrintMalloc) {
       
   662     tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
       
   663   }
   758   // Copy to new memory if malloc didn't fail
   664   // Copy to new memory if malloc didn't fail
   759   if ( ptr != NULL ) {
   665   if ( ptr != NULL ) {
   760     memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
   666     GuardedMemory guarded(memblock);
   761     if (paranoid) verify_block(ptr);
   667     memcpy(ptr, memblock, MIN2(size, guarded.get_user_size()));
       
   668     if (paranoid) verify_memory(ptr);
   762     if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
   669     if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
   763       tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
   670       tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
   764       breakpoint();
   671       breakpoint();
   765     }
   672     }
   766     free(memblock);
   673     os::free(memblock);
   767   }
   674   }
   768   return ptr;
   675   return ptr;
   769 #endif
   676 #endif
   770 }
   677 }
   771 
   678 
   772 
   679 
   773 void  os::free(void *memblock, MEMFLAGS memflags) {
   680 void  os::free(void *memblock, MEMFLAGS memflags) {
       
   681   address trackp = (address) memblock;
   774   NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
   682   NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
   775 #ifdef ASSERT
   683 #ifdef ASSERT
   776   if (memblock == NULL) return;
   684   if (memblock == NULL) return;
   777   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
   685   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
   778     if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
   686     if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
   779     breakpoint();
   687     breakpoint();
   780   }
   688   }
   781   verify_block(memblock);
   689   verify_memory(memblock);
   782   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   690   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   783   // Added by detlefs.
   691 
   784   if (MallocCushion) {
   692   GuardedMemory guarded(memblock);
   785     u_char* ptr = (u_char*)memblock - space_before;
   693   size_t size = guarded.get_user_size();
   786     for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
   694   inc_stat_counter(&free_bytes, size);
   787       guarantee(*p == badResourceValue,
   695   memblock = guarded.release_for_freeing();
   788                 "Thing freed should be malloc result.");
   696   if (PrintMalloc && tty != NULL) {
   789       *p = (u_char)freeBlockPad;
       
   790     }
       
   791     size_t size = get_size(memblock);
       
   792     inc_stat_counter(&free_bytes, size);
       
   793     u_char* end = ptr + space_before + size;
       
   794     for (u_char* q = end; q < end + MallocCushion; q++) {
       
   795       guarantee(*q == badResourceValue,
       
   796                 "Thing freed should be malloc result.");
       
   797       *q = (u_char)freeBlockPad;
       
   798     }
       
   799     if (PrintMalloc && tty != NULL)
       
   800       fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
   697       fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
   801   } else if (PrintMalloc && tty != NULL) {
   698   }
   802     // tty->print_cr("os::free %p", memblock);
   699 #endif
   803     fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
   700   MemTracker::record_free(trackp, memflags);
   804   }
   701 
   805 #endif
   702   ::free(memblock);
   806   MemTracker::record_free((address)memblock, memflags);
       
   807 
       
   808   ::free((char*)memblock - space_before);
       
   809 }
   703 }
   810 
   704 
   811 void os::init_random(long initval) {
   705 void os::init_random(long initval) {
   812   _rand_seed = initval;
   706   _rand_seed = initval;
   813 }
   707 }