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'; |