< prev index next >

src/share/vm/runtime/os.cpp

Print this page
rev 7526 : 8066875: VirtualSpace does not use large pages (01)


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
< prev index next >