1382 // Returns true if the current stack pointer is above the stack shadow
1383 // pages, false otherwise.
1384
1385 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
1386 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
1387 address sp = current_stack_pointer();
1388 // Check if we have StackShadowPages above the yellow zone. This parameter
1389 // is dependent on the depth of the maximum VM call stack possible from
1390 // the handler for stack overflow. 'instanceof' in the stack overflow
1391 // handler or a println uses at least 8k stack of VM and native code
1392 // respectively.
1393 const int framesize_in_bytes =
1394 Interpreter::size_top_interpreter_activation(method()) * wordSize;
1395 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
1396 * vm_page_size()) + framesize_in_bytes;
1397 // The very lower end of the stack
1398 address stack_limit = thread->stack_base() - thread->stack_size();
1399 return (sp > (stack_limit + reserved_area));
1400 }
1401
1402 size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
1403 assert(min_pages > 0, "sanity");
1404 if (UseLargePages) {
1405 const size_t max_page_size = region_size / min_pages;
1406
1407 for (size_t i = 0; _page_sizes[i] != 0; ++i) {
1408 const size_t page_size = _page_sizes[i];
1409 if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
1410 return page_size;
1411 }
1412 }
1413 }
1414
1415 return vm_page_size();
1416 }
1417
1418 size_t os::largest_page_size_less_than(size_t sz) {
1419 if (UseLargePages) {
1420 // The page sizes are sorted descendingly.
1421 for (size_t i = 0; _page_sizes[i] != 0; ++i) {
1422 if (_page_sizes[i] <= sz) {
1423 return _page_sizes[i];
1424 }
1425 }
1426 }
1427 return vm_page_size();
1428 }
1429
1430 #ifndef PRODUCT
1431 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
1432 {
1433 if (TracePageSizes) {
1434 tty->print("%s: ", str);
1435 for (int i = 0; i < count; ++i) {
1436 tty->print(" " SIZE_FORMAT, page_sizes[i]);
1437 }
1438 tty->cr();
1439 }
1440 }
1441
1442 void os::trace_page_sizes(const char* str, const size_t region_min_size,
1443 const size_t region_max_size, const size_t page_size,
1444 const char* base, const size_t size)
1445 {
1446 if (TracePageSizes) {
1447 tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT
1653 // success
1654 return to;
1655 }
1656 return result;
1657 }
1658 #endif
1659
1660 /////////////// Unit tests ///////////////
1661
1662 #ifndef PRODUCT
1663
1664 #define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
1665
1666 class TestOS : AllStatic {
1667 static size_t small_page_size() {
1668 return os::vm_page_size();
1669 }
1670
1671 static size_t large_page_size() {
1672 const size_t large_page_size_example = 4 * M;
1673 return os::page_size_for_region(large_page_size_example, 1);
1674 }
1675
1676 static void test_page_size_for_region() {
1677 if (UseLargePages) {
1678 const size_t small_page = small_page_size();
1679 const size_t large_page = large_page_size();
1680
1681 if (large_page > small_page) {
1682 size_t num_small_pages_in_large = large_page / small_page;
1683 size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
1684
1685 assert_eq(page, small_page);
1686 }
1687 }
1688 }
1689
1690 static void test_page_size_for_region_alignment() {
1691 if (UseLargePages) {
1692 const size_t small_page = small_page_size();
1693 const size_t large_page = large_page_size();
1694 if (large_page > small_page) {
1695 const size_t unaligned_region = large_page + 17;
1696 size_t page = os::page_size_for_region(unaligned_region, 1);
1697 assert_eq(page, small_page);
1698
1699 const size_t num_pages = 5;
1700 const size_t aligned_region = large_page * num_pages;
1701 page = os::page_size_for_region(aligned_region, num_pages);
1702 assert_eq(page, large_page);
1703 }
1704 }
1705 }
1706
1707 static void test_largest_page_size_less_than() {
1708 if (UseLargePages) {
1709 // Given exact page size, should return that page size
1710 for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
1711 size_t expected = os::_page_sizes[i];
1712 size_t actual = os::largest_page_size_less_than(expected);
1713 assert_eq(expected, actual);
1714 }
1715
1716 // Given slightly larger size than a page size, return the page size
1717 for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
1718 size_t expected = os::_page_sizes[i];
1719 size_t actual = os::largest_page_size_less_than(expected + 17);
1720 assert_eq(expected, actual);
1721 }
1722
1723 // Given a slightly smaller size than a page size,
1724 // return the next smaller page size
1725 if (os::_page_sizes[1] > os::_page_sizes[0]) {
1726 size_t expected = os::_page_sizes[0];
1727 size_t actual = os::largest_page_size_less_than(os::_page_sizes[1] - 17);
1728 assert_eq(actual, expected);
1729 }
1730
1731 // Return small page size for values less than a small page
1732 size_t small_page = small_page_size();
1733 size_t actual = os::largest_page_size_less_than(small_page - 17);
1734 assert_eq(small_page, actual);
1735 }
1736 }
1737
1738 public:
1739 static void run_tests() {
1740 test_page_size_for_region();
1741 test_page_size_for_region_alignment();
1742 test_largest_page_size_less_than();
1743 }
1744 };
1745
1746 void TestOS_test() {
1747 TestOS::run_tests();
1748 }
1749
1750 #endif // PRODUCT
|
1382 // Returns true if the current stack pointer is above the stack shadow
1383 // pages, false otherwise.
1384
1385 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
1386 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
1387 address sp = current_stack_pointer();
1388 // Check if we have StackShadowPages above the yellow zone. This parameter
1389 // is dependent on the depth of the maximum VM call stack possible from
1390 // the handler for stack overflow. 'instanceof' in the stack overflow
1391 // handler or a println uses at least 8k stack of VM and native code
1392 // respectively.
1393 const int framesize_in_bytes =
1394 Interpreter::size_top_interpreter_activation(method()) * wordSize;
1395 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
1396 * vm_page_size()) + framesize_in_bytes;
1397 // The very lower end of the stack
1398 address stack_limit = thread->stack_base() - thread->stack_size();
1399 return (sp > (stack_limit + reserved_area));
1400 }
1401
1402 size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
1403 assert(min_pages > 0, "sanity");
1404 if (UseLargePages) {
1405 const size_t max_page_size = region_size / min_pages;
1406
1407 for (size_t i = 0; _page_sizes[i] != 0; ++i) {
1408 const size_t page_size = _page_sizes[i];
1409 if (page_size <= max_page_size) {
1410 if (!must_be_aligned) {
1411 return page_size;
1412 }
1413 if (is_size_aligned(region_size, page_size)) {
1414 return page_size;
1415 }
1416 }
1417 }
1418 }
1419
1420 return vm_page_size();
1421 }
1422
1423 size_t os::page_size_for_region_aligned(size_t region_size, size_t min_pages) {
1424 return page_size_for_region(region_size, min_pages, true);
1425 }
1426
1427 size_t os::page_size_for_region_unaligned(size_t region_size, size_t min_pages) {
1428 return page_size_for_region(region_size, min_pages, false);
1429 }
1430
1431 #ifndef PRODUCT
1432 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
1433 {
1434 if (TracePageSizes) {
1435 tty->print("%s: ", str);
1436 for (int i = 0; i < count; ++i) {
1437 tty->print(" " SIZE_FORMAT, page_sizes[i]);
1438 }
1439 tty->cr();
1440 }
1441 }
1442
1443 void os::trace_page_sizes(const char* str, const size_t region_min_size,
1444 const size_t region_max_size, const size_t page_size,
1445 const char* base, const size_t size)
1446 {
1447 if (TracePageSizes) {
1448 tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT
1654 // success
1655 return to;
1656 }
1657 return result;
1658 }
1659 #endif
1660
1661 /////////////// Unit tests ///////////////
1662
1663 #ifndef PRODUCT
1664
1665 #define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
1666
1667 class TestOS : AllStatic {
1668 static size_t small_page_size() {
1669 return os::vm_page_size();
1670 }
1671
1672 static size_t large_page_size() {
1673 const size_t large_page_size_example = 4 * M;
1674 return os::page_size_for_region_aligned(large_page_size_example, 1);
1675 }
1676
1677 static void test_page_size_for_region_aligned() {
1678 if (UseLargePages) {
1679 const size_t small_page = small_page_size();
1680 const size_t large_page = large_page_size();
1681
1682 if (large_page > small_page) {
1683 size_t num_small_pages_in_large = large_page / small_page;
1684 size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
1685
1686 assert_eq(page, small_page);
1687 }
1688 }
1689 }
1690
1691 static void test_page_size_for_region_alignment() {
1692 if (UseLargePages) {
1693 const size_t small_page = small_page_size();
1694 const size_t large_page = large_page_size();
1695 if (large_page > small_page) {
1696 const size_t unaligned_region = large_page + 17;
1697 size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
1698 assert_eq(page, small_page);
1699
1700 const size_t num_pages = 5;
1701 const size_t aligned_region = large_page * num_pages;
1702 page = os::page_size_for_region_aligned(aligned_region, num_pages);
1703 assert_eq(page, large_page);
1704 }
1705 }
1706 }
1707
1708 static void test_page_size_for_region_unaligned() {
1709 if (UseLargePages) {
1710 // Given exact page size, should return that page size
1711 for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
1712 size_t expected = os::_page_sizes[i];
1713 size_t actual = os::page_size_for_region_unaligned(expected, 1);
1714 assert_eq(expected, actual);
1715 }
1716
1717 // Given slightly larger size than a page size, return the page size
1718 for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
1719 size_t expected = os::_page_sizes[i];
1720 size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
1721 assert_eq(expected, actual);
1722 }
1723
1724 // Given a slightly smaller size than a page size,
1725 // return the next smaller page size
1726 if (os::_page_sizes[1] > os::_page_sizes[0]) {
1727 size_t expected = os::_page_sizes[0];
1728 size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
1729 assert_eq(actual, expected);
1730 }
1731
1732 // Return small page size for values less than a small page
1733 size_t small_page = small_page_size();
1734 size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
1735 assert_eq(small_page, actual);
1736 }
1737 }
1738
1739 public:
1740 static void run_tests() {
1741 test_page_size_for_region_aligned();
1742 test_page_size_for_region_alignment();
1743 test_page_size_for_region_unaligned();
1744 }
1745 };
1746
1747 void TestOS_test() {
1748 TestOS::run_tests();
1749 }
1750
1751 #endif // PRODUCT
|