175 Thread::current()->is_VM_thread()),
176 "not locked");
177 HeapWord* obj = top();
178 if (pointer_delta(end(), obj) >= size) {
179 HeapWord* new_top = obj + size;
180 set_top(new_top);
181 assert(is_object_aligned(obj) && is_object_aligned(new_top),
182 "checking alignment");
183 return obj;
184 } else {
185 return NULL;
186 }
187 }
188
189 // This version is lock-free.
190 HeapWord* MutableSpace::cas_allocate(size_t size) {
191 do {
192 HeapWord* obj = top();
193 if (pointer_delta(end(), obj) >= size) {
194 HeapWord* new_top = obj + size;
195 HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj);
196 // result can be one of two:
197 // the old top value: the exchange succeeded
198 // otherwise: the new value of the top is returned.
199 if (result != obj) {
200 continue; // another thread beat us to the allocation, try again
201 }
202 assert(is_object_aligned(obj) && is_object_aligned(new_top),
203 "checking alignment");
204 return obj;
205 } else {
206 return NULL;
207 }
208 } while (true);
209 }
210
211 // Try to deallocate previous allocation. Returns true upon success.
212 bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) {
213 HeapWord* expected_top = obj + size;
214 return (HeapWord*)Atomic::cmpxchg_ptr(obj, top_addr(), expected_top) == expected_top;
215 }
216
217 void MutableSpace::oop_iterate_no_header(OopClosure* cl) {
218 HeapWord* obj_addr = bottom();
219 HeapWord* t = top();
220 // Could call objects iterate, but this is easier.
221 while (obj_addr < t) {
222 obj_addr += oop(obj_addr)->oop_iterate_no_header(cl);
223 }
224 }
225
226 void MutableSpace::object_iterate(ObjectClosure* cl) {
227 HeapWord* p = bottom();
228 while (p < top()) {
229 cl->do_object(oop(p));
230 p += oop(p)->size();
231 }
232 }
233
234 void MutableSpace::print_short() const { print_short_on(tty); }
|
175 Thread::current()->is_VM_thread()),
176 "not locked");
177 HeapWord* obj = top();
178 if (pointer_delta(end(), obj) >= size) {
179 HeapWord* new_top = obj + size;
180 set_top(new_top);
181 assert(is_object_aligned(obj) && is_object_aligned(new_top),
182 "checking alignment");
183 return obj;
184 } else {
185 return NULL;
186 }
187 }
188
189 // This version is lock-free.
190 HeapWord* MutableSpace::cas_allocate(size_t size) {
191 do {
192 HeapWord* obj = top();
193 if (pointer_delta(end(), obj) >= size) {
194 HeapWord* new_top = obj + size;
195 HeapWord* result = Atomic::cmpxchg(new_top, top_addr(), obj);
196 // result can be one of two:
197 // the old top value: the exchange succeeded
198 // otherwise: the new value of the top is returned.
199 if (result != obj) {
200 continue; // another thread beat us to the allocation, try again
201 }
202 assert(is_object_aligned(obj) && is_object_aligned(new_top),
203 "checking alignment");
204 return obj;
205 } else {
206 return NULL;
207 }
208 } while (true);
209 }
210
211 // Try to deallocate previous allocation. Returns true upon success.
212 bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) {
213 HeapWord* expected_top = obj + size;
214 return Atomic::cmpxchg(obj, top_addr(), expected_top) == expected_top;
215 }
216
217 void MutableSpace::oop_iterate_no_header(OopClosure* cl) {
218 HeapWord* obj_addr = bottom();
219 HeapWord* t = top();
220 // Could call objects iterate, but this is easier.
221 while (obj_addr < t) {
222 obj_addr += oop(obj_addr)->oop_iterate_no_header(cl);
223 }
224 }
225
226 void MutableSpace::object_iterate(ObjectClosure* cl) {
227 HeapWord* p = bottom();
228 while (p < top()) {
229 cl->do_object(oop(p));
230 p += oop(p)->size();
231 }
232 }
233
234 void MutableSpace::print_short() const { print_short_on(tty); }
|