1 #ifdef USE_PRAGMA_IDENT_HDR
   2 #pragma ident "@(#)psPromotionLAB.hpp   1.13 07/05/05 17:05:30 JVM"
   3 #endif
   4 /*
   5  * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  
  26  */
  27 
  28 //
  29 // PSPromotionLAB is a parallel scavenge promotion lab. This class acts very
  30 // much like a MutableSpace. We couldn't embed a MutableSpace, though, as
  31 // it has a considerable number of asserts and invariants that are violated.
  32 //
  33 
  34 class ObjectStartArray;
  35 
  36 class PSPromotionLAB : public CHeapObj {
  37  protected:
  38   static size_t filler_header_size;
  39 
  40   enum LabState {
  41     needs_flush,
  42     flushed,
  43     zero_size
  44   };
  45 
  46   HeapWord* _top;
  47   HeapWord* _bottom;
  48   HeapWord* _end;
  49   LabState _state;
  50 
  51   void set_top(HeapWord* value)    { _top = value; }
  52   void set_bottom(HeapWord* value) { _bottom = value; }
  53   void set_end(HeapWord* value)    { _end = value; }
  54 
  55   // The shared initialize code invokes this.
  56   debug_only(virtual bool lab_is_valid(MemRegion lab) { return false; });
  57 
  58   PSPromotionLAB() : _top(NULL), _bottom(NULL), _end(NULL) { }
  59 
  60  public:
  61   // Filling and flushing.
  62   void initialize(MemRegion lab);
  63 
  64   virtual void flush();
  65 
  66   // Accessors
  67   HeapWord* bottom() const           { return _bottom; }
  68   HeapWord* end() const              { return _end;    }
  69   HeapWord* top() const              { return _top;    }
  70 
  71   bool is_flushed()                  { return _state == flushed; }
  72 
  73   bool unallocate_object(oop obj);
  74 
  75   // Returns a subregion containing all objects in this space.
  76   MemRegion used_region()            { return MemRegion(bottom(), top()); }
  77 
  78   // Boolean querries.
  79   bool is_empty() const              { return used() == 0; }
  80   bool not_empty() const             { return used() > 0; }
  81   bool contains(const void* p) const { return _bottom <= p && p < _end; }
  82 
  83   // Size computations.  Sizes are in bytes.
  84   size_t capacity() const            { return byte_size(bottom(), end()); }
  85   size_t used() const                { return byte_size(bottom(), top()); }
  86   size_t free() const                { return byte_size(top(),    end()); }
  87 };
  88 
  89 class PSYoungPromotionLAB : public PSPromotionLAB {
  90  public:
  91   PSYoungPromotionLAB() { }
  92 
  93   // Not MT safe
  94   HeapWord* allocate(size_t size) {
  95     // Can't assert this, when young fills, we keep the LAB around, but flushed.
  96     // assert(_state != flushed, "Sanity");
  97     HeapWord* obj = top();
  98     HeapWord* new_top = obj + size;
  99     // The 'new_top>obj' check is needed to detect overflow of obj+size.
 100     if (new_top > obj && new_top <= end()) {
 101       set_top(new_top);
 102       assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top),
 103              "checking alignment");
 104       return obj;
 105     }
 106 
 107     return NULL;
 108   }
 109 
 110   debug_only(virtual bool lab_is_valid(MemRegion lab));
 111 };
 112 
 113 class PSOldPromotionLAB : public PSPromotionLAB {
 114  private:
 115   ObjectStartArray* _start_array;
 116 
 117  public:
 118   PSOldPromotionLAB() : _start_array(NULL) { }
 119   PSOldPromotionLAB(ObjectStartArray* start_array) : _start_array(start_array) { }
 120 
 121   void set_start_array(ObjectStartArray* start_array) { _start_array = start_array; }
 122 
 123   void flush();
 124 
 125   // Not MT safe
 126   HeapWord* allocate(size_t size) {
 127     // Cannot test for this now that we're doing promotion failures
 128     // assert(_state != flushed, "Sanity");
 129     assert(_start_array != NULL, "Sanity");
 130     HeapWord* obj = top();
 131     HeapWord* new_top = obj + size;
 132     // The 'new_top>obj' check is needed to detect overflow of obj+size.
 133     if (new_top > obj && new_top <= end()) {
 134       set_top(new_top);
 135       assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top),
 136              "checking alignment");
 137       _start_array->allocate_block(obj);
 138       return obj;
 139     }
 140 
 141     return NULL;
 142   }
 143 
 144   debug_only(virtual bool lab_is_valid(MemRegion lab));
 145 };
 146 
 147