< prev index next >

src/hotspot/share/gc/shared/memAllocator.cpp

Print this page

        

@@ -42,11 +42,11 @@
 class MemAllocator::Allocation: StackObj {
   friend class MemAllocator;
 
   const MemAllocator& _allocator;
   Thread*             _thread;
-  oop*                _obj_ptr;
+  Handle              _handle;
   bool                _overhead_limit_exceeded;
   bool                _allocated_outside_tlab;
   size_t              _allocated_tlab_size;
   bool                _tlab_end_reset_for_sample;
 

@@ -62,17 +62,14 @@
   void check_for_bad_heap_word_value() const;
 #ifdef ASSERT
   void check_for_valid_allocation_state() const;
 #endif
 
-  class PreserveObj;
-
 public:
-  Allocation(const MemAllocator& allocator, oop* obj_ptr)
+  Allocation(const MemAllocator& allocator)
     : _allocator(allocator),
       _thread(Thread::current()),
-      _obj_ptr(obj_ptr),
       _overhead_limit_exceeded(false),
       _allocated_outside_tlab(false),
       _allocated_tlab_size(0),
       _tlab_end_reset_for_sample(false)
   {

@@ -84,34 +81,12 @@
       verify_after();
       notify_allocation();
     }
   }
 
-  oop obj() const { return *_obj_ptr; }
-};
-
-class MemAllocator::Allocation::PreserveObj: StackObj {
-  HandleMark _handle_mark;
-  Handle     _handle;
-  oop* const _obj_ptr;
-
-public:
-  PreserveObj(Thread* thread, oop* obj_ptr)
-    : _handle_mark(thread),
-      _handle(thread, *obj_ptr),
-      _obj_ptr(obj_ptr)
-  {
-    *obj_ptr = NULL;
-  }
-
-  ~PreserveObj() {
-    *_obj_ptr = _handle();
-  }
-
-  oop operator()() const {
-    return _handle();
-  }
+  void set_obj(oop obj) { _handle = Handle(_thread, obj); }
+  oop obj() const { return _handle(); }
 };
 
 bool MemAllocator::Allocation::check_out_of_memory() {
   Thread* THREAD = _thread;
   assert(!HAS_PENDING_EXCEPTION, "Unexpected exception, will result in uninitialized storage");

@@ -196,26 +171,25 @@
     // Sample if it's a non-TLAB allocation, or a TLAB allocation that either refills the TLAB
     // or expands it due to taking a sampler induced slow path.
     return;
   }
 
-  // If we want to be sampling, protect the allocated object with a Handle
+  // If we want to be sampling, the allocated object is protected with a Handle
   // before doing the callback. The callback is done in the destructor of
   // the JvmtiSampledObjectAllocEventCollector.
   size_t bytes_since_last = 0;
 
   {
-    PreserveObj obj_h(_thread, _obj_ptr);
     JvmtiSampledObjectAllocEventCollector collector;
     size_t size_in_bytes = _allocator._word_size * HeapWordSize;
     ThreadLocalAllocBuffer& tlab = _thread->tlab();
 
     if (!_allocated_outside_tlab) {
       bytes_since_last = tlab.bytes_since_last_sample_point();
     }
 
-    _thread->heap_sampler().check_for_sampling(obj_h(), size_in_bytes, bytes_since_last);
+    _thread->heap_sampler().check_for_sampling(obj(), size_in_bytes, bytes_since_last);
   }
 
   if (_tlab_end_reset_for_sample || _allocated_tlab_size != 0) {
     // Tell tlab to forget bytes_since_last if we passed it to the heap sampler.
     _thread->tlab().set_sample_end(bytes_since_last != 0);

@@ -362,19 +336,23 @@
 
   return allocate_outside_tlab(allocation);
 }
 
 oop MemAllocator::allocate() const {
-  oop obj = NULL;
+  HandleMark hm(_thread);
+  Handle obj_h;
   {
-    Allocation allocation(*this, &obj);
+    Allocation allocation(*this);
     HeapWord* mem = mem_allocate(allocation);
     if (mem != NULL) {
-      obj = initialize(mem);
+      oop obj = initialize(mem);
+      // Save obj in a handle for destructor safepoints
+      allocation.set_obj(obj);
+      obj_h = Handle(_thread, obj);
     }
   }
-  return obj;
+  return obj_h();
 }
 
 void MemAllocator::mem_clear(HeapWord* mem) const {
   assert(mem != NULL, "cannot initialize NULL object");
   const size_t hs = oopDesc::header_size();
< prev index next >