Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_base/GenerationalAccessBarrierComponent.cpp
5985 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2021 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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
22
*******************************************************************************/
23
24
25
/**
26
* @file
27
* @ingroup GC_Base
28
*/
29
30
#include "j9.h"
31
#include "j9cfg.h"
32
#include "j9consts.h"
33
#include "j9protos.h"
34
#include "ModronAssertions.h"
35
#include "j9nongenerated.h"
36
37
#if defined(J9VM_GC_GENERATIONAL)
38
39
#include "GenerationalAccessBarrierComponent.hpp"
40
41
#include "AtomicOperations.hpp"
42
#include "Debug.hpp"
43
#include "EnvironmentBase.hpp"
44
#include "mmhook_internal.h"
45
#include "GCExtensions.hpp"
46
#include "ObjectModel.hpp"
47
#include "SublistFragment.hpp"
48
49
extern "C" {
50
/**
51
* Inform consumers of RememberedSet overflow.
52
*/
53
static void
54
reportRememberedSetOverflow(J9VMThread *vmThread)
55
{
56
Trc_MM_RememberedSetOverflow(vmThread);
57
TRIGGER_J9HOOK_MM_PRIVATE_REMEMBEREDSET_OVERFLOW(MM_GCExtensions::getExtensions(vmThread->javaVM)->privateHookInterface, (OMR_VMThread *)vmThread->omrVMThread);
58
}
59
} /* extern "C" */
60
61
bool
62
MM_GenerationalAccessBarrierComponent::initialize(MM_EnvironmentBase *env)
63
{
64
return true;
65
}
66
67
void
68
MM_GenerationalAccessBarrierComponent::tearDown(MM_EnvironmentBase *env)
69
{
70
}
71
72
/**
73
* Generational write barrier call when a single object is stored into another.
74
* The remembered set system consists of a physical list of objects in the OLD area that
75
* may contain references to the new area. The mutator is responsible for adding these old
76
* area objects to the remembered set; the collectors are responsible for removing these objects
77
* from the list when they no longer contain references. Objects that are to be remembered have their
78
* REMEMBERED bit set in the flags field. For performance reasons, sublists are used to maintain the
79
* remembered set.
80
*
81
* @param vmThread The current thread that has performed the store.
82
* @param dstObject The object which is being stored into.
83
* @param srcObject The object being stored.
84
*
85
* @note The write barrier can be called with minimal, all, or no validation checking.
86
* @note Any object that contains a new reference MUST have its REMEMBERED bit set.
87
*/
88
void
89
MM_GenerationalAccessBarrierComponent::postObjectStore(J9VMThread *vmThread, J9Object *dstObject, J9Object *srcObject)
90
{
91
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
92
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
93
94
/* If the source object is NULL, there is no need for a write barrier. */
95
/* If scavenger not enabled then no need to add to remembered set */
96
if ((NULL != srcObject) && extensions->scavengerEnabled) {
97
if (extensions->isOld(dstObject) && !extensions->isOld(srcObject)) {
98
if (extensions->objectModel.atomicSetRememberedState(dstObject, STATE_REMEMBERED)) {
99
/* Successfully set the remembered bit in the object. Now allocate an entry from the
100
* remembered set fragment of the current thread and store the destination object into
101
* the remembered set.
102
*/
103
MM_SublistFragment fragment((J9VMGC_SublistFragment*)&vmThread->gcRememberedSet);
104
105
if (!fragment.add(env, (UDATA)dstObject )) {
106
/* No slot was available from any fragment. Set the remembered set overflow flag.
107
* The REMEMBERED bit is kept in the object for optimization purposes (only scan objects
108
* whose REMEMBERED bit is set in an overflow scan)
109
*/
110
extensions->setRememberedSetOverflowState();
111
reportRememberedSetOverflow(vmThread);
112
}
113
}
114
}
115
}
116
}
117
118
/**
119
* Generational write barrier call when a group of objects are stored into a single object.
120
* The remembered set system consists of a physical list of objects in the OLD area that
121
* may contain references to the new area. The mutator is responsible for adding these old
122
* area objects to the remembered set; the collectors are responsible for removing these objects
123
* from the list when they no longer contain references. Objects that are to be remembered have their
124
* REMEMBERED bit set in the flags field. For performance reasons, sublists are used to maintain the
125
* remembered set.
126
*
127
* @param vmThread The current thread that has performed the store.
128
* @param dstObject The object which is being stored into.
129
*
130
* @note The write barrier can be called with minimal, all, or no validation checking.
131
* @note Any object that contains a new reference MUST have its REMEMBERED bit set.
132
* @note This call is typically used by array copies, when it may be more efficient
133
* to optimistically add an object to the remembered set without checking too hard.
134
*/
135
void
136
MM_GenerationalAccessBarrierComponent::postBatchObjectStore(J9VMThread *vmThread, J9Object *dstObject)
137
{
138
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
139
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
140
141
/* If scavenger not enabled then no need to add to remembered set */
142
if (extensions->scavengerEnabled) {
143
/* Since we don't know what the references stored into dstObject were, we have to pessimistically
144
* assume they included old->new references, and the object should be added to the remembered set */
145
if (extensions->isOld(dstObject)) {
146
if (extensions->objectModel.atomicSetRememberedState(dstObject, STATE_REMEMBERED)) {
147
/* Successfully set the remembered bit in the object. Now allocate an entry from the
148
* remembered set fragment of the current thread and store the destination object into
149
* the remembered set. */
150
UDATA *rememberedSlot;
151
MM_SublistFragment fragment((J9VMGC_SublistFragment*)&vmThread->gcRememberedSet);
152
if (NULL == (rememberedSlot = (UDATA *)fragment.allocate(env))) {
153
/* No slot was available from any fragment. Set the remembered set overflow flag.
154
* The REMEMBERED bit is kept in the object for optimization purposes (only scan objects
155
* whose REMEMBERED bit is set in an overflow scan) */
156
extensions->setRememberedSetOverflowState();
157
reportRememberedSetOverflow(vmThread);
158
} else {
159
/* Successfully allocated a slot from the remembered set. Record the object. */
160
*rememberedSlot = (UDATA)dstObject;
161
}
162
}
163
}
164
}
165
}
166
167
#endif /* J9VM_GC_GENERATIONAL */
168
169
170