Path: blob/master/runtime/gc_base/GenerationalAccessBarrierComponent.cpp
5985 views
1/*******************************************************************************2* Copyright (c) 1991, 2021 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* 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 and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*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-exception21*******************************************************************************/222324/**25* @file26* @ingroup GC_Base27*/2829#include "j9.h"30#include "j9cfg.h"31#include "j9consts.h"32#include "j9protos.h"33#include "ModronAssertions.h"34#include "j9nongenerated.h"3536#if defined(J9VM_GC_GENERATIONAL)3738#include "GenerationalAccessBarrierComponent.hpp"3940#include "AtomicOperations.hpp"41#include "Debug.hpp"42#include "EnvironmentBase.hpp"43#include "mmhook_internal.h"44#include "GCExtensions.hpp"45#include "ObjectModel.hpp"46#include "SublistFragment.hpp"4748extern "C" {49/**50* Inform consumers of RememberedSet overflow.51*/52static void53reportRememberedSetOverflow(J9VMThread *vmThread)54{55Trc_MM_RememberedSetOverflow(vmThread);56TRIGGER_J9HOOK_MM_PRIVATE_REMEMBEREDSET_OVERFLOW(MM_GCExtensions::getExtensions(vmThread->javaVM)->privateHookInterface, (OMR_VMThread *)vmThread->omrVMThread);57}58} /* extern "C" */5960bool61MM_GenerationalAccessBarrierComponent::initialize(MM_EnvironmentBase *env)62{63return true;64}6566void67MM_GenerationalAccessBarrierComponent::tearDown(MM_EnvironmentBase *env)68{69}7071/**72* Generational write barrier call when a single object is stored into another.73* The remembered set system consists of a physical list of objects in the OLD area that74* may contain references to the new area. The mutator is responsible for adding these old75* area objects to the remembered set; the collectors are responsible for removing these objects76* from the list when they no longer contain references. Objects that are to be remembered have their77* REMEMBERED bit set in the flags field. For performance reasons, sublists are used to maintain the78* remembered set.79*80* @param vmThread The current thread that has performed the store.81* @param dstObject The object which is being stored into.82* @param srcObject The object being stored.83*84* @note The write barrier can be called with minimal, all, or no validation checking.85* @note Any object that contains a new reference MUST have its REMEMBERED bit set.86*/87void88MM_GenerationalAccessBarrierComponent::postObjectStore(J9VMThread *vmThread, J9Object *dstObject, J9Object *srcObject)89{90MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);91MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);9293/* If the source object is NULL, there is no need for a write barrier. */94/* If scavenger not enabled then no need to add to remembered set */95if ((NULL != srcObject) && extensions->scavengerEnabled) {96if (extensions->isOld(dstObject) && !extensions->isOld(srcObject)) {97if (extensions->objectModel.atomicSetRememberedState(dstObject, STATE_REMEMBERED)) {98/* Successfully set the remembered bit in the object. Now allocate an entry from the99* remembered set fragment of the current thread and store the destination object into100* the remembered set.101*/102MM_SublistFragment fragment((J9VMGC_SublistFragment*)&vmThread->gcRememberedSet);103104if (!fragment.add(env, (UDATA)dstObject )) {105/* No slot was available from any fragment. Set the remembered set overflow flag.106* The REMEMBERED bit is kept in the object for optimization purposes (only scan objects107* whose REMEMBERED bit is set in an overflow scan)108*/109extensions->setRememberedSetOverflowState();110reportRememberedSetOverflow(vmThread);111}112}113}114}115}116117/**118* Generational write barrier call when a group of objects are stored into a single object.119* The remembered set system consists of a physical list of objects in the OLD area that120* may contain references to the new area. The mutator is responsible for adding these old121* area objects to the remembered set; the collectors are responsible for removing these objects122* from the list when they no longer contain references. Objects that are to be remembered have their123* REMEMBERED bit set in the flags field. For performance reasons, sublists are used to maintain the124* remembered set.125*126* @param vmThread The current thread that has performed the store.127* @param dstObject The object which is being stored into.128*129* @note The write barrier can be called with minimal, all, or no validation checking.130* @note Any object that contains a new reference MUST have its REMEMBERED bit set.131* @note This call is typically used by array copies, when it may be more efficient132* to optimistically add an object to the remembered set without checking too hard.133*/134void135MM_GenerationalAccessBarrierComponent::postBatchObjectStore(J9VMThread *vmThread, J9Object *dstObject)136{137MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);138MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);139140/* If scavenger not enabled then no need to add to remembered set */141if (extensions->scavengerEnabled) {142/* Since we don't know what the references stored into dstObject were, we have to pessimistically143* assume they included old->new references, and the object should be added to the remembered set */144if (extensions->isOld(dstObject)) {145if (extensions->objectModel.atomicSetRememberedState(dstObject, STATE_REMEMBERED)) {146/* Successfully set the remembered bit in the object. Now allocate an entry from the147* remembered set fragment of the current thread and store the destination object into148* the remembered set. */149UDATA *rememberedSlot;150MM_SublistFragment fragment((J9VMGC_SublistFragment*)&vmThread->gcRememberedSet);151if (NULL == (rememberedSlot = (UDATA *)fragment.allocate(env))) {152/* No slot was available from any fragment. Set the remembered set overflow flag.153* The REMEMBERED bit is kept in the object for optimization purposes (only scan objects154* whose REMEMBERED bit is set in an overflow scan) */155extensions->setRememberedSetOverflowState();156reportRememberedSetOverflow(vmThread);157} else {158/* Successfully allocated a slot from the remembered set. Record the object. */159*rememberedSlot = (UDATA)dstObject;160}161}162}163}164}165166#endif /* J9VM_GC_GENERATIONAL */167168169170