Mercurial > hg > truffle
annotate src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp @ 17833:bfdf528be8e8
8038498: Fix includes and C inlining after 8035330
Summary: Change 8035330: Remove G1ParScanPartialArrayClosure and G1ParScanHeapEvacClosure broke the debug build on AIX. The method do_oop_partial_array() is added in a header, but requires the inline function par_write_ref() through several inlined calls. In some cpp files, like arguments.cpp, par_write_ref() is not defined as the corresponding inline header and is not included. The AIX debug VM does not start because of the missing symbol. This change solves this by cleaning up include dependencies.
Reviewed-by: tschatzl, stefank
author | tschatzl |
---|---|
date | Fri, 04 Apr 2014 10:43:56 +0200 |
parents | 63e54c37ac64 |
children |
rev | line source |
---|---|
1010 | 1 /* |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
2256
diff
changeset
|
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
3 * Copyright 2007, 2008, 2011 Red Hat, Inc. |
1010 | 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1010
diff
changeset
|
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1010
diff
changeset
|
21 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1010
diff
changeset
|
22 * questions. |
1010 | 23 * |
24 */ | |
25 | |
1972 | 26 #ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP |
27 #define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP | |
28 | |
29 #include "runtime/atomic.hpp" | |
30 #include "runtime/os.hpp" | |
31 #include "vm_version_zero.hpp" | |
32 | |
1010 | 33 // Implementation of class atomic |
34 | |
35 #ifdef M68K | |
36 | |
37 /* | |
38 * __m68k_cmpxchg | |
39 * | |
40 * Atomically store newval in *ptr if *ptr is equal to oldval for user space. | |
41 * Returns newval on success and oldval if no exchange happened. | |
42 * This implementation is processor specific and works on | |
43 * 68020 68030 68040 and 68060. | |
44 * | |
45 * It will not work on ColdFire, 68000 and 68010 since they lack the CAS | |
46 * instruction. | |
47 * Using a kernelhelper would be better for arch complete implementation. | |
48 * | |
49 */ | |
50 | |
51 static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) { | |
52 int ret; | |
53 __asm __volatile ("cas%.l %0,%2,%1" | |
54 : "=d" (ret), "+m" (*(ptr)) | |
55 : "d" (newval), "0" (oldval)); | |
56 return ret; | |
57 } | |
58 | |
59 /* Perform an atomic compare and swap: if the current value of `*PTR' | |
60 is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of | |
61 `*PTR' before the operation.*/ | |
62 static inline int m68k_compare_and_swap(volatile int *ptr, | |
63 int oldval, | |
64 int newval) { | |
65 for (;;) { | |
66 int prev = *ptr; | |
67 if (prev != oldval) | |
68 return prev; | |
69 | |
70 if (__m68k_cmpxchg (prev, newval, ptr) == newval) | |
71 // Success. | |
72 return prev; | |
73 | |
74 // We failed even though prev == oldval. Try again. | |
75 } | |
76 } | |
77 | |
78 /* Atomically add an int to memory. */ | |
79 static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) { | |
80 for (;;) { | |
81 // Loop until success. | |
82 | |
83 int prev = *ptr; | |
84 | |
85 if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value) | |
86 return prev + add_value; | |
87 } | |
88 } | |
89 | |
90 /* Atomically write VALUE into `*PTR' and returns the previous | |
91 contents of `*PTR'. */ | |
92 static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) { | |
93 for (;;) { | |
94 // Loop until success. | |
95 int prev = *ptr; | |
96 | |
97 if (__m68k_cmpxchg (prev, newval, ptr) == prev) | |
98 return prev; | |
99 } | |
100 } | |
101 #endif // M68K | |
102 | |
103 #ifdef ARM | |
104 | |
105 /* | |
106 * __kernel_cmpxchg | |
107 * | |
108 * Atomically store newval in *ptr if *ptr is equal to oldval for user space. | |
109 * Return zero if *ptr was changed or non-zero if no exchange happened. | |
110 * The C flag is also set if *ptr was changed to allow for assembly | |
111 * optimization in the calling code. | |
112 * | |
113 */ | |
114 | |
115 typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); | |
116 #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) | |
117 | |
118 | |
119 | |
120 /* Perform an atomic compare and swap: if the current value of `*PTR' | |
121 is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of | |
122 `*PTR' before the operation.*/ | |
123 static inline int arm_compare_and_swap(volatile int *ptr, | |
124 int oldval, | |
125 int newval) { | |
126 for (;;) { | |
127 int prev = *ptr; | |
128 if (prev != oldval) | |
129 return prev; | |
130 | |
131 if (__kernel_cmpxchg (prev, newval, ptr) == 0) | |
132 // Success. | |
133 return prev; | |
134 | |
135 // We failed even though prev == oldval. Try again. | |
136 } | |
137 } | |
138 | |
139 /* Atomically add an int to memory. */ | |
140 static inline int arm_add_and_fetch(volatile int *ptr, int add_value) { | |
141 for (;;) { | |
142 // Loop until a __kernel_cmpxchg succeeds. | |
143 | |
144 int prev = *ptr; | |
145 | |
146 if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) | |
147 return prev + add_value; | |
148 } | |
149 } | |
150 | |
151 /* Atomically write VALUE into `*PTR' and returns the previous | |
152 contents of `*PTR'. */ | |
153 static inline int arm_lock_test_and_set(volatile int *ptr, int newval) { | |
154 for (;;) { | |
155 // Loop until a __kernel_cmpxchg succeeds. | |
156 int prev = *ptr; | |
157 | |
158 if (__kernel_cmpxchg (prev, newval, ptr) == 0) | |
159 return prev; | |
160 } | |
161 } | |
162 #endif // ARM | |
163 | |
164 inline void Atomic::store(jint store_value, volatile jint* dest) { | |
165 *dest = store_value; | |
166 } | |
167 | |
168 inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { | |
169 *dest = store_value; | |
170 } | |
171 | |
172 inline jint Atomic::add(jint add_value, volatile jint* dest) { | |
173 #ifdef ARM | |
174 return arm_add_and_fetch(dest, add_value); | |
175 #else | |
176 #ifdef M68K | |
177 return m68k_add_and_fetch(dest, add_value); | |
178 #else | |
179 return __sync_add_and_fetch(dest, add_value); | |
180 #endif // M68K | |
181 #endif // ARM | |
182 } | |
183 | |
184 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { | |
185 #ifdef ARM | |
186 return arm_add_and_fetch(dest, add_value); | |
187 #else | |
188 #ifdef M68K | |
189 return m68k_add_and_fetch(dest, add_value); | |
190 #else | |
191 return __sync_add_and_fetch(dest, add_value); | |
192 #endif // M68K | |
193 #endif // ARM | |
194 } | |
195 | |
196 inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { | |
197 return (void *) add_ptr(add_value, (volatile intptr_t *) dest); | |
198 } | |
199 | |
200 inline void Atomic::inc(volatile jint* dest) { | |
201 add(1, dest); | |
202 } | |
203 | |
204 inline void Atomic::inc_ptr(volatile intptr_t* dest) { | |
205 add_ptr(1, dest); | |
206 } | |
207 | |
208 inline void Atomic::inc_ptr(volatile void* dest) { | |
209 add_ptr(1, dest); | |
210 } | |
211 | |
212 inline void Atomic::dec(volatile jint* dest) { | |
213 add(-1, dest); | |
214 } | |
215 | |
216 inline void Atomic::dec_ptr(volatile intptr_t* dest) { | |
217 add_ptr(-1, dest); | |
218 } | |
219 | |
220 inline void Atomic::dec_ptr(volatile void* dest) { | |
221 add_ptr(-1, dest); | |
222 } | |
223 | |
224 inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { | |
225 #ifdef ARM | |
226 return arm_lock_test_and_set(dest, exchange_value); | |
227 #else | |
228 #ifdef M68K | |
229 return m68k_lock_test_and_set(dest, exchange_value); | |
230 #else | |
231 // __sync_lock_test_and_set is a bizarrely named atomic exchange | |
232 // operation. Note that some platforms only support this with the | |
233 // limitation that the only valid value to store is the immediate | |
234 // constant 1. There is a test for this in JNI_CreateJavaVM(). | |
235 return __sync_lock_test_and_set (dest, exchange_value); | |
236 #endif // M68K | |
237 #endif // ARM | |
238 } | |
239 | |
240 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, | |
241 volatile intptr_t* dest) { | |
242 #ifdef ARM | |
243 return arm_lock_test_and_set(dest, exchange_value); | |
244 #else | |
245 #ifdef M68K | |
246 return m68k_lock_test_and_set(dest, exchange_value); | |
247 #else | |
248 return __sync_lock_test_and_set (dest, exchange_value); | |
249 #endif // M68K | |
250 #endif // ARM | |
251 } | |
252 | |
253 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { | |
254 return (void *) xchg_ptr((intptr_t) exchange_value, | |
255 (volatile intptr_t*) dest); | |
256 } | |
257 | |
258 inline jint Atomic::cmpxchg(jint exchange_value, | |
259 volatile jint* dest, | |
260 jint compare_value) { | |
261 #ifdef ARM | |
262 return arm_compare_and_swap(dest, compare_value, exchange_value); | |
263 #else | |
264 #ifdef M68K | |
265 return m68k_compare_and_swap(dest, compare_value, exchange_value); | |
266 #else | |
267 return __sync_val_compare_and_swap(dest, compare_value, exchange_value); | |
268 #endif // M68K | |
269 #endif // ARM | |
270 } | |
271 | |
272 inline jlong Atomic::cmpxchg(jlong exchange_value, | |
273 volatile jlong* dest, | |
274 jlong compare_value) { | |
275 | |
276 return __sync_val_compare_and_swap(dest, compare_value, exchange_value); | |
277 } | |
278 | |
279 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, | |
280 volatile intptr_t* dest, | |
281 intptr_t compare_value) { | |
282 #ifdef ARM | |
283 return arm_compare_and_swap(dest, compare_value, exchange_value); | |
284 #else | |
285 #ifdef M68K | |
286 return m68k_compare_and_swap(dest, compare_value, exchange_value); | |
287 #else | |
288 return __sync_val_compare_and_swap(dest, compare_value, exchange_value); | |
289 #endif // M68K | |
290 #endif // ARM | |
291 } | |
292 | |
293 inline void* Atomic::cmpxchg_ptr(void* exchange_value, | |
294 volatile void* dest, | |
295 void* compare_value) { | |
296 | |
297 return (void *) cmpxchg_ptr((intptr_t) exchange_value, | |
298 (volatile intptr_t*) dest, | |
299 (intptr_t) compare_value); | |
300 } | |
1972 | 301 |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
302 inline jlong Atomic::load(volatile jlong* src) { |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
303 volatile jlong dest; |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
304 os::atomic_copy64(src, &dest); |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
305 return dest; |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
306 } |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
307 |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
308 inline void Atomic::store(jlong store_value, jlong* dest) { |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
309 os::atomic_copy64((volatile jlong*)&store_value, (volatile jlong*)dest); |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
310 } |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
311 |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
312 inline void Atomic::store(jlong store_value, volatile jlong* dest) { |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
313 os::atomic_copy64((volatile jlong*)&store_value, dest); |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
314 } |
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
1972
diff
changeset
|
315 |
1972 | 316 #endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP |