|
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,61 @@ 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 | 1585 | mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof(UDATA)) + vm->thrStaggerMax; |
| 1586 | + if (pageGuards) { |
| 1587 | + mallocSize += (pageSize * 2); |
| 1588 | + } |
| 1589 | + |
1577 | 1590 | if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) { |
1578 | | - stack = (J9JavaStack*)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
| 1591 | + stack = (J9JavaStack *)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
1579 | 1592 | } else { |
1580 | | - stack = (J9JavaStack*)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
| 1593 | + stack = (J9JavaStack *)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK); |
1581 | 1594 | } |
| 1595 | + |
| 1596 | + if (pageGuards) { |
| 1597 | + if (NULL != stack) { |
| 1598 | + stackMemory = (UDATA)(stack + 1); |
| 1599 | + stackMemory = ROUND_UP_TO_POWEROF2(stackMemory, pageSize); |
| 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, &stack->defaultProtection)) { |
| 1604 | +#endif |
| 1605 | + stack->guardedPage = (UDATA *)stackMemory; |
| 1606 | + stackMemory += pageSize; |
| 1607 | + } else { |
| 1608 | + if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) { |
| 1609 | + j9mem_free_memory32(stack); |
| 1610 | + } else { |
| 1611 | + j9mem_free_memory(stack); |
| 1612 | + } |
| 1613 | + stack = NULL; |
| 1614 | + } |
| 1615 | + } |
| 1616 | + } |
| 1617 | + |
1582 | 1618 | if (stack != NULL) { |
1583 | 1619 | /* for hyperthreading platforms, make sure that stacks are relatively misaligned */ |
1584 | | - UDATA end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize; |
| 1620 | + UDATA end = 0; |
1585 | 1621 | UDATA stagger = vm->thrStagger; |
| 1622 | + |
| 1623 | + if (pageGuards) { |
| 1624 | + end = stackMemory + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize; |
| 1625 | + } else { |
| 1626 | + end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize; |
| 1627 | + } |
| 1628 | + |
1586 | 1629 | stagger += vm->thrStaggerStep; |
1587 | 1630 | vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger; |
1588 | 1631 | if (vm->thrStaggerMax != 0) { |
@@ -1613,23 +1656,39 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack) |
1613 | 1656 |
|
1614 | 1657 | #if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING) |
1615 | 1658 | if (vm->runtimeFlags & J9_RUNTIME_PAINT_STACK) { |
1616 | | - UDATA * currentSlot = (UDATA *) (stack + 1); |
| 1659 | + UDATA *currentSlot = NULL; |
| 1660 | + if (pageGuards) { |
| 1661 | + currentSlot = (UDATA *)stackMemory; |
| 1662 | + } else { |
| 1663 | + currentSlot = (UDATA *)(stack + 1); |
| 1664 | + } |
1617 | 1665 |
|
1618 | 1666 | while (currentSlot != stack->end) |
1619 | 1667 | *currentSlot++ = J9_RUNTIME_STACK_FILL; |
1620 | 1668 | } |
1621 | 1669 | #endif |
| 1670 | + Trc_VM_allocateJavaStack_stackBounds(stack, stack->guardedPage, pageSize, stack->end, stack->size); |
1622 | 1671 | } |
1623 | 1672 |
|
1624 | 1673 | return stack; |
1625 | 1674 | } |
1626 | 1675 |
|
1627 | 1676 |
|
1628 | 1677 | void |
1629 | | -freeJavaStack(J9JavaVM * vm, J9JavaStack * stack) |
| 1678 | +freeJavaStack(J9JavaVM *vm, J9JavaStack *stack) |
1630 | 1679 | { |
1631 | 1680 | PORT_ACCESS_FROM_JAVAVM(vm); |
1632 | | - |
| 1681 | + if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES)) { |
| 1682 | + UDATA pageSize = vm->defaultPageSize; |
| 1683 | + Trc_VM_allocateJavaStack_stackBounds(stack, stack->guardedPage, pageSize, stack->end, stack->size); |
| 1684 | +#if defined(LINUX) |
| 1685 | + if (0 != mprotect((void *)stack->guardedPage, pageSize, PROT_READ|PROT_WRITE)) { |
| 1686 | +#elif defined(WINDOWS) |
| 1687 | + if (0 == VirtualProtect(stack->guardedPage, pageSize, 0, NULL)) { |
| 1688 | +#endif |
| 1689 | + Assert_VM_unreachable(); |
| 1690 | + } |
| 1691 | + } |
1633 | 1692 | if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) { |
1634 | 1693 | j9mem_free_memory32(stack); |
1635 | 1694 | } else { |
|
0 commit comments