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

Wed, 22 Jan 2014 17:42:23 -0800

author
kvn
date
Wed, 22 Jan 2014 17:42:23 -0800
changeset 6503
a9becfeecd1b
parent 4196
685df3c6f84b
child 6876
710a3c8b516e
permissions
-rw-r--r--

Merge

coleenp@622 1 /*
mikael@4153 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
coleenp@622 22 *
coleenp@622 23 */
coleenp@622 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREECHUNK_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREECHUNK_HPP
stefank@2314 27
stefank@2314 28 #include "memory/allocation.hpp"
stefank@2314 29 #include "memory/memRegion.hpp"
stefank@2314 30 #include "oops/markOop.hpp"
stefank@2314 31 #include "runtime/mutex.hpp"
stefank@2314 32 #include "utilities/debug.hpp"
stefank@2314 33 #include "utilities/globalDefinitions.hpp"
stefank@2314 34 #include "utilities/ostream.hpp"
stefank@2314 35
coleenp@622 36 //
coleenp@622 37 // Free block maintenance for Concurrent Mark Sweep Generation
coleenp@622 38 //
coleenp@622 39 // The main data structure for free blocks are
coleenp@622 40 // . an indexed array of small free blocks, and
coleenp@622 41 // . a dictionary of large free blocks
coleenp@622 42 //
coleenp@622 43
coleenp@622 44 // No virtuals in FreeChunk (don't want any vtables).
coleenp@622 45
coleenp@622 46 // A FreeChunk is merely a chunk that can be in a doubly linked list
coleenp@622 47 // and has a size field. NOTE: FreeChunks are distinguished from allocated
coleenp@622 48 // objects in two ways (by the sweeper), depending on whether the VM is 32 or
coleenp@622 49 // 64 bits.
coleenp@622 50 // In 32 bits or 64 bits without CompressedOops, the second word (prev) has the
coleenp@622 51 // LSB set to indicate a free chunk; allocated objects' klass() pointers
coleenp@622 52 // don't have their LSB set. The corresponding bit in the CMSBitMap is
coleenp@622 53 // set when the chunk is allocated. There are also blocks that "look free"
coleenp@622 54 // but are not part of the free list and should not be coalesced into larger
coleenp@622 55 // free blocks. These free blocks have their two LSB's set.
coleenp@622 56
coleenp@622 57 class FreeChunk VALUE_OBJ_CLASS_SPEC {
coleenp@622 58 friend class VMStructs;
coleenp@622 59 // For 64 bit compressed oops, the markOop encodes both the size and the
coleenp@622 60 // indication that this is a FreeChunk and not an object.
coleenp@622 61 volatile size_t _size;
coleenp@622 62 FreeChunk* _prev;
coleenp@622 63 FreeChunk* _next;
coleenp@622 64
coleenp@622 65 markOop mark() const volatile { return (markOop)_size; }
coleenp@622 66 void set_mark(markOop m) { _size = (size_t)m; }
coleenp@622 67
coleenp@622 68 public:
coleenp@622 69 NOT_PRODUCT(static const size_t header_size();)
coleenp@622 70
coleenp@622 71 // Returns "true" if the address indicates that the block represents
coleenp@622 72 // a free chunk.
coleenp@622 73 static bool indicatesFreeChunk(const HeapWord* addr) {
coleenp@622 74 // Force volatile read from addr because value might change between
coleenp@622 75 // calls. We really want the read of _mark and _prev from this pointer
coleenp@622 76 // to be volatile but making the fields volatile causes all sorts of
coleenp@622 77 // compilation errors.
jmasa@3732 78 return ((volatile FreeChunk*)addr)->is_free();
coleenp@622 79 }
coleenp@622 80
jmasa@3732 81 bool is_free() const volatile {
coleenp@622 82 LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
coleenp@622 83 return (((intptr_t)_prev) & 0x1) == 0x1;
coleenp@622 84 }
coleenp@622 85 bool cantCoalesce() const {
jmasa@3732 86 assert(is_free(), "can't get coalesce bit on not free");
coleenp@622 87 return (((intptr_t)_prev) & 0x2) == 0x2;
coleenp@622 88 }
coleenp@622 89 void dontCoalesce() {
coleenp@622 90 // the block should be free
jmasa@3732 91 assert(is_free(), "Should look like a free block");
coleenp@622 92 _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
coleenp@622 93 }
coleenp@622 94 FreeChunk* prev() const {
coleenp@622 95 return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
coleenp@622 96 }
coleenp@622 97
coleenp@622 98 debug_only(void* prev_addr() const { return (void*)&_prev; })
jmasa@698 99 debug_only(void* next_addr() const { return (void*)&_next; })
jmasa@698 100 debug_only(void* size_addr() const { return (void*)&_size; })
coleenp@622 101
coleenp@622 102 size_t size() const volatile {
coleenp@622 103 LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
coleenp@622 104 return _size;
coleenp@622 105 }
jmasa@3732 106 void set_size(size_t sz) {
coleenp@622 107 LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
coleenp@622 108 _size = sz;
coleenp@622 109 }
coleenp@622 110
coleenp@622 111 FreeChunk* next() const { return _next; }
coleenp@622 112
jmasa@3732 113 void link_after(FreeChunk* ptr) {
jmasa@3732 114 link_next(ptr);
jmasa@3732 115 if (ptr != NULL) ptr->link_prev(this);
coleenp@622 116 }
jmasa@3732 117 void link_next(FreeChunk* ptr) { _next = ptr; }
jmasa@3732 118 void link_prev(FreeChunk* ptr) {
ysr@2071 119 LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
ysr@2071 120 _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
coleenp@622 121 }
jmasa@3732 122 void clear_next() { _next = NULL; }
coleenp@622 123 void markNotFree() {
ysr@2071 124 // Set _prev (klass) to null before (if) clearing the mark word below
ysr@2071 125 _prev = NULL;
ysr@2071 126 #ifdef _LP64
ysr@2071 127 if (UseCompressedOops) {
ysr@2071 128 OrderAccess::storestore();
ysr@2071 129 set_mark(markOopDesc::prototype());
ysr@2071 130 }
ysr@2071 131 #endif
jmasa@3732 132 assert(!is_free(), "Error");
coleenp@622 133 }
coleenp@622 134
coleenp@622 135 // Return the address past the end of this chunk
jmasa@4196 136 uintptr_t* end() const { return ((uintptr_t*) this) + size(); }
coleenp@622 137
coleenp@622 138 // debugging
coleenp@622 139 void verify() const PRODUCT_RETURN;
coleenp@622 140 void verifyList() const PRODUCT_RETURN;
coleenp@622 141 void mangleAllocated(size_t size) PRODUCT_RETURN;
coleenp@622 142 void mangleFreed(size_t size) PRODUCT_RETURN;
ysr@1580 143
ysr@1580 144 void print_on(outputStream* st);
coleenp@622 145 };
coleenp@622 146
kvn@1926 147 extern size_t MinChunkSize;
coleenp@622 148
stefank@2314 149
stefank@2314 150 #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREECHUNK_HPP

mercurial