Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/j9vm/java11vmi.c
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2015, 2022 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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-exception
21
*******************************************************************************/
22
23
#include <assert.h>
24
#include "vm_api.h"
25
#include "j2sever.h"
26
#include "j9.h"
27
#include "hashtable_api.h"
28
#include "../util/ut_module.h"
29
#undef UT_MODULE_LOADED
30
#undef UT_MODULE_UNLOADED
31
#include "ut_j9scar.h"
32
#include "jclprots.h"
33
#include "jvminit.h"
34
#include "util_api.h"
35
#include "j9vmnls.h"
36
#include "j9version.h"
37
38
#if JAVA_SPEC_VERSION >= 11
39
40
#define J9TIME_NANOSECONDS_PER_SECOND ((jlong) 1000000000)
41
/* Need to do a |currentSecondsTime - secondsOffset| < (2^32) check to ensure that the
42
* resulting time fits into a long so it doesn't overflow. This is equivalent to doing
43
* |currentNanoTime - nanoTimeOffset| < 4294967295000000000.
44
*/
45
#define TIME_LONG_MAX ((jlong) 4294967295000000000LL)
46
#define TIME_LONG_MIN ((jlong)-4294967295000000000LL)
47
#define OFFSET_MAX ((jlong) 0x225C17D04LL) /* 2^63/10^9 */
48
#define OFFSET_MIN ((jlong) 0xFFFFFFFDDA3E82FCLL) /* -2^63/10^9 */
49
50
#define HASHTABLE_ATPUT_GENERAL_FAILURE ((UDATA) 1U)
51
#define HASHTABLE_ATPUT_COLLISION_FAILURE ((UDATA) 2U)
52
#define HASHTABLE_ATPUT_SUCCESS ((UDATA) 0U)
53
54
#define INITIAL_INTERNAL_MODULE_HASHTABLE_SIZE 1
55
#define INITIAL_INTERNAL_PACKAGE_HASHTABLE_SIZE 1
56
57
/* All the helper functions below assume that:
58
* a) If VMAccess is required, it assumes the caller has already done so
59
* b) If performing a hash operation, it assumes the caller has already locked vm->classLoaderModuleAndLocationMutex
60
*/
61
static UDATA hashPackageTableDelete(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName);
62
static J9Package * createPackage(J9VMThread * currentThread, J9Module * fromModule, const char *package);
63
static void freePackageDefinition(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName);
64
static BOOLEAN removePackageDefinition(J9VMThread * currentThread, J9Module * fromModule, const char *packageName);
65
static BOOLEAN addPackageDefinition(J9VMThread * currentThread, J9Module * fromModule, const char *package);
66
static UDATA addMulPackageDefinitions(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 numPackages);
67
static void removeMulPackageDefinitions(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 packagesIndex);
68
static UDATA addModuleDefinition(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 numPackages, jstring version);
69
static BOOLEAN isPackageDefined(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName);
70
static BOOLEAN areNoPackagesDefined(J9VMThread * currentThread, J9ClassLoader * classLoader, const char* const* packages, U_32 numPackages);
71
static UDATA exportPackageToAll(J9VMThread * currentThread, J9Module * fromModule, const char *package);
72
static UDATA exportPackageToAllUnamed(J9VMThread * currentThread, J9Module * fromModule, const char *package);
73
static UDATA exportPackageToModule(J9VMThread * currentThread, J9Module * fromModule, const char *package, J9Module * toModule);
74
static void trcModulesCreationPackage(J9VMThread * currentThread, J9Module * fromModule, const char *package);
75
static void trcModulesAddModuleExportsToAll(J9VMThread * currentThread, J9Module * fromModule, const char *package);
76
static void trcModulesAddModuleExportsToAllUnnamed(J9VMThread * currentThread, J9Module * fromModule, const char *package);
77
static void trcModulesAddModuleExports(J9VMThread * currentThread, J9Module * fromModule, const char *package, J9Module * toModule);
78
static void trcModulesAddModulePackage(J9VMThread *currentThread, J9Module *j9mod, const char *package);
79
static UDATA hashTableAtPut(J9HashTable * table, void * value, BOOLEAN collisionIsFailure);
80
static void throwExceptionHelper(J9VMThread * currentThread, UDATA errCode);
81
static void freePackage(J9VMThread * currentThread, J9Package * j9package);
82
static J9ClassLoader * getModuleObjectClassLoader(J9VMThread * currentThread, j9object_t moduleObject);
83
static J9Module * createModule(J9VMThread * currentThread, j9object_t moduleObject, J9ClassLoader * classLoader, j9object_t moduleName);
84
static J9Module * getJ9Module(J9VMThread * currentThread, jobject module);
85
static BOOLEAN isModuleNameValid(j9object_t moduleName);
86
static BOOLEAN isModuleJavaBase(j9object_t moduleName);
87
static BOOLEAN isModuleNameGood(j9object_t moduleName);
88
static UDATA allowReadAccessToModule(J9VMThread * currentThread, J9Module * fromModule, J9Module * toModule);
89
static void trcModulesAddReadsModule(J9VMThread *currentThread, jobject toModule, J9Module *j9FromMod, J9Module *j9ToMod);
90
91
92
#if !defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
93
/* These come from jvm.c */
94
extern IDATA (*f_monitorEnter)(omrthread_monitor_t monitor);
95
extern IDATA (*f_monitorExit)(omrthread_monitor_t monitor);
96
#endif /* !defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
97
98
static UDATA
99
hashTableAtPut(J9HashTable * table, void * value, BOOLEAN collisionIsFailure)
100
{
101
UDATA retval = HASHTABLE_ATPUT_GENERAL_FAILURE;
102
void * node = NULL;
103
104
/* hashTableAdd() will return the conflicting entry found in the hash in case of collision. Therefore,
105
* we can't use it to figure out whether our value is already found in the has
106
*/
107
node = hashTableFind(table, value);
108
109
/* If no conflicting entry is found ... */
110
if (NULL == node) {
111
node = hashTableAdd(table, value);
112
113
if (NULL != node) {
114
retval = HASHTABLE_ATPUT_SUCCESS;
115
}
116
} else if (collisionIsFailure) {
117
retval = HASHTABLE_ATPUT_COLLISION_FAILURE;
118
} else {
119
Trc_MODULE_hashTableAtPut(table, value, node);
120
retval = HASHTABLE_ATPUT_SUCCESS;
121
}
122
123
return retval;
124
}
125
126
static UDATA
127
hashPackageTableDelete(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName)
128
{
129
J9HashTable * table = classLoader->packageHashTable;
130
J9Package package = {0};
131
J9Package * packagePtr = &package;
132
PORT_ACCESS_FROM_VMC(currentThread);
133
UDATA rc = 1; /* hashTableRemove failure code */
134
U_8 buf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
135
136
if (!addUTFNameToPackage(currentThread, packagePtr, packageName, buf, J9VM_PACKAGE_NAME_BUFFER_LENGTH)) {
137
return rc;
138
}
139
140
rc = hashTableRemove(table, &package);
141
142
if ((U_8 *) package.packageName != (U_8 *)buf) {
143
j9mem_free_memory((void *) package.packageName);
144
}
145
return rc;
146
}
147
148
/** @todo The strings below need to be NLS and also provide more debug info */
149
static void
150
throwExceptionHelper(J9VMThread * currentThread, UDATA errCode)
151
{
152
J9JavaVM const * const vm = currentThread->javaVM;
153
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
154
155
J9_DECLARE_CONSTANT_UTF8(errGeneralFailure, "general failure");
156
J9_DECLARE_CONSTANT_UTF8(errPackageAlreadyDefined, "a package in the list has already been define");
157
J9_DECLARE_CONSTANT_UTF8(errModuleAlreadyDefined, "the module has already been defined");
158
J9_DECLARE_CONSTANT_UTF8(errHashTableOperationFailed, "hash operation failed");
159
J9_DECLARE_CONSTANT_UTF8(errDuplicatePackageInList, "the list contains duplicate packages");
160
J9_DECLARE_CONSTANT_UTF8(errModuleWasntFound, "module was not found");
161
J9_DECLARE_CONSTANT_UTF8(errPackageWasntFound, "package was not found");
162
163
static J9UTF8 const * const errMessages[] = {
164
NULL, /* ERRCODE_SUCCESS */
165
(J9UTF8*)&errGeneralFailure, /* ERRCODE_GENERAL_FAILURE */
166
(J9UTF8*)&errPackageAlreadyDefined, /* ERRCODE_PACKAGE_ALREADY_DEFINED */
167
(J9UTF8*)&errModuleAlreadyDefined, /* ERRCODE_MODULE_ALREADY_DEFINED */
168
(J9UTF8*)&errHashTableOperationFailed, /* ERRCODE_HASHTABLE_OPERATION_FAILED */
169
(J9UTF8*)&errDuplicatePackageInList, /* ERRCODE_DUPLICATE_PACKAGE_IN_LIST */
170
(J9UTF8*)&errModuleWasntFound, /* ERRCODE_MODULE_WASNT_FOUND */
171
(J9UTF8*)&errPackageWasntFound /* ERRCODE_PACKAGE_WASNT_FOUND */
172
};
173
174
if (ERRCODE_SUCCESS != errCode) {
175
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, (const char*)errMessages[errCode]);
176
}
177
}
178
179
static void
180
freePackage(J9VMThread * currentThread, J9Package * j9package)
181
{
182
if (NULL != j9package) {
183
J9JavaVM * const vm = currentThread->javaVM;
184
PORT_ACCESS_FROM_JAVAVM(vm);
185
186
if (NULL != j9package->exportsHashTable) {
187
hashTableFree(j9package->exportsHashTable);
188
}
189
j9mem_free_memory((void *) j9package->packageName);
190
pool_removeElement(vm->modularityPool, j9package);
191
}
192
}
193
194
static J9Package *
195
createPackage(J9VMThread * currentThread, J9Module * fromModule, const char *package)
196
{
197
J9JavaVM * const vm = currentThread->javaVM;
198
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
199
J9Package * retval = NULL;
200
201
J9ClassLoader * const classLoader = fromModule->classLoader;
202
J9Package * j9package = pool_newElement(vm->modularityPool);
203
204
if (NULL != j9package) {
205
j9package->module = fromModule;
206
j9package->classLoader = fromModule->classLoader;
207
if (!addUTFNameToPackage(currentThread, j9package, package, NULL, 0)) {
208
freePackage(currentThread, j9package);
209
return retval;
210
}
211
j9package->exportsHashTable = vmFuncs->hashModulePointerTableNew(vm, INITIAL_INTERNAL_MODULE_HASHTABLE_SIZE);
212
if (NULL != j9package->exportsHashTable) {
213
retval = j9package;
214
}
215
}
216
217
/* if we failed to create the package */
218
if (NULL == retval) {
219
if (NULL != j9package) {
220
freePackage(currentThread, j9package);
221
}
222
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
223
}
224
225
return retval;
226
}
227
228
/** @note It assumes moduleObject is guaranteed not to be NULL
229
* @return Pointer to module's classloader
230
*/
231
static J9ClassLoader *
232
getModuleObjectClassLoader(J9VMThread * currentThread, j9object_t moduleObject)
233
{
234
j9object_t classLoader = J9VMJAVALANGMODULE_LOADER(currentThread, moduleObject);
235
if (NULL == classLoader) {
236
return currentThread->javaVM->systemClassLoader;
237
} else {
238
J9ClassLoader *loader = J9VMJAVALANGCLASSLOADER_VMREF(currentThread, classLoader);
239
if (NULL == loader) {
240
J9JavaVM * const vm = currentThread->javaVM;
241
loader = vm->internalVMFunctions->internalAllocateClassLoader(vm, classLoader);
242
}
243
return loader;
244
}
245
}
246
247
/** @throws OutOfMemory exception if memory cannot be allocated */
248
static J9Module *
249
createModule(J9VMThread * currentThread, j9object_t moduleObject, J9ClassLoader * classLoader, j9object_t moduleName)
250
{
251
J9JavaVM * const vm = currentThread->javaVM;
252
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
253
J9Module * j9mod = NULL;
254
J9Module * retval = NULL;
255
256
if (J9_ARE_ALL_BITS_SET(vm->runtimeFlags, J9_RUNTIME_JAVA_BASE_MODULE_CREATED)) {
257
j9mod = pool_newElement(vm->modularityPool);
258
} else {
259
if (NULL == moduleName) {
260
/* moduleName is passed as NULL for the unnamed module for bootloader created by JVM_SetBootLoaderUnnamedModule() */
261
j9mod = vm->unamedModuleForSystemLoader;
262
} else {
263
j9mod = vm->javaBaseModule;
264
j9mod->isLoose = TRUE;
265
}
266
}
267
if (NULL != j9mod) {
268
j9mod->moduleName = moduleName;
269
270
j9mod->readAccessHashTable = vmFuncs->hashModulePointerTableNew(vm, INITIAL_INTERNAL_MODULE_HASHTABLE_SIZE);
271
272
if (NULL != j9mod->readAccessHashTable) {
273
j9mod->classLoader = classLoader;
274
/* The GC is expected to update pointer below if it moves the object */
275
j9mod->moduleObject = moduleObject;
276
277
/* Bind J9Module and module object via the hidden field */
278
J9OBJECT_ADDRESS_STORE(currentThread, moduleObject, vm->modulePointerOffset, j9mod);
279
280
retval = j9mod;
281
}
282
}
283
284
/* If we failed to create the module */
285
if (NULL == retval) {
286
if (NULL != j9mod) {
287
vmFuncs->freeJ9Module(vm, j9mod);
288
}
289
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
290
}
291
292
return retval;
293
}
294
295
static void
296
freePackageDefinition(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName)
297
{
298
J9Package * j9package = hashPackageTableAt(currentThread, classLoader, packageName);
299
300
if (NULL != j9package) {
301
freePackage(currentThread, j9package);
302
}
303
}
304
305
static BOOLEAN
306
removePackageDefinition(J9VMThread * currentThread, J9Module * fromModule, const char *packageName)
307
{
308
J9ClassLoader * const classLoader = fromModule->classLoader;
309
310
BOOLEAN const retval = (0 == hashPackageTableDelete(currentThread, classLoader, packageName));
311
312
freePackageDefinition(currentThread, classLoader, packageName);
313
314
return retval;
315
}
316
317
static void
318
trcModulesCreationPackage(J9VMThread * currentThread, J9Module * fromModule, const char *package)
319
{
320
PORT_ACCESS_FROM_VMC(currentThread);
321
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
322
char moduleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
323
char *moduleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
324
currentThread, fromModule->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, moduleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
325
326
if (NULL != moduleNameUTF) {
327
if (0 == strcmp(moduleNameUTF, JAVA_BASE_MODULE)) {
328
Trc_MODULE_createPackage(currentThread, package, "java.base", fromModule);
329
} else {
330
Trc_MODULE_createPackage(currentThread, package, moduleNameUTF, fromModule);
331
}
332
if (moduleNameBuf != moduleNameUTF) {
333
j9mem_free_memory(moduleNameUTF);
334
}
335
} else {
336
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
337
}
338
}
339
340
static BOOLEAN
341
addPackageDefinition(J9VMThread * currentThread, J9Module * fromModule, const char *package)
342
{
343
J9ClassLoader * const classLoader = fromModule->classLoader;
344
345
BOOLEAN retval = FALSE;
346
347
J9Package * j9package = createPackage(currentThread, fromModule, package);
348
349
if (NULL != j9package) {
350
Trc_MODULE_invokeHashTableAtPut(currentThread, "addPackageDefinition", classLoader, classLoader->packageHashTable, &j9package, j9package, "true");
351
retval = (0 == hashTableAtPut(classLoader->packageHashTable, (void*)&j9package, TRUE));
352
}
353
354
if (!retval) {
355
freePackage(currentThread, j9package);
356
} else {
357
if (TrcEnabled_Trc_MODULE_createPackage) {
358
trcModulesCreationPackage(currentThread, fromModule, package);
359
}
360
}
361
362
return retval;
363
}
364
365
static void
366
removeMulPackageDefinitions(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 packagesIndex)
367
{
368
BOOLEAN stopLoop = FALSE;
369
U_32 i = packagesIndex;
370
371
while (!stopLoop) {
372
const char *packageName = packages[i];
373
374
Assert_SC_true(removePackageDefinition(currentThread, fromModule, packageName));
375
376
stopLoop = (0 == i);
377
--i;
378
}
379
}
380
381
static UDATA
382
addMulPackageDefinitions(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 numPackages)
383
{
384
UDATA retval = ERRCODE_SUCCESS;
385
386
if (NULL != packages) {
387
U_32 const arrayLength = numPackages;
388
if (0 != arrayLength) {
389
U_32 i = 0;
390
391
for (i = 0; i < arrayLength; i++) {
392
const char *packageName = packages[i];
393
if (!addPackageDefinition(currentThread, fromModule, packageName)) {
394
J9ClassLoader * const classLoader = fromModule->classLoader;
395
396
if (isPackageDefined(currentThread, classLoader, packageName)) {
397
retval = ERRCODE_DUPLICATE_PACKAGE_IN_LIST;
398
}
399
break;
400
}
401
}
402
403
/* Remove from the hash table the entries that made through. Note that the last entry (the one we are
404
* processing right now) was the one that failed so we don't need to worry about that one.
405
*/
406
if (ERRCODE_SUCCESS != retval) {
407
if (i > 0) {
408
--i;
409
removeMulPackageDefinitions(currentThread, fromModule, packages, i);
410
}
411
}
412
}
413
}
414
415
return retval;
416
}
417
418
static UDATA
419
addModuleDefinition(J9VMThread * currentThread, J9Module * fromModule, const char* const* packages, U_32 numPackages, jstring version)
420
{
421
J9ClassLoader * const classLoader = fromModule->classLoader;
422
423
UDATA retval = ERRCODE_GENERAL_FAILURE;
424
if (!areNoPackagesDefined(currentThread, classLoader, packages, numPackages)) {
425
retval = ERRCODE_PACKAGE_ALREADY_DEFINED;
426
} else if (isModuleDefined(currentThread, fromModule)) {
427
retval = ERRCODE_MODULE_ALREADY_DEFINED;
428
} else {
429
retval = addMulPackageDefinitions(currentThread, fromModule, packages, numPackages);
430
if (ERRCODE_SUCCESS == retval) {
431
BOOLEAN const success = (0 == hashTableAtPut(classLoader->moduleHashTable, (void*)&fromModule, TRUE));
432
Trc_MODULE_invokeHashTableAtPut(currentThread, "addModuleDefinition", classLoader, classLoader->moduleHashTable, &fromModule, fromModule, "true");
433
if (NULL != version) {
434
fromModule->version = J9_JNI_UNWRAP_REFERENCE(version);
435
}
436
if (!success) {
437
/* If we failed to add the module to the hash table */
438
if (NULL != packages) {
439
removeMulPackageDefinitions(currentThread, fromModule, packages, numPackages);
440
}
441
442
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
443
}
444
}
445
}
446
447
return retval;
448
}
449
450
static BOOLEAN
451
isPackageDefined(J9VMThread * currentThread, J9ClassLoader * classLoader, const char *packageName)
452
{
453
J9Package const * target = NULL;
454
455
target = hashPackageTableAt(currentThread, classLoader, packageName);
456
457
return (NULL != target);
458
}
459
460
static BOOLEAN
461
areNoPackagesDefined(J9VMThread * currentThread, J9ClassLoader * classLoader, const char* const* packages, U_32 numPackages)
462
{
463
BOOLEAN success = TRUE;
464
J9JavaVM * vm = currentThread->javaVM;
465
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
466
467
/*
468
* This check will be ignored for calls to this method that occur before java.base is defined.
469
* Classes are loaded before java.base is created that are added to the classHashTable.
470
* These classes will eventually be fixed up to be part of java.base, but should not be considered duplicate packages
471
* before that happens.
472
*/
473
BOOLEAN checkDefinedPackages = J9_ARE_ALL_BITS_SET(vm->runtimeFlags, J9_RUNTIME_JAVA_BASE_MODULE_CREATED);
474
475
if (NULL != packages) {
476
U_32 const arrayLength = numPackages;
477
if (0 != arrayLength) {
478
U_32 i = 0;
479
for (i = 0; success && (i < arrayLength); i++) {
480
const char *packageName = packages[i];
481
if (checkDefinedPackages
482
&& vmFuncs->isAnyClassLoadedFromPackage(classLoader, (U_8*) packageName, strlen(packageName))
483
) {
484
success = FALSE;
485
}
486
}
487
}
488
}
489
490
return success;
491
}
492
493
static void
494
trcModulesAddModuleExportsToAll(J9VMThread * currentThread, J9Module * fromModule, const char *package)
495
{
496
PORT_ACCESS_FROM_VMC(currentThread);
497
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
498
char fromModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
499
char *fromModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
500
currentThread, fromModule->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, fromModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
501
if (NULL != fromModuleNameUTF) {
502
Trc_MODULE_addModuleExportsToAll(currentThread, package, fromModuleNameUTF, fromModule);
503
if (fromModuleNameBuf != fromModuleNameUTF) {
504
j9mem_free_memory(fromModuleNameUTF);
505
}
506
}
507
}
508
509
static UDATA
510
exportPackageToAll(J9VMThread * currentThread, J9Module * fromModule, const char *package)
511
{
512
UDATA retval = ERRCODE_GENERAL_FAILURE;
513
J9Package * const j9package = getPackageDefinition(currentThread, fromModule, package, &retval);
514
if (NULL != j9package) {
515
j9package->exportToAll = 1;
516
if (TrcEnabled_Trc_MODULE_addModuleExportsToAll) {
517
trcModulesAddModuleExportsToAll(currentThread, fromModule, package);
518
}
519
}
520
521
return retval;
522
}
523
524
static void
525
trcModulesAddModuleExportsToAllUnnamed(J9VMThread * currentThread, J9Module * fromModule, const char *package)
526
{
527
PORT_ACCESS_FROM_VMC(currentThread);
528
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
529
char fromModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
530
char *fromModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
531
currentThread, fromModule->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, fromModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
532
if (NULL != fromModuleNameUTF) {
533
Trc_MODULE_addModuleExportsToAllUnnamed(currentThread, package, fromModuleNameUTF, fromModule);
534
if (fromModuleNameBuf != fromModuleNameUTF) {
535
j9mem_free_memory(fromModuleNameUTF);
536
}
537
}
538
}
539
540
static UDATA
541
exportPackageToAllUnamed(J9VMThread * currentThread, J9Module * fromModule, const char *package)
542
{
543
UDATA retval = ERRCODE_GENERAL_FAILURE;
544
J9Package * const j9package = getPackageDefinition(currentThread, fromModule, package, &retval);
545
if (NULL != j9package) {
546
j9package->exportToAllUnnamed = 1;
547
if (TrcEnabled_Trc_MODULE_addModuleExportsToAllUnnamed) {
548
trcModulesAddModuleExportsToAllUnnamed(currentThread, fromModule, package);
549
}
550
}
551
552
return retval;
553
}
554
555
/** @return the J9Module associated with a Module object */
556
static J9Module *
557
getJ9Module(J9VMThread * currentThread, jobject module)
558
{
559
J9JavaVM const * const vm = currentThread->javaVM;
560
561
j9object_t modObj = J9_JNI_UNWRAP_REFERENCE(module);
562
563
/* Get J9Module* via the hidden field */
564
return J9OBJECT_ADDRESS_LOAD(currentThread, modObj, vm->modulePointerOffset);
565
}
566
567
static BOOLEAN
568
isModuleJavaBase(j9object_t moduleName)
569
{
570
/** @todo compare against string 'java.base' */
571
return FALSE;
572
}
573
574
static BOOLEAN
575
isModuleNameGood(j9object_t moduleName)
576
{
577
/** @todo implement this */
578
return TRUE;
579
}
580
581
static BOOLEAN
582
isModuleNameValid(j9object_t moduleName)
583
{
584
BOOLEAN retval = FALSE;
585
586
if (NULL != moduleName) {
587
retval = TRUE;
588
if (!isModuleJavaBase(moduleName)) {
589
retval = isModuleNameGood(moduleName);
590
}
591
}
592
593
return retval;
594
}
595
596
static void
597
trcModulesAddModuleExports(J9VMThread *currentThread, J9Module *fromModule, const char *package, J9Module *toModule)
598
{
599
PORT_ACCESS_FROM_VMC(currentThread);
600
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
601
char fromModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
602
char toModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
603
char *fromModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
604
currentThread, fromModule->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, fromModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
605
char *toModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
606
currentThread, toModule->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, toModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
607
if ((NULL != fromModuleNameUTF) && (NULL != toModuleNameUTF)) {
608
Trc_MODULE_addModuleExports(currentThread, package, fromModuleNameUTF, fromModule, toModuleNameUTF, toModule);
609
}
610
if (fromModuleNameBuf != fromModuleNameUTF) {
611
j9mem_free_memory(fromModuleNameUTF);
612
}
613
if (toModuleNameBuf != toModuleNameUTF) {
614
j9mem_free_memory(toModuleNameUTF);
615
}
616
}
617
618
static UDATA
619
exportPackageToModule(J9VMThread * currentThread, J9Module * fromModule, const char *package, J9Module * toModule)
620
{
621
UDATA retval = ERRCODE_GENERAL_FAILURE;
622
J9Package * const j9package = getPackageDefinition(currentThread, fromModule, package, &retval);
623
if (NULL != j9package) {
624
if (isModuleDefined(currentThread, toModule)) {
625
Trc_MODULE_invokeHashTableAtPut(currentThread, "exportPackageToModule(exportsHashTable)", j9package, j9package->exportsHashTable, &toModule, toModule, "false");
626
if (0 == hashTableAtPut(j9package->exportsHashTable, (void*)&toModule, FALSE)) {
627
retval = ERRCODE_SUCCESS;
628
/*
629
* Need to keep track of package that is exported to toModule in case toModule gets unloaded
630
* before fromModule. An unloaded module in packageHashtable will result in a crash when doing hashtable lookups.
631
* We use this hashtable to remove instances of toModule in packages when unloading toModule.
632
* We only need to worry about modules in different layers as modules in the same layer are unloaded
633
* at the same time.
634
*/
635
if (NULL == toModule->removeExportsHashTable) {
636
J9JavaVM *vm = currentThread->javaVM;
637
toModule->removeExportsHashTable = vm->internalVMFunctions->hashPackageTableNew(vm, INITIAL_INTERNAL_PACKAGE_HASHTABLE_SIZE);
638
}
639
if (NULL != toModule->removeExportsHashTable) {
640
Trc_MODULE_invokeHashTableAtPut(currentThread, "exportPackageToModule(removeExportsHashTable)", toModule, toModule->removeExportsHashTable, &j9package, j9package, "false");
641
if (0 != hashTableAtPut(toModule->removeExportsHashTable, (void*)&j9package, FALSE)) {
642
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
643
}
644
} else {
645
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
646
}
647
} else {
648
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
649
}
650
} else {
651
retval = ERRCODE_MODULE_WASNT_FOUND;
652
}
653
}
654
if (ERRCODE_SUCCESS == retval && TrcEnabled_Trc_MODULE_addModuleExports) {
655
trcModulesAddModuleExports(currentThread, fromModule, package, toModule);
656
}
657
658
return retval;
659
}
660
661
static UDATA
662
allowReadAccessToModule(J9VMThread * currentThread, J9Module * fromModule, J9Module * toModule)
663
{
664
UDATA retval = ERRCODE_MODULE_WASNT_FOUND;
665
666
if (isModuleDefined(currentThread, fromModule)) {
667
J9JavaVM *vm = currentThread->javaVM;
668
669
if (J9_IS_J9MODULE_UNNAMED(vm, toModule)) {
670
fromModule->isLoose = TRUE;
671
retval = ERRCODE_SUCCESS;
672
} else if (isModuleDefined(currentThread, toModule)) {
673
BOOLEAN success = FALSE;
674
Trc_MODULE_invokeHashTableAtPut(currentThread, "allowReadAccessToModule(readAccessHashTable)", toModule, toModule->readAccessHashTable, &fromModule, fromModule, "false");
675
if (0 == hashTableAtPut(toModule->readAccessHashTable, (void*)&fromModule, FALSE)) {
676
success = TRUE;
677
/*
678
* Need to keep track of toModule that can read fromModule in case fromModule gets unloaded
679
* before toModule. An unloaded module in toModule will result in a crash when doing hashtable lookups.
680
* We use removeAccessHashTable to remove instances of fromModule in toModules when unloading fromModule.
681
* We only need to worry about modules in different layers as modules in the same layer are unloaded
682
* at the same time.
683
*/
684
if (NULL == fromModule->removeAccessHashTable) {
685
fromModule->removeAccessHashTable = vm->internalVMFunctions->hashModulePointerTableNew(vm, INITIAL_INTERNAL_MODULE_HASHTABLE_SIZE);
686
}
687
if (NULL != fromModule->removeAccessHashTable) {
688
Trc_MODULE_invokeHashTableAtPut(currentThread, "allowReadAccessToModule(removeAccessHashTable)", fromModule, fromModule->removeAccessHashTable, &toModule, toModule, "false");
689
if (0 != hashTableAtPut(fromModule->removeAccessHashTable, (void*)&toModule, FALSE)) {
690
success = FALSE;
691
}
692
} else {
693
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
694
}
695
}
696
697
if (success) {
698
retval = ERRCODE_SUCCESS;
699
} else {
700
701
retval = ERRCODE_HASHTABLE_OPERATION_FAILED;
702
}
703
}
704
}
705
706
return retval;
707
}
708
709
/**
710
* Define a module containing the specified packages. It will create the module record in the ClassLoader's module hash table and
711
* create package records in the class loader's package hash table if necessary.
712
*
713
* @throws NullPointerExceptions a if module is null.
714
* @throws IllegalArgumentExceptions if
715
* - Class loader already has a module with that name
716
* - Class loader has already defined types for any of the module's packages
717
* - Module_name is 'java.base'
718
* - Module_name is syntactically bad
719
* - Packages contains an illegal package name
720
* - Packages contains a duplicate package name
721
* - A package already exists in another module for this class loader
722
* - Class loader is not a subclass of java.lang.ClassLoader
723
* - Module is an unnamed module
724
* @throws LayerInstantiationException if a module with name 'java.base' is defined by non-bootstrap classloader.
725
*
726
* @return If successful, returns a java.lang.reflect.Module object. Otherwise, returns NULL.
727
*/
728
jobject JNICALL
729
#if JAVA_SPEC_VERSION >= 15
730
JVM_DefineModule(JNIEnv * env, jobject module, jboolean isOpen, jstring version, jstring location, jobjectArray packageArray)
731
#else
732
JVM_DefineModule(JNIEnv * env, jobject module, jboolean isOpen, jstring version, jstring location, const char* const* packages, jsize numPackages)
733
#endif /* JAVA_SPEC_VERSION >= 15 */
734
{
735
J9VMThread * const currentThread = (J9VMThread*)env;
736
J9JavaVM * vm = currentThread->javaVM;
737
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
738
#if JAVA_SPEC_VERSION >= 15
739
BOOLEAN oom = FALSE;
740
jsize numPackages = 0;
741
UDATA packagesNumBytes = 0;
742
const char** packages = NULL;
743
PORT_ACCESS_FROM_ENV(env);
744
#endif /* JAVA_SPEC_VERSION >= 15 */
745
746
vmFuncs->internalEnterVMFromJNI(currentThread);
747
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
748
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
749
#else
750
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
751
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
752
753
#if JAVA_SPEC_VERSION >= 15
754
if (NULL != packageArray) {
755
numPackages = J9INDEXABLEOBJECT_SIZE(currentThread, J9_JNI_UNWRAP_REFERENCE(packageArray));
756
packagesNumBytes = sizeof(char*) * numPackages;
757
} else {
758
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_PACKAGES_IS_NULL);
759
goto done;
760
}
761
packages = (const char**)j9mem_allocate_memory(packagesNumBytes, OMRMEM_CATEGORY_VM);
762
if (NULL != packages) {
763
jsize pkgIndex = 0;
764
memset((void *)packages, 0, packagesNumBytes);
765
for (pkgIndex = 0; pkgIndex < numPackages; pkgIndex++) {
766
j9array_t array = (j9array_t)J9_JNI_UNWRAP_REFERENCE(packageArray);
767
j9object_t stringObject = J9JAVAARRAYOFOBJECT_LOAD(currentThread, array, pkgIndex);
768
if (NULL != stringObject) {
769
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
770
char *packageName = (char*)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
771
if (NULL == packageName) {
772
oom = TRUE;
773
break;
774
}
775
vmFuncs->copyStringToUTF8Helper(currentThread, stringObject, J9_STR_NULL_TERMINATE_RESULT | J9_STR_XLAT , 0, J9VMJAVALANGSTRING_LENGTH(currentThread, stringObject), (U_8 *)packageName, utfLength);
776
packages[pkgIndex] = packageName;
777
} else {
778
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_PACKAGE_IS_NULL);
779
goto done;
780
}
781
}
782
}
783
if ((NULL == packages) || oom) {
784
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
785
goto done;
786
}
787
#endif /* JAVA_SPEC_VERSION >= 15 */
788
789
if (NULL == module) {
790
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_MODULE_IS_NULL);
791
} else {
792
j9object_t modObj = J9_JNI_UNWRAP_REFERENCE(module);
793
794
J9ClassLoader * const classLoader = getModuleObjectClassLoader(currentThread, modObj);
795
j9object_t moduleName = J9VMJAVALANGMODULE_NAME(currentThread, modObj);
796
797
/* extensionClassLoader holds the platform class loader in Java 11+ */
798
if ((classLoader != vm->systemClassLoader) && (classLoader != vm->extensionClassLoader)) {
799
jsize pkgIndex = 0;
800
for (pkgIndex = 0; pkgIndex < numPackages; pkgIndex++) {
801
const char *packageName = packages[pkgIndex];
802
if (0 == strncmp(packageName, "java", 4)) {
803
char nextCh = packageName[4];
804
if (('\0' == nextCh) || ('.' == nextCh) || ('/' == nextCh)) {
805
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, J9NLS_VM_ONLY_BOOT_PLATFORM_CLASSLOADER_DEFINE_PKG_JAVA);
806
goto done;
807
}
808
}
809
}
810
}
811
812
if (NULL == moduleName) {
813
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, J9NLS_VM_MODULE_IS_UNNAMED);
814
} else if (!isModuleNameValid(moduleName)) {
815
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, J9NLS_VM_MODULE_NAME_IS_INVALID);
816
} else if (NULL == classLoader) {
817
/* An exception should be pending if classLoader is null */
818
Assert_SC_true(NULL != currentThread->currentException);
819
} else {
820
char buf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
821
char *nameUTF = buf;
822
823
PORT_ACCESS_FROM_VMC(currentThread);
824
nameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
825
currentThread, moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, buf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
826
if (NULL == nameUTF) {
827
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
828
} else if ((classLoader != vm->systemClassLoader) && (0 == strcmp(nameUTF, JAVA_BASE_MODULE))) {
829
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGLAYERINSTANTIATIONEXCEPTION, J9NLS_VM_ONLY_BOOTCLASSLOADER_LOAD_MODULE_JAVABASE);
830
} else {
831
J9Module *j9mod = createModule(currentThread, modObj, classLoader, moduleName);
832
if (NULL != j9mod) {
833
BOOLEAN success = FALSE;
834
UDATA rc = addModuleDefinition(currentThread, j9mod, packages, (U_32) numPackages, version);
835
j9mod->isOpen = isOpen;
836
success = (ERRCODE_SUCCESS == rc);
837
if (success) {
838
/* For "java.base" module setting of jrt URL and patch paths is already done during startup. Avoid doing it here. */
839
if (J9_ARE_ALL_BITS_SET(vm->runtimeFlags, J9_RUNTIME_JAVA_BASE_MODULE_CREATED)) {
840
Trc_MODULE_defineModule(currentThread, nameUTF, j9mod);
841
if (classLoader == vm->systemClassLoader) {
842
success = vmFuncs->setBootLoaderModulePatchPaths(vm, j9mod, (const char *)nameUTF);
843
if (FALSE == success) {
844
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
845
} else {
846
const char* moduleName = "openj9.sharedclasses";
847
848
if (0 == strcmp(nameUTF, moduleName)) {
849
J9VMDllLoadInfo *entry = FIND_DLL_TABLE_ENTRY(J9_SHARED_DLL_NAME);
850
851
if ((NULL == entry)
852
|| (J9_ARE_ALL_BITS_SET(entry->loadFlags, FAILED_TO_LOAD))
853
) {
854
j9nls_printf(PORTLIB, J9NLS_WARNING, J9NLS_VM_FAILED_TO_LOAD_MODULE_REQUIRED_DLL, J9_SHARED_DLL_NAME, moduleName);
855
}
856
}
857
}
858
}
859
} else {
860
/* first module; must be "java.base" */
861
J9ClassWalkState classWalkState;
862
J9Class* clazz = NULL;
863
864
Assert_SC_true(0 == strcmp(nameUTF, JAVA_BASE_MODULE));
865
866
clazz = vmFuncs->allClassesStartDo(&classWalkState, vm, vm->systemClassLoader);
867
while (NULL != clazz) {
868
Assert_SC_true(clazz->module == vm->javaBaseModule);
869
J9VMJAVALANGCLASS_SET_MODULE(currentThread, clazz->classObject, modObj);
870
clazz = vmFuncs->allClassesNextDo(&classWalkState);
871
}
872
vmFuncs->allClassesEndDo(&classWalkState);
873
874
if (vm->anonClassCount > 0) {
875
J9ClassWalkState classWalkStateAnon = {0};
876
J9Class *clazzAnon = NULL;
877
878
Assert_SC_notNull(vm->anonClassLoader);
879
clazzAnon = vmFuncs->allClassesStartDo(&classWalkStateAnon, vm, vm->anonClassLoader);
880
while (NULL != clazzAnon) {
881
Assert_SC_true(clazzAnon->module == vm->javaBaseModule);
882
J9VMJAVALANGCLASS_SET_MODULE(currentThread, clazzAnon->classObject, modObj);
883
clazzAnon = vmFuncs->allClassesNextDo(&classWalkStateAnon);
884
}
885
vmFuncs->allClassesEndDo(&classWalkStateAnon);
886
}
887
888
vm->runtimeFlags |= J9_RUNTIME_JAVA_BASE_MODULE_CREATED;
889
Trc_MODULE_defineModule(currentThread, "java.base", j9mod);
890
}
891
892
TRIGGER_J9HOOK_VM_MODULE_LOAD(vm->hookInterface, currentThread, j9mod);
893
} else {
894
throwExceptionHelper(currentThread, rc);
895
}
896
if (FALSE == success) {
897
vmFuncs->freeJ9Module(vm, j9mod);
898
Assert_SC_true(NULL != currentThread->currentException);
899
}
900
}
901
}
902
if (nameUTF != buf) {
903
j9mem_free_memory(nameUTF);
904
}
905
}
906
}
907
908
done:
909
#if JAVA_SPEC_VERSION >= 15
910
if (NULL != packages) {
911
jsize pkgIndex = 0;
912
for (pkgIndex = 0; pkgIndex < numPackages; pkgIndex++) {
913
const char* packageName = packages[pkgIndex];
914
j9mem_free_memory((void *)packageName);
915
}
916
j9mem_free_memory((void *)packages);
917
}
918
#endif /* JAVA_SPEC_VERSION >= 15 */
919
920
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
921
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
922
#else
923
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
924
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
925
vmFuncs->internalExitVMToJNI(currentThread);
926
927
return module;
928
}
929
930
/**
931
* Qualified export of package in fromModule to toModule.
932
*
933
* @todo the null toModule case is not outlined in the spec but the spec does not specify what to do in this case
934
* @throws NullPointerExceptions a if toModule is null.
935
* @throws IllegalArgumentExceptions if
936
* 1) Module fromModule does not exist
937
* 2) Module toModule is not null and does not exist
938
* 3) Package is not syntactically correct
939
* 4) Package is not defined for fromModule's class loader
940
* 5) Package is not in module fromModule.
941
*/
942
#if JAVA_SPEC_VERSION >= 15
943
void JNICALL
944
JVM_AddModuleExports(JNIEnv * env, jobject fromModule, jstring packageObj, jobject toModule)
945
#else
946
void JNICALL
947
JVM_AddModuleExports(JNIEnv * env, jobject fromModule, const char *package, jobject toModule)
948
#endif /* JAVA_SPEC_VERSION >= 15 */
949
{
950
J9VMThread * const currentThread = (J9VMThread*)env;
951
J9JavaVM const * const vm = currentThread->javaVM;
952
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
953
#if JAVA_SPEC_VERSION >= 15
954
const char *package = NULL;
955
PORT_ACCESS_FROM_ENV(env);
956
#endif /* JAVA_SPEC_VERSION >= 15 */
957
958
vmFuncs->internalEnterVMFromJNI(currentThread);
959
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
960
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
961
#else
962
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
963
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
964
965
#if JAVA_SPEC_VERSION >= 15
966
if (NULL != packageObj) {
967
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
968
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
969
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
970
if (NULL == packageName) {
971
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
972
goto done;
973
}
974
vmFuncs->copyStringToUTF8Helper(currentThread, stringObject, J9_STR_NULL_TERMINATE_RESULT | J9_STR_XLAT , 0, J9VMJAVALANGSTRING_LENGTH(currentThread, stringObject), (U_8 *)packageName, utfLength);
975
package = packageName;
976
} else {
977
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_PACKAGE_IS_NULL);
978
goto done;
979
}
980
#endif /* JAVA_SPEC_VERSION >= 15 */
981
982
if (NULL == toModule) {
983
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, "module is null");
984
} else {
985
UDATA rc = ERRCODE_GENERAL_FAILURE;
986
J9Module * const j9FromMod = getJ9Module(currentThread, fromModule);
987
J9Module * const j9ToMod = getJ9Module(currentThread, toModule);
988
989
if (isModuleUnnamed(currentThread, J9_JNI_UNWRAP_REFERENCE(toModule))) {
990
rc = exportPackageToAllUnamed(currentThread, j9FromMod, package);
991
} else {
992
rc = exportPackageToModule(currentThread, j9FromMod, package, j9ToMod);
993
}
994
995
if (ERRCODE_SUCCESS != rc) {
996
throwExceptionHelper(currentThread, rc);
997
}
998
}
999
1000
#if JAVA_SPEC_VERSION >= 15
1001
done:
1002
if (NULL != package) {
1003
j9mem_free_memory((void*)package);
1004
}
1005
#endif /* JAVA_SPEC_VERSION >= 15 */
1006
1007
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1008
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1009
#else
1010
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1011
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1012
vmFuncs->internalExitVMToJNI(currentThread);
1013
}
1014
1015
/**
1016
* Unqualified export of package in fromModule
1017
*
1018
* @throws IllegalArgumentExceptions if
1019
* 1) Module fromModule does not exist
1020
* 2) Package is not syntactically correct
1021
* 3) Package is not defined for fromModule's class loader
1022
* 4) Package is not in module fromModule.
1023
*/
1024
#if JAVA_SPEC_VERSION >= 15
1025
void JNICALL
1026
JVM_AddModuleExportsToAll(JNIEnv * env, jobject fromModule, jstring packageObj)
1027
#else
1028
void JNICALL
1029
JVM_AddModuleExportsToAll(JNIEnv * env, jobject fromModule, const char *package)
1030
#endif /* JAVA_SPEC_VERSION >= 15 */
1031
{
1032
J9VMThread * const currentThread = (J9VMThread*)env;
1033
J9JavaVM const * const vm = currentThread->javaVM;
1034
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1035
#if JAVA_SPEC_VERSION >= 15
1036
const char *package = NULL;
1037
PORT_ACCESS_FROM_ENV(env);
1038
#endif /* JAVA_SPEC_VERSION >= 15 */
1039
1040
vmFuncs->internalEnterVMFromJNI(currentThread);
1041
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1042
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1043
#else
1044
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1045
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1046
1047
#if JAVA_SPEC_VERSION >= 15
1048
if (NULL != packageObj) {
1049
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
1050
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
1051
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1052
if (NULL == packageName) {
1053
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
1054
goto done;
1055
}
1056
vmFuncs->copyStringToUTF8Helper(currentThread, stringObject, J9_STR_NULL_TERMINATE_RESULT | J9_STR_XLAT , 0, J9VMJAVALANGSTRING_LENGTH(currentThread, stringObject), (U_8 *)packageName, utfLength);
1057
package = packageName;
1058
} else {
1059
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_PACKAGE_IS_NULL);
1060
goto done;
1061
}
1062
#endif /* JAVA_SPEC_VERSION >= 15 */
1063
1064
{
1065
UDATA rc = ERRCODE_GENERAL_FAILURE;
1066
1067
J9Module * const j9FromMod = getJ9Module(currentThread, fromModule);
1068
1069
rc = exportPackageToAll(currentThread, j9FromMod, package);
1070
1071
if (ERRCODE_SUCCESS != rc) {
1072
throwExceptionHelper(currentThread, rc);
1073
}
1074
}
1075
1076
#if JAVA_SPEC_VERSION >= 15
1077
done:
1078
if (NULL != package) {
1079
j9mem_free_memory((void*)package);
1080
}
1081
#endif /* JAVA_SPEC_VERSION >= 15 */
1082
1083
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1084
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1085
#else
1086
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1087
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1088
vmFuncs->internalExitVMToJNI(currentThread);
1089
}
1090
1091
static void
1092
trcModulesAddReadsModule(J9VMThread *currentThread, jobject toModule, J9Module *j9FromMod, J9Module *j9ToMod)
1093
{
1094
PORT_ACCESS_FROM_VMC(currentThread);
1095
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
1096
char fromModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
1097
char toModuleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
1098
char *fromModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
1099
currentThread, j9FromMod->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, fromModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
1100
char *toModuleNameUTF = NULL;
1101
1102
if (NULL != j9ToMod) {
1103
if (NULL != j9ToMod->moduleName) {
1104
toModuleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
1105
currentThread, j9ToMod->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, toModuleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
1106
} else {
1107
#define UNNAMED_MODULE "unnamed "
1108
PORT_ACCESS_FROM_VMC(currentThread);
1109
Assert_SC_true(J9VM_PACKAGE_NAME_BUFFER_LENGTH >= sizeof(UNNAMED_MODULE));
1110
memcpy(toModuleNameBuf, UNNAMED_MODULE, sizeof(UNNAMED_MODULE));
1111
toModuleNameUTF = toModuleNameBuf;
1112
#undef UNNAMED_MODULE
1113
}
1114
} else {
1115
#define LOOSE_MODULE "loose "
1116
PORT_ACCESS_FROM_VMC(currentThread);
1117
Assert_SC_true(J9VM_PACKAGE_NAME_BUFFER_LENGTH >= sizeof(LOOSE_MODULE));
1118
memcpy(toModuleNameBuf, LOOSE_MODULE, sizeof(LOOSE_MODULE));
1119
toModuleNameUTF = toModuleNameBuf;
1120
#undef LOOSE_MODULE
1121
}
1122
if ((NULL != fromModuleNameUTF) && (NULL != toModuleNameUTF)) {
1123
Trc_MODULE_addReadsModule(currentThread, fromModuleNameUTF, j9FromMod, toModuleNameUTF, toModule);
1124
}
1125
if (fromModuleNameBuf != fromModuleNameUTF) {
1126
j9mem_free_memory(fromModuleNameUTF);
1127
}
1128
if (toModuleNameBuf != toModuleNameUTF) {
1129
j9mem_free_memory(toModuleNameUTF);
1130
}
1131
}
1132
1133
/**
1134
* Add toModule to the list of modules that fromModule can read. If fromModule is the same as toModule, do nothing.
1135
* If toModule is null then fromModule is marked as a loose module (i.e., fromModule can read all current and future unnamed modules).
1136
*
1137
* @throws IllegalArgumentExceptions if
1138
* 1) if fromModule is null or if modules do not exist.
1139
*/
1140
void JNICALL
1141
JVM_AddReadsModule(JNIEnv * env, jobject fromModule, jobject toModule)
1142
{
1143
if (fromModule != toModule) {
1144
J9VMThread * const currentThread = (J9VMThread*)env;
1145
J9JavaVM const * const vm = currentThread->javaVM;
1146
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1147
1148
vmFuncs->internalEnterVMFromJNI(currentThread);
1149
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1150
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1151
#else
1152
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1153
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1154
{
1155
UDATA rc = ERRCODE_GENERAL_FAILURE;
1156
1157
J9Module * const j9FromMod = getJ9Module(currentThread, fromModule);
1158
J9Module * const j9ToMod = (NULL != toModule) ? getJ9Module(currentThread, toModule) : NULL;
1159
1160
/* Slightly different then check above since above I was dealing with the stack addr */
1161
if (j9FromMod != j9ToMod) {
1162
rc = allowReadAccessToModule(currentThread, j9FromMod, j9ToMod);
1163
1164
if (ERRCODE_SUCCESS != rc) {
1165
throwExceptionHelper(currentThread, rc);
1166
} else {
1167
if (TrcEnabled_Trc_MODULE_addReadsModule) {
1168
trcModulesAddReadsModule(currentThread, toModule, j9FromMod, j9ToMod);
1169
}
1170
}
1171
}
1172
}
1173
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1174
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1175
#else
1176
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1177
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1178
vmFuncs->internalExitVMToJNI(currentThread);
1179
}
1180
}
1181
1182
/**
1183
* @return TRUE if:
1184
* 1. askModule can read srcModule or
1185
* 2. if both are the same module or
1186
* 3. if askModule is loose and srcModule is null.
1187
* FALSE otherwise
1188
*
1189
* @throws IllegalArgumentExceptions if
1190
* 1) either askModule or srcModule is not a java.lang.reflect.Module
1191
*/
1192
jboolean JNICALL
1193
JVM_CanReadModule(JNIEnv * env, jobject askModule, jobject srcModule)
1194
{
1195
J9VMThread * const currentThread = (J9VMThread*)env;
1196
J9JavaVM const * const vm = currentThread->javaVM;
1197
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1198
BOOLEAN canRead = FALSE;
1199
1200
if (askModule == srcModule) {
1201
canRead = TRUE;
1202
} else {
1203
vmFuncs->internalEnterVMFromJNI(currentThread);
1204
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1205
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1206
#else
1207
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1208
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1209
{
1210
UDATA rc = ERRCODE_GENERAL_FAILURE;
1211
1212
J9Module * const j9FromMod = getJ9Module(currentThread, askModule);
1213
J9Module * const j9ToMod = getJ9Module(currentThread, srcModule);
1214
1215
canRead = isAllowedReadAccessToModule(currentThread, j9FromMod, j9ToMod, &rc);
1216
1217
if (ERRCODE_SUCCESS != rc) {
1218
throwExceptionHelper(currentThread, rc);
1219
}
1220
}
1221
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1222
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1223
#else
1224
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1225
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1226
vmFuncs->internalExitVMToJNI(currentThread);
1227
}
1228
1229
return (jboolean)canRead;
1230
}
1231
1232
static void
1233
trcModulesAddModulePackage(J9VMThread *currentThread, J9Module *j9mod, const char *package)
1234
{
1235
PORT_ACCESS_FROM_VMC(currentThread);
1236
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
1237
char moduleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
1238
char *moduleNameUTF = vmFuncs->copyStringToUTF8WithMemAlloc(
1239
currentThread, j9mod->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, moduleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
1240
if (NULL != moduleNameUTF) {
1241
Trc_MODULE_addModulePackage(currentThread, package, moduleNameUTF, j9mod);
1242
if (moduleNameBuf != moduleNameUTF) {
1243
j9mem_free_memory(moduleNameUTF);
1244
}
1245
}
1246
}
1247
/**
1248
* Adds a package to a module
1249
*
1250
* @throws IllegalArgumentException is thrown if
1251
* 1) Module is bad
1252
* 2) Module is unnamed
1253
* 3) Package is not syntactically correct
1254
* 4) Package is already defined for module's class loader.
1255
*/
1256
void JNICALL
1257
JVM_AddModulePackage(JNIEnv * env, jobject module, const char *package)
1258
{
1259
J9VMThread * const currentThread = (J9VMThread*)env;
1260
J9JavaVM const * const vm = currentThread->javaVM;
1261
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1262
1263
vmFuncs->internalEnterVMFromJNI(currentThread);
1264
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1265
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1266
#else
1267
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1268
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1269
{
1270
J9Module * const j9mod = getJ9Module(currentThread, module);
1271
UDATA rc = addPackageDefinition(currentThread, j9mod, package);
1272
if (ERRCODE_SUCCESS != rc) {
1273
throwExceptionHelper(currentThread, rc);
1274
} else {
1275
if (TrcEnabled_Trc_MODULE_addModulePackage) {
1276
trcModulesAddModulePackage(currentThread, j9mod, package);
1277
}
1278
}
1279
}
1280
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1281
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1282
#else
1283
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1284
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1285
vmFuncs->internalExitVMToJNI(currentThread);
1286
}
1287
1288
/**
1289
* Marks the specified package as exported to all unnamed modules.
1290
*
1291
* @throws NullPointerExceptions if either module or package is null.
1292
* @throws IllegalArgumentExceptions if
1293
* 1) module or package is bad or
1294
* 2) module is unnamed or
1295
* 3) package is not in module
1296
*/
1297
#if JAVA_SPEC_VERSION >= 15
1298
void JNICALL
1299
JVM_AddModuleExportsToAllUnnamed(JNIEnv * env, jobject fromModule, jstring packageObj)
1300
#else
1301
void JNICALL
1302
JVM_AddModuleExportsToAllUnnamed(JNIEnv * env, jobject fromModule, const char *package)
1303
#endif /* JAVA_SPEC_VERSION >= 15 */
1304
{
1305
J9VMThread * const currentThread = (J9VMThread*)env;
1306
J9JavaVM const * const vm = currentThread->javaVM;
1307
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1308
#if JAVA_SPEC_VERSION >= 15
1309
const char *package = NULL;
1310
PORT_ACCESS_FROM_ENV(env);
1311
#endif /* JAVA_SPEC_VERSION >= 15 */
1312
1313
vmFuncs->internalEnterVMFromJNI(currentThread);
1314
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1315
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1316
#else
1317
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1318
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1319
1320
#if JAVA_SPEC_VERSION >= 15
1321
if (NULL != packageObj) {
1322
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
1323
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
1324
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1325
if (NULL == packageName) {
1326
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
1327
goto done;
1328
}
1329
vmFuncs->copyStringToUTF8Helper(currentThread, stringObject, J9_STR_NULL_TERMINATE_RESULT | J9_STR_XLAT , 0, J9VMJAVALANGSTRING_LENGTH(currentThread, stringObject), (U_8 *)packageName, utfLength);
1330
package = packageName;
1331
} else {
1332
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, J9NLS_VM_PACKAGE_IS_NULL);
1333
goto done;
1334
}
1335
#endif /* JAVA_SPEC_VERSION >= 15 */
1336
1337
{
1338
UDATA rc = ERRCODE_GENERAL_FAILURE;
1339
1340
J9Module * const j9FromMod = getJ9Module(currentThread, fromModule);
1341
1342
rc = exportPackageToAllUnamed(currentThread, j9FromMod, package);
1343
1344
if (ERRCODE_SUCCESS != rc) {
1345
throwExceptionHelper(currentThread, rc);
1346
}
1347
}
1348
1349
#if JAVA_SPEC_VERSION >= 15
1350
done:
1351
if (NULL != package) {
1352
j9mem_free_memory((void*)package);
1353
}
1354
#endif /* JAVA_SPEC_VERSION >= 15 */
1355
1356
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1357
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1358
#else
1359
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1360
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1361
vmFuncs->internalExitVMToJNI(currentThread);
1362
}
1363
1364
jstring JNICALL
1365
JVM_GetSimpleBinaryName(JNIEnv *env, jclass arg1)
1366
{
1367
assert(!"JVM_GetSimpleBinaryName unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1368
return NULL;
1369
}
1370
1371
void JNICALL
1372
JVM_SetMethodInfo(JNIEnv *env, jobject arg1)
1373
{
1374
assert(!"JVM_SetMethodInfo unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1375
}
1376
1377
jint JNICALL
1378
JVM_ConstantPoolGetNameAndTypeRefIndexAt(JNIEnv *env, jobject arg1, jobject arg2, jint arg3)
1379
{
1380
assert(!"JVM_ConstantPoolGetNameAndTypeRefIndexAt unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1381
return -1;
1382
}
1383
1384
jint JNICALL
1385
JVM_MoreStackWalk(JNIEnv *env, jobject arg1, jlong arg2, jlong arg3, jint arg4, jint arg5, jobjectArray arg6, jobjectArray arg7)
1386
{
1387
assert(!"JVM_MoreStackWalk unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1388
return -1;
1389
}
1390
1391
jint JNICALL
1392
JVM_ConstantPoolGetClassRefIndexAt(JNIEnv *env, jobject arg1, jlong arg2, jint arg3)
1393
{
1394
assert(!"JVM_ConstantPoolGetClassRefIndexAt unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1395
return -1;
1396
}
1397
1398
jobjectArray JNICALL
1399
JVM_GetVmArguments(JNIEnv *env)
1400
{
1401
J9VMThread* currentThread = (J9VMThread*)env;
1402
J9JavaVM* vm = currentThread->javaVM;
1403
J9InternalVMFunctions* internalFunctions = vm->internalVMFunctions;
1404
jobjectArray result = NULL;
1405
J9Class* vmClass = NULL;
1406
1407
internalFunctions->internalEnterVMFromJNI(currentThread);
1408
1409
vmClass = J9VMCOMIBMOTIVMVM_OR_NULL(vm);
1410
1411
if (NULL != vmClass) {
1412
J9Method* method = internalFunctions->findJNIMethod(currentThread, vmClass, "getVMArgs", "()[Ljava/lang/String;");
1413
1414
if (NULL != method) {
1415
jmethodID mid = (jmethodID)internalFunctions->getJNIMethodID(currentThread, method);
1416
1417
if (NULL != mid) {
1418
jclass vmJniClass = (jclass)internalFunctions->j9jni_createLocalRef(env, vmClass->classObject);
1419
1420
if (NULL != vmJniClass) {
1421
/* exit vm before calling jni method */
1422
internalFunctions->internalExitVMToJNI(currentThread);
1423
1424
result = (jobjectArray)((*env)->CallObjectMethod(env, vmJniClass, mid));
1425
1426
internalFunctions->internalEnterVMFromJNI(currentThread);
1427
internalFunctions->j9jni_deleteLocalRef(env, (jobject)vmJniClass);
1428
goto success;
1429
}
1430
}
1431
}
1432
}
1433
/* if code reaches here, something went wrong */
1434
internalFunctions->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGINTERNALERROR, NULL);
1435
1436
success:
1437
internalFunctions->internalExitVMToJNI(currentThread);
1438
return result;
1439
}
1440
1441
void JNICALL
1442
JVM_FillStackFrames(JNIEnv *env, jclass arg1, jint arg2, jobjectArray arg3, jint arg4, jint arg5)
1443
{
1444
assert(!"JVM_FillStackFrames unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1445
}
1446
1447
jclass JNICALL
1448
JVM_FindClassFromCaller(JNIEnv* env, const char* arg1, jboolean arg2, jobject arg3, jclass arg4)
1449
{
1450
assert(!"JVM_FindClassFromCaller unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1451
return NULL;
1452
}
1453
1454
jobjectArray JNICALL
1455
JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, jobject arg1, jobject arg2, jint arg3)
1456
{
1457
assert(!"JVM_ConstantPoolGetNameAndTypeRefInfoAt unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1458
return NULL;
1459
}
1460
1461
jbyte JNICALL
1462
JVM_ConstantPoolGetTagAt(JNIEnv *env, jobject arg1, jobject arg2, jint arg3)
1463
{
1464
assert(!"JVM_ConstantPoolGetTagAt unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1465
return 0;
1466
}
1467
1468
jobject JNICALL
1469
JVM_CallStackWalk(JNIEnv *env, jobject arg1, jlong arg2, jint arg3, jint arg4, jint arg5, jobjectArray arg6, jobjectArray arg7)
1470
{
1471
assert(!"JVM_CallStackWalk unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1472
return NULL;
1473
}
1474
1475
JNIEXPORT jobject JNICALL
1476
JVM_GetAndClearReferencePendingList(JNIEnv *env)
1477
{
1478
assert(!"JVM_GetAndClearReferencePendingList unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1479
return NULL;
1480
}
1481
1482
JNIEXPORT jboolean JNICALL
1483
JVM_HasReferencePendingList(JNIEnv *env)
1484
{
1485
assert(!"JVM_HasReferencePendingList unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1486
return JNI_FALSE;
1487
}
1488
1489
JNIEXPORT void JNICALL
1490
JVM_WaitForReferencePendingList(JNIEnv *env)
1491
{
1492
assert(!"JVM_WaitForReferencePendingList unimplemented"); /* Jazz 108925: Revive J9JCL raw pConfig build */
1493
return;
1494
}
1495
1496
/**
1497
* Adds an unnamed module to the bootLoader
1498
*
1499
* @param module module
1500
*
1501
* @throws IllegalArgumentException is thrown if
1502
* 1) Module is named
1503
* 2) Module is not j.l.r.Module or subclass of
1504
* 3) Module is not loaded by the bootLoader
1505
*
1506
* @throws NullPointerException if module is NULL
1507
*/
1508
void JNICALL
1509
JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module)
1510
{
1511
J9VMThread * const currentThread = (J9VMThread*)env;
1512
J9JavaVM * vm = currentThread->javaVM;
1513
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1514
1515
vmFuncs->internalEnterVMFromJNI(currentThread);
1516
if (module == NULL) {
1517
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, "module is null");
1518
} else {
1519
j9object_t modObj = J9_JNI_UNWRAP_REFERENCE(module);
1520
J9ClassLoader *systemClassLoader = vm->systemClassLoader;
1521
J9Class *instanceClazz = J9OBJECT_CLAZZ(currentThread, modObj);
1522
if (!currentThread->currentException) {
1523
J9Class *moduleClass = vmFuncs->internalFindKnownClass(currentThread,
1524
J9VMCONSTANTPOOL_JAVALANGMODULE,
1525
J9_FINDKNOWNCLASS_FLAG_INITIALIZE);
1526
if (!isModuleUnnamed(currentThread, modObj)) {
1527
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, "named module was supplied");
1528
} else if (!isSameOrSuperClassOf(moduleClass, instanceClazz)) {
1529
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, "module supplied is not same or sub class of java/lang/Module");
1530
} else if (instanceClazz->classLoader != systemClassLoader) {
1531
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, "module was not loaded by the bootclassloader");
1532
} else {
1533
if (NULL == J9VMJAVALANGCLASSLOADER_UNNAMEDMODULE(currentThread, systemClassLoader->classLoaderObject)) {
1534
J9Module *j9mod = createModule(currentThread, modObj, systemClassLoader, NULL /* NULL name field */);
1535
J9VMJAVALANGCLASSLOADER_SET_UNNAMEDMODULE(currentThread, systemClassLoader->classLoaderObject, modObj);
1536
Trc_MODULE_setBootloaderUnnamedModule(currentThread, j9mod);
1537
} else {
1538
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGINTERNALERROR, "module is already set in the bootclassloader");
1539
}
1540
}
1541
}
1542
}
1543
vmFuncs->internalExitVMToJNI(currentThread);
1544
}
1545
1546
void JNICALL
1547
JVM_ToStackTraceElement(JNIEnv* env, jobject arg1, jobject arg2)
1548
{
1549
assert(!"JVM_ToStackTraceElement unimplemented");
1550
}
1551
1552
void JNICALL
1553
JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements)
1554
{
1555
assert(!"JVM_GetStackTraceElements unimplemented");
1556
}
1557
1558
void JNICALL
1559
JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable)
1560
{
1561
assert(!"JVM_InitStackTraceElementArray unimplemented");
1562
}
1563
1564
void JNICALL
1565
JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo)
1566
{
1567
assert(!"JVM_InitStackTraceElement unimplemented");
1568
}
1569
1570
/* JVM_GetModuleByPackageName is to be deleted for b156 */
1571
/**
1572
* Returns the j.l.r.Module object for this classLoader and package. If the classLoader
1573
* has not loaded any classes in the package, method returns NULL. The package should contain /'s,
1574
* not .'s, ex: java/lang, not java.lang. Throws NPE if package is null. throws
1575
* IllegalArgumentException, if loader is not null and a subtype of j.l.Classloader.
1576
*
1577
* @param [in] env pointer to JNIEnv
1578
* @param [in] classLoader ClassLoader object
1579
* @param [in] packageName name of package
1580
*
1581
* @return a module, NULL on failure
1582
*/
1583
jobject JNICALL
1584
JVM_GetModuleByPackageName(JNIEnv *env, jobject classLoader, jstring packageName)
1585
{
1586
J9VMThread * const currentThread = (J9VMThread*)env;
1587
J9JavaVM * vm = currentThread->javaVM;
1588
J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions;
1589
jobject module = NULL;
1590
1591
vmFuncs->internalEnterVMFromJNI(currentThread);
1592
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1593
omrthread_monitor_enter(vm->classLoaderModuleAndLocationMutex);
1594
#else
1595
f_monitorEnter(vm->classLoaderModuleAndLocationMutex);
1596
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1597
if (NULL == packageName) {
1598
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, "package name is null");
1599
} else {
1600
J9ClassLoader *thisVMClassLoader = NULL;
1601
J9UTF8 *packageUTF8 = NULL;
1602
UDATA packageLength = 0;
1603
char buf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
1604
j9object_t packageObj = J9_JNI_UNWRAP_REFERENCE(packageName);
1605
j9object_t moduleObj = NULL;
1606
J9Module *vmModule = NULL;
1607
PORT_ACCESS_FROM_VMC(currentThread);
1608
1609
if (NULL == classLoader) {
1610
thisVMClassLoader = vm->systemClassLoader;
1611
} else {
1612
j9object_t thisClassloader = NULL;
1613
J9Class *thisClassLoaderClass = NULL;
1614
J9Class *classLoaderClass = vmFuncs->internalFindKnownClass(currentThread,
1615
J9VMCONSTANTPOOL_JAVALANGCLASSLOADER,
1616
J9_FINDKNOWNCLASS_FLAG_INITIALIZE
1617
);
1618
thisClassloader = J9_JNI_UNWRAP_REFERENCE(classLoader);
1619
thisClassLoaderClass = J9OBJECT_CLAZZ(currentThread, thisClassloader);
1620
1621
if (!isSameOrSuperClassOf(classLoaderClass, thisClassLoaderClass)) {
1622
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, "classLoader is not same or subclass of java/lang/ClassLoader");
1623
goto exit;
1624
}
1625
1626
thisVMClassLoader = J9VMJAVALANGCLASSLOADER_VMREF(currentThread, thisClassloader);
1627
}
1628
1629
packageUTF8 = vmFuncs->copyStringToJ9UTF8WithMemAlloc(currentThread, packageObj, J9_STR_NULL_TERMINATE_RESULT, "", 0, buf, J9VM_PACKAGE_NAME_BUFFER_LENGTH);
1630
1631
if (NULL == packageUTF8) {
1632
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
1633
goto exit;
1634
}
1635
1636
if (NULL != strchr((const char*)J9UTF8_DATA(packageUTF8), '.')) {
1637
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, "package name contains '.' instead of '/'");
1638
} else {
1639
if (vmFuncs->isAnyClassLoadedFromPackage(thisVMClassLoader, J9UTF8_DATA(packageUTF8), J9UTF8_LENGTH(packageUTF8))) {
1640
vmModule = vmFuncs->findModuleForPackageUTF8(currentThread, thisVMClassLoader, packageUTF8);
1641
if (NULL == vmModule) {
1642
moduleObj = J9VMJAVALANGCLASSLOADER_UNNAMEDMODULE(currentThread, thisVMClassLoader->classLoaderObject);
1643
} else {
1644
moduleObj = vmModule->moduleObject;
1645
}
1646
module = vmFuncs->j9jni_createLocalRef((JNIEnv *) currentThread, moduleObj);
1647
if (NULL == module) {
1648
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
1649
}
1650
}
1651
}
1652
if (packageUTF8 != (J9UTF8*)buf) {
1653
j9mem_free_memory(packageUTF8);
1654
}
1655
}
1656
exit:
1657
#if defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY)
1658
omrthread_monitor_exit(vm->classLoaderModuleAndLocationMutex);
1659
#else
1660
f_monitorExit(vm->classLoaderModuleAndLocationMutex);
1661
#endif /* defined(CALL_BUNDLED_FUNCTIONS_DIRECTLY) */
1662
vmFuncs->internalExitVMToJNI(currentThread);
1663
1664
return module;
1665
}
1666
1667
/**
1668
* Return the clock time in nanoseconds at given offset
1669
*
1670
* @param [in] env pointer to JNIEnv
1671
* @param [in] clazz Class object
1672
* @param [in] offsetSeconds offset in seconds
1673
*
1674
* @return nanoSeconds, -1 on failure
1675
*/
1676
jlong JNICALL
1677
JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass clazz, jlong offsetSeconds)
1678
{
1679
PORT_ACCESS_FROM_ENV(env);
1680
jlong offsetNanoSeconds = 0;
1681
jlong currentTimeNano = 0;
1682
jlong result = -1;
1683
1684
/* 2^63/10^9 is the largest number offsetSeconds can be such that multiplying it
1685
* by J9TIME_NANOSECONDS_PER_SECOND (10^9) will not result in an overflow
1686
*/
1687
if ((offsetSeconds <= OFFSET_MAX) && (offsetSeconds >= OFFSET_MIN)) {
1688
UDATA success = 0;
1689
offsetNanoSeconds = offsetSeconds * J9TIME_NANOSECONDS_PER_SECOND;
1690
currentTimeNano = (jlong) j9time_current_time_nanos(&success);
1691
if (success) {
1692
if ((offsetNanoSeconds >= (currentTimeNano - TIME_LONG_MAX))
1693
&& (offsetNanoSeconds <= (currentTimeNano - TIME_LONG_MIN))
1694
) {
1695
result = currentTimeNano - offsetNanoSeconds;
1696
}
1697
}
1698
}
1699
1700
return result;
1701
}
1702
1703
JNIEXPORT jclass JNICALL
1704
JVM_GetNestHost(JNIEnv *env, jclass clz)
1705
{
1706
assert(!"JVM_GetNestHost unimplemented");
1707
return NULL;
1708
}
1709
1710
JNIEXPORT jobjectArray JNICALL
1711
JVM_GetNestMembers(JNIEnv *env, jclass clz)
1712
{
1713
assert(!"JVM_GetNestMembers unimplemented");
1714
return NULL;
1715
}
1716
1717
/**
1718
* Check if two classes belong to the same nest
1719
*
1720
* @param [in] env pointer to JNIEnv
1721
* @param [in] jClassOne Class object 1
1722
* @param [in] jClassTwo Class object 2
1723
*
1724
* @return JNI_TRUE if classes belong to the same nest, JNI_FALSE otherwise
1725
*/
1726
JNIEXPORT jboolean JNICALL
1727
JVM_AreNestMates(JNIEnv *env, jclass jClassOne, jclass jClassTwo)
1728
{
1729
jboolean result = JNI_FALSE;
1730
1731
if ((NULL != jClassOne) && (NULL != jClassTwo)) {
1732
j9object_t clazzObjectOne = NULL;
1733
j9object_t clazzObjectTwo = NULL;
1734
J9VMThread *currentThread = (J9VMThread*)env;
1735
J9InternalVMFunctions *vmFuncs = currentThread->javaVM->internalVMFunctions;
1736
1737
vmFuncs->internalEnterVMFromJNI(currentThread);
1738
clazzObjectOne = J9_JNI_UNWRAP_REFERENCE(jClassOne);
1739
clazzObjectTwo = J9_JNI_UNWRAP_REFERENCE(jClassTwo);
1740
1741
if (clazzObjectOne == clazzObjectTwo) {
1742
result = JNI_TRUE;
1743
} else {
1744
J9Class *clazzOne = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, clazzObjectOne);
1745
J9Class *clazzTwo = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, clazzObjectTwo);
1746
1747
if (NULL == clazzOne->nestHost) {
1748
if (J9_VISIBILITY_ALLOWED != vmFuncs->loadAndVerifyNestHost(currentThread, clazzOne, J9_LOOK_NO_THROW)) {
1749
goto done;
1750
}
1751
}
1752
1753
if (NULL == clazzTwo->nestHost) {
1754
if (J9_VISIBILITY_ALLOWED != vmFuncs->loadAndVerifyNestHost(currentThread, clazzTwo, J9_LOOK_NO_THROW)) {
1755
goto done;
1756
}
1757
}
1758
1759
if (clazzOne->nestHost == clazzTwo->nestHost) {
1760
result = JNI_TRUE;
1761
}
1762
}
1763
done:
1764
vmFuncs->internalExitVMToJNI(currentThread);
1765
}
1766
1767
return result;
1768
}
1769
#endif /* JAVA_SPEC_VERSION >= 11 */
1770
1771
#if JAVA_SPEC_VERSION >= 15
1772
JNIEXPORT void JNICALL
1773
JVM_RegisterLambdaProxyClassForArchiving(JNIEnv *env, jclass arg1, jstring arg2, jobject arg3, jobject arg4, jobject arg5, jobject arg6, jclass arg7)
1774
{
1775
assert(!"JVM_RegisterLambdaProxyClassForArchiving unimplemented");
1776
}
1777
1778
JNIEXPORT jclass JNICALL
1779
JVM_LookupLambdaProxyClassFromArchive(JNIEnv *env, jclass arg1, jstring arg2, jobject arg3, jobject arg4, jobject arg5, jobject arg6
1780
#if JAVA_SPEC_VERSION == 15
1781
, jboolean arg7
1782
#endif /* JAVA_SPEC_VERSION == 15 */
1783
)
1784
{
1785
assert(!"JVM_LookupLambdaProxyClassFromArchive unimplemented");
1786
return NULL;
1787
}
1788
1789
JNIEXPORT jboolean JNICALL
1790
JVM_IsCDSDumpingEnabled(JNIEnv *env)
1791
{
1792
/* OpenJ9 does not support -Xshare:dump, so we return false unconditionally. */
1793
return JNI_FALSE;
1794
}
1795
#endif /* JAVA_SPEC_VERSION >= 15 */
1796
1797
#if JAVA_SPEC_VERSION >= 16
1798
1799
JNIEXPORT jlong JNICALL
1800
JVM_GetRandomSeedForDumping()
1801
{
1802
/* OpenJ9 does not support -Xshare:dump, so we return zero unconditionally. */
1803
return 0;
1804
}
1805
1806
JNIEXPORT jboolean JNICALL
1807
JVM_IsSharingEnabled(JNIEnv *env)
1808
{
1809
/* OpenJ9 does not support CDS, so we return false unconditionally. */
1810
return JNI_FALSE;
1811
}
1812
1813
#endif /* JAVA_SPEC_VERSION >= 16 */
1814
1815
JNIEXPORT jboolean JNICALL
1816
JVM_IsUseContainerSupport(JNIEnv *env)
1817
{
1818
PORT_ACCESS_FROM_ENV(env);
1819
OMRPORT_ACCESS_FROM_J9PORT(PORTLIB);
1820
BOOLEAN inContainer = omrsysinfo_is_running_in_container();
1821
1822
return inContainer ? JNI_TRUE : JNI_FALSE;
1823
}
1824
1825