annotate src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp @ 1716:be3f9c242c9d

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
author ysr
date Mon, 16 Aug 2010 15:58:42 -0700
parents e9ff18c4ace7
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
1 /*
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
4 *
790e66e5fbac 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
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
7 * published by the Free Software Foundation.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
8 *
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
13 * accompanied this code).
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
14 *
790e66e5fbac 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
790e66e5fbac 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,
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1145
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1145
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1145
diff changeset
21 * questions.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
22 *
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
23 */
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
24
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
25 //
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
26 // Free block maintenance for Concurrent Mark Sweep Generation
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
27 //
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
28 // The main data structure for free blocks are
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
29 // . an indexed array of small free blocks, and
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
30 // . a dictionary of large free blocks
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
31 //
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
32
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
33 // No virtuals in FreeChunk (don't want any vtables).
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
34
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
36 // and has a size field. NOTE: FreeChunks are distinguished from allocated
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
38 // 64 bits.
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
40 // LSB set to indicate a free chunk; allocated objects' klass() pointers
790e66e5fbac 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
790e66e5fbac 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"
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
44 // free blocks. These free blocks have their two LSB's set.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
45
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
46 class FreeChunk VALUE_OBJ_CLASS_SPEC {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
47 friend class VMStructs;
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
49 // indication that this is a FreeChunk and not an object.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
50 volatile size_t _size;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
51 FreeChunk* _prev;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
52 FreeChunk* _next;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
53
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
54 markOop mark() const volatile { return (markOop)_size; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
55 void set_mark(markOop m) { _size = (size_t)m; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
56
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
57 public:
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
58 NOT_PRODUCT(static const size_t header_size();)
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
59
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
60 // Returns "true" if the address indicates that the block represents
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
61 // a free chunk.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
62 static bool indicatesFreeChunk(const HeapWord* addr) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
63 // Force volatile read from addr because value might change between
790e66e5fbac 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
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
65 // to be volatile but making the fields volatile causes all sorts of
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
66 // compilation errors.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
67 return ((volatile FreeChunk*)addr)->isFree();
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
68 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
69
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
70 bool isFree() const volatile {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
71 LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
72 return (((intptr_t)_prev) & 0x1) == 0x1;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
73 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
74 bool cantCoalesce() const {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
75 assert(isFree(), "can't get coalesce bit on not free");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
76 return (((intptr_t)_prev) & 0x2) == 0x2;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
77 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
78 void dontCoalesce() {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
79 // the block should be free
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
80 assert(isFree(), "Should look like a free block");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
81 _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
82 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
83 FreeChunk* prev() const {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
84 return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
85 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
86
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
87 debug_only(void* prev_addr() const { return (void*)&_prev; })
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 187
diff changeset
88 debug_only(void* next_addr() const { return (void*)&_next; })
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 187
diff changeset
89 debug_only(void* size_addr() const { return (void*)&_size; })
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
90
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
91 size_t size() const volatile {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
92 LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
93 return _size;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
94 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
95 void setSize(size_t sz) {
790e66e5fbac 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 )
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
97 _size = sz;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
98 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
99
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
100 FreeChunk* next() const { return _next; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
101
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
102 void linkAfter(FreeChunk* ptr) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
103 linkNext(ptr);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
104 if (ptr != NULL) ptr->linkPrev(this);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
105 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
106 void linkAfterNonNull(FreeChunk* ptr) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
107 assert(ptr != NULL, "precondition violation");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
108 linkNext(ptr);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
109 ptr->linkPrev(this);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
110 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
111 void linkNext(FreeChunk* ptr) { _next = ptr; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
112 void linkPrev(FreeChunk* ptr) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
113 LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
114 _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
115 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
116 void clearPrev() { _prev = NULL; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
117 void clearNext() { _next = NULL; }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
118 void markNotFree() {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
119 // Set _prev (klass) to null before (if) clearing the mark word below
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
120 _prev = NULL;
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
121 #ifdef _LP64
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
122 if (UseCompressedOops) {
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
123 OrderAccess::storestore();
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
124 set_mark(markOopDesc::prototype());
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
125 }
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
126 #endif
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1579
diff changeset
127 assert(!isFree(), "Error");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
128 }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
129
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
130 // Return the address past the end of this chunk
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
131 HeapWord* end() const { return ((HeapWord*) this) + size(); }
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
132
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
133 // debugging
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
134 void verify() const PRODUCT_RETURN;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
135 void verifyList() const PRODUCT_RETURN;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
136 void mangleAllocated(size_t size) PRODUCT_RETURN;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
137 void mangleFreed(size_t size) PRODUCT_RETURN;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 269
diff changeset
138
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 269
diff changeset
139 void print_on(outputStream* st);
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
140 };
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
141
1571
2d127394260e 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 1145
diff changeset
142 extern size_t MinChunkSize;
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents:
diff changeset
143