Path: blob/master/runtime/jcl/common/jclcinit.c
6000 views
/*******************************************************************************1* Copyright (c) 1998, 2021 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 <string.h>23#include <ctype.h>2425#include "jcl.h"26#include "j9consts.h"27#include "jvminit.h"28#include "omrgcconsts.h"29#include "jni.h"30#include "j9protos.h"31#include "j9cp.h"32#include "jclprots.h"33#include "exelib_api.h"34#include "util_api.h"35#if defined(J9VM_OPT_SIDECAR)36#include "j2sever.h"37#endif38#include "ut_j9jcl.h"39#include "jclglob.h"40#include "j9version.h"41#include "omrversionstrings.h"42#include "j9modron.h"43#include "omr.h"44#include "vendor_version.h"4546/* The vm version which must match the JCL.47* It has the format 0xAABBCCCC48* AA - vm version, BB - jcl version, CCCC - main version49* CCCC must match exactly with the JCL50* Up the vm version (AA) when adding natives51* BB is the required level of JCL to run the vm52*/53#define JCL_VERSION 0x060402705455extern void *jclConfig;5657static UDATA58doJCLCheck(J9JavaVM *vm, J9Class *j9VMInternalsClass);596061/*62Calculate the value for java.vm.info (and java.fullversion) system/vm properties.63Currently allocates into a fixed-size buffer. This really should be fixed.64*/65jint computeFullVersionString(J9JavaVM* vm)66{67VMI_ACCESS_FROM_JAVAVM((JavaVM*)vm);68PORT_ACCESS_FROM_JAVAVM(vm);69const char *osarch = NULL;70const char *osname = NULL;71const char *j2se_version_info = NULL;72const char *jitEnabled = "";73const char *aotEnabled = "";74const char *memInfo = NULL;75#define BUFFER_SIZE 5127677/* The actual allowed BUFFER_SIZE is 512, the extra 1 char is added to check for overflow */78char vminfo[BUFFER_SIZE + 1];7980#if defined(J9VM_INTERP_NATIVE_SUPPORT)81J9JITConfig *jitConfig = vm->jitConfig;82jitEnabled = "dis";83aotEnabled = "dis";8485if (NULL != jitConfig) {86if (J9_ARE_ALL_BITS_SET(jitConfig->runtimeFlags, J9JIT_JIT_ATTACHED)) {87jitEnabled = "en";88}89if (J9_ARE_ALL_BITS_SET(jitConfig->runtimeFlags, J9JIT_AOT_ATTACHED)) {90aotEnabled = "en";91}92}93#define JIT_INFO " (JIT %sabled, AOT %sabled)\nOpenJ9 - "94#else95#define JIT_INFO "%s%s"96#endif /* J9VM_INTERP_NATIVE_SUPPORT */9798#if JAVA_SPEC_VERSION == 899if ((J2SE_VERSION(vm) & J2SE_RELEASE_MASK) == J2SE_18) {100j2se_version_info = "1.8.0";101} else {102j2se_version_info = "1.8.?";103}104#else /* JAVA_SPEC_VERSION == 8 */105if ((J2SE_VERSION(vm) & J2SE_RELEASE_MASK) == J2SE_CURRENT_VERSION) {106j2se_version_info = JAVA_SPEC_VERSION_STRING;107} else {108j2se_version_info = JAVA_SPEC_VERSION_STRING ".?";109}110#endif /* JAVA_SPEC_VERSION == 8 */111112osname = j9sysinfo_get_OS_type();113osarch = j9sysinfo_get_CPU_architecture();114115#ifdef J9VM_ENV_DATA64116memInfo = J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm) ? "64-Bit Compressed References": "64-Bit";117#else118#if defined(J9ZOS390) || defined(S390)119memInfo = "31-Bit";120#else121memInfo = "32-Bit";122#endif123#endif124125#if defined(J9VM_GC_MODRON_GC)126#define OMR_INFO "\nOMR - " OMR_VERSION_STRING127#else128#define OMR_INFO ""129#endif /* J9VM_GC_MODRON_GC */130131#if defined(OPENJDK_TAG) && defined(OPENJDK_SHA)132#define OPENJDK_INFO "\nJCL - " OPENJDK_SHA " based on " OPENJDK_TAG133#else134#define OPENJDK_INFO ""135#endif /* OPENJDK_TAG && OPENJDK_SHA */136137#if defined(VENDOR_SHORT_NAME) && defined(VENDOR_SHA)138#define VENDOR_INFO "\n" VENDOR_SHORT_NAME " - " VENDOR_SHA139#else140#define VENDOR_INFO ""141#endif /* VENDOR_SHORT_NAME && VENDOR_SHA */142143if (BUFFER_SIZE <= j9str_printf(PORTLIB, vminfo, BUFFER_SIZE + 1,144"JRE %s %s %s-%s %s" JIT_INFO J9VM_VERSION_STRING OMR_INFO VENDOR_INFO OPENJDK_INFO,145j2se_version_info,146(NULL != osname ? osname : " "),147osarch,148memInfo,149EsBuildVersionString,150jitEnabled,151aotEnabled)) {152j9tty_err_printf(PORTLIB, "\n%s - %d: %s: Error: Java VM info string exceeds buffer size\n", __FILE__, __LINE__, __FUNCTION__);153return JNI_ERR;154}155156#undef BUFFER_SIZE157#undef JIT_INFO158#undef MEM_INFO159#undef OMR_INFO160#undef VENDOR_INFO161162(*VMI)->SetSystemProperty(VMI, "java.vm.info", vminfo);163(*VMI)->SetSystemProperty(VMI, "java.fullversion", vminfo);164return JNI_OK;165}166167168static jint initializeStaticMethod(J9JavaVM* vm, UDATA offset)169{170J9ConstantPool * jclConstantPool = (J9ConstantPool *) vm->jclConstantPool;171J9RAMStaticMethodRef * staticMethodConstantPool = (J9RAMStaticMethodRef *) vm->jclConstantPool;172J9ROMMethodRef * romMethodConstantPool = (J9ROMMethodRef *) jclConstantPool->romConstantPool;173J9ROMClass * jclROMClass = jclConstantPool->ramClass->romClass;174UDATA cpType = J9_CP_TYPE(J9ROMCLASS_CPSHAPEDESCRIPTION(jclROMClass), offset);175176if ((J9CPTYPE_STATIC_METHOD == cpType) || (J9CPTYPE_INTERFACE_STATIC_METHOD == cpType)) {177if (NULL == vm->internalVMFunctions->resolveStaticMethodRef(vm->mainThread, jclConstantPool, offset, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_JCL_CONSTANT_POOL)) {178if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romMethodConstantPool[offset].classRefCPIndex)->value) {179Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForMethodRef(vm->mainThread, romMethodConstantPool[offset].classRefCPIndex, offset);180} else {181Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, offset);182return JNI_ERR;183}184} else {185Trc_JCL_initializeKnownClasses_ResolvedStaticMethodRef(vm->mainThread, offset, staticMethodConstantPool[offset].method);186}187}188189return JNI_OK;190}191192#if 0193static jint194initializeInstanceField(J9JavaVM* vm, UDATA offset)195{196J9ConstantPool * jclConstantPool = (J9ConstantPool *) vm->jclConstantPool;197J9RAMFieldRef * instanceFieldConstantPool = (J9RAMFieldRef *) vm->jclConstantPool;198J9ROMFieldRef * romFieldConstantPool = (J9ROMFieldRef *) jclConstantPool->romConstantPool;199J9ROMClass * jclROMClass = jclConstantPool->ramClass->romClass;200U_32 * cpShapeDescription = J9ROMCLASS_CPSHAPEDESCRIPTION(jclROMClass);201202if (J9CPTYPE_FIELD == J9_CP_TYPE(cpShapeDescription, offset)) {203if (-1 == vm->internalVMFunctions->resolveInstanceFieldRef(vm->mainThread, NULL, jclConstantPool, offset, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL)) {204if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romFieldConstantPool[offset].classRefCPIndex)->value) {205Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForInstanceFieldRef(vm->mainThread, romFieldConstantPool[offset].classRefCPIndex, offset);206} else {207Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, offset);208return JNI_ERR;209}210} else {211Trc_JCL_initializeKnownClasses_ResolvedInstanceFieldRef(vm->mainThread, offset, instanceFieldConstantPool[offset].valueOffset);212}213return JNI_OK;214}215216return JNI_EINVAL;217}218#endif219220static jint221initializeStaticField(J9JavaVM* vm, UDATA offset, UDATA resolveFlags)222{223J9ConstantPool * jclConstantPool = (J9ConstantPool *) vm->jclConstantPool;224J9RAMStaticFieldRef * staticFieldConstantPool = (J9RAMStaticFieldRef *) vm->jclConstantPool;225J9ROMFieldRef * romFieldConstantPool = (J9ROMFieldRef *) jclConstantPool->romConstantPool;226J9ROMClass * jclROMClass = jclConstantPool->ramClass->romClass;227U_32 * cpShapeDescription = J9ROMCLASS_CPSHAPEDESCRIPTION(jclROMClass);228229if (J9CPTYPE_FIELD == J9_CP_TYPE(cpShapeDescription, offset)) {230if (NULL == vm->internalVMFunctions->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, offset, resolveFlags, NULL)) {231if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romFieldConstantPool[offset].classRefCPIndex)->value) {232Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForStaticFieldRef(vm->mainThread, romFieldConstantPool[offset].classRefCPIndex, offset);233} else {234Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, offset);235return JNI_ERR;236}237} else {238Trc_JCL_initializeKnownClasses_ResolvedStaticFieldRef(vm->mainThread, offset, J9RAMSTATICFIELDREF_VALUEADDRESS(staticFieldConstantPool + offset));239}240return JNI_OK;241}242return JNI_EINVAL;243}244245jint initializeKnownClasses(J9JavaVM* vm, U_32 runtimeFlags)246{247J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;248J9ConstantPool * jclConstantPool = (J9ConstantPool *) vm->jclConstantPool;249J9RAMFieldRef * instanceFieldConstantPool = (J9RAMFieldRef *) vm->jclConstantPool;250J9RAMStaticFieldRef * staticFieldConstantPool = (J9RAMStaticFieldRef *) vm->jclConstantPool;251J9RAMStaticMethodRef * staticMethodConstantPool = (J9RAMStaticMethodRef *) vm->jclConstantPool;252J9RAMVirtualMethodRef * virtualMethodConstantPool = (J9RAMVirtualMethodRef *) vm->jclConstantPool;253J9RAMSpecialMethodRef * specialMethodConstantPool = (J9RAMSpecialMethodRef *) vm->jclConstantPool;254J9RAMInterfaceMethodRef * interfaceMethodConstantPool = (J9RAMInterfaceMethodRef *) vm->jclConstantPool;255J9ROMFieldRef * romFieldConstantPool = (J9ROMFieldRef *) jclConstantPool->romConstantPool;256J9ROMMethodRef * romMethodConstantPool = (J9ROMMethodRef *) jclConstantPool->romConstantPool;257J9ROMClassRef * romClassConstantPool = (J9ROMClassRef *) jclConstantPool->romConstantPool;258J9ROMClass * jclROMClass = jclConstantPool->ramClass->romClass;259U_32 * cpShapeDescription = J9ROMCLASS_CPSHAPEDESCRIPTION(jclROMClass);260U_32 constPoolCount = jclROMClass->romConstantPoolCount;261U_32 i;262263Trc_JCL_initializeKnownClasses_Entry(vm->mainThread);264265for (i = 0; i < constPoolCount; i++) {266if (J9CPTYPE_FIELD == J9_CP_TYPE(cpShapeDescription, i)) {267J9ROMClassRef* romClassRef = &romClassConstantPool[romMethodConstantPool[i].classRefCPIndex];268269if (0 == (romClassRef->runtimeFlags & runtimeFlags)) {270Trc_JCL_initializeKnownClasses_SkippingResolve(vm->mainThread, i, romClassRef, romClassRef->runtimeFlags, runtimeFlags);271} else {272/* Try resolving as a static fieldref, then as an instance fieldref. */273if (NULL != vmFuncs->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL)) {274Trc_JCL_initializeKnownClasses_ResolvedStaticFieldRef(vm->mainThread, i, J9RAMSTATICFIELDREF_VALUEADDRESS(staticFieldConstantPool + i));275} else if (-1 != vmFuncs->resolveInstanceFieldRef(vm->mainThread, NULL, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL)) {276Trc_JCL_initializeKnownClasses_ResolvedInstanceFieldRef(vm->mainThread, i, instanceFieldConstantPool[i].valueOffset);277} else if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romFieldConstantPool[i].classRefCPIndex)->value) {278/* TODO replace this tracepoint with Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForFieldRef */279Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForInstanceFieldRef(vm->mainThread, romFieldConstantPool[i].classRefCPIndex, i);280} else {281Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, i);282Trc_JCL_Assert_StartupFailure();283return JNI_ERR;284}285}286} else if ((J9CPTYPE_INSTANCE_METHOD == J9_CP_TYPE(cpShapeDescription, i))287|| (J9CPTYPE_INTERFACE_INSTANCE_METHOD == J9_CP_TYPE(cpShapeDescription, i))288) {289J9ROMClassRef* romClassRef = &romClassConstantPool[romMethodConstantPool[i].classRefCPIndex];290291if (0 == (romClassRef->runtimeFlags & runtimeFlags)) {292Trc_JCL_initializeKnownClasses_SkippingResolve(vm->mainThread, i, romClassRef, romClassRef->runtimeFlags, runtimeFlags);293} else {294/* Resolve as both special and virtual method. It is an error for both to fail, but not for one to fail. */295BOOLEAN resolved = FALSE;296J9Method *resolvedMethod;297if (0 != vmFuncs->resolveVirtualMethodRef(vm->mainThread, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_JCL_CONSTANT_POOL, &resolvedMethod)) {298Trc_JCL_initializeKnownClasses_ResolvedVirtualMethodRef(vm->mainThread, i, virtualMethodConstantPool[i].methodIndexAndArgCount);299resolved = TRUE;300}301if (NULL != vmFuncs->resolveSpecialMethodRef(vm->mainThread, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_JCL_CONSTANT_POOL)) {302Trc_JCL_initializeKnownClasses_ResolvedSpecialMethodRef(vm->mainThread, i, specialMethodConstantPool[i].method);303resolved = TRUE;304}305if (!resolved) {306if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romMethodConstantPool[i].classRefCPIndex)->value) {307Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForMethodRef(vm->mainThread, romMethodConstantPool[i].classRefCPIndex, i);308} else {309Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, i);310Trc_JCL_Assert_StartupFailure();311return JNI_ERR;312}313}314}315} else if (J9CPTYPE_STATIC_METHOD == J9_CP_TYPE(cpShapeDescription, i)316|| (J9CPTYPE_INTERFACE_STATIC_METHOD == J9_CP_TYPE(cpShapeDescription, i))317) {318J9ROMClassRef* romClassRef = &romClassConstantPool[romMethodConstantPool[i].classRefCPIndex];319if (0 == (romClassRef->runtimeFlags & runtimeFlags)) {320Trc_JCL_initializeKnownClasses_SkippingResolve(vm->mainThread, i, romClassRef, romClassRef->runtimeFlags, runtimeFlags);321} else {322if (NULL == vmFuncs->resolveStaticMethodRef(vm->mainThread, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_JCL_CONSTANT_POOL)) {323if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romMethodConstantPool[i].classRefCPIndex)->value) {324Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForMethodRef(vm->mainThread, romMethodConstantPool[i].classRefCPIndex, i);325} else {326Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, i);327Trc_JCL_Assert_StartupFailure();328return JNI_ERR;329}330} else {331Trc_JCL_initializeKnownClasses_ResolvedStaticMethodRef(vm->mainThread, i, staticMethodConstantPool[i].method);332}333}334} else if (J9CPTYPE_INTERFACE_METHOD == J9_CP_TYPE(cpShapeDescription, i)) {335J9ROMClassRef* romClassRef = &romClassConstantPool[romMethodConstantPool[i].classRefCPIndex];336if (0 == (romClassRef->runtimeFlags & runtimeFlags)) {337Trc_JCL_initializeKnownClasses_SkippingResolve(vm->mainThread, i, romClassRef, romClassRef->runtimeFlags, runtimeFlags);338} else {339if (NULL == vmFuncs->resolveInterfaceMethodRef(vm->mainThread, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_JCL_CONSTANT_POOL)) {340if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romMethodConstantPool[i].classRefCPIndex)->value) {341Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForMethodRef(vm->mainThread, romMethodConstantPool[i].classRefCPIndex, i);342} else {343Trc_JCL_initializeKnownClasses_ExitError(vm->mainThread, i);344Trc_JCL_Assert_StartupFailure();345return JNI_ERR;346}347} else {348Trc_JCL_initializeKnownClasses_ResolvedInterfaceMethodRef(vm->mainThread, i, interfaceMethodConstantPool[i].methodIndexAndArgCount);349}350}351}352}353354Trc_JCL_initializeKnownClasses_Exit(vm->mainThread);355356return JNI_OK;357}358359360static UDATA361doJCLCheck(J9JavaVM *vm, J9Class *j9VMInternalsClass)362{363J9VMThread *vmThread = vm->mainThread;364J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;365J9ROMStaticFieldShape *jclField;366U_8 *cConfigPtr;367U_8 *jclConfigPtr = NULL;368UDATA jclVersion = -1;369370/* get the jcl specified by the class library (i.e. java.lang.J9VMInternals) */371vmFuncs->staticFieldAddress(vmThread, j9VMInternalsClass, (U_8*)"j9Config", sizeof("j9Config") - 1, (U_8*)"J", 1, NULL, (UDATA *)&jclField, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL);372if (jclField != NULL) {373jclConfigPtr = (U_8 *)&jclField->initialValue;374/* get the jcl version from the class library (i.e. java.lang.J9VMInternals) */375vmFuncs->staticFieldAddress(vmThread, j9VMInternalsClass, (U_8*)"j9Version", sizeof("j9Version") - 1, (U_8*)"I", 1, NULL, (UDATA *)&jclField, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL);376if (jclField != NULL) {377jclVersion = jclField->initialValue;378}379}380381/* get the jcl specified by the DLL */382cConfigPtr = (U_8 *)&jclConfig;383384/* check the values and report any errors */385return checkJCL(vmThread, cConfigPtr, jclConfigPtr, JCL_VERSION, jclVersion);386}387388/**389* Initialize a static int field in a Class.390*391* @param[in] *vmThread the J9VMThread392* @param[in] *clazz the J9Class containing the static field393* @param[in] vmCPIndex the VM constant pool index of the static field ref394* @param[in] value the int value to store in the field395*396* @return a JNI result code397*/398static jint399initializeStaticIntField(J9VMThread *vmThread, J9Class *clazz, UDATA vmCPIndex, I_32 value)400{401jint rc = initializeStaticField(vmThread->javaVM, vmCPIndex, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL);402if (JNI_OK == rc) {403J9STATIC_I32_STORE(vmThread, clazz, J9VMCONSTANTPOOL_STATICFIELD_ADDRESS(vmThread->javaVM, vmCPIndex), value);404}405return rc;406}407408typedef struct {409const UDATA vmCPIndex;410const I_32 value;411} J9IntConstantMapping;412413static const J9IntConstantMapping intVMConstants[] = {414{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_NONE, J9_GC_WRITE_BARRIER_TYPE_NONE },415{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_ALWAYS, J9_GC_WRITE_BARRIER_TYPE_ALWAYS },416{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_OLDCHECK, J9_GC_WRITE_BARRIER_TYPE_OLDCHECK },417{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_CARDMARK, J9_GC_WRITE_BARRIER_TYPE_CARDMARK },418{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_CARDMARK_INCREMENTAL, J9_GC_WRITE_BARRIER_TYPE_CARDMARK_INCREMENTAL },419{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_CARDMARK_AND_OLDCHECK, J9_GC_WRITE_BARRIER_TYPE_CARDMARK_AND_OLDCHECK },420{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_SATB, J9_GC_WRITE_BARRIER_TYPE_SATB },421{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE_SATB_AND_OLDCHECK, J9_GC_WRITE_BARRIER_TYPE_SATB_AND_OLDCHECK },422423{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_ALLOCATION_TYPE_TLH, J9_GC_ALLOCATION_TYPE_TLH },424{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_ALLOCATION_TYPE_SEGREGATED, J9_GC_ALLOCATION_TYPE_SEGREGATED },425426{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_OPTTHRUPUT, J9_GC_POLICY_OPTTHRUPUT },427{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_OPTAVGPAUSE, J9_GC_POLICY_OPTAVGPAUSE },428{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_GENCON, J9_GC_POLICY_GENCON },429{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_BALANCED, J9_GC_POLICY_BALANCED },430{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_METRONOME, J9_GC_POLICY_METRONOME },431{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY_NOGC, J9_GC_POLICY_NOGC },432433{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_JAVA_CLASS_RAM_SHAPE_SHIFT, J9AccClassRAMShapeShift },434{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_OBJECT_HEADER_SHAPE_MASK, OBJECT_HEADER_SHAPE_MASK },435{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_INSTANCESIZE_OFFSET, offsetof(J9Class, totalInstanceSize) },436{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_INSTANCE_DESCRIPTION_OFFSET, offsetof(J9Class, instanceDescription) },437{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_LOCK_OFFSET_OFFSET, offsetof(J9Class, lockOffset) },438{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_LOCK_RESERVATION_HISTORY_RESERVED_COUNTER_OFFSET, offsetof(J9Class, reservedCounter) },439{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_LOCK_RESERVATION_HISTORY_CANCEL_COUNTER_OFFSET, offsetof(J9Class, cancelCounter) },440441{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_INITIALIZE_STATUS_OFFSET, offsetof(J9Class, initializeStatus) },442{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_SIZE, (I_32)sizeof(J9Class) },443{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_ADDRESS_SIZE, (I_32)sizeof(UDATA) },444{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_CLASS_DEPTH_AND_FLAGS_OFFSET, offsetof(J9Class, classDepthAndFlags) },445{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_INIT_SUCCEEDED, J9ClassInitSucceeded },446{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_SUPERCLASSES_OFFSET, offsetof(J9Class, superclasses) },447{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_ROMCLASS_OFFSET, offsetof(J9Class, romClass) },448{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9ROMCLASS_MODIFIERS_OFFSET, offsetof(J9ROMClass, modifiers) },449{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_JAVA_CLASS_DEPTH_MASK, J9AccClassDepthMask },450{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_JAVA_CLASS_MASK, ~(J9_REQUIRED_CLASS_ALIGNMENT - 1) },451{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_ACC_CLASS_INTERNAL_PRIMITIVE_TYPE, J9AccClassInternalPrimitiveType },452{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_ACC_CLASS_ARRAY, J9AccClassArray },453{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_OBJECT_HEADER_HAS_BEEN_MOVED_IN_CLASS, OBJECT_HEADER_HAS_BEEN_MOVED_IN_CLASS },454#if defined(J9VM_ENV_LITTLE_ENDIAN)455{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_IS_BIG_ENDIAN, JNI_FALSE},456#else457{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_IS_BIG_ENDIAN, JNI_TRUE},458#endif459{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_CLASSLOADER_TYPE_OTHERS, J9_CLASSLOADER_TYPE_OTHERS },460{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_CLASSLOADER_TYPE_BOOT, J9_CLASSLOADER_TYPE_BOOT },461{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_CLASSLOADER_TYPE_PLATFORM, J9_CLASSLOADER_TYPE_PLATFORM },462{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9CLASS_RESERVABLE_LOCK_WORD_INIT, J9ClassReservableLockWordInit },463{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_OBJECT_HEADER_LOCK_RESERVED, OBJECT_HEADER_LOCK_RESERVED },464{ J9VMCONSTANTPOOL_COMIBMOTIVMVM_OBJECT_HEADER_LOCK_LEARNING, OBJECT_HEADER_LOCK_LEARNING },465};466467/**468* Initialize all of the constants in com.ibm.oti.vm.VM469*470* @param[in] *currentThread the current J9VMThread471*472* @return a JNI result code473*/474static jint475intializeVMConstants(J9VMThread *currentThread)476{477J9JavaVM *vm = currentThread->javaVM;478OMR_VM *omrVM = (OMR_VM *)vm->omrVM;479jint rc = JNI_ERR;480UDATA i = 0;481/* Load the VM class and mark it as initialized to prevent running the <clinit> */482J9Class *vmClass = vm->internalVMFunctions->internalFindKnownClass(currentThread, J9VMCONSTANTPOOL_COMIBMOTIVMVM, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);483if ((NULL == vmClass) || (NULL != currentThread->currentException)) {484goto done;485}486vmClass->initializeStatus = J9ClassInitSucceeded;487488/* Initialize non-constant fields */489rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_WRITE_BARRIER_TYPE, (I_32)vm->gcWriteBarrierType);490if (JNI_OK != rc) {491goto done;492}493rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_ALLOCATION_TYPE, (I_32)vm->gcAllocationType);494if (JNI_OK != rc) {495goto done;496}497rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_GC_POLICY, (I_32)omrVM->gcPolicy);498if (JNI_OK != rc) {499goto done;500}501502rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_JIT_STRING_DEDUP_POLICY, vm->memoryManagerFunctions->j9gc_get_jit_string_dedup_policy(vm));503if (JNI_OK != rc) {504goto done;505}506507rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_J9_STRING_COMPRESSION_ENABLED, (I_32)IS_STRING_COMPRESSION_ENABLED_VM(vm));508if (JNI_OK != rc) {509goto done;510}511512rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_OBJECT_HEADER_SIZE, (I_32)J9JAVAVM_OBJECT_HEADER_SIZE(vm));513if (JNI_OK != rc) {514goto done;515}516517rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_FJ9OBJECT_SIZE, (I_32)J9JAVAVM_REFERENCE_SIZE(vm));518if (JNI_OK != rc) {519goto done;520}521522rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_GLR_ENABLE_GLOBAL_LOCK_RESERVATION, (I_32)vm->enableGlobalLockReservation);523if (JNI_OK != rc) {524goto done;525}526527rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_GLR_RESERVED_ABSOLUTE_THRESHOLD, (I_32)vm->reservedAbsoluteThreshold);528if (JNI_OK != rc) {529goto done;530}531532rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_GLR_MINIMUM_RESERVED_RATIO, (I_32)vm->minimumReservedRatio);533if (JNI_OK != rc) {534goto done;535}536537rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_GLR_CANCEL_ABSOLUTE_THRESHOLD, (I_32)vm->cancelAbsoluteThreshold);538if (JNI_OK != rc) {539goto done;540}541542rc = initializeStaticIntField(currentThread, vmClass, J9VMCONSTANTPOOL_COMIBMOTIVMVM_GLR_MINIMUM_LEARNING_RATIO, (I_32)vm->minimumLearningRatio);543if (JNI_OK != rc) {544goto done;545}546547/* Initialize constant int fields */548for (i = 0; i < sizeof(intVMConstants) / sizeof(J9IntConstantMapping); ++i) {549UDATA vmCPIndex = intVMConstants[i].vmCPIndex;550I_32 value = intVMConstants[i].value;551rc = initializeStaticIntField(currentThread, vmClass, vmCPIndex, value);552if (JNI_OK != rc) {553goto done;554}555}556done:557return rc;558}559560#define ADDMODS_PROPERTY_BASE "jdk.module.addmods."561UDATA562initializeRequiredClasses(J9VMThread *vmThread, char* dllName)563{564J9JavaVM *vm = vmThread->javaVM;565J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;566J9MemoryManagerFunctions *gcFuncs = vm->memoryManagerFunctions;567UDATA jniVersion, i;568J9Class *objectClass;569J9Class *vmInternalsClass;570J9Class *classClass;571J9Class *clazz;572J9Class *stringClass;573J9Class *lockClass;574J9ClassWalkState state;575J9NativeLibrary* nativeLibrary = NULL;576j9object_t oom;577PORT_ACCESS_FROM_JAVAVM(vm);578static UDATA requiredClasses[] = {579J9VMCONSTANTPOOL_JAVALANGTHREAD,580J9VMCONSTANTPOOL_JAVALANGCLASSLOADER,581J9VMCONSTANTPOOL_JAVALANGSTACKTRACEELEMENT,582J9VMCONSTANTPOOL_JAVALANGTHROWABLE,583J9VMCONSTANTPOOL_JAVALANGSTACKOVERFLOWERROR,584J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,585J9VMCONSTANTPOOL_JAVALANGLINKAGEERROR,586J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR,587J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION,588#if JAVA_SPEC_VERSION >= 15589J9VMCONSTANTPOOL_JDKINTERNALLOADERNATIVELIBRARIES,590J9VMCONSTANTPOOL_JDKINTERNALLOADERNATIVELIBRARIESNATIVELIBRARYIMPL,591#endif /* JAVA_SPEC_VERSION >= 15 */592#if JAVA_SPEC_VERSION >= 18593J9VMCONSTANTPOOL_JAVALANGINVOKEMETHODHANDLENATIVES,594#endif /* JAVA_SPEC_VERSION >= 18 */595};596597/* Determine java/lang/String.value signature before any required class is initialized */598if (J2SE_VERSION(vm) >= J2SE_V11) {599vm->runtimeFlags |= J9_RUNTIME_STRING_BYTE_ARRAY;600}601602/* CANNOT hold VM Access while calling registerBootstrapLibrary */603vmFuncs->internalReleaseVMAccess(vmThread);604605if (vmFuncs->registerBootstrapLibrary(vmThread, dllName, &nativeLibrary, FALSE) != J9NATIVELIB_LOAD_OK) {606return 1;607}608609/* If we have a JitConfig, add the JIT dll to the bootstrap loader so we can add JNI natives in the JIT */610if (NULL != vm->jitConfig) {611J9NativeLibrary* jitLibrary = NULL;612613if (vmFuncs->registerBootstrapLibrary(vmThread, J9_JIT_DLL_NAME, &jitLibrary, FALSE) != J9NATIVELIB_LOAD_OK) {614return 1;615}616}617vmFuncs->internalAcquireVMAccess(vmThread);618619/* request an extra slot in java/lang/Module which we will use to connect native data to the Module object */620if (0 != vmFuncs->addHiddenInstanceField(vm, "java/lang/Module", "modulePointer", "J", &vm->modulePointerOffset)) {621return 1;622}623624#ifdef J9VM_OPT_OPENJDK_METHODHANDLE625if (0 != vmFuncs->addHiddenInstanceField(vm, "java/lang/invoke/MemberName", "vmindex", "J", &vm->vmindexOffset)) {626return 1;627}628629if (0 != vmFuncs->addHiddenInstanceField(vm, "java/lang/invoke/MemberName", "vmtarget", "J", &vm->vmtargetOffset)) {630return 1;631}632633if (0 != vmFuncs->addHiddenInstanceField(vm, "java/lang/invoke/MutableCallSite", "invalidationCookie", "J", &vm->mutableCallSiteInvalidationCookieOffset)) {634return 1;635}636637if (0 != vmFuncs->addHiddenInstanceField(vm, "java/lang/invoke/MethodHandle", "jitVMEntryKeepAlive", "Ljava/lang/invoke/MemberName;", &vm->jitVMEntryKeepAliveOffset)) {638return 1;639}640#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */641642643vmThread->privateFlags |= J9_PRIVATE_FLAGS_REPORT_ERROR_LOADING_CLASS;644645objectClass = vmFuncs->internalFindKnownClass(vmThread, J9VMCONSTANTPOOL_JAVALANGOBJECT, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);646if (NULL == objectClass) {647return 1;648}649vmInternalsClass = vmFuncs->internalFindKnownClass(vmThread, J9VMCONSTANTPOOL_JAVALANGJ9VMINTERNALS, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);650if ((NULL == vmInternalsClass) || (NULL != vmThread->currentException)) {651return 1;652}653vmInternalsClass->initializeStatus = J9ClassInitSucceeded;654if (JNI_OK != intializeVMConstants(vmThread)) {655return 1;656}657658if (doJCLCheck(vm, vmInternalsClass) != 0) {659return 1;660}661662/* Load ClassInitializationLock as early as possible */663664lockClass = vmFuncs->internalFindKnownClass(vmThread, J9VMCONSTANTPOOL_JAVALANGJ9VMINTERNALSCLASSINITIALIZATIONLOCK, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);665if ((NULL == lockClass) || (NULL != vmThread->currentException)) {666return 1;667}668lockClass->initializeStatus = J9ClassInitSucceeded;669670/* Load java.lang.Class. This makes sure that the slot in the known class array is filled in. Since671* the slot was previously uninitialized, set the class of all existing classes java.lang.Class. Subsequent672* class creations will correctly initialize the value from the slot in the known class array. This code673* runs only in JNI_CreateJavaVM, so no need to mutex the class table access.674*/675676classClass = vmFuncs->internalFindKnownClass(vmThread, J9VMCONSTANTPOOL_JAVALANGCLASS, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);677if ((NULL == classClass) || (NULL != vmThread->currentException)) {678return 1;679}680681clazz = vmFuncs->allClassesStartDo(&state, vm, vm->systemClassLoader);682do {683j9object_t classObj = gcFuncs->J9AllocateObject(vmThread, classClass, J9_GC_ALLOCATE_OBJECT_TENURED | J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE | J9_GC_ALLOCATE_OBJECT_HASHED);684j9object_t lockObject;685UDATA allocateFlags = J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE;686687if (NULL == classObj) {688return 1;689}690J9VMJAVALANGCLASS_SET_VMREF(vmThread, classObj, clazz);691clazz->classObject = classObj;692lockObject = gcFuncs->J9AllocateObject(vmThread, lockClass, allocateFlags);693classObj = clazz->classObject;694if (lockObject == NULL) {695return 1;696}697J9VMJAVALANGJ9VMINTERNALSCLASSINITIALIZATIONLOCK_SET_THECLASS(vmThread, lockObject, (j9object_t)classObj);698J9VMJAVALANGCLASS_SET_INITIALIZATIONLOCK(vmThread, (j9object_t)classObj, lockObject);699} while ((clazz = vmFuncs->allClassesNextDo(&state)) != NULL);700vmFuncs->allClassesEndDo(&state);701702/* This runtime flag indicates that j.l.Class has been loaded, and all classes have a valid classObject.703* It is not safe to invoke GC before this point.704*/705vm->extendedRuntimeFlags |= J9_EXTENDED_RUNTIME_CLASS_OBJECT_ASSIGNED;706707if (vmFuncs->internalCreateBaseTypePrimitiveAndArrayClasses(vmThread) != 0) {708return 1;709}710711/* Initialize early since sendInitialize() uses this */712if (initializeStaticMethod(vm, J9VMCONSTANTPOOL_JAVALANGJ9VMINTERNALS_INITIALIZATIONALREADYFAILED)) {713return 1;714}715if (initializeStaticMethod(vm, J9VMCONSTANTPOOL_JAVALANGJ9VMINTERNALS_RECORDINITIALIZATIONFAILURE)) {716return 1;717}718/* Load java.lang.String. This makes sure that the slot in the known class array is filled in.719* String may be needed to initialize Object.720*/721stringClass = vmFuncs->internalFindKnownClass(vmThread, J9VMCONSTANTPOOL_JAVALANGSTRING, J9_FINDKNOWNCLASS_FLAG_NON_FATAL);722if ((NULL == stringClass) || (NULL != vmThread->currentException)) {723return 1;724}725726/* Initialize the java.lang.String.compressionFlag static field early enough so that we have727* access to it during the resolution of other classes in which Strings may need to be created728* in StringTable.cpp729*/730if (initializeStaticField(vm, J9VMCONSTANTPOOL_JAVALANGSTRING_COMPRESSIONFLAG, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL | J9_RESOLVE_FLAG_NO_CLASS_INIT)) {731return 1;732}733734/* Run the JCL initialization code (what used to be JNI_OnLoad) */735jniVersion = nativeLibrary->send_lifecycle_event(vmThread, nativeLibrary, "JCL_OnLoad", JNI_VERSION_1_1);736if (!vmFuncs->jniVersionIsValid(jniVersion)) {737return 1;738}739740/* Initialize java.lang.String which will also initialize java.lang.Object. */741vmFuncs->initializeClass(vmThread, stringClass);742if (vmThread->currentException != NULL) {743return 1;744}745746/* Initialize java.lang.Class. */747vmFuncs->initializeClass(vmThread, classClass);748if (vmThread->currentException != NULL) {749return 1;750}751752/* Load some other needed classes. */753for (i=0; i < sizeof(requiredClasses) / sizeof(UDATA); i++) {754clazz = vmFuncs->internalFindKnownClass(vmThread, requiredClasses[i], J9_FINDKNOWNCLASS_FLAG_NON_FATAL);755if ((NULL == clazz) || (NULL != vmThread->currentException)) {756Trc_JCL_initializeRequiredClasses_ExitError(vmThread, i);757Trc_JCL_Assert_StartupFailure();758return 1;759}760vmFuncs->initializeClass(vmThread, clazz);761if (NULL != vmThread->currentException) {762return 1;763}764}765766if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_LOAD_AGENT_MODULE)767&& (NULL != vm->modulesPathEntry->extraInfo))768{769const char *packageName = "jdk/internal/agent";770const char *expectedModuleName = "jdk.management.agent";771const char *moduleName = vm->jimageIntf->jimagePackageToModule(772vm->jimageIntf, (UDATA) vm->modulesPathEntry->extraInfo,773packageName);774if (NULL == moduleName) {775Trc_JCL_initializeRequiredClasses_moduleForPackageNotFound(vmThread, packageName);776} else if (0 != strcmp(expectedModuleName, moduleName)) {777Trc_JCL_initializeRequiredClasses_unexpectedModuleForPackage(vmThread, packageName, moduleName, expectedModuleName);778} else {779J9VMSystemProperty *systemProperty = NULL;780Trc_JCL_initializeRequiredClasses_addAgentModuleEntry(vmThread, moduleName);781/* Handle the case where there are no user-specified modules. In this case, there782* is typically one system property but no user-set "add-modules" arguments.783*/784if ((0 == vm->addModulesCount)785&& (J9SYSPROP_ERROR_NONE == vmFuncs->getSystemProperty(vm, ADDMODS_PROPERTY_BASE "0", &systemProperty)))786{787/* this is implicitly an unused property */788vmFuncs->setSystemProperty(vm, systemProperty, moduleName);789} else {790UDATA indexLen = j9str_printf(PORTLIB, NULL, 0, "%zu", vm->addModulesCount); /* get the length of the number string */791char *propNameBuffer = j9mem_allocate_memory(sizeof(ADDMODS_PROPERTY_BASE) + indexLen, OMRMEM_CATEGORY_VM);792if (NULL == propNameBuffer) {793Trc_JCL_initializeRequiredClasses_addAgentModuleOutOfMemory(vmThread);794return 1;795}796j9str_printf(PORTLIB, propNameBuffer, sizeof(ADDMODS_PROPERTY_BASE) + indexLen, ADDMODS_PROPERTY_BASE "%zu", vm->addModulesCount);797Trc_JCL_initializeRequiredClasses_addAgentModuleSetProperty(vmThread, propNameBuffer, moduleName);798vmFuncs->addSystemProperty(vm, propNameBuffer, moduleName, J9SYSPROP_FLAG_NAME_ALLOCATED);799}800vm->addModulesCount += 1;801}802}803804if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_LOAD_HEALTHCENTER_MODULE)805&& (NULL != vm->modulesPathEntry->extraInfo))806{807const char *packageName = "com/ibm/java/diagnostics/healthcenter/agent";808const char *expectedModuleName = "ibm.healthcenter";809const char *moduleName = vm->jimageIntf->jimagePackageToModule(810vm->jimageIntf, (UDATA) vm->modulesPathEntry->extraInfo,811packageName);812if (NULL == moduleName) {813Trc_JCL_initializeRequiredClasses_moduleForPackageNotFound(vmThread, packageName);814} else if (0 != strcmp(expectedModuleName, moduleName)) {815// package %s found in module %s (expected %s) - not loading"816Trc_JCL_initializeRequiredClasses_unexpectedModuleForPackage(vmThread, packageName, moduleName, expectedModuleName);817} else {818J9VMSystemProperty *systemProperty = NULL;819Trc_JCL_initializeRequiredClasses_addAgentModuleEntry(vmThread, moduleName);820/* Handle the case where there are no user-specified modules. In this case, there821* is typically one system property but no user-set "add-modules" arguments.822*/823if ((0 == vm->addModulesCount)824&& (J9SYSPROP_ERROR_NONE == vmFuncs->getSystemProperty(vm, ADDMODS_PROPERTY_BASE "0", &systemProperty)))825{826/* this is implicitly an unused property */827vmFuncs->setSystemProperty(vm, systemProperty, moduleName);828} else {829UDATA indexLen = j9str_printf(PORTLIB, NULL, 0, "%zu", vm->addModulesCount); /* get the length of the number string */830char *propNameBuffer = j9mem_allocate_memory(sizeof(ADDMODS_PROPERTY_BASE) + indexLen, OMRMEM_CATEGORY_VM);831if (NULL == propNameBuffer) {832Trc_JCL_initializeRequiredClasses_addAgentModuleOutOfMemory(vmThread);833return 1;834}835j9str_printf(PORTLIB, propNameBuffer, sizeof(ADDMODS_PROPERTY_BASE) + indexLen, ADDMODS_PROPERTY_BASE "%zu", vm->addModulesCount);836Trc_JCL_initializeRequiredClasses_addAgentModuleSetProperty(vmThread, propNameBuffer, moduleName);837vmFuncs->addSystemProperty(vm, propNameBuffer, moduleName, J9SYSPROP_FLAG_NAME_ALLOCATED);838}839vm->addModulesCount += 1;840}841}842843vmThread->privateFlags &= (~J9_PRIVATE_FLAGS_REPORT_ERROR_LOADING_CLASS);844845/* Create an OutOfMemoryError now in case we run out during startup846* (1GDH3HI: J9VM:Neutrino - GPF reading manifest file during class loading).847*/848oom = vmFuncs->createCachedOutOfMemoryError(vmThread, NULL);849if (NULL == oom) {850return 1;851}852vmThread->outOfMemoryError = oom;853854return 0;855}856#undef ADDMODS_PROPERTY_BASE857858859