|
24 | 24 |
|
25 | 25 | #include <string.h> |
26 | 26 |
|
| 27 | +#if defined(LINUX) |
| 28 | +#include <sys/mman.h> |
| 29 | +#elif defined(WINDOWS) |
| 30 | +#include <windows.h> |
| 31 | +#endif |
| 32 | + |
27 | 33 | #include "omrcfg.h" |
28 | 34 | #include "j9.h" |
29 | 35 | #include "j9cfg.h" |
@@ -1565,24 +1571,59 @@ J9JavaStack * |
1565 | 1571 | allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack) |
1566 | 1572 | { |
1567 | 1573 | PORT_ACCESS_FROM_JAVAVM(vm); |
1568 | | - J9JavaStack * stack; |
1569 | | - UDATA mallocSize; |
| 1574 | + J9JavaStack *stack = NULL; |
| 1575 | + UDATA mallocSize = 0; |
| 1576 | + UDATA pageSize = vm->defaultPageSize; |
| 1577 | + bool pageGuards = J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES); |
| 1578 | + UDATA stackMemory = 0; |
1570 | 1579 |
|
1571 | 1580 | /* Allocate the stack, adding the header and overflow area size. |
1572 | 1581 | * Add one slot for possible double-slot alignment. |
1573 | 1582 | * If stagger is in use, add the maximum stagger value to account for that alignment. |
1574 | 1583 | */ |
1575 | 1584 |
|
1576 | | - mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof(UDATA)) + vm->thrStaggerMax; |
| 1585 | + if (pageGuards) { |
| 1586 | + mallocSize = (pageSize * 2) + sizeof(J9JavaStack) + (stackSize + sizeof(UDATA)) + vm->thrStaggerMax; |
| 1587 | + } else { |
| 1588 | + mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof(UDATA)) + vm->thrStaggerMax; |
| 1589 | + } |
| 1590 | + |
1577 | 1591 | if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) { |
1578 | 1592 | stack = (J9JavaStack*)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
1579 | 1593 | } else { |
1580 | 1594 | stack = (J9JavaStack*)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
1581 | 1595 | } |
| 1596 | + |
| 1597 | + if (pageGuards) { |
| 1598 | + stackMemory = ROUND_UP_TO_POWEROF2(stackMemory, pageSize); |
| 1599 | + |
| 1600 | +#if defined(LINUX) |
| 1601 | + if (0 == mprotect((void *)stackMemory, pageSize, PROT_NONE)) { |
| 1602 | +#elif defined(WINDOWS) |
| 1603 | + if (0 != VirtualProtect(stackMemory, pageSize, PAGE_NOACCESS, NULL)) { |
| 1604 | +#endif |
| 1605 | + stackMemory += pageSize; |
| 1606 | + } else { |
| 1607 | + if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) { |
| 1608 | + j9mem_free_memory32(stack); |
| 1609 | + } else { |
| 1610 | + j9mem_free_memory(stack); |
| 1611 | + } |
| 1612 | + stack = NULL; |
| 1613 | + } |
| 1614 | + } |
| 1615 | + |
1582 | 1616 | if (stack != NULL) { |
1583 | 1617 | /* for hyperthreading platforms, make sure that stacks are relatively misaligned */ |
1584 | | - UDATA end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize; |
| 1618 | + UDATA end = 0; |
1585 | 1619 | UDATA stagger = vm->thrStagger; |
| 1620 | + |
| 1621 | + if (pageGuards) { |
| 1622 | + end = stackMemory + stackSize; |
| 1623 | + } else { |
| 1624 | + end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize; |
| 1625 | + } |
| 1626 | + |
1586 | 1627 | stagger += vm->thrStaggerStep; |
1587 | 1628 | vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger; |
1588 | 1629 | if (vm->thrStaggerMax != 0) { |
@@ -1613,7 +1654,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack) |
1613 | 1654 |
|
1614 | 1655 | #if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING) |
1615 | 1656 | if (vm->runtimeFlags & J9_RUNTIME_PAINT_STACK) { |
1616 | | - UDATA * currentSlot = (UDATA *) (stack + 1); |
| 1657 | + UDATA *currentSlot = NULL; |
| 1658 | + if (pageGuards) { |
| 1659 | + currentSlot = (UDATA *)stackMemory; |
| 1660 | + } else { |
| 1661 | + currentSlot = (UDATA *)(stack + 1); |
| 1662 | + } |
1617 | 1663 |
|
1618 | 1664 | while (currentSlot != stack->end) |
1619 | 1665 | *currentSlot++ = J9_RUNTIME_STACK_FILL; |
|
0 commit comments