src/hotspot/os/aix/os_aix.cpp
changeset 55754 d645d7ca8ee8
parent 55691 443f7359b34d
child 57599 98dfaf0f9442
equal deleted inserted replaced
55753:b9798272720b 55754:d645d7ca8ee8
   485       struct shmid_ds shm_buf = { 0 };
   485       struct shmid_ds shm_buf = { 0 };
   486       shm_buf.shm_pagesize = pagesize;
   486       shm_buf.shm_pagesize = pagesize;
   487       if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {
   487       if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {
   488         const int en = errno;
   488         const int en = errno;
   489         ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
   489         ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
   490         trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%n",
   490         trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%d", errno);
   491           errno);
       
   492       } else {
   491       } else {
   493         // Attach and double check pageisze.
   492         // Attach and double check pageisze.
   494         void* p = ::shmat(shmid, NULL, 0);
   493         void* p = ::shmat(shmid, NULL, 0);
   495         ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
   494         ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
   496         guarantee0(p != (void*) -1); // Should always work.
   495         guarantee0(p != (void*) -1); // Should always work.
   497         const size_t real_pagesize = os::Aix::query_pagesize(p);
   496         const size_t real_pagesize = os::Aix::query_pagesize(p);
   498         if (real_pagesize != pagesize) {
   497         if (real_pagesize != pagesize) {
   499           trcVerbose("real page size (0x%llX) differs.", real_pagesize);
   498           trcVerbose("real page size (" SIZE_FORMAT_HEX ") differs.", real_pagesize);
   500         } else {
   499         } else {
   501           can_use = true;
   500           can_use = true;
   502         }
   501         }
   503         ::shmdt(p);
   502         ::shmdt(p);
   504       }
   503       }
  1886   // also check that range is fully page aligned to the page size if the block.
  1885   // also check that range is fully page aligned to the page size if the block.
  1887   void assert_is_valid_subrange(char* p, size_t s) const {
  1886   void assert_is_valid_subrange(char* p, size_t s) const {
  1888     if (!contains_range(p, s)) {
  1887     if (!contains_range(p, s)) {
  1889       trcVerbose("[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "
  1888       trcVerbose("[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "
  1890               "range of [" PTR_FORMAT " - " PTR_FORMAT "].",
  1889               "range of [" PTR_FORMAT " - " PTR_FORMAT "].",
  1891               p, p + s, addr, addr + size);
  1890               p2i(p), p2i(p + s), p2i(addr), p2i(addr + size));
  1892       guarantee0(false);
  1891       guarantee0(false);
  1893     }
  1892     }
  1894     if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {
  1893     if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {
  1895       trcVerbose("range [" PTR_FORMAT " - " PTR_FORMAT "] is not"
  1894       trcVerbose("range [" PTR_FORMAT " - " PTR_FORMAT "] is not"
  1896               " aligned to pagesize (%lu)", p, p + s, (unsigned long) pagesize);
  1895               " aligned to pagesize (%lu)", p2i(p), p2i(p + s), (unsigned long) pagesize);
  1897       guarantee0(false);
  1896       guarantee0(false);
  1898     }
  1897     }
  1899   }
  1898   }
  1900 };
  1899 };
  1901 
  1900 
  1962   char* requested_addr,
  1961   char* requested_addr,
  1963   size_t alignment_hint) {
  1962   size_t alignment_hint) {
  1964 
  1963 
  1965   trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "
  1964   trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "
  1966     PTR_FORMAT ", alignment_hint " UINTX_FORMAT "...",
  1965     PTR_FORMAT ", alignment_hint " UINTX_FORMAT "...",
  1967     bytes, requested_addr, alignment_hint);
  1966     bytes, p2i(requested_addr), alignment_hint);
  1968 
  1967 
  1969   // Either give me wish address or wish alignment but not both.
  1968   // Either give me wish address or wish alignment but not both.
  1970   assert0(!(requested_addr != NULL && alignment_hint != 0));
  1969   assert0(!(requested_addr != NULL && alignment_hint != 0));
  1971 
  1970 
  1972   // We must prevent anyone from attaching too close to the
  1971   // We must prevent anyone from attaching too close to the
  1973   // BRK because that may cause malloc OOM.
  1972   // BRK because that may cause malloc OOM.
  1974   if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
  1973   if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
  1975     trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
  1974     trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
  1976       "Will attach anywhere.", requested_addr);
  1975       "Will attach anywhere.", p2i(requested_addr));
  1977     // Act like the OS refused to attach there.
  1976     // Act like the OS refused to attach there.
  1978     requested_addr = NULL;
  1977     requested_addr = NULL;
  1979   }
  1978   }
  1980 
  1979 
  1981   // For old AS/400's (V5R4 and older) we should not even be here - System V shared memory is not
  1980   // For old AS/400's (V5R4 and older) we should not even be here - System V shared memory is not
  2023     assert(false, "failed to remove shared memory segment!");
  2022     assert(false, "failed to remove shared memory segment!");
  2024   }
  2023   }
  2025 
  2024 
  2026   // Handle shmat error. If we failed to attach, just return.
  2025   // Handle shmat error. If we failed to attach, just return.
  2027   if (addr == (char*)-1) {
  2026   if (addr == (char*)-1) {
  2028     trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", requested_addr, errno_shmat);
  2027     trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", p2i(requested_addr), errno_shmat);
  2029     return NULL;
  2028     return NULL;
  2030   }
  2029   }
  2031 
  2030 
  2032   // Just for info: query the real page size. In case setting the page size did not
  2031   // Just for info: query the real page size. In case setting the page size did not
  2033   // work (see above), the system may have given us something other then 4K (LDR_CNTRL).
  2032   // work (see above), the system may have given us something other then 4K (LDR_CNTRL).
  2034   const size_t real_pagesize = os::Aix::query_pagesize(addr);
  2033   const size_t real_pagesize = os::Aix::query_pagesize(addr);
  2035   if (real_pagesize != shmbuf.shm_pagesize) {
  2034   if (real_pagesize != shmbuf.shm_pagesize) {
  2036     trcVerbose("pagesize is, surprisingly, %h.", real_pagesize);
  2035     trcVerbose("pagesize is, surprisingly, " SIZE_FORMAT, real_pagesize);
  2037   }
  2036   }
  2038 
  2037 
  2039   if (addr) {
  2038   if (addr) {
  2040     trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",
  2039     trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",
  2041       addr, addr + size - 1, size, size/real_pagesize, describe_pagesize(real_pagesize));
  2040       p2i(addr), p2i(addr + size - 1), size, size/real_pagesize, describe_pagesize(real_pagesize));
  2042   } else {
  2041   } else {
  2043     if (requested_addr != NULL) {
  2042     if (requested_addr != NULL) {
  2044       trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, requested_addr);
  2043       trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, p2i(requested_addr));
  2045     } else {
  2044     } else {
  2046       trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);
  2045       trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);
  2047     }
  2046     }
  2048   }
  2047   }
  2049 
  2048 
  2055 }
  2054 }
  2056 
  2055 
  2057 static bool release_shmated_memory(char* addr, size_t size) {
  2056 static bool release_shmated_memory(char* addr, size_t size) {
  2058 
  2057 
  2059   trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2058   trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2060     addr, addr + size - 1);
  2059     p2i(addr), p2i(addr + size - 1));
  2061 
  2060 
  2062   bool rc = false;
  2061   bool rc = false;
  2063 
  2062 
  2064   // TODO: is there a way to verify shm size without doing bookkeeping?
  2063   // TODO: is there a way to verify shm size without doing bookkeeping?
  2065   if (::shmdt(addr) != 0) {
  2064   if (::shmdt(addr) != 0) {
  2071   return rc;
  2070   return rc;
  2072 }
  2071 }
  2073 
  2072 
  2074 static bool uncommit_shmated_memory(char* addr, size_t size) {
  2073 static bool uncommit_shmated_memory(char* addr, size_t size) {
  2075   trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2074   trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2076     addr, addr + size - 1);
  2075     p2i(addr), p2i(addr + size - 1));
  2077 
  2076 
  2078   const bool rc = my_disclaim64(addr, size);
  2077   const bool rc = my_disclaim64(addr, size);
  2079 
  2078 
  2080   if (!rc) {
  2079   if (!rc) {
  2081     trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", addr, size);
  2080     trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", p2i(addr), size);
  2082     return false;
  2081     return false;
  2083   }
  2082   }
  2084   return true;
  2083   return true;
  2085 }
  2084 }
  2086 
  2085 
  2093 // allocate at an address aligned with the given alignment. Failing that, memory
  2092 // allocate at an address aligned with the given alignment. Failing that, memory
  2094 // is aligned anywhere.
  2093 // is aligned anywhere.
  2095 static char* reserve_mmaped_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
  2094 static char* reserve_mmaped_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
  2096   trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT ", "
  2095   trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT ", "
  2097     "alignment_hint " UINTX_FORMAT "...",
  2096     "alignment_hint " UINTX_FORMAT "...",
  2098     bytes, requested_addr, alignment_hint);
  2097     bytes, p2i(requested_addr), alignment_hint);
  2099 
  2098 
  2100   // If a wish address is given, but not aligned to 4K page boundary, mmap will fail.
  2099   // If a wish address is given, but not aligned to 4K page boundary, mmap will fail.
  2101   if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {
  2100   if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {
  2102     trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", requested_addr);
  2101     trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", p2i(requested_addr));
  2103     return NULL;
  2102     return NULL;
  2104   }
  2103   }
  2105 
  2104 
  2106   // We must prevent anyone from attaching too close to the
  2105   // We must prevent anyone from attaching too close to the
  2107   // BRK because that may cause malloc OOM.
  2106   // BRK because that may cause malloc OOM.
  2108   if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
  2107   if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
  2109     trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
  2108     trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
  2110       "Will attach anywhere.", requested_addr);
  2109       "Will attach anywhere.", p2i(requested_addr));
  2111     // Act like the OS refused to attach there.
  2110     // Act like the OS refused to attach there.
  2112     requested_addr = NULL;
  2111     requested_addr = NULL;
  2113   }
  2112   }
  2114 
  2113 
  2115   // Specify one or the other but not both.
  2114   // Specify one or the other but not both.
  2152 
  2151 
  2153   char* addr = (char*)::mmap(requested_addr, extra_size,
  2152   char* addr = (char*)::mmap(requested_addr, extra_size,
  2154       PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
  2153       PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
  2155 
  2154 
  2156   if (addr == MAP_FAILED) {
  2155   if (addr == MAP_FAILED) {
  2157     trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", requested_addr, size, errno);
  2156     trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", p2i(requested_addr), size, errno);
  2158     return NULL;
  2157     return NULL;
  2159   }
  2158   }
  2160 
  2159 
  2161   // Handle alignment.
  2160   // Handle alignment.
  2162   char* const addr_aligned = align_up(addr, alignment_hint);
  2161   char* const addr_aligned = align_up(addr, alignment_hint);
  2171   }
  2170   }
  2172   addr = addr_aligned;
  2171   addr = addr_aligned;
  2173 
  2172 
  2174   if (addr) {
  2173   if (addr) {
  2175     trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",
  2174     trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",
  2176       addr, addr + bytes, bytes);
  2175       p2i(addr), p2i(addr + bytes), bytes);
  2177   } else {
  2176   } else {
  2178     if (requested_addr != NULL) {
  2177     if (requested_addr != NULL) {
  2179       trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at wish address " PTR_FORMAT ".", bytes, requested_addr);
  2178       trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at wish address " PTR_FORMAT ".", bytes, p2i(requested_addr));
  2180     } else {
  2179     } else {
  2181       trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at any address.", bytes);
  2180       trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at any address.", bytes);
  2182     }
  2181     }
  2183   }
  2182   }
  2184 
  2183 
  2194 static bool release_mmaped_memory(char* addr, size_t size) {
  2193 static bool release_mmaped_memory(char* addr, size_t size) {
  2195   assert0(is_aligned_to(addr, os::vm_page_size()));
  2194   assert0(is_aligned_to(addr, os::vm_page_size()));
  2196   assert0(is_aligned_to(size, os::vm_page_size()));
  2195   assert0(is_aligned_to(size, os::vm_page_size()));
  2197 
  2196 
  2198   trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2197   trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2199     addr, addr + size - 1);
  2198     p2i(addr), p2i(addr + size - 1));
  2200   bool rc = false;
  2199   bool rc = false;
  2201 
  2200 
  2202   if (::munmap(addr, size) != 0) {
  2201   if (::munmap(addr, size) != 0) {
  2203     trcVerbose("failed (%d)\n", errno);
  2202     trcVerbose("failed (%d)\n", errno);
  2204     rc = false;
  2203     rc = false;
  2214 
  2213 
  2215   assert0(is_aligned_to(addr, os::vm_page_size()));
  2214   assert0(is_aligned_to(addr, os::vm_page_size()));
  2216   assert0(is_aligned_to(size, os::vm_page_size()));
  2215   assert0(is_aligned_to(size, os::vm_page_size()));
  2217 
  2216 
  2218   trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2217   trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
  2219     addr, addr + size - 1);
  2218     p2i(addr), p2i(addr + size - 1));
  2220   bool rc = false;
  2219   bool rc = false;
  2221 
  2220 
  2222   // Uncommit mmap memory with msync MS_INVALIDATE.
  2221   // Uncommit mmap memory with msync MS_INVALIDATE.
  2223   if (::msync(addr, size, MS_INVALIDATE) != 0) {
  2222   if (::msync(addr, size, MS_INVALIDATE) != 0) {
  2224     trcVerbose("failed (%d)\n", errno);
  2223     trcVerbose("failed (%d)\n", errno);
  2245 
  2244 
  2246 #ifdef PRODUCT
  2245 #ifdef PRODUCT
  2247 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
  2246 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
  2248                                     int err) {
  2247                                     int err) {
  2249   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
  2248   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
  2250           ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
  2249           ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,
  2251           os::errno_name(err), err);
  2250           os::errno_name(err), err);
  2252 }
  2251 }
  2253 #endif
  2252 #endif
  2254 
  2253 
  2255 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
  2254 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
  2273 
  2272 
  2274   vmembk_t* const vmi = vmembk_find(addr);
  2273   vmembk_t* const vmi = vmembk_find(addr);
  2275   guarantee0(vmi);
  2274   guarantee0(vmi);
  2276   vmi->assert_is_valid_subrange(addr, size);
  2275   vmi->assert_is_valid_subrange(addr, size);
  2277 
  2276 
  2278   trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", addr, addr + size - 1);
  2277   trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", p2i(addr), p2i(addr + size - 1));
  2279 
  2278 
  2280   if (UseExplicitCommit) {
  2279   if (UseExplicitCommit) {
  2281     // AIX commits memory on touch. So, touch all pages to be committed.
  2280     // AIX commits memory on touch. So, touch all pages to be committed.
  2282     for (char* p = addr; p < (addr + size); p += 4*K) {
  2281     for (char* p = addr; p < (addr + size); p += 4*K) {
  2283       *p = '\0';
  2282       *p = '\0';