Skip to content

Commit 7c15c33

Browse files
committed
Java stack guard pages
Signed-off-by: tajila <atobia@ca.ibm.com>
1 parent 5a147ad commit 7c15c33

File tree

5 files changed

+67
-6
lines changed

5 files changed

+67
-6
lines changed

runtime/oti/j9consts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ extern "C" {
377377
#define J9_EXTENDED_RUNTIME3_DISCLAIM_ROM_CLASS_MEMORY 0x10
378378
#define J9_EXTENDED_RUNTIME3_DISCLAIM_RAM_CLASS_MEMORY 0x20
379379
#define J9_EXTENDED_RUNTIME3_USE_DEBUG_LOCAL_MAP 0x40
380+
#define J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES 0x80
380381

381382
#define J9_OBJECT_HEADER_AGE_DEFAULT 0xA /* OBJECT_HEADER_AGE_DEFAULT */
382383
#define J9_OBJECT_HEADER_SHAPE_MASK 0xE /* OBJECT_HEADER_SHAPE_MASK */

runtime/oti/j9nonbuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6584,6 +6584,7 @@ typedef struct J9JavaVM {
65846584
int64_t prevProcTimestamp;
65856585
omrthread_monitor_t cpuUtilCacheMutex;
65866586
#endif /* defined(OMR_THR_YIELD_ALG) */
6587+
UDATA defaultPageSize;
65876588
} J9JavaVM;
65886589

65896590
#define J9JFR_SAMPLER_STATE_UNINITIALIZED 0

runtime/oti/jvminit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ enum INIT_STAGE {
417417
#define VMOPT_XXDISABLEEXTENDEDHCR "-XX:-EnableExtendedHCR"
418418
#define VMOPT_XXUSEDEBUGLOCALMAP "-XX:+UseDebugLocalMap"
419419
#define VMOPT_XXNOUSEDEBUGLOCALMAP "-XX:-UseDebugLocalMap"
420+
#define VMOPT_XXGUARDPAGEONJAVASTACK "-XX:+GuardPageOnJavaStack"
421+
#define VMOPT_XXNOGUARDPAGEONJAVASTACK "-XX:-GuardPageOnJavaStack"
420422

421423
#if defined(J9VM_ZOS_3164_INTEROPERABILITY)
422424
#define VMOPT_XXENABLE3164INTEROPERABILITY "-XX:+Enable3164Interoperability"

runtime/vm/jvminit.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ initializeJavaVM(void * osMainThread, J9JavaVM ** vmPtr, J9CreateJavaVMParams *c
11931193
vm->loadedClassCount = 0;
11941194
vm->jfrState.blobFileDescriptor = -1;
11951195
#endif /* defined(J9VM_OPT_JFR) */
1196-
1196+
vm->defaultPageSize = j9vmem_supported_page_sizes()[0];
11971197
#if JAVA_SPEC_VERSION >= 19
11981198
/* tid 1 will be use by main thread, first usable tid starts at 2 */
11991199
vm->nextTID = 2;
@@ -4250,6 +4250,17 @@ processVMArgsFromFirstToLast(J9JavaVM * vm)
42504250
vm->extendedRuntimeFlags2 &= ~(UDATA)J9_EXTENDED_RUNTIME2_LEGACY_MANGLING;
42514251
}
42524252
}
4253+
{
4254+
IDATA enableGuardPages = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXGUARDPAGEONJAVASTACK, NULL);
4255+
IDATA disableGuardPages = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXNOGUARDPAGEONJAVASTACK, NULL);
4256+
if (enableGuardPages > disableGuardPages) {
4257+
vm->extendedRuntimeFlags3 |= J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4258+
} else if (enableGuardPages <= disableGuardPages) {
4259+
vm->extendedRuntimeFlags3 &= ~(UDATA)J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4260+
}
4261+
/* test */
4262+
vm->extendedRuntimeFlags3 |= J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4263+
}
42534264

42544265
#if defined(J9VM_ZOS_3164_INTEROPERABILITY)
42554266
{

runtime/vm/vmthread.cpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
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,59 @@ J9JavaStack *
15651571
allocateJavaStack(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

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+
15771591
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {
15781592
stack = (J9JavaStack*)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
15791593
} else {
15801594
stack = (J9JavaStack*)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
15811595
}
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+
15821616
if (stack != NULL) {
15831617
/* 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;
15851619
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+
15861627
stagger += vm->thrStaggerStep;
15871628
vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger;
15881629
if (vm->thrStaggerMax != 0) {
@@ -1613,7 +1654,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16131654

16141655
#if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING)
16151656
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+
}
16171663

16181664
while (currentSlot != stack->end)
16191665
*currentSlot++ = J9_RUNTIME_STACK_FILL;

0 commit comments

Comments
 (0)