Path: blob/master/runtime/gc_modron_standard/ReadBarrierVerifier.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 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*******************************************************************************/212223/**24* @file25* @ingroup GC_Modron_Base26*/272829#include "ReadBarrierVerifier.hpp"3031#include "AtomicOperations.hpp"32#include "Debug.hpp"33#include "EnvironmentStandard.hpp"34#include "HeapRegionManager.hpp"35#include "j9cfg.h"36#include "mmhook_internal.h"37#include "ModronAssertions.h"3839#include "RootScannerReadBarrierVerifier.hpp"40#include "Scavenger.hpp"41#include "SublistFragment.hpp"4243#if defined(OMR_ENV_DATA64) && defined(OMR_GC_FULL_POINTERS)4445MM_ReadBarrierVerifier *46MM_ReadBarrierVerifier::newInstance(MM_EnvironmentBase *env, MM_MarkingScheme *markingScheme)47{48MM_ReadBarrierVerifier *barrier;4950barrier = (MM_ReadBarrierVerifier *)env->getForge()->allocate(sizeof(MM_ReadBarrierVerifier), MM_AllocationCategory::FIXED, J9_GET_CALLSITE());51if (barrier) {52new(barrier) MM_ReadBarrierVerifier(env, markingScheme);53if (!barrier->initialize(env)) {54barrier->kill(env);55barrier = NULL;56}57}5859return barrier;60}6162bool63MM_ReadBarrierVerifier::initialize(MM_EnvironmentBase *env)64{65return MM_StandardAccessBarrier::initialize(env);66}6768void69MM_ReadBarrierVerifier::kill(MM_EnvironmentBase *env)70{71tearDown(env);72env->getForge()->free(this);73}7475void76MM_ReadBarrierVerifier::tearDown(MM_EnvironmentBase *env)77{78MM_StandardAccessBarrier::tearDown(env);79}80bool81MM_ReadBarrierVerifier::preObjectRead(J9VMThread *vmThread, J9Object *srcObject, fj9object_t *srcAddress)82{83Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);84healSlot(_extensions, srcAddress);8586return true;87}8889void90MM_ReadBarrierVerifier::poisonSlot(MM_GCExtensionsBase *extensions, omrobjectptr_t *slot)91{92uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();93uintptr_t heapTop = (uintptr_t)extensions->heap->getHeapTop();94uintptr_t referenceFromSlot = (uintptr_t)*slot;9596if ((heapTop > referenceFromSlot) && (heapBase <= referenceFromSlot)) {97uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;98*slot = (omrobjectptr_t) (shadowHeapBase + (referenceFromSlot - heapBase));99}100}101102void103MM_ReadBarrierVerifier::poisonJniWeakReferenceSlots(MM_EnvironmentBase *env)104{105MM_RootScannerReadBarrierVerifier scanner(env, true, true);106scanner.scanJNIWeakGlobalReferences(env);107}108109void110MM_ReadBarrierVerifier::poisonMonitorReferenceSlots(MM_EnvironmentBase *env)111{112MM_RootScannerReadBarrierVerifier scanner(env, true, true);113scanner.scanMonitorReferences(env);114}115116void117MM_ReadBarrierVerifier::poisonClass(MM_EnvironmentBase *env)118{119MM_RootScannerReadBarrierVerifier scanner(env, true, true);120scanner.scanClass(env);121}122123void124MM_ReadBarrierVerifier::poisonSlots(MM_EnvironmentBase *env)125{126MM_GCExtensionsBase *extensions = env->getExtensions();127if (1 == extensions->fvtest_enableJNIGlobalWeakReadBarrierVerification) {128poisonJniWeakReferenceSlots(env);129}130if (1 == extensions->fvtest_enableMonitorObjectsReadBarrierVerification) {131poisonMonitorReferenceSlots(env);132}133if (1 == extensions->fvtest_enableClassStaticsReadBarrierVerification) {134poisonClass(env);135}136}137138void139MM_ReadBarrierVerifier::healSlot(MM_GCExtensionsBase *extensions, fomrobject_t *srcAddress)140{141uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;142uintptr_t shadowHeapTop = (uintptr_t)extensions->shadowHeapTop;143GC_SlotObject slotObject(extensions->getOmrVM(), srcAddress);144omrobjectptr_t object = slotObject.readReferenceFromSlot();145146if ((shadowHeapTop > (uintptr_t)object) && (shadowHeapBase <= (uintptr_t)object)) {147148uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();149uintptr_t healedAddress = heapBase + ((uintptr_t)object - shadowHeapBase);150151/* We don't care if the write fails, some other thread probably wrote a healed value to the slot */152slotObject.atomicWriteReferenceToSlot(object, (omrobjectptr_t)healedAddress);153154}155}156157void158MM_ReadBarrierVerifier::healSlot(MM_GCExtensionsBase *extensions, omrobjectptr_t *slot)159{160uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;161uintptr_t shadowHeapTop = (uintptr_t)extensions->shadowHeapTop;162uintptr_t referenceFromSlot = (uintptr_t)*slot;163164if ((shadowHeapTop > referenceFromSlot) && (shadowHeapBase <= referenceFromSlot)) {165166uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();167uintptr_t healedHeapAddress = heapBase + (referenceFromSlot - shadowHeapBase);168169/* We don't care if the write fails, some other thread probably wrote a healed value to the slot */170MM_AtomicOperations::lockCompareExchange((uintptr_t *)slot, referenceFromSlot, healedHeapAddress);171172}173}174175void176MM_ReadBarrierVerifier::healJniWeakReferenceSlots(MM_EnvironmentBase *env)177{178MM_RootScannerReadBarrierVerifier scanner(env, true);179scanner.scanJNIWeakGlobalReferences(env);180}181182void183MM_ReadBarrierVerifier::healMonitorReferenceSlots(MM_EnvironmentBase *env)184{185MM_RootScannerReadBarrierVerifier scanner(env, true);186scanner.scanMonitorReferences(env);187}188189void190MM_ReadBarrierVerifier::healClass(MM_EnvironmentBase *env)191{192MM_RootScannerReadBarrierVerifier scanner(env, true);193scanner.scanClass(env);194}195196void197MM_ReadBarrierVerifier::healSlots(MM_EnvironmentBase *env)198{199MM_GCExtensionsBase *extensions = env->getExtensions();200if (1 == extensions->fvtest_enableJNIGlobalWeakReadBarrierVerification) {201healJniWeakReferenceSlots(env);202}203if (1 == extensions->fvtest_enableMonitorObjectsReadBarrierVerification) {204healMonitorReferenceSlots(env);205}206if (1 == extensions->fvtest_enableClassStaticsReadBarrierVerification) {207healClass(env);208}209210}211212bool213MM_ReadBarrierVerifier::preObjectRead(J9VMThread *vmThread, J9Class *srcClass, j9object_t *srcAddress)214{215Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);216healSlot(_extensions, srcAddress);217return true;218}219220bool221MM_ReadBarrierVerifier::preWeakRootSlotRead(J9VMThread *vmThread, j9object_t *srcAddress)222{223Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);224healSlot(_extensions, srcAddress);225return true;226}227228bool229MM_ReadBarrierVerifier::preWeakRootSlotRead(J9JavaVM *vm, j9object_t *srcAddress)230{231healSlot(_extensions, srcAddress);232return true;233}234235#endif /* defined(OMR_ENV_DATA64) && defined(OMR_GC_FULL_POINTERS) */236237238239