160 161 void MutableSpace::set_top_for_allocations(HeapWord* v) { 162 mangler()->set_top_for_allocations(v); 163 } 164 165 void MutableSpace::set_top_for_allocations() { 166 mangler()->set_top_for_allocations(top()); 167 } 168 #endif 169 170 // This version requires locking. */ 171 HeapWord* MutableSpace::allocate(size_t size) { 172 assert(Heap_lock->owned_by_self() || 173 (SafepointSynchronize::is_at_safepoint() && 174 Thread::current()->is_VM_thread()), 175 "not locked"); 176 HeapWord* obj = top(); 177 if (pointer_delta(end(), obj) >= size) { 178 HeapWord* new_top = obj + size; 179 set_top(new_top); 180 assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top), 181 "checking alignment"); 182 return obj; 183 } else { 184 return NULL; 185 } 186 } 187 188 // This version is lock-free. 189 HeapWord* MutableSpace::cas_allocate(size_t size) { 190 do { 191 HeapWord* obj = top(); 192 if (pointer_delta(end(), obj) >= size) { 193 HeapWord* new_top = obj + size; 194 HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj); 195 // result can be one of two: 196 // the old top value: the exchange succeeded 197 // otherwise: the new value of the top is returned. 198 if (result != obj) { 199 continue; // another thread beat us to the allocation, try again 200 } 201 assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top), 202 "checking alignment"); 203 return obj; 204 } else { 205 return NULL; 206 } 207 } while (true); 208 } 209 210 // Try to deallocate previous allocation. Returns true upon success. 211 bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) { 212 HeapWord* expected_top = obj + size; 213 return (HeapWord*)Atomic::cmpxchg_ptr(obj, top_addr(), expected_top) == expected_top; 214 } 215 216 void MutableSpace::oop_iterate_no_header(OopClosure* cl) { 217 HeapWord* obj_addr = bottom(); 218 HeapWord* t = top(); 219 // Could call objects iterate, but this is easier. 220 while (obj_addr < t) { 221 obj_addr += oop(obj_addr)->oop_iterate_no_header(cl); | 160 161 void MutableSpace::set_top_for_allocations(HeapWord* v) { 162 mangler()->set_top_for_allocations(v); 163 } 164 165 void MutableSpace::set_top_for_allocations() { 166 mangler()->set_top_for_allocations(top()); 167 } 168 #endif 169 170 // This version requires locking. */ 171 HeapWord* MutableSpace::allocate(size_t size) { 172 assert(Heap_lock->owned_by_self() || 173 (SafepointSynchronize::is_at_safepoint() && 174 Thread::current()->is_VM_thread()), 175 "not locked"); 176 HeapWord* obj = top(); 177 if (pointer_delta(end(), obj) >= size) { 178 HeapWord* new_top = obj + size; 179 set_top(new_top); 180 assert(is_ptr_object_aligned(obj) && is_ptr_object_aligned(new_top), 181 "checking alignment"); 182 return obj; 183 } else { 184 return NULL; 185 } 186 } 187 188 // This version is lock-free. 189 HeapWord* MutableSpace::cas_allocate(size_t size) { 190 do { 191 HeapWord* obj = top(); 192 if (pointer_delta(end(), obj) >= size) { 193 HeapWord* new_top = obj + size; 194 HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj); 195 // result can be one of two: 196 // the old top value: the exchange succeeded 197 // otherwise: the new value of the top is returned. 198 if (result != obj) { 199 continue; // another thread beat us to the allocation, try again 200 } 201 assert(is_ptr_object_aligned(obj) && is_ptr_object_aligned(new_top), 202 "checking alignment"); 203 return obj; 204 } else { 205 return NULL; 206 } 207 } while (true); 208 } 209 210 // Try to deallocate previous allocation. Returns true upon success. 211 bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) { 212 HeapWord* expected_top = obj + size; 213 return (HeapWord*)Atomic::cmpxchg_ptr(obj, top_addr(), expected_top) == expected_top; 214 } 215 216 void MutableSpace::oop_iterate_no_header(OopClosure* cl) { 217 HeapWord* obj_addr = bottom(); 218 HeapWord* t = top(); 219 // Could call objects iterate, but this is easier. 220 while (obj_addr < t) { 221 obj_addr += oop(obj_addr)->oop_iterate_no_header(cl); |