hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
author ysr
Mon, 16 Aug 2010 15:58:42 -0700
changeset 6258 68f252c6e825
parent 5702 201c5cde25bb
child 7397 5b173b4ca846
permissions -rw-r--r--
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     1
/*
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
     2
 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     4
 *
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     7
 * published by the Free Software Foundation.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     8
 *
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    13
 * accompanied this code).
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    14
 *
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4574
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4574
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4574
diff changeset
    21
 * questions.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    22
 *
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    23
 */
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    24
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    25
//
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    26
// Free block maintenance for Concurrent Mark Sweep Generation
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    27
//
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    28
// The main data structure for free blocks are
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    29
// . an indexed array of small free blocks, and
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    30
// . a dictionary of large free blocks
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    31
//
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    32
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    33
// No virtuals in FreeChunk (don't want any vtables).
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    34
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    35
// A FreeChunk is merely a chunk that can be in a doubly linked list
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    36
// and has a size field. NOTE: FreeChunks are distinguished from allocated
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    37
// objects in two ways (by the sweeper), depending on whether the VM is 32 or
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    38
// 64 bits.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    39
// In 32 bits or 64 bits without CompressedOops, the second word (prev) has the
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    40
// LSB set to indicate a free chunk; allocated objects' klass() pointers
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    41
// don't have their LSB set. The corresponding bit in the CMSBitMap is
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    42
// set when the chunk is allocated. There are also blocks that "look free"
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    43
// but are not part of the free list and should not be coalesced into larger
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    44
// free blocks. These free blocks have their two LSB's set.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    45
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    46
class FreeChunk VALUE_OBJ_CLASS_SPEC {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    47
  friend class VMStructs;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    48
  // For 64 bit compressed oops, the markOop encodes both the size and the
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    49
  // indication that this is a FreeChunk and not an object.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    50
  volatile size_t   _size;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    51
  FreeChunk* _prev;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    52
  FreeChunk* _next;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    53
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    54
  markOop mark()     const volatile { return (markOop)_size; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    55
  void set_mark(markOop m)          { _size = (size_t)m; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    56
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    57
 public:
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    58
  NOT_PRODUCT(static const size_t header_size();)
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    59
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    60
  // Returns "true" if the address indicates that the block represents
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    61
  // a free chunk.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    62
  static bool indicatesFreeChunk(const HeapWord* addr) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    63
    // Force volatile read from addr because value might change between
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    64
    // calls.  We really want the read of _mark and _prev from this pointer
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    65
    // to be volatile but making the fields volatile causes all sorts of
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    66
    // compilation errors.
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    67
    return ((volatile FreeChunk*)addr)->isFree();
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    68
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    69
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    70
  bool isFree() const volatile {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    71
    LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    72
    return (((intptr_t)_prev) & 0x1) == 0x1;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    73
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    74
  bool cantCoalesce() const {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    75
    assert(isFree(), "can't get coalesce bit on not free");
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    76
    return (((intptr_t)_prev) & 0x2) == 0x2;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    77
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    78
  void dontCoalesce() {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    79
    // the block should be free
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    80
    assert(isFree(), "Should look like a free block");
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    81
    _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    82
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    83
  FreeChunk* prev() const {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    84
    return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    85
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    86
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    87
  debug_only(void* prev_addr() const { return (void*)&_prev; })
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 613
diff changeset
    88
  debug_only(void* next_addr() const { return (void*)&_next; })
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 613
diff changeset
    89
  debug_only(void* size_addr() const { return (void*)&_size; })
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    90
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    91
  size_t size() const volatile {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    92
    LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    93
    return _size;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    94
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    95
  void setSize(size_t sz) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    96
    LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    97
    _size = sz;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    98
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
    99
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   100
  FreeChunk* next()   const { return _next; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   101
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   102
  void linkAfter(FreeChunk* ptr) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   103
    linkNext(ptr);
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   104
    if (ptr != NULL) ptr->linkPrev(this);
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   105
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   106
  void linkAfterNonNull(FreeChunk* ptr) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   107
    assert(ptr != NULL, "precondition violation");
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   108
    linkNext(ptr);
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   109
    ptr->linkPrev(this);
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   110
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   111
  void linkNext(FreeChunk* ptr) { _next = ptr; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   112
  void linkPrev(FreeChunk* ptr) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   113
    LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   114
    _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   115
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   116
  void clearPrev()              { _prev = NULL; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   117
  void clearNext()              { _next = NULL; }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   118
  void markNotFree() {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   119
    // Set _prev (klass) to null before (if) clearing the mark word below
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   120
    _prev = NULL;
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   121
#ifdef _LP64
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   122
    if (UseCompressedOops) {
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   123
      OrderAccess::storestore();
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   124
      set_mark(markOopDesc::prototype());
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   125
    }
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   126
#endif
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5702
diff changeset
   127
    assert(!isFree(), "Error");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   128
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   129
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   130
  // Return the address past the end of this chunk
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   131
  HeapWord* end() const { return ((HeapWord*) this) + size(); }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   132
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   133
  // debugging
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   134
  void verify()             const PRODUCT_RETURN;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   135
  void verifyList()         const PRODUCT_RETURN;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   136
  void mangleAllocated(size_t size) PRODUCT_RETURN;
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   137
  void mangleFreed(size_t size)     PRODUCT_RETURN;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 977
diff changeset
   138
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 977
diff changeset
   139
  void print_on(outputStream* st);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   140
};
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   141
5694
1e0532a6abff 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 4574
diff changeset
   142
extern size_t MinChunkSize;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
   143