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

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial