136
137 inline void Atomic::inc(volatile size_t* dest) {
138 inc_ptr((volatile intptr_t*) dest);
139 }
140
141 inline void Atomic::dec(volatile size_t* dest) {
142 dec_ptr((volatile intptr_t*) dest);
143 }
144
145 #ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE
146 /*
147 * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg
148 * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition
149 * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific
150 * implementation to be used instead.
151 */
152 inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest,
153 jbyte compare_value, cmpxchg_memory_order order) {
154 STATIC_ASSERT(sizeof(jbyte) == 1);
155 volatile jint* dest_int =
156 reinterpret_cast<volatile jint*>(align_ptr_down(dest, sizeof(jint)));
157 size_t offset = pointer_delta(dest, dest_int, 1);
158 jint cur = *dest_int;
159 jbyte* cur_as_bytes = reinterpret_cast<jbyte*>(&cur);
160
161 // current value may not be what we are looking for, so force it
162 // to that value so the initial cmpxchg will fail if it is different
163 cur_as_bytes[offset] = compare_value;
164
165 // always execute a real cmpxchg so that we get the required memory
166 // barriers even on initial failure
167 do {
168 // value to swap in matches current value ...
169 jint new_value = cur;
170 // ... except for the one jbyte we want to update
171 reinterpret_cast<jbyte*>(&new_value)[offset] = exchange_value;
172
173 jint res = cmpxchg(new_value, dest_int, cur, order);
174 if (res == cur) break; // success
175
176 // at least one jbyte in the jint changed value, so update
|
136
137 inline void Atomic::inc(volatile size_t* dest) {
138 inc_ptr((volatile intptr_t*) dest);
139 }
140
141 inline void Atomic::dec(volatile size_t* dest) {
142 dec_ptr((volatile intptr_t*) dest);
143 }
144
145 #ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE
146 /*
147 * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg
148 * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition
149 * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific
150 * implementation to be used instead.
151 */
152 inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest,
153 jbyte compare_value, cmpxchg_memory_order order) {
154 STATIC_ASSERT(sizeof(jbyte) == 1);
155 volatile jint* dest_int =
156 reinterpret_cast<volatile jint*>(align_down(dest, sizeof(jint)));
157 size_t offset = pointer_delta(dest, dest_int, 1);
158 jint cur = *dest_int;
159 jbyte* cur_as_bytes = reinterpret_cast<jbyte*>(&cur);
160
161 // current value may not be what we are looking for, so force it
162 // to that value so the initial cmpxchg will fail if it is different
163 cur_as_bytes[offset] = compare_value;
164
165 // always execute a real cmpxchg so that we get the required memory
166 // barriers even on initial failure
167 do {
168 // value to swap in matches current value ...
169 jint new_value = cur;
170 // ... except for the one jbyte we want to update
171 reinterpret_cast<jbyte*>(&new_value)[offset] = exchange_value;
172
173 jint res = cmpxchg(new_value, dest_int, cur, order);
174 if (res == cur) break; // success
175
176 // at least one jbyte in the jint changed value, so update
|