2424
2525#include < string.h>
2626
27+ #if defined(LINUX)
28+ #include < sys/mman.h>
29+ #elif defined(WINDOWS)
30+ #include < windows.h>
31+ #endif
32+
2733#include " omrcfg.h"
2834#include " j9.h"
2935#include " j9cfg.h"
@@ -1565,24 +1571,61 @@ J9JavaStack *
15651571allocateJavaStack (J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
15661572{
15671573 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 ;
15701579
15711580 /* Allocate the stack, adding the header and overflow area size.
15721581 * Add one slot for possible double-slot alignment.
15731582 * If stagger is in use, add the maximum stagger value to account for that alignment.
15741583 */
15751584
15761585 mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof (UDATA)) + vm->thrStaggerMax ;
1586+ if (pageGuards) {
1587+ mallocSize += (pageSize * 2 );
1588+ }
1589+
15771590 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);
15791592 } 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);
15811594 }
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+
15821618 if (stack != NULL ) {
15831619 /* 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 ;
15851621 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+
15861629 stagger += vm->thrStaggerStep ;
15871630 vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger;
15881631 if (vm->thrStaggerMax != 0 ) {
@@ -1613,7 +1656,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16131656
16141657#if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING)
16151658 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+ }
16171665
16181666 while (currentSlot != stack->end )
16191667 *currentSlot++ = J9_RUNTIME_STACK_FILL;
@@ -1626,10 +1674,19 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16261674
16271675
16281676void
1629- freeJavaStack (J9JavaVM * vm, J9JavaStack * stack)
1677+ freeJavaStack (J9JavaVM *vm, J9JavaStack *stack)
16301678{
16311679 PORT_ACCESS_FROM_JAVAVM (vm);
1632-
1680+ if (J9_ARE_ALL_BITS_SET (vm->extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES)) {
1681+ UDATA pageSize = vm->defaultPageSize ;
1682+ #if defined(LINUX)
1683+ if (0 != mprotect ((void *)stack->guardedPage , pageSize, PROT_READ|PROT_WRITE)) {
1684+ #elif defined(WINDOWS)
1685+ if (0 == VirtualProtect (stack->guardedPage , pageSize, 0 , NULL )) {
1686+ #endif
1687+ Assert_VM_unreachable ();
1688+ }
1689+ }
16331690 if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES (vm)) {
16341691 j9mem_free_memory32 (stack);
16351692 } else {
0 commit comments