From 204cef9d2bfcd0eecaf097a64346c33e13e1bc9b Mon Sep 17 00:00:00 2001 From: Victor Ding Date: Thu, 21 Sep 2017 16:44:07 -0400 Subject: [PATCH 1/2] Updated CompareAndSwap and PatchFence OMR has migrated CompareAndSwap and PatchFence to Intrinsics. This is related update on J9. Signed-off-by: Victor Ding --- runtime/tr.source/trj9/runtime/JitRuntime.cpp | 12 +++++++----- runtime/tr.source/trj9/runtime/Trampoline.cpp | 10 +++++----- runtime/tr.source/trj9/x/runtime/Recomp.cpp | 10 ++++------ runtime/tr.source/trj9/x/runtime/X86Codert.asm | 4 ---- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/runtime/tr.source/trj9/runtime/JitRuntime.cpp b/runtime/tr.source/trj9/runtime/JitRuntime.cpp index 58ba1175eac..bf24249cbb4 100644 --- a/runtime/tr.source/trj9/runtime/JitRuntime.cpp +++ b/runtime/tr.source/trj9/runtime/JitRuntime.cpp @@ -64,6 +64,10 @@ #include "runtime/Runtime.hpp" #endif +#if defined(TR_HOST_X86) +#include "x/runtime/X86Runtime.hpp" +#endif + #include "runtime/J9ValueProfiler.hpp" #if defined(J9ZOS390) @@ -1268,9 +1272,7 @@ void initializeJitRuntimeHelperTable(char isSMP) #undef SET } -#if defined (TR_TARGET_X86) -extern "C" int32_t compareAndExchange4(uint32_t *ptr, uint32_t, uint32_t); -#elif defined (TR_HOST_S390) +#if defined (TR_HOST_S390) extern "C" int32_t _CompareAndSwap4(int32_t * addr, uint32_t, uint32_t); #elif defined (TR_HOST_PPC) extern "C" _tr_try_lock(uint32_t *a, uint32_t b, uint32_t c); // return 1 if compareAndSwap "c" successfully into "a"; otherwise 0; @@ -1293,7 +1295,7 @@ uint8_t platformLightweightLockingIsSupported() uint32_t platformTryLock(uint32_t *ptr) { #if defined(TR_TARGET_X86) - return compareAndExchange4(ptr, PLATFORM_MONITOR_UNLOCKED, PLATFORM_MONITOR_LOCKED); + return AtomicCompareAndSwap(ptr, PLATFORM_MONITOR_UNLOCKED, PLATFORM_MONITOR_LOCKED); #elif defined (TR_HOST_S390) return _CompareAndSwap4((int32_t *)ptr, PLATFORM_MONITOR_UNLOCKED, PLATFORM_MONITOR_LOCKED); #elif defined (TR_HOST_PPC) @@ -1306,7 +1308,7 @@ uint32_t platformTryLock(uint32_t *ptr) void platformUnlock(uint32_t *ptr) { #if defined(TR_TARGET_X86) - compareAndExchange4(ptr, PLATFORM_MONITOR_LOCKED, PLATFORM_MONITOR_UNLOCKED); + AtomicCompareAndSwap(ptr, PLATFORM_MONITOR_LOCKED, PLATFORM_MONITOR_UNLOCKED); #elif defined (TR_HOST_S390) _CompareAndSwap4((int32_t *)ptr, PLATFORM_MONITOR_LOCKED, PLATFORM_MONITOR_UNLOCKED); #elif defined (TR_HOST_PPC) diff --git a/runtime/tr.source/trj9/runtime/Trampoline.cpp b/runtime/tr.source/trj9/runtime/Trampoline.cpp index 1df332c07a2..9bb0cc9bd0f 100644 --- a/runtime/tr.source/trj9/runtime/Trampoline.cpp +++ b/runtime/tr.source/trj9/runtime/Trampoline.cpp @@ -502,6 +502,7 @@ void ppcCodeCacheParameters(int32_t *trampolineSize, void **callBacks, int32_t * #endif /*(TR_TARGET_POWER)*/ #if defined(TR_TARGET_X86) && defined(TR_TARGET_64BIT) +#include "x/runtime/X86Runtime.hpp" // Hack markers // @@ -514,7 +515,6 @@ void ppcCodeCacheParameters(int32_t *trampolineSize, void **callBacks, int32_t * #define IS_32BIT_RIP(x,rip) ((intptrj_t)(x) == (intptrj_t)(rip) + (int32_t)((intptrj_t)(x) - (intptrj_t)(rip))) #define TRAMPOLINE_SIZE 16 #define CALL_INSTR_LENGTH 5 -extern "C" void _patchingFence16(void *startAddr); void amd64CodeCacheConfig(int32_t ccSizeInByte, uint32_t *numTempTrampolines) { @@ -641,11 +641,11 @@ int32_t amd64CodePatching(void *theMethod, void *callSite, void *currentPC, void // Self-loop *(uint16_t *)currentTramp = 0xfeeb; - _patchingFence16(currentTramp); + patchingFence16(currentTramp); // Store the new address *(intptrj_t *)((uint8_t *)currentTramp + 2) = (intptrj_t)entryAddress; - _patchingFence16(currentTramp); + patchingFence16(currentTramp); // Restore the MOV instruction *(uint16_t *)currentTramp = 0xbf48; @@ -676,12 +676,12 @@ int32_t amd64CodePatching(void *theMethod, void *callSite, void *currentPC, void // time.) *(uint16_t *)patchAddr = 0xfeeb; - _patchingFence16(patchAddr); + patchingFence16(patchAddr); patchAddr[2] = (distance>>8) & 0xff; patchAddr[3] = (distance>>16) & 0xff; patchAddr[4] = (distance>>24) & 0xff; - _patchingFence16(patchAddr); + patchingFence16(patchAddr); *(uint16_t *)patchAddr = 0xe8 | ((distance<<8) & 0xff00); } diff --git a/runtime/tr.source/trj9/x/runtime/Recomp.cpp b/runtime/tr.source/trj9/x/runtime/Recomp.cpp index 8177241ab42..3318b85482b 100644 --- a/runtime/tr.source/trj9/x/runtime/Recomp.cpp +++ b/runtime/tr.source/trj9/x/runtime/Recomp.cpp @@ -27,11 +27,9 @@ #include "env/jittypes.h" #include "runtime/CodeCacheManager.hpp" #include "runtime/Runtime.hpp" +#include "x/runtime/X86Runtime.hpp" #include "trj9/env/VMJ9.h" -extern "C" int32_t compareAndExchange2(uint16_t *ptr, uint16_t, uint16_t); -extern "C" void _patchingFence16(void *startAddr); - #if defined(TR_HOST_X86) && defined(TR_HOST_64BIT) #define IS_32BIT_RIP(x,rip) ((intptrj_t)(x) == (intptrj_t)(rip) + (int32_t)((intptrj_t)(x) - (intptrj_t)(rip))) @@ -155,7 +153,7 @@ void J9::Recompilation::fixUpMethodCode(void *startPC) uint16_t newInstruction = jitEntryJmpInstruction(startPC, START_PC_TO_RECOMPILE_SAMPLING); uint16_t oldInstruction = *(uint16_t*)((uint8_t*)startPC + START_PC_TO_ORIGINAL_ENTRY_BYTES); uint16_t *startBytes = (uint16_t*)((uint8_t*)startPC + jitEntryOffset(startPC)); - compareAndExchange2(startBytes, oldInstruction, newInstruction); + AtomicCompareAndSwap(startBytes, oldInstruction, newInstruction); } } @@ -207,7 +205,7 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart offset = ((char*)helperAddr) - startByte - 5; *((int16_t*)startByte) = SPIN_LOOP_INSTRUCTION; - _patchingFence16(startByte); + patchingFence16(startByte); *((int32_t*)(startByte+2)) = offset >> 8; // Offset from CALL's return address to oldStartPC @@ -217,7 +215,7 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart // Finish patching and unlock spin loop // - _patchingFence16(startByte); + patchingFence16(startByte); *((int16_t*)startByte) = ((offset & 0xFF) << 8) | CALL_INSTRUCTION; bytesToSaveAtStart = 7 + jitEntryOffset(oldStartPC); // the new call instruction + 2-byte offset; TODO: this could be 5 on IA32 diff --git a/runtime/tr.source/trj9/x/runtime/X86Codert.asm b/runtime/tr.source/trj9/x/runtime/X86Codert.asm index 6d68c181d97..91db6f44c06 100644 --- a/runtime/tr.source/trj9/x/runtime/X86Codert.asm +++ b/runtime/tr.source/trj9/x/runtime/X86Codert.asm @@ -1580,8 +1580,6 @@ ifndef TR_HOST_64BIT public clearFPStack -include x/i386/runtime/IA32AsmUtil.inc - jitReleaseVMAccess PROC NEAR pusha push ebp @@ -1616,8 +1614,6 @@ else ; ; -------------------------------------------------------------------------------- -include x/amd64/runtime/AMD64AsmUtil.inc - jitReleaseVMAccess proc ; Save system-linkage volatile regs ; GPRs From c5fa2f9ce2e1953db51c2f964a6dea14856d0291 Mon Sep 17 00:00:00 2001 From: tajila Date: Thu, 19 Oct 2017 16:19:06 -0400 Subject: [PATCH 2/2] fix visibility checks for methodTypes Perform visibility checks methodType returnTypes and parameterTypes during resolution. Also, always perform visibility checks on the leafComponentType when one of the classes is an array. Signed-off-by: tajila --- runtime/vm/j9vm.tdf | 4 +++ runtime/vm/resolvesupport.cpp | 57 ++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/runtime/vm/j9vm.tdf b/runtime/vm/j9vm.tdf index a9a8b81faac..8d9b6caf296 100644 --- a/runtime/vm/j9vm.tdf +++ b/runtime/vm/j9vm.tdf @@ -759,3 +759,7 @@ TraceEvent=Trc_VM_CreateRAMClassFromROMClass_nestTopLoaded Overhead=1 Level=3 Te TraceException=Trc_VM_CreateRAMClassFromROMClass_nestTopNotSamePackage Overhead=1 Level=1 Template="The nest top class (RAM class=%p, class loader=%p, this class loader=%p) is not in the same package." TraceException=Trc_VM_CreateRAMClassFromROMClass_nestTopNotSameClassLoader Overhead=1 Level=1 Template="The nest top class (RAM class=%p, class loader=%p, this class loader=%p) has not been loaded by the same class loader." TraceException=Trc_VM_CreateRAMClassFromROMClass_nestTopNotVerified Overhead=1 Level=1 Template="The nest top (nest top class=%p, class loader=%p, this class loader=%p) does not claim the nest member (nest member=%p)." + +TraceEntry=Trc_VM_sendResolveMethodTypeRefInto_Entry Overhead=1 Level=5 Template="sendResolveMethodTypeRefInto ramCP=%p cpIndex=%zu resolveFlags=%zu" +TraceException=Trc_VM_sendResolveMethodTypeRefInto_Exception Overhead=1 Level=1 Template="Sender class=%p cannot access receiver class=%p, errorCode=%zi." +TraceExit=Trc_VM_sendResolveMethodTypeRefInto_Exit Overhead=1 Level=5 Template="sendResolveMethodTypeRefInto methodType=%p." diff --git a/runtime/vm/resolvesupport.cpp b/runtime/vm/resolvesupport.cpp index c364d87c895..1ce046e1509 100644 --- a/runtime/vm/resolvesupport.cpp +++ b/runtime/vm/resolvesupport.cpp @@ -1550,6 +1550,8 @@ resolveMethodTypeRefInto(J9VMThread *vmThread, J9ConstantPool *ramCP, UDATA cpIn J9ROMMethodTypeRef *romMethodTypeRef = NULL; J9UTF8 *lookupSig = NULL; + Trc_VM_sendResolveMethodTypeRefInto_Entry(vmThread, ramCP, cpIndex, resolveFlags); + /* Check if already resolved */ if (ramCPEntry->type != NULL) { return ramCPEntry->type; @@ -1588,14 +1590,67 @@ resolveMethodTypeRefInto(J9VMThread *vmThread, J9ConstantPool *ramCP, UDATA cpIn } } + /* perform visibility checks for the returnType and all parameters */ + if (NULL != methodType) { + /* check returnType */ + J9Class *senderClass = ramCP->ramClass; + J9Class *returnTypeClass = J9VM_J9CLASS_FROM_HEAPCLASS(vmThread, J9VMJAVALANGINVOKEMETHODTYPE_RETURNTYPE(vmThread, methodType)); + J9Class *illegalClass = NULL; + IDATA visibilityReturnCode = 0; + + if (J9ROMCLASS_IS_ARRAY(senderClass->romClass)) { + senderClass = ((J9ArrayClass *)senderClass)->leafComponentType; + } + if (J9ROMCLASS_IS_ARRAY(returnTypeClass->romClass)) { + returnTypeClass = ((J9ArrayClass *)returnTypeClass)->leafComponentType; + } + + visibilityReturnCode = checkVisibility(vmThread, senderClass, returnTypeClass, returnTypeClass->romClass->modifiers, resolveFlags); + + if (J9_VISIBILITY_ALLOWED != visibilityReturnCode) { + illegalClass = returnTypeClass; + } else { + /* check paramTypes */ + j9object_t argTypesObject = J9VMJAVALANGINVOKEMETHODTYPE_ARGUMENTS(vmThread, methodType); + U_32 typeCount = J9INDEXABLEOBJECT_SIZE(vmThread, argTypesObject); + + for (UDATA i = 0; i < typeCount; i++) { + J9Class *paramClass = J9VM_J9CLASS_FROM_HEAPCLASS(vmThread, J9JAVAARRAYOFOBJECT_LOAD(vmThread, argTypesObject, i)); + + if (J9ROMCLASS_IS_ARRAY(paramClass->romClass)) { + paramClass = ((J9ArrayClass *)paramClass)->leafComponentType; + } + + visibilityReturnCode = checkVisibility(vmThread, senderClass, paramClass, paramClass->romClass->modifiers, resolveFlags); + + if (J9_VISIBILITY_ALLOWED != visibilityReturnCode) { + illegalClass = paramClass; + break; + } + } + } + if (NULL != illegalClass) { + char *errorMsg = illegalAccessMessage(vmThread, illegalClass->romClass->modifiers, senderClass, illegalClass, visibilityReturnCode); + if (NULL == errorMsg) { + setNativeOutOfMemoryError(vmThread, 0, 0); + } else { + setCurrentExceptionUTF(vmThread, J9VMCONSTANTPOOL_JAVALANGILLEGALACCESSERROR, errorMsg); + } + Trc_VM_sendResolveMethodTypeRefInto_Exception(vmThread, senderClass, illegalClass, visibilityReturnCode); + methodType = NULL; + } + } + /* Only write the value in if its not null */ - if (methodType != NULL) { + if (NULL != methodType ) { J9Class *clazz = J9_CLASS_FROM_CP(ramCP); j9object_t *methodTypeObjectP = &ramCPEntry->type; /* Overwriting NULL with an immortal pointer, so no exception can occur */ J9STATIC_OBJECT_STORE(vmThread, clazz, methodTypeObjectP, methodType); } + Trc_VM_sendResolveMethodTypeRefInto_Exit(vmThread, methodType); + return methodType; }