Mercurial > hg > truffle
annotate src/share/vm/code/exceptionHandlerTable.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 78bbf4d43a14 |
children |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
1972
diff
changeset
|
2 * Copyright (c) 1998, 2014, 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:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
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:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/exceptionHandlerTable.hpp" | |
27 #include "code/nmethod.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
0 | 29 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
1972
diff
changeset
|
30 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
1972
diff
changeset
|
31 |
0 | 32 void ExceptionHandlerTable::add_entry(HandlerTableEntry entry) { |
33 _nesting.check(); | |
34 if (_length >= _size) { | |
35 // not enough space => grow the table (amortized growth, double its size) | |
36 guarantee(_size > 0, "no space allocated => cannot grow the table since it is part of nmethod"); | |
37 int new_size = _size * 2; | |
38 _table = REALLOC_RESOURCE_ARRAY(HandlerTableEntry, _table, _size, new_size); | |
39 _size = new_size; | |
40 } | |
41 assert(_length < _size, "sanity check"); | |
42 _table[_length++] = entry; | |
43 } | |
44 | |
45 | |
46 HandlerTableEntry* ExceptionHandlerTable::subtable_for(int catch_pco) const { | |
47 int i = 0; | |
48 while (i < _length) { | |
49 HandlerTableEntry* t = _table + i; | |
50 if (t->pco() == catch_pco) { | |
51 // found subtable matching the catch_pco | |
52 return t; | |
53 } else { | |
54 // advance to next subtable | |
55 i += t->len() + 1; // +1 for header | |
56 } | |
57 } | |
58 return NULL; | |
59 } | |
60 | |
61 | |
62 ExceptionHandlerTable::ExceptionHandlerTable(int initial_size) { | |
63 guarantee(initial_size > 0, "initial size must be > 0"); | |
64 _table = NEW_RESOURCE_ARRAY(HandlerTableEntry, initial_size); | |
65 _length = 0; | |
66 _size = initial_size; | |
67 } | |
68 | |
69 | |
70 ExceptionHandlerTable::ExceptionHandlerTable(const nmethod* nm) { | |
71 _table = (HandlerTableEntry*)nm->handler_table_begin(); | |
72 _length = nm->handler_table_size() / sizeof(HandlerTableEntry); | |
73 _size = 0; // no space allocated by ExeptionHandlerTable! | |
74 } | |
75 | |
76 | |
77 void ExceptionHandlerTable::add_subtable( | |
78 int catch_pco, | |
79 GrowableArray<intptr_t>* handler_bcis, | |
80 GrowableArray<intptr_t>* scope_depths_from_top_scope, | |
81 GrowableArray<intptr_t>* handler_pcos | |
82 ) { | |
83 assert(subtable_for(catch_pco) == NULL, "catch handlers for this catch_pco added twice"); | |
84 assert(handler_bcis->length() == handler_pcos->length(), "bci & pc table have different length"); | |
85 assert(scope_depths_from_top_scope == NULL || handler_bcis->length() == scope_depths_from_top_scope->length(), "bci & scope_depths table have different length"); | |
86 if (handler_bcis->length() > 0) { | |
87 // add subtable header | |
88 add_entry(HandlerTableEntry(handler_bcis->length(), catch_pco, 0)); | |
89 // add individual entries | |
90 for (int i = 0; i < handler_bcis->length(); i++) { | |
91 intptr_t scope_depth = 0; | |
92 if (scope_depths_from_top_scope != NULL) { | |
93 scope_depth = scope_depths_from_top_scope->at(i); | |
94 } | |
95 add_entry(HandlerTableEntry(handler_bcis->at(i), handler_pcos->at(i), scope_depth)); | |
96 assert(entry_for(catch_pco, handler_bcis->at(i), scope_depth)->pco() == handler_pcos->at(i), "entry not added correctly (1)"); | |
97 assert(entry_for(catch_pco, handler_bcis->at(i), scope_depth)->scope_depth() == scope_depth, "entry not added correctly (2)"); | |
98 } | |
99 } | |
100 } | |
101 | |
102 | |
103 void ExceptionHandlerTable::copy_to(nmethod* nm) { | |
104 assert(size_in_bytes() == nm->handler_table_size(), "size of space allocated in nmethod incorrect"); | |
105 memmove(nm->handler_table_begin(), _table, size_in_bytes()); | |
106 } | |
107 | |
108 | |
109 HandlerTableEntry* ExceptionHandlerTable::entry_for(int catch_pco, int handler_bci, int scope_depth) const { | |
110 HandlerTableEntry* t = subtable_for(catch_pco); | |
111 if (t != NULL) { | |
112 int l = t->len(); | |
113 while (l-- > 0) { | |
114 t++; | |
115 if (t->bci() == handler_bci && t->scope_depth() == scope_depth) return t; | |
116 } | |
117 } | |
118 return NULL; | |
119 } | |
120 | |
121 | |
122 void ExceptionHandlerTable::print_subtable(HandlerTableEntry* t) const { | |
123 int l = t->len(); | |
124 tty->print_cr("catch_pco = %d (%d entries)", t->pco(), l); | |
125 while (l-- > 0) { | |
126 t++; | |
127 tty->print_cr(" bci %d at scope depth %d -> pco %d", t->bci(), t->scope_depth(), t->pco()); | |
128 } | |
129 } | |
130 | |
131 | |
132 void ExceptionHandlerTable::print() const { | |
133 tty->print_cr("ExceptionHandlerTable (size = %d bytes)", size_in_bytes()); | |
134 int i = 0; | |
135 while (i < _length) { | |
136 HandlerTableEntry* t = _table + i; | |
137 print_subtable(t); | |
138 // advance to next subtable | |
139 i += t->len() + 1; // +1 for header | |
140 } | |
141 } | |
142 | |
143 void ExceptionHandlerTable::print_subtable_for(int catch_pco) const { | |
144 HandlerTableEntry* subtable = subtable_for(catch_pco); | |
145 | |
146 if( subtable != NULL ) { print_subtable( subtable ); } | |
147 } | |
148 | |
149 // ---------------------------------------------------------------------------- | |
150 // Implicit null exception tables. Maps an exception PC offset to a | |
151 // continuation PC offset. During construction it's a variable sized | |
152 // array with a max size and current length. When stored inside an | |
153 // nmethod a zero length table takes no space. This is detected by | |
154 // nul_chk_table_size() == 0. Otherwise the table has a length word | |
155 // followed by pairs of <excp-offset, const-offset>. | |
156 void ImplicitExceptionTable::set_size( uint size ) { | |
157 _size = size; | |
158 _data = NEW_RESOURCE_ARRAY(implicit_null_entry, (size*2)); | |
159 _len = 0; | |
160 } | |
161 | |
162 void ImplicitExceptionTable::append( uint exec_off, uint cont_off ) { | |
163 assert( (sizeof(implicit_null_entry) >= 4) || (exec_off < 65535), "" ); | |
164 assert( (sizeof(implicit_null_entry) >= 4) || (cont_off < 65535), "" ); | |
165 uint l = len(); | |
166 if (l == _size) { | |
167 uint old_size_in_elements = _size*2; | |
168 if (_size == 0) _size = 4; | |
169 _size *= 2; | |
170 uint new_size_in_elements = _size*2; | |
171 _data = REALLOC_RESOURCE_ARRAY(uint, _data, old_size_in_elements, new_size_in_elements); | |
172 } | |
173 *(adr(l) ) = exec_off; | |
174 *(adr(l)+1) = cont_off; | |
175 _len = l+1; | |
176 }; | |
177 | |
178 uint ImplicitExceptionTable::at( uint exec_off ) const { | |
179 uint l = len(); | |
180 for( uint i=0; i<l; i++ ) | |
181 if( *adr(i) == exec_off ) | |
182 return *(adr(i)+1); | |
183 return 0; // Failed to find any execption offset | |
184 } | |
185 | |
186 void ImplicitExceptionTable::print(address base) const { | |
187 tty->print("{"); | |
188 for( uint i=0; i<len(); i++ ) | |
189 tty->print("< "INTPTR_FORMAT", "INTPTR_FORMAT" > ",base + *adr(i), base + *(adr(i)+1)); | |
190 tty->print_cr("}"); | |
191 } | |
192 | |
193 ImplicitExceptionTable::ImplicitExceptionTable(const nmethod* nm) { | |
194 if (nm->nul_chk_table_size() == 0) { | |
195 _len = 0; | |
196 _data = NULL; | |
197 } else { | |
198 // the first word is the length if non-zero, so read it out and | |
199 // skip to the next word to get the table. | |
200 _data = (implicit_null_entry*)nm->nul_chk_table_begin(); | |
201 _len = _data[0]; | |
202 _data++; | |
203 } | |
204 _size = len(); | |
205 assert(size_in_bytes() <= nm->nul_chk_table_size(), "size of space allocated in nmethod incorrect"); | |
206 } | |
207 | |
208 void ImplicitExceptionTable::copy_to( nmethod* nm ) { | |
209 assert(size_in_bytes() <= nm->nul_chk_table_size(), "size of space allocated in nmethod incorrect"); | |
210 if (len() != 0) { | |
211 implicit_null_entry* nmdata = (implicit_null_entry*)nm->nul_chk_table_begin(); | |
212 // store the length in the first uint | |
213 nmdata[0] = _len; | |
214 nmdata++; | |
215 // copy the table after the length | |
216 memmove( nmdata, _data, 2 * len() * sizeof(implicit_null_entry)); | |
217 } else { | |
218 // zero length table takes zero bytes | |
219 assert(size_in_bytes() == 0, "bad size"); | |
220 assert(nm->nul_chk_table_size() == 0, "bad size"); | |
221 } | |
222 } | |
223 | |
224 void ImplicitExceptionTable::verify(nmethod *nm) const { | |
225 for (uint i = 0; i < len(); i++) { | |
1748 | 226 if ((*adr(i) > (unsigned int)nm->insts_size()) || |
227 (*(adr(i)+1) > (unsigned int)nm->insts_size())) | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
0
diff
changeset
|
228 fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data)); |
0 | 229 } |
230 } |