src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 704
850fdf70db2b
child 1580
e018e6884bd8
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

coleenp@622 1 /*
xdono@631 2 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
coleenp@622 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
coleenp@622 4 *
coleenp@622 5 * This code is free software; you can redistribute it and/or modify it
coleenp@622 6 * under the terms of the GNU General Public License version 2 only, as
coleenp@622 7 * published by the Free Software Foundation.
coleenp@622 8 *
coleenp@622 9 * This code is distributed in the hope that it will be useful, but WITHOUT
coleenp@622 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
coleenp@622 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
coleenp@622 12 * version 2 for more details (a copy is included in the LICENSE file that
coleenp@622 13 * accompanied this code).
coleenp@622 14 *
coleenp@622 15 * You should have received a copy of the GNU General Public License version
coleenp@622 16 * 2 along with this work; if not, write to the Free Software Foundation,
coleenp@622 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
coleenp@622 18 *
coleenp@622 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
coleenp@622 20 * CA 95054 USA or visit www.sun.com if you need additional information or
coleenp@622 21 * have any questions.
coleenp@622 22 *
coleenp@622 23 */
coleenp@622 24
coleenp@622 25 //
coleenp@622 26 // Free block maintenance for Concurrent Mark Sweep Generation
coleenp@622 27 //
coleenp@622 28 // The main data structure for free blocks are
coleenp@622 29 // . an indexed array of small free blocks, and
coleenp@622 30 // . a dictionary of large free blocks
coleenp@622 31 //
coleenp@622 32
coleenp@622 33 // No virtuals in FreeChunk (don't want any vtables).
coleenp@622 34
coleenp@622 35 // A FreeChunk is merely a chunk that can be in a doubly linked list
coleenp@622 36 // and has a size field. NOTE: FreeChunks are distinguished from allocated
coleenp@622 37 // objects in two ways (by the sweeper), depending on whether the VM is 32 or
coleenp@622 38 // 64 bits.
coleenp@622 39 // In 32 bits or 64 bits without CompressedOops, the second word (prev) has the
coleenp@622 40 // LSB set to indicate a free chunk; allocated objects' klass() pointers
coleenp@622 41 // don't have their LSB set. The corresponding bit in the CMSBitMap is
coleenp@622 42 // set when the chunk is allocated. There are also blocks that "look free"
coleenp@622 43 // but are not part of the free list and should not be coalesced into larger
coleenp@622 44 // free blocks. These free blocks have their two LSB's set.
coleenp@622 45
coleenp@622 46 class FreeChunk VALUE_OBJ_CLASS_SPEC {
coleenp@622 47 friend class VMStructs;
coleenp@622 48 // For 64 bit compressed oops, the markOop encodes both the size and the
coleenp@622 49 // indication that this is a FreeChunk and not an object.
coleenp@622 50 volatile size_t _size;
coleenp@622 51 FreeChunk* _prev;
coleenp@622 52 FreeChunk* _next;
coleenp@622 53
coleenp@622 54 markOop mark() const volatile { return (markOop)_size; }
coleenp@622 55 void set_mark(markOop m) { _size = (size_t)m; }
coleenp@622 56
coleenp@622 57 public:
coleenp@622 58 NOT_PRODUCT(static const size_t header_size();)
coleenp@622 59
coleenp@622 60 // Returns "true" if the address indicates that the block represents
coleenp@622 61 // a free chunk.
coleenp@622 62 static bool indicatesFreeChunk(const HeapWord* addr) {
coleenp@622 63 // Force volatile read from addr because value might change between
coleenp@622 64 // calls. We really want the read of _mark and _prev from this pointer
coleenp@622 65 // to be volatile but making the fields volatile causes all sorts of
coleenp@622 66 // compilation errors.
coleenp@622 67 return ((volatile FreeChunk*)addr)->isFree();
coleenp@622 68 }
coleenp@622 69
coleenp@622 70 bool isFree() const volatile {
coleenp@622 71 LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
coleenp@622 72 return (((intptr_t)_prev) & 0x1) == 0x1;
coleenp@622 73 }
coleenp@622 74 bool cantCoalesce() const {
coleenp@622 75 assert(isFree(), "can't get coalesce bit on not free");
coleenp@622 76 return (((intptr_t)_prev) & 0x2) == 0x2;
coleenp@622 77 }
coleenp@622 78 void dontCoalesce() {
coleenp@622 79 // the block should be free
coleenp@622 80 assert(isFree(), "Should look like a free block");
coleenp@622 81 _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
coleenp@622 82 }
coleenp@622 83 FreeChunk* prev() const {
coleenp@622 84 return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
coleenp@622 85 }
coleenp@622 86
coleenp@622 87 debug_only(void* prev_addr() const { return (void*)&_prev; })
jmasa@698 88 debug_only(void* next_addr() const { return (void*)&_next; })
jmasa@698 89 debug_only(void* size_addr() const { return (void*)&_size; })
coleenp@622 90
coleenp@622 91 size_t size() const volatile {
coleenp@622 92 LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
coleenp@622 93 return _size;
coleenp@622 94 }
coleenp@622 95 void setSize(size_t sz) {
coleenp@622 96 LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
coleenp@622 97 _size = sz;
coleenp@622 98 }
coleenp@622 99
coleenp@622 100 FreeChunk* next() const { return _next; }
coleenp@622 101
coleenp@622 102 void linkAfter(FreeChunk* ptr) {
coleenp@622 103 linkNext(ptr);
coleenp@622 104 if (ptr != NULL) ptr->linkPrev(this);
coleenp@622 105 }
coleenp@622 106 void linkAfterNonNull(FreeChunk* ptr) {
coleenp@622 107 assert(ptr != NULL, "precondition violation");
coleenp@622 108 linkNext(ptr);
coleenp@622 109 ptr->linkPrev(this);
coleenp@622 110 }
coleenp@622 111 void linkNext(FreeChunk* ptr) { _next = ptr; }
coleenp@622 112 void linkPrev(FreeChunk* ptr) {
coleenp@622 113 LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
coleenp@622 114 _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
coleenp@622 115 }
coleenp@622 116 void clearPrev() { _prev = NULL; }
coleenp@622 117 void clearNext() { _next = NULL; }
coleenp@622 118 void markNotFree() {
coleenp@622 119 LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::prototype());)
coleenp@622 120 // Also set _prev to null
coleenp@622 121 _prev = NULL;
coleenp@622 122 }
coleenp@622 123
coleenp@622 124 // Return the address past the end of this chunk
coleenp@622 125 HeapWord* end() const { return ((HeapWord*) this) + size(); }
coleenp@622 126
coleenp@622 127 // debugging
coleenp@622 128 void verify() const PRODUCT_RETURN;
coleenp@622 129 void verifyList() const PRODUCT_RETURN;
coleenp@622 130 void mangleAllocated(size_t size) PRODUCT_RETURN;
coleenp@622 131 void mangleFreed(size_t size) PRODUCT_RETURN;
coleenp@622 132 };
coleenp@622 133
coleenp@622 134 // Alignment helpers etc.
coleenp@622 135 #define numQuanta(x,y) ((x+y-1)/y)
coleenp@622 136 enum AlignmentConstants {
coleenp@622 137 MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment
coleenp@622 138 };
coleenp@622 139

mercurial