hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp
changeset 1 489c9b5090e2
child 2131 98f9cef66a34
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 2001-2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 //
       
    26 // This class can be used to locate the beginning of an object in the
       
    27 // covered region.
       
    28 //
       
    29 
       
    30 class ObjectStartArray : public CHeapObj {
       
    31  friend class VerifyObjectStartArrayClosure;
       
    32 
       
    33  private:
       
    34   PSVirtualSpace  _virtual_space;
       
    35   MemRegion       _reserved_region;
       
    36   MemRegion       _covered_region;
       
    37   MemRegion       _blocks_region;
       
    38   jbyte*          _raw_base;
       
    39   jbyte*          _offset_base;
       
    40 
       
    41  public:
       
    42 
       
    43   enum BlockValueConstants {
       
    44     clean_block                  = -1
       
    45   };
       
    46 
       
    47   enum BlockSizeConstants {
       
    48     block_shift                  = 9,
       
    49     block_size                   = 1 << block_shift,
       
    50     block_size_in_words          = block_size / sizeof(HeapWord)
       
    51   };
       
    52 
       
    53  protected:
       
    54 
       
    55   // Mapping from address to object start array entry
       
    56   jbyte* block_for_addr(void* p) const {
       
    57     assert(_covered_region.contains(p),
       
    58            "out of bounds access to object start array");
       
    59     jbyte* result = &_offset_base[uintptr_t(p) >> block_shift];
       
    60     assert(_blocks_region.contains(result),
       
    61            "out of bounds result in byte_for");
       
    62     return result;
       
    63   }
       
    64 
       
    65   // Mapping from object start array entry to address of first word
       
    66   HeapWord* addr_for_block(jbyte* p) {
       
    67     assert(_blocks_region.contains(p),
       
    68            "out of bounds access to object start array");
       
    69     size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte));
       
    70     HeapWord* result = (HeapWord*) (delta << block_shift);
       
    71     assert(_covered_region.contains(result),
       
    72            "out of bounds accessor from card marking array");
       
    73     return result;
       
    74   }
       
    75 
       
    76   // Mapping that includes the derived offset.
       
    77   // If the block is clean, returns the last address in the covered region.
       
    78   // If the block is < index 0, returns the start of the covered region.
       
    79   HeapWord* offset_addr_for_block (jbyte* p) const {
       
    80     // We have to do this before the assert
       
    81     if (p < _raw_base) {
       
    82       return _covered_region.start();
       
    83     }
       
    84 
       
    85     assert(_blocks_region.contains(p),
       
    86            "out of bounds access to object start array");
       
    87 
       
    88     if (*p == clean_block) {
       
    89       return _covered_region.end();
       
    90     }
       
    91 
       
    92     size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte));
       
    93     HeapWord* result = (HeapWord*) (delta << block_shift);
       
    94     result += *p;
       
    95 
       
    96     assert(_covered_region.contains(result),
       
    97            "out of bounds accessor from card marking array");
       
    98 
       
    99     return result;
       
   100   }
       
   101 
       
   102  public:
       
   103 
       
   104   // This method is in lieu of a constructor, so that this class can be
       
   105   // embedded inline in other classes.
       
   106   void initialize(MemRegion reserved_region);
       
   107 
       
   108   void set_covered_region(MemRegion mr);
       
   109 
       
   110   void reset();
       
   111 
       
   112   MemRegion covered_region() { return _covered_region; }
       
   113 
       
   114   void allocate_block(HeapWord* p) {
       
   115     assert(_covered_region.contains(p), "Must be in covered region");
       
   116     jbyte* block = block_for_addr(p);
       
   117     HeapWord* block_base = addr_for_block(block);
       
   118     size_t offset = pointer_delta(p, block_base, sizeof(HeapWord*));
       
   119     assert(offset < 128, "Sanity");
       
   120     // When doing MT offsets, we can't assert this.
       
   121     //assert(offset > *block, "Found backwards allocation");
       
   122     *block = (jbyte)offset;
       
   123 
       
   124     // tty->print_cr("[%p]", p);
       
   125   }
       
   126 
       
   127   // Optimized for finding the first object that crosses into
       
   128   // a given block. The blocks contain the offset of the last
       
   129   // object in that block. Scroll backwards by one, and the first
       
   130   // object hit should be at the begining of the block
       
   131   HeapWord* object_start(HeapWord* addr) const {
       
   132     assert(_covered_region.contains(addr), "Must be in covered region");
       
   133     jbyte* block = block_for_addr(addr);
       
   134     HeapWord* scroll_forward = offset_addr_for_block(block--);
       
   135     while (scroll_forward > addr) {
       
   136       scroll_forward = offset_addr_for_block(block--);
       
   137     }
       
   138 
       
   139     HeapWord* next = scroll_forward;
       
   140     while (next <= addr) {
       
   141       scroll_forward = next;
       
   142       next += oop(next)->size();
       
   143     }
       
   144     assert(scroll_forward <= addr, "wrong order for current and arg");
       
   145     assert(addr <= next, "wrong order for arg and next");
       
   146     return scroll_forward;
       
   147   }
       
   148 
       
   149   bool is_block_allocated(HeapWord* addr) {
       
   150     assert(_covered_region.contains(addr), "Must be in covered region");
       
   151     jbyte* block = block_for_addr(addr);
       
   152     if (*block == clean_block)
       
   153       return false;
       
   154 
       
   155     return true;
       
   156   }
       
   157 
       
   158   // Return true if an object starts in the range of heap addresses.
       
   159   // If an object starts at an address corresponding to
       
   160   // "start", the method will return true.
       
   161   bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const;
       
   162 };