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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
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
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
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
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 # include "os_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 # include "os_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 # include "os_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #endif
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 1972
diff changeset
40 #ifdef TARGET_OS_FAMILY_bsd
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 1972
diff changeset
41 # include "os_bsd.inline.hpp"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 1972
diff changeset
42 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
45 oop* HandleArea::allocate_handle(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark");
a61af66fc99e Initial load
duke
parents:
diff changeset
47 assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark");
6867
bdb5f8c9978b 7199068: NPG: SharedSkipVerify is meaningless
coleenp
parents: 6725
diff changeset
48 assert(obj->is_oop(), "sanity check");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
49 return real_allocate_handle(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 Handle::Handle(Thread* thread, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 assert(thread == Thread::current(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
54 if (obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _handle = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _handle = thread->handle_area()->allocate_handle(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 static uintx chunk_oops_do(OopClosure* f, Chunk* chunk, char* chunk_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 oop* bottom = (oop*) chunk->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
65 oop* top = (oop*) chunk_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 uintx handles_visited = top - bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 assert(top >= bottom && top <= (oop*) chunk->top(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // during GC phase 3, a handle may be a forward pointer that
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // is not yet valid, so loosen the assertion
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
75 f->do_oop(bottom++);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return handles_visited;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Used for debugging handle allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 NOT_PRODUCT(jint _nof_handlemarks = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 void HandleArea::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 uintx handles_visited = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // First handle the current chunk. It is filled to the high water mark.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 handles_visited += chunk_oops_do(f, _chunk, _hwm);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Then handle all previous chunks. They are completely filled.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 Chunk* k = _first;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 while(k != _chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 handles_visited += chunk_oops_do(f, k, k->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
91 k = k->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // The thread local handle areas should not get very large
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if (TraceHandleAllocation && handles_visited > TotalHandleAllocationLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
97 warning("%d: Visited in HandleMark : %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _nof_handlemarks, handles_visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
100 warning("Visited in HandleMark : %d", handles_visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (_prev != NULL) _prev->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 void HandleMark::initialize(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Save area
a61af66fc99e Initial load
duke
parents:
diff changeset
109 _area = thread->handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Save current top
a61af66fc99e Initial load
duke
parents:
diff changeset
111 _chunk = _area->_chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 _hwm = _area->_hwm;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 _max = _area->_max;
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 3960
diff changeset
114 _size_in_bytes = _area->_size_in_bytes;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
115 debug_only(_area->_handle_mark_nesting++);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 assert(_area->_handle_mark_nesting > 0, "must stack allocate HandleMarks");
a61af66fc99e Initial load
duke
parents:
diff changeset
117 debug_only(Atomic::inc(&_nof_handlemarks);)
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // Link this in the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
120 set_previous_handle_mark(thread->last_handle_mark());
a61af66fc99e Initial load
duke
parents:
diff changeset
121 thread->set_last_handle_mark(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 HandleMark::~HandleMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 HandleArea* area = _area; // help compilers with poor alias analysis
a61af66fc99e Initial load
duke
parents:
diff changeset
127 assert(area == _thread->handle_area(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
128 assert(area->_handle_mark_nesting > 0, "must stack allocate HandleMarks" );
a61af66fc99e Initial load
duke
parents:
diff changeset
129 debug_only(area->_handle_mark_nesting--);
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // Debug code to trace the number of handles allocated per mark/
a61af66fc99e Initial load
duke
parents:
diff changeset
132 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (TraceHandleAllocation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 size_t handles = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 Chunk *c = _chunk->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if (c == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 handles = area->_hwm - _hwm; // no new chunk allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
138 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 handles = _max - _hwm; // add rest in first chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
140 while(c != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 handles += c->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
142 c = c->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 handles -= area->_max - area->_hwm; // adjust for last trunk not full
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 handles /= sizeof(void *); // Adjust for size of a handle
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (handles > HandleAllocationLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Note: _nof_handlemarks is only set in debug mode
a61af66fc99e Initial load
duke
parents:
diff changeset
149 warning("%d: Allocated in HandleMark : %d", _nof_handlemarks, handles);
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Delete later chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Roll back arena to saved top markers
a61af66fc99e Initial load
duke
parents:
diff changeset
167 area->_chunk = _chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 area->_hwm = _hwm;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 area->_max = _max;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // clear out first chunk (to detect allocation bugs)
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if (ZapVMHandleArea) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 memset(_hwm, badHandleValue, _max - _hwm);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 Atomic::dec(&_nof_handlemarks);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Unlink this from the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
179 _thread->set_last_handle_mark(previous_handle_mark());
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 NoHandleMark::NoHandleMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 HandleArea* area = Thread::current()->handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
186 area->_no_handle_mark_nesting++;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 NoHandleMark::~NoHandleMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 HandleArea* area = Thread::current()->handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
193 assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );
a61af66fc99e Initial load
duke
parents:
diff changeset
194 area->_no_handle_mark_nesting--;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 ResetNoHandleMark::ResetNoHandleMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 HandleArea* area = Thread::current()->handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _no_handle_mark_nesting = area->_no_handle_mark_nesting;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 area->_no_handle_mark_nesting = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 ResetNoHandleMark::~ResetNoHandleMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 HandleArea* area = Thread::current()->handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 area->_no_handle_mark_nesting = _no_handle_mark_nesting;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 #endif