Mercurial > hg > graal-compiler
annotate src/share/vm/code/scopeDesc.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 | 5857923e563c da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
1748 | 2 * Copyright (c) 1997, 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:
1253
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1253
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:
1253
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/debugInfoRec.hpp" | |
27 #include "code/pcDesc.hpp" | |
28 #include "code/scopeDesc.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "oops/oop.inline.hpp" | |
31 #include "runtime/handles.inline.hpp" | |
0 | 32 |
33 | |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
931
diff
changeset
|
34 ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { |
0 | 35 _code = code; |
36 _decode_offset = decode_offset; | |
37 _objects = decode_object_values(obj_decode_offset); | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
900
diff
changeset
|
38 _reexecute = reexecute; |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
931
diff
changeset
|
39 _return_oop = return_oop; |
0 | 40 decode_body(); |
41 } | |
42 | |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
931
diff
changeset
|
43 ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) { |
0 | 44 _code = code; |
45 _decode_offset = decode_offset; | |
46 _objects = decode_object_values(DebugInformationRecorder::serialized_null); | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
900
diff
changeset
|
47 _reexecute = reexecute; |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
931
diff
changeset
|
48 _return_oop = return_oop; |
0 | 49 decode_body(); |
50 } | |
51 | |
52 | |
53 ScopeDesc::ScopeDesc(const ScopeDesc* parent) { | |
54 _code = parent->_code; | |
55 _decode_offset = parent->_sender_decode_offset; | |
56 _objects = parent->_objects; | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
900
diff
changeset
|
57 _reexecute = false; //reexecute only applies to the first scope |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
931
diff
changeset
|
58 _return_oop = false; |
0 | 59 decode_body(); |
60 } | |
61 | |
62 | |
63 void ScopeDesc::decode_body() { | |
64 if (decode_offset() == DebugInformationRecorder::serialized_null) { | |
65 // This is a sentinel record, which is only relevant to | |
66 // approximate queries. Decode a reasonable frame. | |
67 _sender_decode_offset = DebugInformationRecorder::serialized_null; | |
68 _method = methodHandle(_code->method()); | |
69 _bci = InvocationEntryBci; | |
70 _locals_decode_offset = DebugInformationRecorder::serialized_null; | |
71 _expressions_decode_offset = DebugInformationRecorder::serialized_null; | |
72 _monitors_decode_offset = DebugInformationRecorder::serialized_null; | |
73 } else { | |
74 // decode header | |
75 DebugInfoReadStream* stream = stream_at(decode_offset()); | |
76 | |
77 _sender_decode_offset = stream->read_int(); | |
78 _method = methodHandle((methodOop) stream->read_oop()); | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
900
diff
changeset
|
79 _bci = stream->read_bci(); |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
196
diff
changeset
|
80 |
0 | 81 // decode offsets for body and sender |
82 _locals_decode_offset = stream->read_int(); | |
83 _expressions_decode_offset = stream->read_int(); | |
84 _monitors_decode_offset = stream->read_int(); | |
85 } | |
86 } | |
87 | |
88 | |
89 GrowableArray<ScopeValue*>* ScopeDesc::decode_scope_values(int decode_offset) { | |
90 if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; | |
91 DebugInfoReadStream* stream = stream_at(decode_offset); | |
92 int length = stream->read_int(); | |
93 GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*> (length); | |
94 for (int index = 0; index < length; index++) { | |
95 result->push(ScopeValue::read_from(stream)); | |
96 } | |
97 return result; | |
98 } | |
99 | |
100 GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) { | |
101 if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; | |
102 GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>(); | |
103 DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); | |
104 int length = stream->read_int(); | |
105 for (int index = 0; index < length; index++) { | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
106 // Objects values are pushed to 'result' array during read so that |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
107 // object's fields could reference it (OBJECT_ID_CODE). |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
108 (void)ScopeValue::read_from(stream); |
0 | 109 } |
110 assert(result->length() == length, "inconsistent debug information"); | |
111 return result; | |
112 } | |
113 | |
114 | |
115 GrowableArray<MonitorValue*>* ScopeDesc::decode_monitor_values(int decode_offset) { | |
116 if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; | |
117 DebugInfoReadStream* stream = stream_at(decode_offset); | |
118 int length = stream->read_int(); | |
119 GrowableArray<MonitorValue*>* result = new GrowableArray<MonitorValue*> (length); | |
120 for (int index = 0; index < length; index++) { | |
121 result->push(new MonitorValue(stream)); | |
122 } | |
123 return result; | |
124 } | |
125 | |
126 DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { | |
127 return new DebugInfoReadStream(_code, decode_offset, _objects); | |
128 } | |
129 | |
130 GrowableArray<ScopeValue*>* ScopeDesc::locals() { | |
131 return decode_scope_values(_locals_decode_offset); | |
132 } | |
133 | |
134 GrowableArray<ScopeValue*>* ScopeDesc::expressions() { | |
135 return decode_scope_values(_expressions_decode_offset); | |
136 } | |
137 | |
138 GrowableArray<MonitorValue*>* ScopeDesc::monitors() { | |
139 return decode_monitor_values(_monitors_decode_offset); | |
140 } | |
141 | |
142 GrowableArray<ScopeValue*>* ScopeDesc::objects() { | |
143 return _objects; | |
144 } | |
145 | |
146 bool ScopeDesc::is_top() const { | |
147 return _sender_decode_offset == DebugInformationRecorder::serialized_null; | |
148 } | |
149 | |
150 ScopeDesc* ScopeDesc::sender() const { | |
151 if (is_top()) return NULL; | |
152 return new ScopeDesc(this); | |
153 } | |
154 | |
155 | |
156 #ifndef PRODUCT | |
157 | |
158 void ScopeDesc::print_value_on(outputStream* st) const { | |
159 tty->print(" "); | |
160 method()()->print_short_name(st); | |
161 int lineno = method()->line_number_from_bci(bci()); | |
162 if (lineno != -1) { | |
163 st->print_cr("@%d (line %d)", bci(), lineno); | |
164 } else { | |
165 st->print_cr("@%d", bci()); | |
166 } | |
167 } | |
168 | |
169 void ScopeDesc::print_on(outputStream* st) const { | |
170 print_on(st, NULL); | |
171 } | |
172 | |
173 void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const { | |
174 // header | |
175 if (pd != NULL) { | |
176 tty->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset()); | |
177 } | |
178 | |
179 print_value_on(st); | |
180 // decode offsets | |
181 if (WizardMode) { | |
1748 | 182 st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->content_begin()); |
0 | 183 st->print_cr(" offset: %d", _decode_offset); |
184 st->print_cr(" bci: %d", bci()); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
196
diff
changeset
|
185 st->print_cr(" reexecute: %s", should_reexecute() ? "true" : "false"); |
0 | 186 st->print_cr(" locals: %d", _locals_decode_offset); |
187 st->print_cr(" stack: %d", _expressions_decode_offset); | |
188 st->print_cr(" monitor: %d", _monitors_decode_offset); | |
189 st->print_cr(" sender: %d", _sender_decode_offset); | |
190 } | |
191 // locals | |
192 { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals(); | |
193 if (l != NULL) { | |
194 tty->print_cr(" Locals"); | |
195 for (int index = 0; index < l->length(); index++) { | |
196 st->print(" - l%d: ", index); | |
197 l->at(index)->print_on(st); | |
198 st->cr(); | |
199 } | |
200 } | |
201 } | |
202 // expressions | |
203 { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions(); | |
204 if (l != NULL) { | |
205 st->print_cr(" Expression stack"); | |
206 for (int index = 0; index < l->length(); index++) { | |
207 st->print(" - @%d: ", index); | |
208 l->at(index)->print_on(st); | |
209 st->cr(); | |
210 } | |
211 } | |
212 } | |
213 // monitors | |
214 { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors(); | |
215 if (l != NULL) { | |
216 st->print_cr(" Monitor stack"); | |
217 for (int index = 0; index < l->length(); index++) { | |
218 st->print(" - @%d: ", index); | |
219 l->at(index)->print_on(st); | |
220 st->cr(); | |
221 } | |
222 } | |
223 } | |
224 | |
225 #ifdef COMPILER2 | |
226 if (DoEscapeAnalysis && is_top() && _objects != NULL) { | |
227 tty->print_cr("Objects"); | |
228 for (int i = 0; i < _objects->length(); i++) { | |
229 ObjectValue* sv = (ObjectValue*) _objects->at(i); | |
230 tty->print(" - %d: ", sv->id()); | |
231 sv->print_fields_on(tty); | |
232 tty->cr(); | |
233 } | |
234 } | |
235 #endif // COMPILER2 | |
236 } | |
237 | |
238 #endif | |
239 | |
240 void ScopeDesc::verify() { | |
241 ResourceMark rm; | |
242 guarantee(method()->is_method(), "type check"); | |
243 | |
244 // check if we have any illegal elements on the expression stack | |
245 { GrowableArray<ScopeValue*>* l = expressions(); | |
246 if (l != NULL) { | |
247 for (int index = 0; index < l->length(); index++) { | |
248 //guarantee(!l->at(index)->is_illegal(), "expression element cannot be illegal"); | |
249 } | |
250 } | |
251 } | |
252 } |