src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp

Mon, 21 Jul 2014 09:40:19 +0200

author
tschatzl
date
Mon, 21 Jul 2014 09:40:19 +0200
changeset 6932
828056cf311f
parent 6925
82693fb204a5
child 6992
2c6ef90f030a
permissions
-rw-r--r--

8040792: G1: Memory usage calculation uses sizeof(this) instead of sizeof(classname)
Summary: A few locations in the code use sizeof(this) which returns the size of the pointer instead of sizeof(classname) which returns the size of the sum of its members. This change fixes these errors and adds a few tests.
Reviewed-by: mgerdin, brutisso

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2014, 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_G1_G1CODECACHEREMSET_HPP
aoqi@0 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1CODECACHEREMSET_HPP
aoqi@0 27
aoqi@0 28 #include "memory/allocation.hpp"
aoqi@0 29 #include "memory/freeList.hpp"
aoqi@0 30 #include "runtime/globals.hpp"
aoqi@0 31
aoqi@0 32 class CodeBlobClosure;
aoqi@0 33
aoqi@0 34 class G1CodeRootChunk : public CHeapObj<mtGC> {
aoqi@0 35 private:
aoqi@0 36 static const int NUM_ENTRIES = 32;
aoqi@0 37 public:
aoqi@0 38 G1CodeRootChunk* _next;
aoqi@0 39 G1CodeRootChunk* _prev;
aoqi@0 40
aoqi@0 41 nmethod** _top;
aoqi@0 42
aoqi@0 43 nmethod* _data[NUM_ENTRIES];
aoqi@0 44
aoqi@0 45 nmethod** bottom() const {
aoqi@0 46 return (nmethod**) &(_data[0]);
aoqi@0 47 }
aoqi@0 48
aoqi@0 49 nmethod** end() const {
aoqi@0 50 return (nmethod**) &(_data[NUM_ENTRIES]);
aoqi@0 51 }
aoqi@0 52
aoqi@0 53 public:
aoqi@0 54 G1CodeRootChunk();
aoqi@0 55 ~G1CodeRootChunk() {}
aoqi@0 56
aoqi@0 57 static size_t word_size() { return (size_t)(align_size_up_(sizeof(G1CodeRootChunk), HeapWordSize) / HeapWordSize); }
aoqi@0 58
aoqi@0 59 // FreeList "interface" methods
aoqi@0 60
aoqi@0 61 G1CodeRootChunk* next() const { return _next; }
aoqi@0 62 G1CodeRootChunk* prev() const { return _prev; }
aoqi@0 63 void set_next(G1CodeRootChunk* v) { _next = v; assert(v != this, "Boom");}
aoqi@0 64 void set_prev(G1CodeRootChunk* v) { _prev = v; assert(v != this, "Boom");}
aoqi@0 65 void clear_next() { set_next(NULL); }
aoqi@0 66 void clear_prev() { set_prev(NULL); }
aoqi@0 67
aoqi@0 68 size_t size() const { return word_size(); }
aoqi@0 69
aoqi@0 70 void link_next(G1CodeRootChunk* ptr) { set_next(ptr); }
aoqi@0 71 void link_prev(G1CodeRootChunk* ptr) { set_prev(ptr); }
aoqi@0 72 void link_after(G1CodeRootChunk* ptr) {
aoqi@0 73 link_next(ptr);
aoqi@0 74 if (ptr != NULL) ptr->link_prev((G1CodeRootChunk*)this);
aoqi@0 75 }
aoqi@0 76
aoqi@0 77 bool is_free() { return true; }
aoqi@0 78
aoqi@0 79 // New G1CodeRootChunk routines
aoqi@0 80
aoqi@0 81 void reset();
aoqi@0 82
aoqi@0 83 bool is_empty() const {
aoqi@0 84 return _top == bottom();
aoqi@0 85 }
aoqi@0 86
aoqi@0 87 bool is_full() const {
aoqi@0 88 return _top == (nmethod**)end();
aoqi@0 89 }
aoqi@0 90
aoqi@0 91 bool contains(nmethod* method) {
aoqi@0 92 nmethod** cur = bottom();
aoqi@0 93 while (cur != _top) {
aoqi@0 94 if (*cur == method) return true;
aoqi@0 95 cur++;
aoqi@0 96 }
aoqi@0 97 return false;
aoqi@0 98 }
aoqi@0 99
aoqi@0 100 bool add(nmethod* method) {
aoqi@0 101 if (is_full()) return false;
aoqi@0 102 *_top = method;
aoqi@0 103 _top++;
aoqi@0 104 return true;
aoqi@0 105 }
aoqi@0 106
aoqi@0 107 bool remove(nmethod* method) {
aoqi@0 108 nmethod** cur = bottom();
aoqi@0 109 while (cur != _top) {
aoqi@0 110 if (*cur == method) {
aoqi@0 111 memmove(cur, cur + 1, (_top - (cur + 1)) * sizeof(nmethod**));
aoqi@0 112 _top--;
aoqi@0 113 return true;
aoqi@0 114 }
aoqi@0 115 cur++;
aoqi@0 116 }
aoqi@0 117 return false;
aoqi@0 118 }
aoqi@0 119
aoqi@0 120 void nmethods_do(CodeBlobClosure* blk);
aoqi@0 121
aoqi@0 122 nmethod* pop() {
aoqi@0 123 if (is_empty()) {
aoqi@0 124 return NULL;
aoqi@0 125 }
aoqi@0 126 _top--;
aoqi@0 127 return *_top;
aoqi@0 128 }
aoqi@0 129 };
aoqi@0 130
tschatzl@6925 131 // Manages free chunks.
tschatzl@6925 132 class G1CodeRootChunkManager VALUE_OBJ_CLASS_SPEC {
tschatzl@6925 133 private:
tschatzl@6925 134 // Global free chunk list management
tschatzl@6925 135 FreeList<G1CodeRootChunk> _free_list;
tschatzl@6925 136 // Total number of chunks handed out
tschatzl@6925 137 size_t _num_chunks_handed_out;
tschatzl@6925 138
tschatzl@6925 139 public:
tschatzl@6925 140 G1CodeRootChunkManager();
tschatzl@6925 141
tschatzl@6925 142 G1CodeRootChunk* new_chunk();
tschatzl@6925 143 void free_chunk(G1CodeRootChunk* chunk);
tschatzl@6925 144 // Free all elements of the given list.
tschatzl@6925 145 void free_all_chunks(FreeList<G1CodeRootChunk>* list);
tschatzl@6925 146
tschatzl@6925 147 void initialize();
tschatzl@6925 148 void purge_chunks(size_t keep_ratio);
tschatzl@6925 149
tschatzl@6932 150 static size_t static_mem_size();
tschatzl@6925 151 size_t fl_mem_size();
tschatzl@6925 152
tschatzl@6925 153 #ifndef PRODUCT
tschatzl@6925 154 size_t num_chunks_handed_out() const;
tschatzl@6925 155 size_t num_free_chunks() const;
tschatzl@6925 156 #endif
tschatzl@6925 157 };
tschatzl@6925 158
aoqi@0 159 // Implements storage for a set of code roots.
aoqi@0 160 // All methods that modify the set are not thread-safe except if otherwise noted.
aoqi@0 161 class G1CodeRootSet VALUE_OBJ_CLASS_SPEC {
aoqi@0 162 private:
tschatzl@6925 163 // Global default free chunk manager instance.
tschatzl@6925 164 static G1CodeRootChunkManager _default_chunk_manager;
aoqi@0 165
tschatzl@6925 166 G1CodeRootChunk* new_chunk() { return _manager->new_chunk(); }
tschatzl@6925 167 void free_chunk(G1CodeRootChunk* chunk) { _manager->free_chunk(chunk); }
aoqi@0 168 // Free all elements of the given list.
tschatzl@6925 169 void free_all_chunks(FreeList<G1CodeRootChunk>* list) { _manager->free_all_chunks(list); }
aoqi@0 170
aoqi@0 171 // Return the chunk that contains the given nmethod, NULL otherwise.
aoqi@0 172 // Scans the list of chunks backwards, as this method is used to add new
aoqi@0 173 // entries, which are typically added in bulk for a single nmethod.
aoqi@0 174 G1CodeRootChunk* find(nmethod* method);
aoqi@0 175 void free(G1CodeRootChunk* chunk);
aoqi@0 176
aoqi@0 177 size_t _length;
aoqi@0 178 FreeList<G1CodeRootChunk> _list;
tschatzl@6925 179 G1CodeRootChunkManager* _manager;
aoqi@0 180
aoqi@0 181 public:
tschatzl@6925 182 // If an instance is initialized with a chunk manager of NULL, use the global
tschatzl@6925 183 // default one.
tschatzl@6925 184 G1CodeRootSet(G1CodeRootChunkManager* manager = NULL);
aoqi@0 185 ~G1CodeRootSet();
aoqi@0 186
aoqi@0 187 static void purge_chunks(size_t keep_ratio);
aoqi@0 188
tschatzl@6932 189 static size_t free_chunks_static_mem_size();
tschatzl@6925 190 static size_t free_chunks_mem_size();
aoqi@0 191
aoqi@0 192 // Search for the code blob from the recently allocated ones to find duplicates more quickly, as this
aoqi@0 193 // method is likely to be repeatedly called with the same nmethod.
aoqi@0 194 void add(nmethod* method);
aoqi@0 195
aoqi@0 196 void remove(nmethod* method);
aoqi@0 197 nmethod* pop();
aoqi@0 198
aoqi@0 199 bool contains(nmethod* method);
aoqi@0 200
aoqi@0 201 void clear();
aoqi@0 202
aoqi@0 203 void nmethods_do(CodeBlobClosure* blk) const;
aoqi@0 204
aoqi@0 205 bool is_empty() { return length() == 0; }
aoqi@0 206
aoqi@0 207 // Length in elements
aoqi@0 208 size_t length() const { return _length; }
aoqi@0 209
tschatzl@6932 210 // Static data memory size in bytes of this set.
tschatzl@6932 211 static size_t static_mem_size();
aoqi@0 212 // Memory size in bytes taken by this set.
aoqi@0 213 size_t mem_size();
aoqi@0 214
aoqi@0 215 static void test() PRODUCT_RETURN;
aoqi@0 216 };
aoqi@0 217
aoqi@0 218 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1CODECACHEREMSET_HPP

mercurial