Mercurial > hg > truffle
annotate src/share/vm/runtime/handles.cpp @ 10246:194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
Summary: Refactor G1's hot card cache and card counts table into their own files. Simplify the card counts table, including removing the encoding of the card index in each entry. The card counts table now has a 1:1 correspondence with the cards spanned by heap. Space for the card counts table is reserved from virtual memory (rather than C heap) during JVM startup and is committed/expanded when the heap is expanded. Changes were also reviewed-by Vitaly Davidovich.
Reviewed-by: tschatzl, jmasa
author | johnc |
---|---|
date | Thu, 09 May 2013 11:16:39 -0700 |
parents | f34d701e952e |
children | f9be75d21404 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.inline.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
27 #include "oops/constantPool.hpp" |
1972 | 28 #include "oops/oop.inline.hpp" |
29 #include "runtime/handles.inline.hpp" | |
7180
f34d701e952e
8003935: Simplify the needed includes for using Thread::current()
stefank
parents:
6882
diff
changeset
|
30 #include "runtime/thread.inline.hpp" |
1972 | 31 #ifdef TARGET_OS_FAMILY_linux |
32 # include "os_linux.inline.hpp" | |
33 #endif | |
34 #ifdef TARGET_OS_FAMILY_solaris | |
35 # include "os_solaris.inline.hpp" | |
36 #endif | |
37 #ifdef TARGET_OS_FAMILY_windows | |
38 # include "os_windows.inline.hpp" | |
39 #endif | |
3960 | 40 #ifdef TARGET_OS_FAMILY_bsd |
41 # include "os_bsd.inline.hpp" | |
42 #endif | |
0 | 43 |
44 #ifdef ASSERT | |
45 oop* HandleArea::allocate_handle(oop obj) { | |
46 assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark"); | |
47 assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark"); | |
6867 | 48 assert(obj->is_oop(), "sanity check"); |
0 | 49 return real_allocate_handle(obj); |
50 } | |
51 | |
52 Handle::Handle(Thread* thread, oop obj) { | |
53 assert(thread == Thread::current(), "sanity check"); | |
54 if (obj == NULL) { | |
55 _handle = NULL; | |
56 } else { | |
57 _handle = thread->handle_area()->allocate_handle(obj); | |
58 } | |
59 } | |
60 | |
61 #endif | |
62 | |
63 static uintx chunk_oops_do(OopClosure* f, Chunk* chunk, char* chunk_top) { | |
64 oop* bottom = (oop*) chunk->bottom(); | |
65 oop* top = (oop*) chunk_top; | |
66 uintx handles_visited = top - bottom; | |
67 assert(top >= bottom && top <= (oop*) chunk->top(), "just checking"); | |
68 // during GC phase 3, a handle may be a forward pointer that | |
69 // is not yet valid, so loosen the assertion | |
70 while (bottom < top) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
71 // This test can be moved up but for now check every oop. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
72 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
73 assert((*bottom)->is_oop(), "handle should point to oop"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
74 |
0 | 75 f->do_oop(bottom++); |
76 } | |
77 return handles_visited; | |
78 } | |
79 | |
80 // Used for debugging handle allocation. | |
81 NOT_PRODUCT(jint _nof_handlemarks = 0;) | |
82 | |
83 void HandleArea::oops_do(OopClosure* f) { | |
84 uintx handles_visited = 0; | |
85 // First handle the current chunk. It is filled to the high water mark. | |
86 handles_visited += chunk_oops_do(f, _chunk, _hwm); | |
87 // Then handle all previous chunks. They are completely filled. | |
88 Chunk* k = _first; | |
89 while(k != _chunk) { | |
90 handles_visited += chunk_oops_do(f, k, k->top()); | |
91 k = k->next(); | |
92 } | |
93 | |
94 // The thread local handle areas should not get very large | |
95 if (TraceHandleAllocation && handles_visited > TotalHandleAllocationLimit) { | |
96 #ifdef ASSERT | |
97 warning("%d: Visited in HandleMark : %d", | |
98 _nof_handlemarks, handles_visited); | |
99 #else | |
100 warning("Visited in HandleMark : %d", handles_visited); | |
101 #endif | |
102 } | |
103 if (_prev != NULL) _prev->oops_do(f); | |
104 } | |
105 | |
106 void HandleMark::initialize(Thread* thread) { | |
107 _thread = thread; | |
108 // Save area | |
109 _area = thread->handle_area(); | |
110 // Save current top | |
111 _chunk = _area->_chunk; | |
112 _hwm = _area->_hwm; | |
113 _max = _area->_max; | |
6197 | 114 _size_in_bytes = _area->_size_in_bytes; |
0 | 115 debug_only(_area->_handle_mark_nesting++); |
116 assert(_area->_handle_mark_nesting > 0, "must stack allocate HandleMarks"); | |
117 debug_only(Atomic::inc(&_nof_handlemarks);) | |
118 | |
119 // Link this in the thread | |
120 set_previous_handle_mark(thread->last_handle_mark()); | |
121 thread->set_last_handle_mark(this); | |
122 } | |
123 | |
124 | |
125 HandleMark::~HandleMark() { | |
126 HandleArea* area = _area; // help compilers with poor alias analysis | |
127 assert(area == _thread->handle_area(), "sanity check"); | |
128 assert(area->_handle_mark_nesting > 0, "must stack allocate HandleMarks" ); | |
129 debug_only(area->_handle_mark_nesting--); | |
130 | |
131 // Debug code to trace the number of handles allocated per mark/ | |
132 #ifdef ASSERT | |
133 if (TraceHandleAllocation) { | |
134 size_t handles = 0; | |
135 Chunk *c = _chunk->next(); | |
136 if (c == NULL) { | |
137 handles = area->_hwm - _hwm; // no new chunk allocated | |
138 } else { | |
139 handles = _max - _hwm; // add rest in first chunk | |
140 while(c != NULL) { | |
141 handles += c->length(); | |
142 c = c->next(); | |
143 } | |
144 handles -= area->_max - area->_hwm; // adjust for last trunk not full | |
145 } | |
146 handles /= sizeof(void *); // Adjust for size of a handle | |
147 if (handles > HandleAllocationLimit) { | |
148 // Note: _nof_handlemarks is only set in debug mode | |
149 warning("%d: Allocated in HandleMark : %d", _nof_handlemarks, handles); | |
150 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
151 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
152 tty->print_cr("Handles %d", handles); |
0 | 153 } |
154 #endif | |
155 | |
156 // Delete later chunks | |
157 if( _chunk->next() ) { | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
158 // reset arena size before delete chunks. Otherwise, the total |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
159 // arena size could exceed total chunk size |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
160 assert(area->size_in_bytes() > size_in_bytes(), "Sanity check"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
161 area->set_size_in_bytes(size_in_bytes()); |
0 | 162 _chunk->next_chop(); |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
163 } else { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6867
diff
changeset
|
164 assert(area->size_in_bytes() == size_in_bytes(), "Sanity check"); |
0 | 165 } |
166 // Roll back arena to saved top markers | |
167 area->_chunk = _chunk; | |
168 area->_hwm = _hwm; | |
169 area->_max = _max; | |
170 #ifdef ASSERT | |
171 // clear out first chunk (to detect allocation bugs) | |
172 if (ZapVMHandleArea) { | |
173 memset(_hwm, badHandleValue, _max - _hwm); | |
174 } | |
175 Atomic::dec(&_nof_handlemarks); | |
176 #endif | |
177 | |
178 // Unlink this from the thread | |
179 _thread->set_last_handle_mark(previous_handle_mark()); | |
180 } | |
181 | |
182 #ifdef ASSERT | |
183 | |
184 NoHandleMark::NoHandleMark() { | |
185 HandleArea* area = Thread::current()->handle_area(); | |
186 area->_no_handle_mark_nesting++; | |
187 assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" ); | |
188 } | |
189 | |
190 | |
191 NoHandleMark::~NoHandleMark() { | |
192 HandleArea* area = Thread::current()->handle_area(); | |
193 assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" ); | |
194 area->_no_handle_mark_nesting--; | |
195 } | |
196 | |
197 | |
198 ResetNoHandleMark::ResetNoHandleMark() { | |
199 HandleArea* area = Thread::current()->handle_area(); | |
200 _no_handle_mark_nesting = area->_no_handle_mark_nesting; | |
201 area->_no_handle_mark_nesting = 0; | |
202 } | |
203 | |
204 | |
205 ResetNoHandleMark::~ResetNoHandleMark() { | |
206 HandleArea* area = Thread::current()->handle_area(); | |
207 area->_no_handle_mark_nesting = _no_handle_mark_nesting; | |
208 } | |
209 | |
210 #endif |