Mercurial > hg > graal-compiler
annotate src/share/vm/code/exceptionHandlerTable.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f95d63e2154a |
children | 78bbf4d43a14 |
rev | line source |
---|---|
0 | 1 /* |
1748 | 2 * Copyright (c) 1998, 2010, 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 |
30 void ExceptionHandlerTable::add_entry(HandlerTableEntry entry) { | |
31 _nesting.check(); | |
32 if (_length >= _size) { | |
33 // not enough space => grow the table (amortized growth, double its size) | |
34 guarantee(_size > 0, "no space allocated => cannot grow the table since it is part of nmethod"); | |
35 int new_size = _size * 2; | |
36 _table = REALLOC_RESOURCE_ARRAY(HandlerTableEntry, _table, _size, new_size); | |
37 _size = new_size; | |
38 } | |
39 assert(_length < _size, "sanity check"); | |
40 _table[_length++] = entry; | |
41 } | |
42 | |
43 | |
44 HandlerTableEntry* ExceptionHandlerTable::subtable_for(int catch_pco) const { | |
45 int i = 0; | |
46 while (i < _length) { | |
47 HandlerTableEntry* t = _table + i; | |
48 if (t->pco() == catch_pco) { | |
49 // found subtable matching the catch_pco | |
50 return t; | |
51 } else { | |
52 // advance to next subtable | |
53 i += t->len() + 1; // +1 for header | |
54 } | |
55 } | |
56 return NULL; | |
57 } | |
58 | |
59 | |
60 ExceptionHandlerTable::ExceptionHandlerTable(int initial_size) { | |
61 guarantee(initial_size > 0, "initial size must be > 0"); | |
62 _table = NEW_RESOURCE_ARRAY(HandlerTableEntry, initial_size); | |
63 _length = 0; | |
64 _size = initial_size; | |
65 } | |
66 | |
67 | |
68 ExceptionHandlerTable::ExceptionHandlerTable(const nmethod* nm) { | |
69 _table = (HandlerTableEntry*)nm->handler_table_begin(); | |
70 _length = nm->handler_table_size() / sizeof(HandlerTableEntry); | |
71 _size = 0; // no space allocated by ExeptionHandlerTable! | |
72 } | |
73 | |
74 | |
75 void ExceptionHandlerTable::add_subtable( | |
76 int catch_pco, | |
77 GrowableArray<intptr_t>* handler_bcis, | |
78 GrowableArray<intptr_t>* scope_depths_from_top_scope, | |
79 GrowableArray<intptr_t>* handler_pcos | |
80 ) { | |
81 assert(subtable_for(catch_pco) == NULL, "catch handlers for this catch_pco added twice"); | |
82 assert(handler_bcis->length() == handler_pcos->length(), "bci & pc table have different length"); | |
83 assert(scope_depths_from_top_scope == NULL || handler_bcis->length() == scope_depths_from_top_scope->length(), "bci & scope_depths table have different length"); | |
84 if (handler_bcis->length() > 0) { | |
85 // add subtable header | |
86 add_entry(HandlerTableEntry(handler_bcis->length(), catch_pco, 0)); | |
87 // add individual entries | |
88 for (int i = 0; i < handler_bcis->length(); i++) { | |
89 intptr_t scope_depth = 0; | |
90 if (scope_depths_from_top_scope != NULL) { | |
91 scope_depth = scope_depths_from_top_scope->at(i); | |
92 } | |
93 add_entry(HandlerTableEntry(handler_bcis->at(i), handler_pcos->at(i), scope_depth)); | |
94 assert(entry_for(catch_pco, handler_bcis->at(i), scope_depth)->pco() == handler_pcos->at(i), "entry not added correctly (1)"); | |
95 assert(entry_for(catch_pco, handler_bcis->at(i), scope_depth)->scope_depth() == scope_depth, "entry not added correctly (2)"); | |
96 } | |
97 } | |
98 } | |
99 | |
100 | |
101 void ExceptionHandlerTable::copy_to(nmethod* nm) { | |
102 assert(size_in_bytes() == nm->handler_table_size(), "size of space allocated in nmethod incorrect"); | |
103 memmove(nm->handler_table_begin(), _table, size_in_bytes()); | |
104 } | |
105 | |
106 | |
107 HandlerTableEntry* ExceptionHandlerTable::entry_for(int catch_pco, int handler_bci, int scope_depth) const { | |
108 HandlerTableEntry* t = subtable_for(catch_pco); | |
109 if (t != NULL) { | |
110 int l = t->len(); | |
111 while (l-- > 0) { | |
112 t++; | |
113 if (t->bci() == handler_bci && t->scope_depth() == scope_depth) return t; | |
114 } | |
115 } | |
116 return NULL; | |
117 } | |
118 | |
119 | |
120 void ExceptionHandlerTable::print_subtable(HandlerTableEntry* t) const { | |
121 int l = t->len(); | |
122 tty->print_cr("catch_pco = %d (%d entries)", t->pco(), l); | |
123 while (l-- > 0) { | |
124 t++; | |
125 tty->print_cr(" bci %d at scope depth %d -> pco %d", t->bci(), t->scope_depth(), t->pco()); | |
126 } | |
127 } | |
128 | |
129 | |
130 void ExceptionHandlerTable::print() const { | |
131 tty->print_cr("ExceptionHandlerTable (size = %d bytes)", size_in_bytes()); | |
132 int i = 0; | |
133 while (i < _length) { | |
134 HandlerTableEntry* t = _table + i; | |
135 print_subtable(t); | |
136 // advance to next subtable | |
137 i += t->len() + 1; // +1 for header | |
138 } | |
139 } | |
140 | |
141 void ExceptionHandlerTable::print_subtable_for(int catch_pco) const { | |
142 HandlerTableEntry* subtable = subtable_for(catch_pco); | |
143 | |
144 if( subtable != NULL ) { print_subtable( subtable ); } | |
145 } | |
146 | |
147 // ---------------------------------------------------------------------------- | |
148 // Implicit null exception tables. Maps an exception PC offset to a | |
149 // continuation PC offset. During construction it's a variable sized | |
150 // array with a max size and current length. When stored inside an | |
151 // nmethod a zero length table takes no space. This is detected by | |
152 // nul_chk_table_size() == 0. Otherwise the table has a length word | |
153 // followed by pairs of <excp-offset, const-offset>. | |
154 void ImplicitExceptionTable::set_size( uint size ) { | |
155 _size = size; | |
156 _data = NEW_RESOURCE_ARRAY(implicit_null_entry, (size*2)); | |
157 _len = 0; | |
158 } | |
159 | |
160 void ImplicitExceptionTable::append( uint exec_off, uint cont_off ) { | |
161 assert( (sizeof(implicit_null_entry) >= 4) || (exec_off < 65535), "" ); | |
162 assert( (sizeof(implicit_null_entry) >= 4) || (cont_off < 65535), "" ); | |
163 uint l = len(); | |
164 if (l == _size) { | |
165 uint old_size_in_elements = _size*2; | |
166 if (_size == 0) _size = 4; | |
167 _size *= 2; | |
168 uint new_size_in_elements = _size*2; | |
169 _data = REALLOC_RESOURCE_ARRAY(uint, _data, old_size_in_elements, new_size_in_elements); | |
170 } | |
171 *(adr(l) ) = exec_off; | |
172 *(adr(l)+1) = cont_off; | |
173 _len = l+1; | |
174 }; | |
175 | |
176 uint ImplicitExceptionTable::at( uint exec_off ) const { | |
177 uint l = len(); | |
178 for( uint i=0; i<l; i++ ) | |
179 if( *adr(i) == exec_off ) | |
180 return *(adr(i)+1); | |
181 return 0; // Failed to find any execption offset | |
182 } | |
183 | |
184 void ImplicitExceptionTable::print(address base) const { | |
185 tty->print("{"); | |
186 for( uint i=0; i<len(); i++ ) | |
187 tty->print("< "INTPTR_FORMAT", "INTPTR_FORMAT" > ",base + *adr(i), base + *(adr(i)+1)); | |
188 tty->print_cr("}"); | |
189 } | |
190 | |
191 ImplicitExceptionTable::ImplicitExceptionTable(const nmethod* nm) { | |
192 if (nm->nul_chk_table_size() == 0) { | |
193 _len = 0; | |
194 _data = NULL; | |
195 } else { | |
196 // the first word is the length if non-zero, so read it out and | |
197 // skip to the next word to get the table. | |
198 _data = (implicit_null_entry*)nm->nul_chk_table_begin(); | |
199 _len = _data[0]; | |
200 _data++; | |
201 } | |
202 _size = len(); | |
203 assert(size_in_bytes() <= nm->nul_chk_table_size(), "size of space allocated in nmethod incorrect"); | |
204 } | |
205 | |
206 void ImplicitExceptionTable::copy_to( nmethod* nm ) { | |
207 assert(size_in_bytes() <= nm->nul_chk_table_size(), "size of space allocated in nmethod incorrect"); | |
208 if (len() != 0) { | |
209 implicit_null_entry* nmdata = (implicit_null_entry*)nm->nul_chk_table_begin(); | |
210 // store the length in the first uint | |
211 nmdata[0] = _len; | |
212 nmdata++; | |
213 // copy the table after the length | |
214 memmove( nmdata, _data, 2 * len() * sizeof(implicit_null_entry)); | |
215 } else { | |
216 // zero length table takes zero bytes | |
217 assert(size_in_bytes() == 0, "bad size"); | |
218 assert(nm->nul_chk_table_size() == 0, "bad size"); | |
219 } | |
220 } | |
221 | |
222 void ImplicitExceptionTable::verify(nmethod *nm) const { | |
223 for (uint i = 0; i < len(); i++) { | |
1748 | 224 if ((*adr(i) > (unsigned int)nm->insts_size()) || |
225 (*(adr(i)+1) > (unsigned int)nm->insts_size())) | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
0
diff
changeset
|
226 fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data)); |
0 | 227 } |
228 } |