Skip to content

Commit c9d4a5a

Browse files
committed
Add disableDoubleMapping option
Fix copyright Fix how to get arraylet leaves Signed-off-by: Igor Braga <higorb1@gmail.com>
1 parent 0b1e009 commit c9d4a5a

6 files changed

+64
-51
lines changed

runtime/gc_base/IndexableObjectAllocationModel.cpp

+23-23
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
#include "HeapRegionManager.hpp"
3232
#include "HeapRegionDescriptorVLHGC.hpp"
3333
#include "Heap.hpp"
34-
35-
#define ARRAYLET_ALLOC_THRESHOLD 64
3634
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
3735

3836
/**
@@ -260,20 +258,24 @@ MM_IndexableObjectAllocationModel::layoutDiscontiguousArraylet(MM_EnvironmentBas
260258
switch (_layout) {
261259
case GC_ArrayletObjectModel::Discontiguous:
262260
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
263-
if (extensions->indexableObjectModel.isDoubleMappingEnabled() && extensions->isVLHGC()) {
261+
if (extensions->indexableObjectModel.isDoubleMappingEnabled()) {
264262
Assert_MM_true(arrayoidIndex == _numberOfArraylets);
265263
UDATA arrayletLeafCount = extensions->indexableObjectModel.numArraylets(spine);
266264
UDATA sizeInElements = extensions->indexableObjectModel.getSizeInElements(spine);
267265
Assert_MM_true(sizeInElements == 0 || arrayletLeafCount > 0);
268266

269-
if ((arrayletLeafCount > 1) && (sizeInElements > 0)) {
267+
/*
268+
* Arraylets that contain only one leaf are contiguous in nature; therefore, there's
269+
* no need to double map it
270+
*/
271+
if ((arrayletLeafCount > 1)) {
270272
doubleMapArraylets(env, (J9Object *)spine);
271273
/*
272-
* If doublemap fails the caller must handle it appropriatly. In case
273-
* of JNI critical, if doublemap fails, it will fall back to copying
274-
* each element of the array to a temporary array. It might hurt performance
275-
* but execution won't halt.
276-
*/
274+
* If doublemap fails the caller must handle it appropriatly. In case
275+
* of JNI critical, if doublemap fails, it will fall back to copying
276+
* each element of the array to a temporary array. It might hurt performance
277+
* but execution won't halt.
278+
*/
277279
}
278280
} else
279281
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
@@ -337,11 +339,10 @@ MM_IndexableObjectAllocationModel::doubleMapArraylets(MM_EnvironmentBase* env, J
337339

338340
void *result = NULL;
339341

342+
#define ARRAYLET_ALLOC_THRESHOLD 64
340343
void *leaves[ARRAYLET_ALLOC_THRESHOLD];
341-
void **arrayletLeaveAddrs;
342-
if (arrayletLeafCount <= ARRAYLET_ALLOC_THRESHOLD) {
343-
arrayletLeaveAddrs = leaves;
344-
} else {
344+
void **arrayletLeaveAddrs = leaves;
345+
if (arrayletLeafCount > ARRAYLET_ALLOC_THRESHOLD) {
345346
arrayletLeaveAddrs = (void **)env->getForge()->allocate(arrayletLeafCount * sizeof(uintptr_t), MM_AllocationCategory::GC_HEAP, J9_GET_CALLSITE());
346347
}
347348

@@ -359,13 +360,14 @@ MM_IndexableObjectAllocationModel::doubleMapArraylets(MM_EnvironmentBase* env, J
359360
count++;
360361
}
361362

362-
J9Object *firstLeafSlot = (J9Object *)((uintptr_t)extensions->indexableObjectModel.getArrayoidPointer((J9IndexableObject*)objectPtr)[0]);
363+
GC_SlotObject objectSlot(env->getOmrVM(), &extensions->indexableObjectModel.getArrayoidPointer((J9IndexableObject*)objectPtr)[0]);
364+
J9Object *firstLeafSlot = objectSlot.readReferenceFromSlot();
363365

364-
MM_HeapRegionDescriptorVLHGC *firstLeafRegionDescriptor = (MM_HeapRegionDescriptorVLHGC *)heap->getHeapRegionManager()->tableDescriptorForAddress(firstLeafSlot);
366+
MM_HeapRegionDescriptorVLHGC *firstLeafRegionDescriptor = (MM_HeapRegionDescriptorVLHGC *)heap->getHeapRegionManager()->tableDescriptorForAddress(firstLeafSlot);
365367

366-
UDATA arrayletLeafSize = javaVM->arrayletLeafSize;
367-
/* gets pagesize or j9vmem_supported_page_sizes()[0]? */
368-
UDATA pageSize = j9mmap_get_region_granularity(NULL);
368+
UDATA arrayletLeafSize = javaVM->arrayletLeafSize;
369+
/* gets pagesize or j9vmem_supported_page_sizes()[0]? */
370+
UDATA pageSize = j9mmap_get_region_granularity(NULL);
369371

370372
/* Get heap and from there call an OMR API that will doble map everything */
371373
result = heap->doubleMapArraylet(env, arrayletLeaveAddrs, count, arrayletLeafSize, elementsSize,
@@ -382,11 +384,9 @@ MM_IndexableObjectAllocationModel::doubleMapArraylets(MM_EnvironmentBase* env, J
382384
printf("Freeing dynamically allocated array!!!!\n");
383385
}
384386

385-
// env->getForge()->free((void*)arrayletLeaveAddrs);
386-
387-
if (NULL == firstLeafRegionDescriptor->_identifier.address) {
388-
result = NULL;
389-
}
387+
if (NULL == firstLeafRegionDescriptor->_identifier.address) {
388+
result = NULL;
389+
}
390390

391391
return result;
392392
}

runtime/gc_base/IndexableObjectAllocationModel.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
/*******************************************************************************
3-
* Copyright (c) 1991, 2014 IBM Corp. and others
3+
* Copyright (c) 1991, 2019 IBM Corp. and others
44
*
55
* This program and the accompanying materials are made available under
66
* the terms of the Eclipse Public License 2.0 which accompanies this

runtime/gc_glue_java/ArrayletObjectModelBase.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class GC_ArrayletObjectModelBase
259259
/* By forcing the layout to be discontiguous in some special cases the last arraylet leaf may be a
260260
* NULL pointer. In that case we do not consider such leaf for this arraylet.
261261
*/
262-
if ((_enableDoubleMapping && 1 < numberOfArraylets) && (0 == unadjustedDataSizeInBytes % leafSize)) {
262+
if ((_enableDoubleMapping && (1 < numberOfArraylets)) && (0 == unadjustedDataSizeInBytes % leafSize)) {
263263
numberOfArraylets -= 1;
264264
}
265265
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */

runtime/gc_modron_startup/mmparseXXgc.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ gcParseXXgcArguments(J9JavaVM *vm, char *optArg)
169169
extensions->indexableObjectModel.setEnableDoubleMapping(true);
170170
continue;
171171
}
172+
if (try_scan(&scan_start, "disableDoubleMapping")) {
173+
extensions->indexableObjectModel.setEnableDoubleMapping(false);
174+
continue;
175+
}
172176
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
173177
if(try_scan(&scan_start, "disableNonDeterministicSweep")) {
174178
extensions->nonDeterministicSweep = false;

runtime/gc_vlhgc/CopyForwardScheme.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -3880,14 +3880,15 @@ class MM_CopyForwardSchemeRootClearer : public MM_RootScanner
38803880

38813881
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
38823882
virtual void doDoubleMappedObjectSlot(J9Object *objectPtr, struct J9PortVmemIdentifier *identifier) {
3883-
MM_EnvironmentVLHGC::getEnvironment(_env)->_copyForwardStats._doubleMappedArrayletsCandidates += 1;
3883+
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(_env);
3884+
env->_copyForwardStats._doubleMappedArrayletsCandidates += 1;
38843885
if (!_copyForwardScheme->isLiveObject(objectPtr)) {
38853886
Assert_MM_true(_copyForwardScheme->isObjectInEvacuateMemory(objectPtr));
38863887
MM_ScavengerForwardedHeader forwardedHeader(objectPtr);
38873888
objectPtr = forwardedHeader.getForwardedObject();
38883889
if (NULL == objectPtr) {
38893890
Assert_MM_mustBeClass(forwardedHeader.getPreservedClass());
3890-
MM_EnvironmentVLHGC::getEnvironment(_env)->_copyForwardStats._doubleMappedArrayletsCleared += 1;
3891+
env->_copyForwardStats._doubleMappedArrayletsCleared += 1;
38913892
PORT_ACCESS_FROM_ENVIRONMENT(_env);
38923893
int result = j9vmem_free_memory(identifier->address, identifier->size, identifier);
38933894
Assert_MM_true(result == 0);

runtime/gc_vlhgc/VLHGCAccessBarrier.cpp

+32-24
Original file line numberDiff line numberDiff line change
@@ -257,45 +257,48 @@ MM_VLHGCAccessBarrier::jniGetPrimitiveArrayCritical(J9VMThread* vmThread, jarray
257257
J9JavaVM *javaVM = vmThread->javaVM;
258258
J9InternalVMFunctions *functions = javaVM->internalVMFunctions;
259259
VM_VMAccess::inlineEnterVMFromJNI(vmThread);
260+
GC_ArrayObjectModel *indexableObjectModel = &_extensions->indexableObjectModel;
260261

261262
J9IndexableObject *arrayObject = (J9IndexableObject*)J9_JNI_UNWRAP_REFERENCE(array);
262263
bool shouldCopy = false;
263264
bool alwaysCopyInCritical = (javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) == J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL;
264265
if (alwaysCopyInCritical) {
265266
shouldCopy = true;
266-
} else if (!_extensions->indexableObjectModel.isInlineContiguousArraylet(arrayObject)) {
267+
} else if (!indexableObjectModel->isInlineContiguousArraylet(arrayObject)) {
267268
/* an array having discontiguous extents is another reason to force the critical section to be a copy */
268269
shouldCopy = true;
269270
}
270271

271272
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
272-
bool successDoubleMap = false;
273-
if (shouldCopy && _extensions->indexableObjectModel.isDoubleMappingEnabled()) {
274-
if (_extensions->indexableObjectModel.numArraylets(arrayObject) > 1) {
275-
J9Object *firstLeafSlot = (J9Object *)((uintptr_t)_extensions->indexableObjectModel.getArrayoidPointer(arrayObject)[0]);
273+
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(vmThread);
274+
bool contiguousDataAvailable = false;
275+
if (shouldCopy && indexableObjectModel->isDoubleMappingEnabled()) {
276+
if (indexableObjectModel->numArraylets(arrayObject) > 1) {
277+
GC_SlotObject objectSlot(env->getOmrVM(), &indexableObjectModel->getArrayoidPointer(arrayObject)[0]);
278+
J9Object *firstLeafSlot = objectSlot.readReferenceFromSlot();
276279
MM_HeapRegionDescriptorVLHGC *firstLeafRegionDescriptor = (MM_HeapRegionDescriptorVLHGC *)_extensions->heapRegionManager->tableDescriptorForAddress(firstLeafSlot);
277280
data = firstLeafRegionDescriptor->_identifier.address;
278281

279282
if (NULL == data) {
280283
/* Doublemap failed, but we still need to continue execution; therefore fallback to previous approach */
281-
successDoubleMap = false;
284+
contiguousDataAvailable = false;
282285
} else {
283-
successDoubleMap = true;
286+
contiguousDataAvailable = true;
284287
}
285288
/* Corner case where there's only one arraylet leaf */
286-
} else if (_extensions->indexableObjectModel.numArraylets(arrayObject) == 1 && _extensions->indexableObjectModel.getSizeInElements(arrayObject) > 0) {
289+
} else if (indexableObjectModel->numArraylets(arrayObject) == 1 && indexableObjectModel->getSizeInElements(arrayObject) > 0) {
287290
/* Solo arraylet leaf is contiguous so we can simply return the data associated with it */
288291
MM_JNICriticalRegion::enterCriticalRegion(vmThread, true);
289292
Assert_MM_true(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS);
290-
data = (J9Object *)((uintptr_t)_extensions->indexableObjectModel.getArrayoidPointer(arrayObject)[0]);
291-
successDoubleMap = true;
293+
GC_SlotObject objectSlot(env->getOmrVM(), &indexableObjectModel->getArrayoidPointer(arrayObject)[0]);
294+
data = objectSlot.readReferenceFromSlot();
295+
contiguousDataAvailable = true;
292296
}
293297
}
294-
if (!successDoubleMap)
298+
if (!contiguousDataAvailable)
295299
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
296300
{
297301
if (shouldCopy) {
298-
GC_ArrayObjectModel* indexableObjectModel = &_extensions->indexableObjectModel;
299302
I_32 sizeInElements = (I_32)indexableObjectModel->getSizeInElements(arrayObject);
300303
UDATA sizeInBytes = indexableObjectModel->getDataSizeInBytes(arrayObject);
301304
data = functions->jniArrayAllocateMemoryFromThread(vmThread, sizeInBytes);
@@ -313,7 +316,7 @@ MM_VLHGCAccessBarrier::jniGetPrimitiveArrayCritical(J9VMThread* vmThread, jarray
313316
MM_JNICriticalRegion::enterCriticalRegion(vmThread, true);
314317
Assert_MM_true(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS);
315318
arrayObject = (J9IndexableObject*)J9_JNI_UNWRAP_REFERENCE(array);
316-
data = (void *)_extensions->indexableObjectModel.getDataPointerForContiguous(arrayObject);
319+
data = (void *)indexableObjectModel->getDataPointerForContiguous(arrayObject);
317320
if (NULL != isCopy) {
318321
*isCopy = JNI_FALSE;
319322
}
@@ -334,34 +337,40 @@ MM_VLHGCAccessBarrier::jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, ja
334337
J9JavaVM *javaVM = vmThread->javaVM;
335338
J9InternalVMFunctions *functions = javaVM->internalVMFunctions;
336339
VM_VMAccess::inlineEnterVMFromJNI(vmThread);
340+
GC_ArrayObjectModel *indexableObjectModel = &_extensions->indexableObjectModel;
337341

338342
J9IndexableObject *arrayObject = (J9IndexableObject*)J9_JNI_UNWRAP_REFERENCE(array);
339343
bool shouldCopy = false;
340344
bool alwaysCopyInCritical = (javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) == J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL;
341345
if (alwaysCopyInCritical) {
342346
shouldCopy = true;
343-
} else if (!_extensions->indexableObjectModel.isInlineContiguousArraylet(arrayObject)) {
347+
} else if (!indexableObjectModel->isInlineContiguousArraylet(arrayObject)) {
344348
/* an array having discontiguous extents is another reason to force the critical section to be a copy */
345349
shouldCopy = true;
346350
}
347351
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
352+
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(vmThread);
348353
bool successfulDoubleMap = false;
349-
if(shouldCopy && (_extensions->indexableObjectModel.numArraylets(arrayObject) == 1)
350-
&& _extensions->indexableObjectModel.isDoubleMappingEnabled()
351-
&& (_extensions->indexableObjectModel.getSizeInElements(arrayObject) > 0)) {
354+
if(shouldCopy && (indexableObjectModel->numArraylets(arrayObject) == 1)
355+
&& indexableObjectModel->isDoubleMappingEnabled()
356+
&& (indexableObjectModel->getSizeInElements(arrayObject) > 0)) {
352357
/*
353358
* Objects can not be moved if critical section is active
354359
* This trace point will be generated if object has been moved or passed value of elems is corrupted
355360
*/
356-
void *data = (J9Object *)((uintptr_t)_extensions->indexableObjectModel.getArrayoidPointer(arrayObject)[0]);
361+
GC_SlotObject objectSlot(env->getOmrVM(), &indexableObjectModel->getArrayoidPointer(arrayObject)[0]);
362+
void *data = objectSlot.readReferenceFromSlot();
363+
357364
if (elems != data) {
358365
Trc_MM_JNIReleasePrimitiveArrayCritical_invalid(vmThread, arrayObject, elems, data);
359366
}
360367
successfulDoubleMap = true;
361368
MM_JNICriticalRegion::exitCriticalRegion(vmThread, true);
362-
} else if (shouldCopy && _extensions->indexableObjectModel.isDoubleMappingEnabled()
363-
&& (_extensions->indexableObjectModel.numArraylets(arrayObject) > 1)) {
364-
J9Object *firstLeafSlot = (J9Object *)((uintptr_t)_extensions->indexableObjectModel.getArrayoidPointer(arrayObject)[0]);
369+
} else if (shouldCopy && indexableObjectModel->isDoubleMappingEnabled()
370+
&& (indexableObjectModel->numArraylets(arrayObject) > 1)) {
371+
GC_SlotObject objectSlot(env->getOmrVM(), &indexableObjectModel->getArrayoidPointer(arrayObject)[0]);
372+
J9Object *firstLeafSlot = objectSlot.readReferenceFromSlot();
373+
365374
MM_HeapRegionDescriptorVLHGC *firstLeafRegionDescriptor = (MM_HeapRegionDescriptorVLHGC *)_extensions->heapRegionManager->tableDescriptorForAddress(firstLeafSlot);
366375

367376
if (NULL == firstLeafRegionDescriptor->_identifier.address) {
@@ -376,9 +385,8 @@ MM_VLHGCAccessBarrier::jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, ja
376385
{
377386
if (shouldCopy) {
378387
if (JNI_ABORT != mode) {
379-
GC_ArrayObjectModel* indexableObjectModel = &_extensions->indexableObjectModel;
380388
I_32 sizeInElements = (I_32)indexableObjectModel->getSizeInElements(arrayObject);
381-
_extensions->indexableObjectModel.memcpyToArray(arrayObject, 0, sizeInElements, elems);
389+
indexableObjectModel->memcpyToArray(arrayObject, 0, sizeInElements, elems);
382390
}
383391

384392
// Commit means copy the data but do not free the buffer.
@@ -397,7 +405,7 @@ MM_VLHGCAccessBarrier::jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, ja
397405
* Objects can not be moved if critical section is active
398406
* This trace point will be generated if object has been moved or passed value of elems is corrupted
399407
*/
400-
void *data = (void *)_extensions->indexableObjectModel.getDataPointerForContiguous(arrayObject);
408+
void *data = (void *)indexableObjectModel->getDataPointerForContiguous(arrayObject);
401409
if(elems != data) {
402410
Trc_MM_JNIReleasePrimitiveArrayCritical_invalid(vmThread, arrayObject, elems, data);
403411
}

0 commit comments

Comments
 (0)