Mercurial > hg > truffle
comparison src/os/linux/vm/os_linux.cpp @ 11173:6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 31 Jul 2013 11:00:54 +0200 |
parents | 836a62f43af9 59b052799158 |
children | cefad50507d8 |
comparison
equal
deleted
inserted
replaced
10912:4ea54634f03e | 11173:6b0fd0964b87 |
---|---|
1680 bool os::address_is_in_vm(address addr) { | 1680 bool os::address_is_in_vm(address addr) { |
1681 static address libjvm_base_addr; | 1681 static address libjvm_base_addr; |
1682 Dl_info dlinfo; | 1682 Dl_info dlinfo; |
1683 | 1683 |
1684 if (libjvm_base_addr == NULL) { | 1684 if (libjvm_base_addr == NULL) { |
1685 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); | 1685 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { |
1686 libjvm_base_addr = (address)dlinfo.dli_fbase; | 1686 libjvm_base_addr = (address)dlinfo.dli_fbase; |
1687 } | |
1687 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); | 1688 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); |
1688 } | 1689 } |
1689 | 1690 |
1690 if (dladdr((void *)addr, &dlinfo)) { | 1691 if (dladdr((void *)addr, &dlinfo) != 0) { |
1691 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; | 1692 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; |
1692 } | 1693 } |
1693 | 1694 |
1694 return false; | 1695 return false; |
1695 } | 1696 } |
1696 | 1697 |
1697 bool os::dll_address_to_function_name(address addr, char *buf, | 1698 bool os::dll_address_to_function_name(address addr, char *buf, |
1698 int buflen, int *offset) { | 1699 int buflen, int *offset) { |
1700 // buf is not optional, but offset is optional | |
1701 assert(buf != NULL, "sanity check"); | |
1702 | |
1699 Dl_info dlinfo; | 1703 Dl_info dlinfo; |
1700 | 1704 |
1701 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { | 1705 if (dladdr((void*)addr, &dlinfo) != 0) { |
1702 if (buf != NULL) { | 1706 // see if we have a matching symbol |
1703 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { | 1707 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { |
1708 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { | |
1704 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); | 1709 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); |
1705 } | 1710 } |
1706 } | 1711 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; |
1707 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; | 1712 return true; |
1708 return true; | 1713 } |
1709 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { | 1714 // no matching symbol so try for just file info |
1710 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), | 1715 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { |
1711 buf, buflen, offset, dlinfo.dli_fname)) { | 1716 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), |
1712 return true; | 1717 buf, buflen, offset, dlinfo.dli_fname)) { |
1713 } | 1718 return true; |
1714 } | 1719 } |
1715 | 1720 } |
1716 if (buf != NULL) buf[0] = '\0'; | 1721 } |
1722 | |
1723 buf[0] = '\0'; | |
1717 if (offset != NULL) *offset = -1; | 1724 if (offset != NULL) *offset = -1; |
1718 return false; | 1725 return false; |
1719 } | 1726 } |
1720 | 1727 |
1721 struct _address_to_library_name { | 1728 struct _address_to_library_name { |
1762 return 0; | 1769 return 0; |
1763 } | 1770 } |
1764 | 1771 |
1765 bool os::dll_address_to_library_name(address addr, char* buf, | 1772 bool os::dll_address_to_library_name(address addr, char* buf, |
1766 int buflen, int* offset) { | 1773 int buflen, int* offset) { |
1774 // buf is not optional, but offset is optional | |
1775 assert(buf != NULL, "sanity check"); | |
1776 | |
1767 Dl_info dlinfo; | 1777 Dl_info dlinfo; |
1768 struct _address_to_library_name data; | 1778 struct _address_to_library_name data; |
1769 | 1779 |
1770 // There is a bug in old glibc dladdr() implementation that it could resolve | 1780 // There is a bug in old glibc dladdr() implementation that it could resolve |
1771 // to wrong library name if the .so file has a base address != NULL. Here | 1781 // to wrong library name if the .so file has a base address != NULL. Here |
1780 | 1790 |
1781 if (rslt) { | 1791 if (rslt) { |
1782 // buf already contains library name | 1792 // buf already contains library name |
1783 if (offset) *offset = addr - data.base; | 1793 if (offset) *offset = addr - data.base; |
1784 return true; | 1794 return true; |
1785 } else if (dladdr((void*)addr, &dlinfo)){ | 1795 } |
1786 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); | 1796 if (dladdr((void*)addr, &dlinfo) != 0) { |
1787 if (offset) *offset = addr - (address)dlinfo.dli_fbase; | 1797 if (dlinfo.dli_fname != NULL) { |
1788 return true; | 1798 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); |
1789 } else { | 1799 } |
1790 if (buf) buf[0] = '\0'; | 1800 if (dlinfo.dli_fbase != NULL && offset != NULL) { |
1791 if (offset) *offset = -1; | 1801 *offset = addr - (address)dlinfo.dli_fbase; |
1792 return false; | 1802 } |
1793 } | 1803 return true; |
1804 } | |
1805 | |
1806 buf[0] = '\0'; | |
1807 if (offset) *offset = -1; | |
1808 return false; | |
1794 } | 1809 } |
1795 | 1810 |
1796 // Loads .dll/.so and | 1811 // Loads .dll/.so and |
1797 // in case of error it checks if .dll/.so was built for the | 1812 // in case of error it checks if .dll/.so was built for the |
1798 // same architecture as Hotspot is running on | 1813 // same architecture as Hotspot is running on |
2315 | 2330 |
2316 char dli_fname[MAXPATHLEN]; | 2331 char dli_fname[MAXPATHLEN]; |
2317 bool ret = dll_address_to_library_name( | 2332 bool ret = dll_address_to_library_name( |
2318 CAST_FROM_FN_PTR(address, os::jvm_path), | 2333 CAST_FROM_FN_PTR(address, os::jvm_path), |
2319 dli_fname, sizeof(dli_fname), NULL); | 2334 dli_fname, sizeof(dli_fname), NULL); |
2320 assert(ret != 0, "cannot locate libjvm"); | 2335 assert(ret, "cannot locate libjvm"); |
2321 char *rp = realpath(dli_fname, buf); | 2336 char *rp = NULL; |
2337 if (ret && dli_fname[0] != '\0') { | |
2338 rp = realpath(dli_fname, buf); | |
2339 } | |
2322 if (rp == NULL) | 2340 if (rp == NULL) |
2323 return; | 2341 return; |
2324 | 2342 |
2325 if (Arguments::created_by_gamma_launcher()) { | 2343 if (Arguments::created_by_gamma_launcher()) { |
2326 // Support for the gamma launcher. Typical value for buf is | 2344 // Support for the gamma launcher. Typical value for buf is |
2610 ::close(fd); | 2628 ::close(fd); |
2611 unlink(buf); | 2629 unlink(buf); |
2612 } | 2630 } |
2613 } | 2631 } |
2614 | 2632 |
2633 static bool recoverable_mmap_error(int err) { | |
2634 // See if the error is one we can let the caller handle. This | |
2635 // list of errno values comes from JBS-6843484. I can't find a | |
2636 // Linux man page that documents this specific set of errno | |
2637 // values so while this list currently matches Solaris, it may | |
2638 // change as we gain experience with this failure mode. | |
2639 switch (err) { | |
2640 case EBADF: | |
2641 case EINVAL: | |
2642 case ENOTSUP: | |
2643 // let the caller deal with these errors | |
2644 return true; | |
2645 | |
2646 default: | |
2647 // Any remaining errors on this OS can cause our reserved mapping | |
2648 // to be lost. That can cause confusion where different data | |
2649 // structures think they have the same memory mapped. The worst | |
2650 // scenario is if both the VM and a library think they have the | |
2651 // same memory mapped. | |
2652 return false; | |
2653 } | |
2654 } | |
2655 | |
2656 static void warn_fail_commit_memory(char* addr, size_t size, bool exec, | |
2657 int err) { | |
2658 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT | |
2659 ", %d) failed; error='%s' (errno=%d)", addr, size, exec, | |
2660 strerror(err), err); | |
2661 } | |
2662 | |
2663 static void warn_fail_commit_memory(char* addr, size_t size, | |
2664 size_t alignment_hint, bool exec, | |
2665 int err) { | |
2666 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT | |
2667 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size, | |
2668 alignment_hint, exec, strerror(err), err); | |
2669 } | |
2670 | |
2615 // NOTE: Linux kernel does not really reserve the pages for us. | 2671 // NOTE: Linux kernel does not really reserve the pages for us. |
2616 // All it does is to check if there are enough free pages | 2672 // All it does is to check if there are enough free pages |
2617 // left at the time of mmap(). This could be a potential | 2673 // left at the time of mmap(). This could be a potential |
2618 // problem. | 2674 // problem. |
2619 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { | 2675 int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) { |
2620 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | 2676 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2621 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | 2677 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, |
2622 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); | 2678 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); |
2623 if (res != (uintptr_t) MAP_FAILED) { | 2679 if (res != (uintptr_t) MAP_FAILED) { |
2624 if (UseNUMAInterleaving) { | 2680 if (UseNUMAInterleaving) { |
2625 numa_make_global(addr, size); | 2681 numa_make_global(addr, size); |
2626 } | 2682 } |
2627 return true; | 2683 return 0; |
2628 } | 2684 } |
2629 return false; | 2685 |
2686 int err = errno; // save errno from mmap() call above | |
2687 | |
2688 if (!recoverable_mmap_error(err)) { | |
2689 warn_fail_commit_memory(addr, size, exec, err); | |
2690 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory."); | |
2691 } | |
2692 | |
2693 return err; | |
2694 } | |
2695 | |
2696 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { | |
2697 return os::Linux::commit_memory_impl(addr, size, exec) == 0; | |
2698 } | |
2699 | |
2700 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, | |
2701 const char* mesg) { | |
2702 assert(mesg != NULL, "mesg must be specified"); | |
2703 int err = os::Linux::commit_memory_impl(addr, size, exec); | |
2704 if (err != 0) { | |
2705 // the caller wants all commit errors to exit with the specified mesg: | |
2706 warn_fail_commit_memory(addr, size, exec, err); | |
2707 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg); | |
2708 } | |
2630 } | 2709 } |
2631 | 2710 |
2632 // Define MAP_HUGETLB here so we can build HotSpot on old systems. | 2711 // Define MAP_HUGETLB here so we can build HotSpot on old systems. |
2633 #ifndef MAP_HUGETLB | 2712 #ifndef MAP_HUGETLB |
2634 #define MAP_HUGETLB 0x40000 | 2713 #define MAP_HUGETLB 0x40000 |
2637 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. | 2716 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. |
2638 #ifndef MADV_HUGEPAGE | 2717 #ifndef MADV_HUGEPAGE |
2639 #define MADV_HUGEPAGE 14 | 2718 #define MADV_HUGEPAGE 14 |
2640 #endif | 2719 #endif |
2641 | 2720 |
2642 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, | 2721 int os::Linux::commit_memory_impl(char* addr, size_t size, |
2643 bool exec) { | 2722 size_t alignment_hint, bool exec) { |
2723 int err; | |
2644 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { | 2724 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { |
2645 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | 2725 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2646 uintptr_t res = | 2726 uintptr_t res = |
2647 (uintptr_t) ::mmap(addr, size, prot, | 2727 (uintptr_t) ::mmap(addr, size, prot, |
2648 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, | 2728 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, |
2649 -1, 0); | 2729 -1, 0); |
2650 if (res != (uintptr_t) MAP_FAILED) { | 2730 if (res != (uintptr_t) MAP_FAILED) { |
2651 if (UseNUMAInterleaving) { | 2731 if (UseNUMAInterleaving) { |
2652 numa_make_global(addr, size); | 2732 numa_make_global(addr, size); |
2653 } | 2733 } |
2654 return true; | 2734 return 0; |
2735 } | |
2736 | |
2737 err = errno; // save errno from mmap() call above | |
2738 | |
2739 if (!recoverable_mmap_error(err)) { | |
2740 // However, it is not clear that this loss of our reserved mapping | |
2741 // happens with large pages on Linux or that we cannot recover | |
2742 // from the loss. For now, we just issue a warning and we don't | |
2743 // call vm_exit_out_of_memory(). This issue is being tracked by | |
2744 // JBS-8007074. | |
2745 warn_fail_commit_memory(addr, size, alignment_hint, exec, err); | |
2746 // vm_exit_out_of_memory(size, OOM_MMAP_ERROR, | |
2747 // "committing reserved memory."); | |
2655 } | 2748 } |
2656 // Fall through and try to use small pages | 2749 // Fall through and try to use small pages |
2657 } | 2750 } |
2658 | 2751 |
2659 if (commit_memory(addr, size, exec)) { | 2752 err = os::Linux::commit_memory_impl(addr, size, exec); |
2753 if (err == 0) { | |
2660 realign_memory(addr, size, alignment_hint); | 2754 realign_memory(addr, size, alignment_hint); |
2661 return true; | 2755 } |
2662 } | 2756 return err; |
2663 return false; | 2757 } |
2758 | |
2759 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, | |
2760 bool exec) { | |
2761 return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0; | |
2762 } | |
2763 | |
2764 void os::pd_commit_memory_or_exit(char* addr, size_t size, | |
2765 size_t alignment_hint, bool exec, | |
2766 const char* mesg) { | |
2767 assert(mesg != NULL, "mesg must be specified"); | |
2768 int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec); | |
2769 if (err != 0) { | |
2770 // the caller wants all commit errors to exit with the specified mesg: | |
2771 warn_fail_commit_memory(addr, size, alignment_hint, exec, err); | |
2772 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg); | |
2773 } | |
2664 } | 2774 } |
2665 | 2775 |
2666 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { | 2776 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
2667 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { | 2777 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { |
2668 // We don't check the return value: madvise(MADV_HUGEPAGE) may not | 2778 // We don't check the return value: madvise(MADV_HUGEPAGE) may not |
2676 // the existing pages. However it won't work for SHM-based large pages that cannot be | 2786 // the existing pages. However it won't work for SHM-based large pages that cannot be |
2677 // uncommitted at all. We don't do anything in this case to avoid creating a segment with | 2787 // uncommitted at all. We don't do anything in this case to avoid creating a segment with |
2678 // small pages on top of the SHM segment. This method always works for small pages, so we | 2788 // small pages on top of the SHM segment. This method always works for small pages, so we |
2679 // allow that in any case. | 2789 // allow that in any case. |
2680 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) { | 2790 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) { |
2681 commit_memory(addr, bytes, alignment_hint, false); | 2791 commit_memory(addr, bytes, alignment_hint, !ExecMem); |
2682 } | 2792 } |
2683 } | 2793 } |
2684 | 2794 |
2685 void os::numa_make_global(char *addr, size_t bytes) { | 2795 void os::numa_make_global(char *addr, size_t bytes) { |
2686 Linux::numa_interleave_memory(addr, bytes); | 2796 Linux::numa_interleave_memory(addr, bytes); |
2929 "growable stack in non-initial thread"); | 3039 "growable stack in non-initial thread"); |
2930 if (stack_extent < (uintptr_t)addr) | 3040 if (stack_extent < (uintptr_t)addr) |
2931 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); | 3041 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); |
2932 } | 3042 } |
2933 | 3043 |
2934 return os::commit_memory(addr, size); | 3044 return os::commit_memory(addr, size, !ExecMem); |
2935 } | 3045 } |
2936 | 3046 |
2937 // If this is a growable mapping, remove the guard pages entirely by | 3047 // If this is a growable mapping, remove the guard pages entirely by |
2938 // munmap()ping them. If not, just call uncommit_memory(). This only | 3048 // munmap()ping them. If not, just call uncommit_memory(). This only |
2939 // affects the main/initial thread, but guard against future OS changes | 3049 // affects the main/initial thread, but guard against future OS changes |
3051 bool result = false; | 3161 bool result = false; |
3052 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, | 3162 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, |
3053 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, | 3163 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, |
3054 -1, 0); | 3164 -1, 0); |
3055 | 3165 |
3056 if (p != (void *) -1) { | 3166 if (p != MAP_FAILED) { |
3057 // We don't know if this really is a huge page or not. | 3167 // We don't know if this really is a huge page or not. |
3058 FILE *fp = fopen("/proc/self/maps", "r"); | 3168 FILE *fp = fopen("/proc/self/maps", "r"); |
3059 if (fp) { | 3169 if (fp) { |
3060 while (!feof(fp)) { | 3170 while (!feof(fp)) { |
3061 char chars[257]; | 3171 char chars[257]; |
3269 if ((addr != NULL) && UseNUMAInterleaving) { | 3379 if ((addr != NULL) && UseNUMAInterleaving) { |
3270 numa_make_global(addr, bytes); | 3380 numa_make_global(addr, bytes); |
3271 } | 3381 } |
3272 | 3382 |
3273 // The memory is committed | 3383 // The memory is committed |
3274 address pc = CALLER_PC; | 3384 MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC); |
3275 MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); | |
3276 MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); | |
3277 | 3385 |
3278 return addr; | 3386 return addr; |
3279 } | 3387 } |
3280 | 3388 |
3281 bool os::release_memory_special(char* base, size_t bytes) { | 3389 bool os::release_memory_special(char* base, size_t bytes) { |
3390 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); | |
3282 // detaching the SHM segment will also delete it, see reserve_memory_special() | 3391 // detaching the SHM segment will also delete it, see reserve_memory_special() |
3283 int rslt = shmdt(base); | 3392 int rslt = shmdt(base); |
3284 if (rslt == 0) { | 3393 if (rslt == 0) { |
3285 MemTracker::record_virtual_memory_uncommit((address)base, bytes); | 3394 tkr.record((address)base, bytes); |
3286 MemTracker::record_virtual_memory_release((address)base, bytes); | |
3287 return true; | 3395 return true; |
3288 } else { | 3396 } else { |
3289 return false; | 3397 tkr.discard(); |
3398 return false; | |
3290 } | 3399 } |
3291 } | 3400 } |
3292 | 3401 |
3293 size_t os::large_page_size() { | 3402 size_t os::large_page_size() { |
3294 return _large_page_size; | 3403 return _large_page_size; |
4391 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); | 4500 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); |
4392 #endif | 4501 #endif |
4393 | 4502 |
4394 if (!UseMembar) { | 4503 if (!UseMembar) { |
4395 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | 4504 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); |
4396 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); | 4505 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page"); |
4397 os::set_memory_serialize_page( mem_serialize_page ); | 4506 os::set_memory_serialize_page( mem_serialize_page ); |
4398 | 4507 |
4399 #ifndef PRODUCT | 4508 #ifndef PRODUCT |
4400 if(Verbose && PrintMiscellaneous) | 4509 if(Verbose && PrintMiscellaneous) |
4401 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); | 4510 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); |
4637 // debug support | 4746 // debug support |
4638 | 4747 |
4639 bool os::find(address addr, outputStream* st) { | 4748 bool os::find(address addr, outputStream* st) { |
4640 Dl_info dlinfo; | 4749 Dl_info dlinfo; |
4641 memset(&dlinfo, 0, sizeof(dlinfo)); | 4750 memset(&dlinfo, 0, sizeof(dlinfo)); |
4642 if (dladdr(addr, &dlinfo)) { | 4751 if (dladdr(addr, &dlinfo) != 0) { |
4643 st->print(PTR_FORMAT ": ", addr); | 4752 st->print(PTR_FORMAT ": ", addr); |
4644 if (dlinfo.dli_sname != NULL) { | 4753 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { |
4645 st->print("%s+%#x", dlinfo.dli_sname, | 4754 st->print("%s+%#x", dlinfo.dli_sname, |
4646 addr - (intptr_t)dlinfo.dli_saddr); | 4755 addr - (intptr_t)dlinfo.dli_saddr); |
4647 } else if (dlinfo.dli_fname) { | 4756 } else if (dlinfo.dli_fbase != NULL) { |
4648 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); | 4757 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); |
4649 } else { | 4758 } else { |
4650 st->print("<absolute address>"); | 4759 st->print("<absolute address>"); |
4651 } | 4760 } |
4652 if (dlinfo.dli_fname) { | 4761 if (dlinfo.dli_fname != NULL) { |
4653 st->print(" in %s", dlinfo.dli_fname); | 4762 st->print(" in %s", dlinfo.dli_fname); |
4654 } | 4763 } |
4655 if (dlinfo.dli_fbase) { | 4764 if (dlinfo.dli_fbase != NULL) { |
4656 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); | 4765 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); |
4657 } | 4766 } |
4658 st->cr(); | 4767 st->cr(); |
4659 | 4768 |
4660 if (Verbose) { | 4769 if (Verbose) { |
4663 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); | 4772 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); |
4664 address lowest = (address) dlinfo.dli_sname; | 4773 address lowest = (address) dlinfo.dli_sname; |
4665 if (!lowest) lowest = (address) dlinfo.dli_fbase; | 4774 if (!lowest) lowest = (address) dlinfo.dli_fbase; |
4666 if (begin < lowest) begin = lowest; | 4775 if (begin < lowest) begin = lowest; |
4667 Dl_info dlinfo2; | 4776 Dl_info dlinfo2; |
4668 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr | 4777 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr |
4669 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) | 4778 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) |
4670 end = (address) dlinfo2.dli_saddr; | 4779 end = (address) dlinfo2.dli_saddr; |
4671 Disassembler::decode(begin, end, st); | 4780 Disassembler::decode(begin, end, st); |
4672 } | 4781 } |
4673 return true; | 4782 return true; |