Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/oops/accessBackend.cpp
40951 views
1
/*
2
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "accessBackend.inline.hpp"
27
#include "gc/shared/collectedHeap.hpp"
28
#include "oops/oop.inline.hpp"
29
#include "runtime/mutexLocker.hpp"
30
#include "runtime/vm_version.hpp"
31
#include "utilities/copy.hpp"
32
33
namespace AccessInternal {
34
// VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'.
35
//
36
// On platforms which do not support atomic compare-and-swap of jlong (8 byte)
37
// values we have to use a lock-based scheme to enforce atomicity. This has to be
38
// applied to all Unsafe operations that set the value of a jlong field. Even so
39
// the compareAndSwapLong operation will not be atomic with respect to direct stores
40
// to the field from Java code. It is important therefore that any Java code that
41
// utilizes these Unsafe jlong operations does not perform direct stores. To permit
42
// direct loads of the field from Java code we must also use Atomic::store within the
43
// locked regions. And for good measure, in case there are direct stores, we also
44
// employ Atomic::load within those regions. Note that the field in question must be
45
// volatile and so must have atomic load/store accesses applied at the Java level.
46
//
47
// The locking scheme could utilize a range of strategies for controlling the locking
48
// granularity: from a lock per-field through to a single global lock. The latter is
49
// the simplest and is used for the current implementation. Note that the Java object
50
// that contains the field, can not, in general, be used for locking. To do so can lead
51
// to deadlocks as we may introduce locking into what appears to the Java code to be a
52
// lock-free path.
53
//
54
// As all the locked-regions are very short and themselves non-blocking we can treat
55
// them as leaf routines and elide safepoint checks (ie we don't perform any thread
56
// state transitions even when blocking for the lock). Note that if we do choose to
57
// add safepoint checks and thread state transitions, we must ensure that we calculate
58
// the address of the field _after_ we have acquired the lock, else the object may have
59
// been moved by the GC
60
61
#ifndef SUPPORTS_NATIVE_CX8
62
63
// This is intentionally in the cpp file rather than the .inline.hpp file. It seems
64
// desirable to trade faster JDK build times (not propagating vm_version.hpp)
65
// for slightly worse runtime atomic jlong performance on 32 bit machines with
66
// support for 64 bit atomics.
67
bool wide_atomic_needs_locking() {
68
return !VM_Version::supports_cx8();
69
}
70
71
AccessLocker::AccessLocker() {
72
assert(!VM_Version::supports_cx8(), "why else?");
73
UnsafeJlong_lock->lock_without_safepoint_check();
74
}
75
76
AccessLocker::~AccessLocker() {
77
UnsafeJlong_lock->unlock();
78
}
79
80
#endif
81
82
// These forward copying calls to Copy without exposing the Copy type in headers unnecessarily
83
84
void arraycopy_arrayof_conjoint_oops(void* src, void* dst, size_t length) {
85
Copy::arrayof_conjoint_oops(reinterpret_cast<HeapWord*>(src),
86
reinterpret_cast<HeapWord*>(dst), length);
87
}
88
89
void arraycopy_conjoint_oops(oop* src, oop* dst, size_t length) {
90
Copy::conjoint_oops_atomic(src, dst, length);
91
}
92
93
void arraycopy_conjoint_oops(narrowOop* src, narrowOop* dst, size_t length) {
94
Copy::conjoint_oops_atomic(src, dst, length);
95
}
96
97
void arraycopy_disjoint_words(void* src, void* dst, size_t length) {
98
Copy::disjoint_words(reinterpret_cast<HeapWord*>(src),
99
reinterpret_cast<HeapWord*>(dst), length);
100
}
101
102
void arraycopy_disjoint_words_atomic(void* src, void* dst, size_t length) {
103
Copy::disjoint_words_atomic(reinterpret_cast<HeapWord*>(src),
104
reinterpret_cast<HeapWord*>(dst), length);
105
}
106
107
template<>
108
void arraycopy_conjoint<jboolean>(jboolean* src, jboolean* dst, size_t length) {
109
Copy::conjoint_jbytes(reinterpret_cast<jbyte*>(src), reinterpret_cast<jbyte*>(dst), length);
110
}
111
112
template<>
113
void arraycopy_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
114
Copy::conjoint_jbytes(src, dst, length);
115
}
116
117
template<>
118
void arraycopy_conjoint<jchar>(jchar* src, jchar* dst, size_t length) {
119
Copy::conjoint_jshorts_atomic(reinterpret_cast<jshort*>(src), reinterpret_cast<jshort*>(dst), length);
120
}
121
122
template<>
123
void arraycopy_conjoint<jshort>(jshort* src, jshort* dst, size_t length) {
124
Copy::conjoint_jshorts_atomic(src, dst, length);
125
}
126
127
template<>
128
void arraycopy_conjoint<jint>(jint* src, jint* dst, size_t length) {
129
Copy::conjoint_jints_atomic(src, dst, length);
130
}
131
132
template<>
133
void arraycopy_conjoint<jfloat>(jfloat* src, jfloat* dst, size_t length) {
134
Copy::conjoint_jints_atomic(reinterpret_cast<jint*>(src), reinterpret_cast<jint*>(dst), length);
135
}
136
137
template<>
138
void arraycopy_conjoint<jlong>(jlong* src, jlong* dst, size_t length) {
139
Copy::conjoint_jlongs_atomic(src, dst, length);
140
}
141
142
template<>
143
void arraycopy_conjoint<jdouble>(jdouble* src, jdouble* dst, size_t length) {
144
Copy::conjoint_jlongs_atomic(reinterpret_cast<jlong*>(src), reinterpret_cast<jlong*>(dst), length);
145
}
146
147
template<>
148
void arraycopy_arrayof_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
149
Copy::arrayof_conjoint_jbytes(reinterpret_cast<HeapWord*>(src),
150
reinterpret_cast<HeapWord*>(dst),
151
length);
152
}
153
154
template<>
155
void arraycopy_arrayof_conjoint<jshort>(jshort* src, jshort* dst, size_t length) {
156
Copy::arrayof_conjoint_jshorts(reinterpret_cast<HeapWord*>(src),
157
reinterpret_cast<HeapWord*>(dst),
158
length);
159
}
160
161
template<>
162
void arraycopy_arrayof_conjoint<jint>(jint* src, jint* dst, size_t length) {
163
Copy::arrayof_conjoint_jints(reinterpret_cast<HeapWord*>(src),
164
reinterpret_cast<HeapWord*>(dst),
165
length);
166
}
167
168
template<>
169
void arraycopy_arrayof_conjoint<jlong>(jlong* src, jlong* dst, size_t length) {
170
Copy::arrayof_conjoint_jlongs(reinterpret_cast<HeapWord*>(src),
171
reinterpret_cast<HeapWord*>(dst),
172
length);
173
}
174
175
template<>
176
void arraycopy_conjoint<void>(void* src, void* dst, size_t length) {
177
Copy::conjoint_jbytes(reinterpret_cast<jbyte*>(src),
178
reinterpret_cast<jbyte*>(dst),
179
length);
180
}
181
182
template<>
183
void arraycopy_conjoint_atomic<jbyte>(jbyte* src, jbyte* dst, size_t length) {
184
Copy::conjoint_jbytes_atomic(src, dst, length);
185
}
186
187
template<>
188
void arraycopy_conjoint_atomic<jshort>(jshort* src, jshort* dst, size_t length) {
189
Copy::conjoint_jshorts_atomic(src, dst, length);
190
}
191
192
template<>
193
void arraycopy_conjoint_atomic<jint>(jint* src, jint* dst, size_t length) {
194
Copy::conjoint_jints_atomic(src, dst, length);
195
}
196
197
template<>
198
void arraycopy_conjoint_atomic<jlong>(jlong* src, jlong* dst, size_t length) {
199
Copy::conjoint_jlongs_atomic(src, dst, length);
200
}
201
202
template<>
203
void arraycopy_conjoint_atomic<void>(void* src, void* dst, size_t length) {
204
Copy::conjoint_memory_atomic(src, dst, length);
205
}
206
}
207
208