Path: blob/master/runtime/codert_vm/CodertVMHelpers.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2022 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "j9protos.h"23#include "jitprotos.h"24#include "stackwalk.h"25#include "rommeth.h"26#include "VMHelpers.hpp"27#include "AtomicSupport.hpp"28#include "MethodMetaData.h"29#include "ut_j9codertvm.h"3031extern "C" {3233/* Until the JIT deletes references to these */34void * jitExitInterpreterX = NULL;35void * jitExitInterpreterY = NULL;36#if defined(J9VM_ENV_CALL_VIA_TABLE)37void init_codert_vm_fntbl(J9JavaVM *javaVM) {}38#endif /* J9VM_ENV_CALL_VIA_TABLE */3940void41initializeDirectJNI(J9JavaVM *vm)42{43vm->jniSendTarget = J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_COUNT_AND_SEND_JNI_NATIVE);44}4546#if defined(J9SW_NEEDS_JIT_2_INTERP_THUNKS)47J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendPatchupVirtual);48#else /* J9SW_NEEDS_JIT_2_INTERP_THUNKS */49J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtual0);50J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtual1);51J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualJ);52J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualF);53J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualD);54J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualL);55J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSync0);56J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSync1);57J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncJ);58J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncF);59J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncD);60J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncL);61J9_EXTERN_BUILDER_SYMBOL(icallVMprJavaSendNativeVirtual);62#endif /* J9SW_NEEDS_JIT_2_INTERP_THUNKS */63J9_EXTERN_BUILDER_SYMBOL(jitFillOSRBufferReturn);64J9_EXTERN_BUILDER_SYMBOL(returnFromJIT0);65J9_EXTERN_BUILDER_SYMBOL(returnFromJIT1);66J9_EXTERN_BUILDER_SYMBOL(returnFromJITJ);67J9_EXTERN_BUILDER_SYMBOL(returnFromJITF);68J9_EXTERN_BUILDER_SYMBOL(returnFromJITD);69#if defined(J9VM_ENV_DATA64)70J9_EXTERN_BUILDER_SYMBOL(returnFromJITL);71#endif /* J9VM_ENV_DATA64 */72J9_EXTERN_BUILDER_SYMBOL(returnFromJITConstructor0);73J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreter0);74J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreter1);75J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterJ);76J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterF);77J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterD);7879static void *i2jReturnTable[16] = {0};8081void *jit2InterpreterSendTargetTable[13] = {0};8283static J9Method* jitGetExceptionCatcher(J9VMThread *currentThread, void *handlerPC, J9JITExceptionTable *metaData, IDATA *location);8485void86initializeCodertFunctionTable(J9JavaVM *javaVM)87{88J9JITConfig *jitConfig = javaVM->jitConfig;89jitConfig->i2jReturnTable = (void*)&i2jReturnTable;90i2jReturnTable[0] = J9_BUILDER_SYMBOL(returnFromJIT0);91i2jReturnTable[1] = J9_BUILDER_SYMBOL(returnFromJIT1);92i2jReturnTable[2] = J9_BUILDER_SYMBOL(returnFromJITJ);93i2jReturnTable[3] = J9_BUILDER_SYMBOL(returnFromJITF);94i2jReturnTable[4] = J9_BUILDER_SYMBOL(returnFromJITD);95#if defined(J9VM_ENV_DATA64)96i2jReturnTable[5] = J9_BUILDER_SYMBOL(returnFromJITL);97#else /* J9VM_ENV_DATA64 */98i2jReturnTable[5] = J9_BUILDER_SYMBOL(returnFromJIT1);99#endif /* J9VM_ENV_DATA64 */100i2jReturnTable[6] = J9_BUILDER_SYMBOL(returnFromJITF);101i2jReturnTable[7] = J9_BUILDER_SYMBOL(returnFromJITD);102i2jReturnTable[8] = J9_BUILDER_SYMBOL(returnFromJITConstructor0);103#if defined(J9SW_NEEDS_JIT_2_INTERP_THUNKS)104void *patchupVirtual = J9_BUILDER_SYMBOL(icallVMprJavaSendPatchupVirtual);105jitConfig->patchupVirtual = patchupVirtual;106for (UDATA i = 0; i < (sizeof(jit2InterpreterSendTargetTable) / sizeof(void*)); ++i) {107jit2InterpreterSendTargetTable[i] = patchupVirtual;108}109#else /* J9SW_NEEDS_JIT_2_INTERP_THUNKS */110jit2InterpreterSendTargetTable[0] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtual0);111jit2InterpreterSendTargetTable[1] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtual1);112jit2InterpreterSendTargetTable[2] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualJ);113jit2InterpreterSendTargetTable[3] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualF);114jit2InterpreterSendTargetTable[4] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualD);115jit2InterpreterSendTargetTable[5] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualL);116jit2InterpreterSendTargetTable[6] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSync0);117jit2InterpreterSendTargetTable[7] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSync1);118jit2InterpreterSendTargetTable[8] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncJ);119jit2InterpreterSendTargetTable[9] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncF);120jit2InterpreterSendTargetTable[10] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncD);121jit2InterpreterSendTargetTable[11] = J9_BUILDER_SYMBOL(icallVMprJavaSendVirtualSyncL);122jit2InterpreterSendTargetTable[12] = J9_BUILDER_SYMBOL(icallVMprJavaSendNativeVirtual);123#endif /* J9SW_NEEDS_JIT_2_INTERP_THUNKS */124jitConfig->j2iInvokeWithArguments = (void*)-1;125jitConfig->jitFillOSRBufferReturn = J9_BUILDER_SYMBOL(jitFillOSRBufferReturn);126jitConfig->jitExitInterpreter0 = J9_BUILDER_SYMBOL(jitExitInterpreter0);127jitConfig->jitExitInterpreter1 = J9_BUILDER_SYMBOL(jitExitInterpreter1);128jitConfig->jitExitInterpreterJ = J9_BUILDER_SYMBOL(jitExitInterpreterJ);129jitConfig->jitExitInterpreterF = J9_BUILDER_SYMBOL(jitExitInterpreterF);130jitConfig->jitExitInterpreterD = J9_BUILDER_SYMBOL(jitExitInterpreterD);131jitConfig->i2jTransition = J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_I2J_TRANSITION);132jitConfig->setUpForDLT = setUpForDLT;133jitConfig->i2jMHTransition = (void*)-3;134jitConfig->runJITHandler = (void*)-5;135jitConfig->performDLT = (void*)-7;136jitConfig->jitGetExceptionCatcher = jitGetExceptionCatcher;137initPureCFunctionTable(javaVM);138}139140#if defined(J9VM_JIT_GC_ON_RESOLVE_SUPPORT)141142static void143jitEmptyObjectSlotIterator(J9VMThread *vmThread, J9StackWalkState *walkState, j9object_t *objectSlot, const void *stackLocation)144{145}146147void148jitCheckScavengeOnResolve(J9VMThread *currentThread)149{150UDATA oldState = currentThread->omrVMThread->vmState;151currentThread->omrVMThread->vmState = J9VMSTATE_SNW_STACK_VALIDATE;152J9JavaVM *vm = currentThread->javaVM;153J9JITConfig *jitConfig = vm->jitConfig;154jitConfig->gcCount += 1;155if (jitConfig->gcCount >= jitConfig->gcOnResolveThreshold) {156if (jitConfig->gcCount == jitConfig->gcOnResolveThreshold) {157PORT_ACCESS_FROM_JAVAVM(vm);158j9tty_printf(PORTLIB, "\n<JIT: scavenge on resolve enabled gc #%d>", jitConfig->gcCount);159}160J9StackWalkState walkState;161walkState.objectSlotWalkFunction = jitEmptyObjectSlotIterator;162walkState.walkThread = currentThread;163walkState.flags = J9_STACKWALK_ITERATE_O_SLOTS;164vm->walkStackFrames(currentThread, &walkState);165}166currentThread->omrVMThread->vmState = oldState;167}168169#endif /* J9VM_JIT_GC_ON_RESOLVE_SUPPORT */170171void172jitMarkMethodReadyForDLT(J9VMThread *currentThread, J9Method *method)173{174VM_AtomicSupport::bitOr((UDATA*)&method->constantPool, J9_STARTPC_DLT_READY);175}176177void178jitMethodFailedTranslation(J9VMThread *currentThread, J9Method *method)179{180J9JITConfig *jitConfig = currentThread->javaVM->jitConfig;181if (J9_ARE_NO_BITS_SET(jitConfig->runtimeFlags, J9JIT_TOSS_CODE)) {182/* Natives are already set correctly before the translation attempt */183if (J9_ARE_NO_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(method)->modifiers, J9AccNative)) {184method->extra = (void*)(UDATA)(IDATA)J9_JIT_NEVER_TRANSLATE;185}186}187}188189void190jitMethodTranslated(J9VMThread *currentThread, J9Method *method, void *jitStartAddress)191{192J9JavaVM *vm = currentThread->javaVM;193J9JITConfig *jitConfig = vm->jitConfig;194if (J9_ARE_NO_BITS_SET(jitConfig->runtimeFlags, J9JIT_TOSS_CODE)) {195if (jitMethodIsBreakpointed(currentThread, method)) {196jitBreakpointedMethodCompiled(currentThread, method, jitStartAddress);197}198/* Slam in the start PC, which also marks the method as having been translated */199method->extra = jitStartAddress;200method->methodRunAddress = J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_I2J_TRANSITION);201/* update vTables for virtual methods */202if (J9ROMMETHOD_HAS_VTABLE(J9_ROM_METHOD_FROM_RAM_METHOD(method))) {203J9Class *currentClass = J9_CLASS_FROM_METHOD(method);204if (J9ROMCLASS_IS_INTERFACE(currentClass->romClass)) {205currentClass = J9VMJAVALANGOBJECT_OR_NULL(vm);206}207UDATA initialClassDepth = VM_VMHelpers::getClassDepth(currentClass);208void *j2jAddress = VM_VMHelpers::jitToJitStartAddress(jitStartAddress);209do {210J9VTableHeader* vTableHeader = J9VTABLE_HEADER_FROM_RAM_CLASS(currentClass);211212/* get number of real methods in Interpreter vTable */213UDATA vTableWriteIndex = vTableHeader->size;214if (0 != vTableWriteIndex) {215/* initialize pointer to first real vTable method */216void **vTableWriteCursor = (void**)JIT_VTABLE_START_ADDRESS(currentClass);217J9Method **vTableReadCursor = J9VTABLE_FROM_HEADER(vTableHeader);218219while (0 != vTableWriteIndex) {220if (method == *vTableReadCursor) {221*vTableWriteCursor = j2jAddress;222}223vTableReadCursor += 1;224vTableWriteCursor -= 1;225vTableWriteIndex -= 1;226}227}228currentClass = currentClass->subclassTraversalLink;229} while (VM_VMHelpers::getClassDepth(currentClass) > initialClassDepth);230}231}232}233234J9_EXTERN_BUILDER_SYMBOL(jitTranslateNewInstanceMethod);235J9_EXTERN_BUILDER_SYMBOL(jitInterpretNewInstanceMethod);236237void*238jitNewInstanceMethodStartAddress(J9VMThread *currentThread, J9Class *clazz)239{240void *addr = NULL;241addr = (void*)clazz->romableAotITable;242if (addr == J9_BUILDER_SYMBOL(jitTranslateNewInstanceMethod)) {243addr = NULL;244}245return addr;246}247248void249jitNewInstanceMethodTranslated(J9VMThread *currentThread, J9Class *clazz, void *jitStartAddress)250{251clazz->romableAotITable = (UDATA)VM_VMHelpers::jitToJitStartAddress(jitStartAddress);252}253254void255jitNewInstanceMethodTranslateFailed(J9VMThread *currentThread, J9Class *clazz)256{257clazz->romableAotITable = (UDATA)J9_BUILDER_SYMBOL(jitInterpretNewInstanceMethod);258}259260UDATA261jitTranslateMethod(J9VMThread *currentThread, J9Method *method)262{263UDATA oldState = currentThread->omrVMThread->vmState;264currentThread->omrVMThread->vmState = J9VMSTATE_JIT;265J9JavaVM *vm = currentThread->javaVM;266J9JITConfig *jitConfig = vm->jitConfig;267UDATA jitStartPC = jitConfig->entryPoint(jitConfig, currentThread, method, 0);268currentThread->omrVMThread->vmState = oldState;269return jitStartPC;270}271272UDATA273jitUpdateCount(J9VMThread *currentThread, J9Method *method, UDATA oldCount, UDATA newCount)274{275return oldCount == VM_AtomicSupport::lockCompareExchange((UDATA*)&method->extra, oldCount, newCount);276}277278typedef void (*overrideCallback)(J9VMThread*, UDATA, J9Method*, J9Method*);279280void281jitUpdateInlineAttribute(J9VMThread *currentThread, J9Class * classPtr, void *jitCallBack)282{283/* Do not walk interface classes */284if (J9_ARE_NO_BITS_SET(classPtr->romClass->modifiers, J9AccInterface)) {285J9Class *superclass = VM_VMHelpers::getSuperclass(classPtr);286/* Methods in Object never override anything */287if (NULL != superclass) {288/* Skip the count field and the first method in the table (not a real method) */289J9VTableHeader *superVTableHeader = J9VTABLE_HEADER_FROM_RAM_CLASS(superclass);290UDATA methodCount = superVTableHeader->size;291J9Method **superMethods = J9VTABLE_FROM_HEADER(superVTableHeader);292J9Method **subMethods = J9VTABLE_FROM_RAM_CLASS(classPtr);293/* Walk all methods which could possibly be overridden */294while (0 != methodCount) {295J9Method *superMethod = *superMethods;296J9Method *subMethod = *subMethods;297/* If the subclass method is different from the superclass method, this is an override */298if (superMethod != subMethod) {299if (NULL != jitCallBack) {300((overrideCallback)jitCallBack)(currentThread, 0, superMethod, subMethod);301}302/* Mark the super method as overridden */303VM_AtomicSupport::bitOr((UDATA*)superMethod->constantPool, J9_STARTPC_METHOD_IS_OVERRIDDEN);304}305superMethods += 1;306subMethods += 1;307methodCount -= 1;308}309310}311}312}313314static J9Method*315jitGetExceptionCatcher(J9VMThread *currentThread, void *handlerPC, J9JITExceptionTable *metaData, IDATA *location)316{317J9Method *method = metaData->ramMethod;318void *stackMap = NULL;319void *inlineMap = NULL;320void *inlinedCallSite = NULL;321/* Note we need to add 1 to the JIT PC here in order to get the correct map at the exception handler322* because jitGetMapsFromPC is expecting a return address, so it subtracts 1. The value passed in is323* the start address of the compiled exception handler.324*/325jitGetMapsFromPC(currentThread, currentThread->javaVM, metaData, (UDATA)handlerPC + 1, &stackMap, &inlineMap);326Assert_CodertVM_false(NULL == inlineMap);327if (NULL != getJitInlinedCallInfo(metaData)) {328inlinedCallSite = getFirstInlinedCallSite(metaData, inlineMap);329if (NULL != inlinedCallSite) {330method = (J9Method*)getInlinedMethod(inlinedCallSite);331}332}333*location = (IDATA)getCurrentByteCodeIndexAndIsSameReceiver(metaData, inlineMap, inlinedCallSite, NULL);334return method;335}336337} /* extern "C" */338339340