src/share/vm/gc_implementation/g1/g1AllocRegion.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2715
abdfc822206f
child 3028
f44782f04dd4
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP
    28 #include "gc_implementation/g1/heapRegion.hpp"
    30 class G1CollectedHeap;
    32 // 0 -> no tracing, 1 -> basic tracing, 2 -> basic + allocation tracing
    33 #define G1_ALLOC_REGION_TRACING 0
    35 class ar_ext_msg;
    37 // A class that holds a region that is active in satisfying allocation
    38 // requests, potentially issued in parallel. When the active region is
    39 // full it will be retired it replaced with a new one. The
    40 // implementation assumes that fast-path allocations will be lock-free
    41 // and a lock will need to be taken when the active region needs to be
    42 // replaced.
    44 class G1AllocRegion VALUE_OBJ_CLASS_SPEC {
    45   friend class ar_ext_msg;
    47 private:
    48   // The active allocating region we are currently allocating out
    49   // of. The invariant is that if this object is initialized (i.e.,
    50   // init() has been called and release() has not) then _alloc_region
    51   // is either an active allocating region or the dummy region (i.e.,
    52   // it can never be NULL) and this object can be used to satisfy
    53   // allocation requests. If this object is not initialized
    54   // (i.e. init() has not been called or release() has been called)
    55   // then _alloc_region is NULL and this object should not be used to
    56   // satisfy allocation requests (it was done this way to force the
    57   // correct use of init() and release()).
    58   HeapRegion* _alloc_region;
    60   // When we set up a new active region we save its used bytes in this
    61   // field so that, when we retire it, we can calculate how much space
    62   // we allocated in it.
    63   size_t _used_bytes_before;
    65   // Specifies whether the allocate calls will do BOT updates or not.
    66   bool _bot_updates;
    68   // Useful for debugging and tracing.
    69   const char* _name;
    71   // A dummy region (i.e., it's been allocated specially for this
    72   // purpose and it is not part of the heap) that is full (i.e., top()
    73   // == end()). When we don't have a valid active region we make
    74   // _alloc_region point to this. This allows us to skip checking
    75   // whether the _alloc_region is NULL or not.
    76   static HeapRegion* _dummy_region;
    78   // Some of the methods below take a bot_updates parameter. Its value
    79   // should be the same as the _bot_updates field. The idea is that
    80   // the parameter will be a constant for a particular alloc region
    81   // and, given that these methods will be hopefully inlined, the
    82   // compiler should compile out the test.
    84   // Perform a non-MT-safe allocation out of the given region.
    85   static inline HeapWord* allocate(HeapRegion* alloc_region,
    86                                    size_t word_size,
    87                                    bool bot_updates);
    89   // Perform a MT-safe allocation out of the given region.
    90   static inline HeapWord* par_allocate(HeapRegion* alloc_region,
    91                                        size_t word_size,
    92                                        bool bot_updates);
    94   // Ensure that the region passed as a parameter has been filled up
    95   // so that noone else can allocate out of it any more.
    96   static void fill_up_remaining_space(HeapRegion* alloc_region,
    97                                       bool bot_updates);
    99   // Retire the active allocating region. If fill_up is true then make
   100   // sure that the region is full before we retire it so that noone
   101   // else can allocate out of it.
   102   void retire(bool fill_up);
   104   // Allocate a new active region and use it to perform a word_size
   105   // allocation. The force parameter will be passed on to
   106   // G1CollectedHeap::allocate_new_alloc_region() and tells it to try
   107   // to allocate a new region even if the max has been reached.
   108   HeapWord* new_alloc_region_and_allocate(size_t word_size, bool force);
   110   void fill_in_ext_msg(ar_ext_msg* msg, const char* message);
   112 protected:
   113   // For convenience as subclasses use it.
   114   static G1CollectedHeap* _g1h;
   116   virtual HeapRegion* allocate_new_region(size_t word_size, bool force) = 0;
   117   virtual void retire_region(HeapRegion* alloc_region,
   118                              size_t allocated_bytes) = 0;
   120   G1AllocRegion(const char* name, bool bot_updates);
   122 public:
   123   static void setup(G1CollectedHeap* g1h, HeapRegion* dummy_region);
   125   HeapRegion* get() const {
   126     // Make sure that the dummy region does not escape this class.
   127     return (_alloc_region == _dummy_region) ? NULL : _alloc_region;
   128   }
   130   // The following two are the building blocks for the allocation method.
   132   // First-level allocation: Should be called without holding a
   133   // lock. It will try to allocate lock-free out of the active region,
   134   // or return NULL if it was unable to.
   135   inline HeapWord* attempt_allocation(size_t word_size, bool bot_updates);
   137   // Second-level allocation: Should be called while holding a
   138   // lock. It will try to first allocate lock-free out of the active
   139   // region or, if it's unable to, it will try to replace the active
   140   // alloc region with a new one. We require that the caller takes the
   141   // appropriate lock before calling this so that it is easier to make
   142   // it conform to its locking protocol.
   143   inline HeapWord* attempt_allocation_locked(size_t word_size,
   144                                              bool bot_updates);
   146   // Should be called to allocate a new region even if the max of this
   147   // type of regions has been reached. Should only be called if other
   148   // allocation attempts have failed and we are not holding a valid
   149   // active region.
   150   inline HeapWord* attempt_allocation_force(size_t word_size,
   151                                             bool bot_updates);
   153   // Should be called before we start using this object.
   154   void init();
   156   // Should be called when we want to release the active region which
   157   // is returned after it's been retired.
   158   HeapRegion* release();
   160 #if G1_ALLOC_REGION_TRACING
   161   void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL);
   162 #else // G1_ALLOC_REGION_TRACING
   163   void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL) { }
   164 #endif // G1_ALLOC_REGION_TRACING
   165 };
   167 class ar_ext_msg : public err_msg {
   168 public:
   169   ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("") {
   170     alloc_region->fill_in_ext_msg(this, message);
   171   }
   172 };
   174 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP

mercurial