1286 // Returns true if the current stack pointer is above the stack shadow
1287 // pages, false otherwise.
1288
1289 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
1290 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
1291 address sp = current_stack_pointer();
1292 // Check if we have StackShadowPages above the yellow zone. This parameter
1293 // is dependent on the depth of the maximum VM call stack possible from
1294 // the handler for stack overflow. 'instanceof' in the stack overflow
1295 // handler or a println uses at least 8k stack of VM and native code
1296 // respectively.
1297 const int framesize_in_bytes =
1298 Interpreter::size_top_interpreter_activation(method()) * wordSize;
1299 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
1300 * vm_page_size()) + framesize_in_bytes;
1301 // The very lower end of the stack
1302 address stack_limit = thread->stack_base() - thread->stack_size();
1303 return (sp > (stack_limit + reserved_area));
1304 }
1305
1306 size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
1307 assert(min_pages > 0, "sanity");
1308 if (UseLargePages) {
1309 const size_t max_page_size = region_size / min_pages;
1310
1311 for (size_t i = 0; _page_sizes[i] != 0; ++i) {
1312 const size_t page_size = _page_sizes[i];
1313 if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
1314 return page_size;
1315 }
1316 }
1317 }
1318
1319 return vm_page_size();
1320 }
1321
1322 #ifndef PRODUCT
1323 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
1324 {
1325 if (TracePageSizes) {
1326 tty->print("%s: ", str);
1327 for (int i = 0; i < count; ++i) {
1328 tty->print(" " SIZE_FORMAT, page_sizes[i]);
1329 }
1330 tty->cr();
1331 }
1332 }
1333
1334 void os::trace_page_sizes(const char* str, const size_t region_min_size,
1522 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
1523 pd_realign_memory(addr, bytes, alignment_hint);
1524 }
1525
1526 #ifndef TARGET_OS_FAMILY_windows
1527 /* try to switch state from state "from" to state "to"
1528 * returns the state set after the method is complete
1529 */
1530 os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
1531 os::SuspendResume::State to)
1532 {
1533 os::SuspendResume::State result =
1534 (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
1535 if (result == from) {
1536 // success
1537 return to;
1538 }
1539 return result;
1540 }
1541 #endif
1542
1543 /////////////// Unit tests ///////////////
1544
1545 #ifndef PRODUCT
1546
1547 #define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
1548
1549 class TestOS : AllStatic {
1550 static size_t small_page_size() {
1551 return os::vm_page_size();
1552 }
1553
1554 static size_t large_page_size() {
1555 const size_t large_page_size_example = 4 * M;
1556 return os::page_size_for_region(large_page_size_example, 1);
1557 }
1558
1559 static void test_page_size_for_region() {
1560 if (UseLargePages) {
1561 const size_t small_page = small_page_size();
1562 const size_t large_page = large_page_size();
1563
1564 if (large_page > small_page) {
1565 size_t num_small_pages_in_large = large_page / small_page;
1566 size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
1567
1568 assert_eq(page, small_page);
1569 }
1570 }
1571 }
1572
1573 static void test_page_size_for_region_alignment() {
1574 if (UseLargePages) {
1575 const size_t small_page = small_page_size();
1576 const size_t large_page = large_page_size();
1577 if (large_page > small_page) {
1578 const size_t unaligned_region = large_page + 17;
1579 size_t page = os::page_size_for_region(unaligned_region, 1);
1580 assert_eq(page, small_page);
1581
1582 const size_t num_pages = 5;
1583 const size_t aligned_region = large_page * num_pages;
1584 page = os::page_size_for_region(aligned_region, num_pages);
1585 assert_eq(page, large_page);
1586 }
1587 }
1588 }
1589
1590 public:
1591 static void run_tests() {
1592 test_page_size_for_region();
1593 test_page_size_for_region_alignment();
1594 }
1595 };
1596
1597 void TestOS_test() {
1598 TestOS::run_tests();
1599 }
1600
1601 #endif // PRODUCT
|
1286 // Returns true if the current stack pointer is above the stack shadow
1287 // pages, false otherwise.
1288
1289 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
1290 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
1291 address sp = current_stack_pointer();
1292 // Check if we have StackShadowPages above the yellow zone. This parameter
1293 // is dependent on the depth of the maximum VM call stack possible from
1294 // the handler for stack overflow. 'instanceof' in the stack overflow
1295 // handler or a println uses at least 8k stack of VM and native code
1296 // respectively.
1297 const int framesize_in_bytes =
1298 Interpreter::size_top_interpreter_activation(method()) * wordSize;
1299 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
1300 * vm_page_size()) + framesize_in_bytes;
1301 // The very lower end of the stack
1302 address stack_limit = thread->stack_base() - thread->stack_size();
1303 return (sp > (stack_limit + reserved_area));
1304 }
1305
1306 size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size,
1307 uint min_pages)
1308 {
1309 assert(min_pages > 0, "sanity");
1310 if (UseLargePages) {
1311 const size_t max_page_size = region_max_size / min_pages;
1312
1313 for (unsigned int i = 0; _page_sizes[i] != 0; ++i) {
1314 const size_t sz = _page_sizes[i];
1315 const size_t mask = sz - 1;
1316 if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) {
1317 // The largest page size with no fragmentation.
1318 return sz;
1319 }
1320
1321 if (sz <= max_page_size) {
1322 // The largest page size that satisfies the min_pages requirement.
1323 return sz;
1324 }
1325 }
1326 }
1327
1328 return vm_page_size();
1329 }
1330
1331 #ifndef PRODUCT
1332 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
1333 {
1334 if (TracePageSizes) {
1335 tty->print("%s: ", str);
1336 for (int i = 0; i < count; ++i) {
1337 tty->print(" " SIZE_FORMAT, page_sizes[i]);
1338 }
1339 tty->cr();
1340 }
1341 }
1342
1343 void os::trace_page_sizes(const char* str, const size_t region_min_size,
1531 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
1532 pd_realign_memory(addr, bytes, alignment_hint);
1533 }
1534
1535 #ifndef TARGET_OS_FAMILY_windows
1536 /* try to switch state from state "from" to state "to"
1537 * returns the state set after the method is complete
1538 */
1539 os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
1540 os::SuspendResume::State to)
1541 {
1542 os::SuspendResume::State result =
1543 (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
1544 if (result == from) {
1545 // success
1546 return to;
1547 }
1548 return result;
1549 }
1550 #endif
|