Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vframe.cpp @ 3917:eca1193ca245
4965777: GC changes to support use of discovered field for pending references
Summary: If and when the reference handler thread is able to use the discovered field to link reference objects in its pending list, so will GC. In that case, GC will scan through this field once a reference object has been placed on the pending list, but not scan that field before that stage, as the field is used by the concurrent GC thread to link discovered objects. When ReferenceHandleR thread does not use the discovered field for the purpose of linking the elements in the pending list, as would be the case in older JDKs, the JVM will fall back to the old behaviour of using the next field for that purpose.
Reviewed-by: jcoomes, mchung, stefank
author | ysr |
---|---|
date | Wed, 07 Sep 2011 13:55:42 -0700 |
parents | 1d1603768966 |
children | 0654ee04b214 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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:
1547
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
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:
1547
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "classfile/vmSymbols.hpp" | |
29 #include "code/codeCache.hpp" | |
30 #include "code/debugInfoRec.hpp" | |
31 #include "code/nmethod.hpp" | |
32 #include "code/pcDesc.hpp" | |
33 #include "code/scopeDesc.hpp" | |
34 #include "interpreter/interpreter.hpp" | |
35 #include "interpreter/oopMapCache.hpp" | |
36 #include "memory/resourceArea.hpp" | |
37 #include "oops/instanceKlass.hpp" | |
38 #include "oops/oop.inline.hpp" | |
39 #include "runtime/handles.inline.hpp" | |
40 #include "runtime/objectMonitor.hpp" | |
41 #include "runtime/objectMonitor.inline.hpp" | |
42 #include "runtime/signature.hpp" | |
43 #include "runtime/stubRoutines.hpp" | |
44 #include "runtime/synchronizer.hpp" | |
45 #include "runtime/vframe.hpp" | |
46 #include "runtime/vframeArray.hpp" | |
47 #include "runtime/vframe_hp.hpp" | |
0 | 48 |
49 vframe::vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) | |
50 : _reg_map(reg_map), _thread(thread) { | |
51 assert(fr != NULL, "must have frame"); | |
52 _fr = *fr; | |
53 } | |
54 | |
55 vframe::vframe(const frame* fr, JavaThread* thread) | |
56 : _reg_map(thread), _thread(thread) { | |
57 assert(fr != NULL, "must have frame"); | |
58 _fr = *fr; | |
59 } | |
60 | |
61 vframe* vframe::new_vframe(const frame* f, const RegisterMap* reg_map, JavaThread* thread) { | |
62 // Interpreter frame | |
63 if (f->is_interpreted_frame()) { | |
64 return new interpretedVFrame(f, reg_map, thread); | |
65 } | |
66 | |
67 // Compiled frame | |
68 CodeBlob* cb = f->cb(); | |
69 if (cb != NULL) { | |
70 if (cb->is_nmethod()) { | |
71 nmethod* nm = (nmethod*)cb; | |
72 return new compiledVFrame(f, reg_map, thread, nm); | |
73 } | |
74 | |
75 if (f->is_runtime_frame()) { | |
76 // Skip this frame and try again. | |
77 RegisterMap temp_map = *reg_map; | |
78 frame s = f->sender(&temp_map); | |
79 return new_vframe(&s, &temp_map, thread); | |
80 } | |
81 } | |
82 | |
83 // External frame | |
84 return new externalVFrame(f, reg_map, thread); | |
85 } | |
86 | |
87 vframe* vframe::sender() const { | |
88 RegisterMap temp_map = *register_map(); | |
89 assert(is_top(), "just checking"); | |
90 if (_fr.is_entry_frame() && _fr.is_first_frame()) return NULL; | |
91 frame s = _fr.real_sender(&temp_map); | |
92 if (s.is_first_frame()) return NULL; | |
93 return vframe::new_vframe(&s, &temp_map, thread()); | |
94 } | |
95 | |
96 vframe* vframe::top() const { | |
97 vframe* vf = (vframe*) this; | |
98 while (!vf->is_top()) vf = vf->sender(); | |
99 return vf; | |
100 } | |
101 | |
102 | |
103 javaVFrame* vframe::java_sender() const { | |
104 vframe* f = sender(); | |
105 while (f != NULL) { | |
106 if (f->is_java_frame()) return javaVFrame::cast(f); | |
107 f = f->sender(); | |
108 } | |
109 return NULL; | |
110 } | |
111 | |
112 // ------------- javaVFrame -------------- | |
113 | |
114 GrowableArray<MonitorInfo*>* javaVFrame::locked_monitors() { | |
115 assert(SafepointSynchronize::is_at_safepoint() || JavaThread::current() == thread(), | |
116 "must be at safepoint or it's a java frame of the current thread"); | |
117 | |
118 GrowableArray<MonitorInfo*>* mons = monitors(); | |
119 GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(mons->length()); | |
120 if (mons->is_empty()) return result; | |
121 | |
122 bool found_first_monitor = false; | |
123 ObjectMonitor *pending_monitor = thread()->current_pending_monitor(); | |
124 ObjectMonitor *waiting_monitor = thread()->current_waiting_monitor(); | |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1506
diff
changeset
|
125 oop pending_obj = (pending_monitor != NULL ? (oop) pending_monitor->object() : (oop) NULL); |
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1506
diff
changeset
|
126 oop waiting_obj = (waiting_monitor != NULL ? (oop) waiting_monitor->object() : (oop) NULL); |
0 | 127 |
128 for (int index = (mons->length()-1); index >= 0; index--) { | |
129 MonitorInfo* monitor = mons->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
130 if (monitor->eliminated() && is_compiled_frame()) continue; // skip eliminated monitor |
0 | 131 oop obj = monitor->owner(); |
132 if (obj == NULL) continue; // skip unowned monitor | |
133 // | |
134 // Skip the monitor that the thread is blocked to enter or waiting on | |
135 // | |
136 if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) { | |
137 continue; | |
138 } | |
139 found_first_monitor = true; | |
140 result->append(monitor); | |
141 } | |
142 return result; | |
143 } | |
144 | |
145 static void print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state) { | |
146 if (obj.not_null()) { | |
147 st->print("\t- %s <" INTPTR_FORMAT "> ", lock_state, (address)obj()); | |
1142 | 148 if (obj->klass() == SystemDictionary::Class_klass()) { |
0 | 149 klassOop target_klass = java_lang_Class::as_klassOop(obj()); |
150 st->print_cr("(a java.lang.Class for %s)", instanceKlass::cast(target_klass)->external_name()); | |
151 } else { | |
152 Klass* k = Klass::cast(obj->klass()); | |
153 st->print_cr("(a %s)", k->external_name()); | |
154 } | |
155 } | |
156 } | |
157 | |
158 void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) { | |
159 ResourceMark rm; | |
160 | |
161 // If this is the first frame, and java.lang.Object.wait(...) then print out the receiver. | |
162 if (frame_count == 0) { | |
163 if (method()->name() == vmSymbols::wait_name() && | |
164 instanceKlass::cast(method()->method_holder())->name() == vmSymbols::java_lang_Object()) { | |
165 StackValueCollection* locs = locals(); | |
166 if (!locs->is_empty()) { | |
167 StackValue* sv = locs->at(0); | |
168 if (sv->type() == T_OBJECT) { | |
169 Handle o = locs->at(0)->get_obj(); | |
170 print_locked_object_class_name(st, o, "waiting on"); | |
171 } | |
172 } | |
173 } else if (thread()->current_park_blocker() != NULL) { | |
174 oop obj = thread()->current_park_blocker(); | |
175 Klass* k = Klass::cast(obj->klass()); | |
176 st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", (address)obj, k->external_name()); | |
177 } | |
178 } | |
179 | |
180 | |
181 // Print out all monitors that we have locked or are trying to lock | |
182 GrowableArray<MonitorInfo*>* mons = monitors(); | |
183 if (!mons->is_empty()) { | |
184 bool found_first_monitor = false; | |
185 for (int index = (mons->length()-1); index >= 0; index--) { | |
186 MonitorInfo* monitor = mons->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
187 if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
188 if (monitor->owner_is_scalar_replaced()) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
189 Klass* k = Klass::cast(monitor->owner_klass()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
190 st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
191 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
192 oop obj = monitor->owner(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
193 if (obj != NULL) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
194 print_locked_object_class_name(st, obj, "eliminated"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
195 } |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
196 } |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
197 continue; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
198 } |
0 | 199 if (monitor->owner() != NULL) { |
200 | |
201 // First, assume we have the monitor locked. If we haven't found an | |
202 // owned monitor before and this is the first frame, then we need to | |
203 // see if we have completed the lock or we are blocked trying to | |
204 // acquire it - we can only be blocked if the monitor is inflated | |
205 | |
206 const char *lock_state = "locked"; // assume we have the monitor locked | |
207 if (!found_first_monitor && frame_count == 0) { | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
208 markOop mark = monitor->owner()->mark(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
209 if (mark->has_monitor() && |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
210 mark->monitor() == thread()->current_pending_monitor()) { |
0 | 211 lock_state = "waiting to lock"; |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
212 } |
0 | 213 } |
214 | |
215 found_first_monitor = true; | |
216 print_locked_object_class_name(st, monitor->owner(), lock_state); | |
217 } | |
218 } | |
219 } | |
220 } | |
221 | |
222 // ------------- interpretedVFrame -------------- | |
223 | |
224 u_char* interpretedVFrame::bcp() const { | |
225 return fr().interpreter_frame_bcp(); | |
226 } | |
227 | |
228 void interpretedVFrame::set_bcp(u_char* bcp) { | |
229 fr().interpreter_frame_set_bcp(bcp); | |
230 } | |
231 | |
232 intptr_t* interpretedVFrame::locals_addr_at(int offset) const { | |
233 assert(fr().is_interpreted_frame(), "frame should be an interpreted frame"); | |
234 return fr().interpreter_frame_local_at(offset); | |
235 } | |
236 | |
237 | |
238 GrowableArray<MonitorInfo*>* interpretedVFrame::monitors() const { | |
239 GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(5); | |
240 for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin())); | |
241 current >= fr().interpreter_frame_monitor_end(); | |
242 current = fr().previous_monitor_in_interpreter_frame(current)) { | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
243 result->push(new MonitorInfo(current->obj(), current->lock(), false, false)); |
0 | 244 } |
245 return result; | |
246 } | |
247 | |
248 int interpretedVFrame::bci() const { | |
249 return method()->bci_from(bcp()); | |
250 } | |
251 | |
252 methodOop interpretedVFrame::method() const { | |
253 return fr().interpreter_frame_method(); | |
254 } | |
255 | |
256 StackValueCollection* interpretedVFrame::locals() const { | |
257 int length = method()->max_locals(); | |
258 | |
259 if (method()->is_native()) { | |
260 // If the method is native, max_locals is not telling the truth. | |
261 // maxlocals then equals the size of parameters | |
262 length = method()->size_of_parameters(); | |
263 } | |
264 | |
265 StackValueCollection* result = new StackValueCollection(length); | |
266 | |
267 // Get oopmap describing oops and int for current bci | |
1506 | 268 InterpreterOopMap oop_mask; |
269 if (TraceDeoptimization && Verbose) { | |
270 methodHandle m_h(thread(), method()); | |
271 OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); | |
0 | 272 } else { |
1506 | 273 method()->mask_for(bci(), &oop_mask); |
274 } | |
275 // handle locals | |
276 for(int i=0; i < length; i++) { | |
277 // Find stack location | |
278 intptr_t *addr = locals_addr_at(i); | |
0 | 279 |
1506 | 280 // Depending on oop/int put it in the right package |
281 StackValue *sv; | |
282 if (oop_mask.is_oop(i)) { | |
283 // oop value | |
284 Handle h(*(oop *)addr); | |
285 sv = new StackValue(h); | |
286 } else { | |
287 // integer | |
288 sv = new StackValue(*addr); | |
0 | 289 } |
1506 | 290 assert(sv != NULL, "sanity check"); |
291 result->add(sv); | |
0 | 292 } |
293 return result; | |
294 } | |
295 | |
296 void interpretedVFrame::set_locals(StackValueCollection* values) const { | |
297 if (values == NULL || values->size() == 0) return; | |
298 | |
299 int length = method()->max_locals(); | |
300 if (method()->is_native()) { | |
301 // If the method is native, max_locals is not telling the truth. | |
302 // maxlocals then equals the size of parameters | |
303 length = method()->size_of_parameters(); | |
304 } | |
305 | |
306 assert(length == values->size(), "Mismatch between actual stack format and supplied data"); | |
307 | |
308 // handle locals | |
309 for (int i = 0; i < length; i++) { | |
310 // Find stack location | |
311 intptr_t *addr = locals_addr_at(i); | |
312 | |
313 // Depending on oop/int put it in the right package | |
314 StackValue *sv = values->at(i); | |
315 assert(sv != NULL, "sanity check"); | |
316 if (sv->type() == T_OBJECT) { | |
317 *(oop *) addr = (sv->get_obj())(); | |
318 } else { // integer | |
319 *addr = sv->get_int(); | |
320 } | |
321 } | |
322 } | |
323 | |
324 StackValueCollection* interpretedVFrame::expressions() const { | |
325 int length = fr().interpreter_frame_expression_stack_size(); | |
326 if (method()->is_native()) { | |
327 // If the method is native, there is no expression stack | |
328 length = 0; | |
329 } | |
330 | |
331 int nof_locals = method()->max_locals(); | |
332 StackValueCollection* result = new StackValueCollection(length); | |
333 | |
1506 | 334 InterpreterOopMap oop_mask; |
335 // Get oopmap describing oops and int for current bci | |
336 if (TraceDeoptimization && Verbose) { | |
337 methodHandle m_h(method()); | |
338 OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); | |
0 | 339 } else { |
1506 | 340 method()->mask_for(bci(), &oop_mask); |
341 } | |
342 // handle expressions | |
343 for(int i=0; i < length; i++) { | |
344 // Find stack location | |
345 intptr_t *addr = fr().interpreter_frame_expression_stack_at(i); | |
0 | 346 |
1506 | 347 // Depending on oop/int put it in the right package |
348 StackValue *sv; | |
349 if (oop_mask.is_oop(i + nof_locals)) { | |
350 // oop value | |
351 Handle h(*(oop *)addr); | |
352 sv = new StackValue(h); | |
353 } else { | |
354 // integer | |
355 sv = new StackValue(*addr); | |
0 | 356 } |
1506 | 357 assert(sv != NULL, "sanity check"); |
358 result->add(sv); | |
0 | 359 } |
360 return result; | |
361 } | |
362 | |
363 | |
364 // ------------- cChunk -------------- | |
365 | |
366 entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) | |
367 : externalVFrame(fr, reg_map, thread) {} | |
368 | |
369 | |
370 void vframeStreamCommon::found_bad_method_frame() { | |
371 // 6379830 Cut point for an assertion that occasionally fires when | |
372 // we are using the performance analyzer. | |
373 // Disable this assert when testing the analyzer with fastdebug. | |
374 // -XX:SuppressErrorAt=vframe.cpp:XXX (XXX=following line number) | |
375 assert(false, "invalid bci or invalid scope desc"); | |
376 } | |
377 | |
378 // top-frame will be skipped | |
379 vframeStream::vframeStream(JavaThread* thread, frame top_frame, | |
380 bool stop_at_java_call_stub) : vframeStreamCommon(thread) { | |
381 _stop_at_java_call_stub = stop_at_java_call_stub; | |
382 | |
383 // skip top frame, as it may not be at safepoint | |
384 _frame = top_frame.sender(&_reg_map); | |
385 while (!fill_from_frame()) { | |
386 _frame = _frame.sender(&_reg_map); | |
387 } | |
388 } | |
389 | |
390 | |
391 // Step back n frames, skip any pseudo frames in between. | |
392 // This function is used in Class.forName, Class.newInstance, Method.Invoke, | |
393 // AccessController.doPrivileged. | |
394 // | |
395 // NOTE that in JDK 1.4 this has been exposed to Java as | |
396 // sun.reflect.Reflection.getCallerClass(), which can be inlined. | |
397 // Inlined versions must match this routine's logic. | |
398 // Native method prefixing logic does not need to match since | |
399 // the method names don't match and inlining will not occur. | |
400 // See, for example, | |
401 // Parse::inline_native_Reflection_getCallerClass in | |
402 // opto/library_call.cpp. | |
403 void vframeStreamCommon::security_get_caller_frame(int depth) { | |
404 bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; | |
405 | |
406 while (!at_end()) { | |
407 if (Universe::reflect_invoke_cache()->is_same_method(method())) { | |
408 // This is Method.invoke() -- skip it | |
409 } else if (use_new_reflection && | |
410 Klass::cast(method()->method_holder()) | |
1142 | 411 ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { |
0 | 412 // This is an auxilary frame -- skip it |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
413 } else if (method()->is_method_handle_adapter()) { |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
414 // This is an internal adapter frame from the MethodHandleCompiler -- skip it |
0 | 415 } else { |
416 // This is non-excluded frame, we need to count it against the depth | |
417 if (depth-- <= 0) { | |
418 // we have reached the desired depth, we are done | |
419 break; | |
420 } | |
421 } | |
422 if (method()->is_prefixed_native()) { | |
423 skip_prefixed_method_and_wrappers(); | |
424 } else { | |
425 next(); | |
426 } | |
427 } | |
428 } | |
429 | |
430 | |
431 void vframeStreamCommon::skip_prefixed_method_and_wrappers() { | |
432 ResourceMark rm; | |
433 HandleMark hm; | |
434 | |
435 int method_prefix_count = 0; | |
436 char** method_prefixes = JvmtiExport::get_all_native_method_prefixes(&method_prefix_count); | |
437 KlassHandle prefixed_klass(method()->method_holder()); | |
438 const char* prefixed_name = method()->name()->as_C_string(); | |
439 size_t prefixed_name_len = strlen(prefixed_name); | |
440 int prefix_index = method_prefix_count-1; | |
441 | |
442 while (!at_end()) { | |
443 next(); | |
444 if (method()->method_holder() != prefixed_klass()) { | |
445 break; // classes don't match, can't be a wrapper | |
446 } | |
447 const char* name = method()->name()->as_C_string(); | |
448 size_t name_len = strlen(name); | |
449 size_t prefix_len = prefixed_name_len - name_len; | |
450 if (prefix_len <= 0 || strcmp(name, prefixed_name + prefix_len) != 0) { | |
451 break; // prefixed name isn't prefixed version of method name, can't be a wrapper | |
452 } | |
453 for (; prefix_index >= 0; --prefix_index) { | |
454 const char* possible_prefix = method_prefixes[prefix_index]; | |
455 size_t possible_prefix_len = strlen(possible_prefix); | |
456 if (possible_prefix_len == prefix_len && | |
457 strncmp(possible_prefix, prefixed_name, prefix_len) == 0) { | |
458 break; // matching prefix found | |
459 } | |
460 } | |
461 if (prefix_index < 0) { | |
462 break; // didn't find the prefix, can't be a wrapper | |
463 } | |
464 prefixed_name = name; | |
465 prefixed_name_len = name_len; | |
466 } | |
467 } | |
468 | |
469 | |
470 void vframeStreamCommon::skip_reflection_related_frames() { | |
471 while (!at_end() && | |
472 (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && | |
1142 | 473 (Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || |
474 Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { | |
0 | 475 next(); |
476 } | |
477 } | |
478 | |
479 | |
480 #ifndef PRODUCT | |
481 void vframe::print() { | |
482 if (WizardMode) _fr.print_value_on(tty,NULL); | |
483 } | |
484 | |
485 | |
486 void vframe::print_value() const { | |
487 ((vframe*)this)->print(); | |
488 } | |
489 | |
490 | |
491 void entryVFrame::print_value() const { | |
492 ((entryVFrame*)this)->print(); | |
493 } | |
494 | |
495 void entryVFrame::print() { | |
496 vframe::print(); | |
497 tty->print_cr("C Chunk inbetween Java"); | |
498 tty->print_cr("C link " INTPTR_FORMAT, _fr.link()); | |
499 } | |
500 | |
501 | |
502 // ------------- javaVFrame -------------- | |
503 | |
504 static void print_stack_values(const char* title, StackValueCollection* values) { | |
505 if (values->is_empty()) return; | |
506 tty->print_cr("\t%s:", title); | |
507 values->print(); | |
508 } | |
509 | |
510 | |
511 void javaVFrame::print() { | |
512 ResourceMark rm; | |
513 vframe::print(); | |
514 tty->print("\t"); | |
515 method()->print_value(); | |
516 tty->cr(); | |
517 tty->print_cr("\tbci: %d", bci()); | |
518 | |
519 print_stack_values("locals", locals()); | |
520 print_stack_values("expressions", expressions()); | |
521 | |
522 GrowableArray<MonitorInfo*>* list = monitors(); | |
523 if (list->is_empty()) return; | |
524 tty->print_cr("\tmonitor list:"); | |
525 for (int index = (list->length()-1); index >= 0; index--) { | |
526 MonitorInfo* monitor = list->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
527 tty->print("\t obj\t"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
528 if (monitor->owner_is_scalar_replaced()) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
529 Klass* k = Klass::cast(monitor->owner_klass()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
530 tty->print("( is scalar replaced %s)", k->external_name()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
531 } else if (monitor->owner() == NULL) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
532 tty->print("( null )"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
533 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
534 monitor->owner()->print_value(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
535 tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
536 } |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
537 if (monitor->eliminated() && is_compiled_frame()) |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
538 tty->print(" ( lock is eliminated )"); |
0 | 539 tty->cr(); |
540 tty->print("\t "); | |
541 monitor->lock()->print_on(tty); | |
542 tty->cr(); | |
543 } | |
544 } | |
545 | |
546 | |
547 void javaVFrame::print_value() const { | |
548 methodOop m = method(); | |
549 klassOop k = m->method_holder(); | |
550 tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", | |
551 _fr.sp(), _fr.unextended_sp(), _fr.fp(), _fr.pc()); | |
552 tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string()); | |
553 | |
554 if (!m->is_native()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
555 Symbol* source_name = instanceKlass::cast(k)->source_file_name(); |
0 | 556 int line_number = m->line_number_from_bci(bci()); |
557 if (source_name != NULL && (line_number != -1)) { | |
558 tty->print("(%s:%d)", source_name->as_C_string(), line_number); | |
559 } | |
560 } else { | |
561 tty->print("(Native Method)"); | |
562 } | |
563 // Check frame size and print warning if it looks suspiciously large | |
564 if (fr().sp() != NULL) { | |
793
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
196
diff
changeset
|
565 RegisterMap map = *register_map(); |
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
196
diff
changeset
|
566 uint size = fr().frame_size(&map); |
0 | 567 #ifdef _LP64 |
568 if (size > 8*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); | |
569 #else | |
570 if (size > 4*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); | |
571 #endif | |
572 } | |
573 } | |
574 | |
575 | |
576 bool javaVFrame::structural_compare(javaVFrame* other) { | |
577 // Check static part | |
578 if (method() != other->method()) return false; | |
579 if (bci() != other->bci()) return false; | |
580 | |
581 // Check locals | |
582 StackValueCollection *locs = locals(); | |
583 StackValueCollection *other_locs = other->locals(); | |
584 assert(locs->size() == other_locs->size(), "sanity check"); | |
585 int i; | |
586 for(i = 0; i < locs->size(); i++) { | |
587 // it might happen the compiler reports a conflict and | |
588 // the interpreter reports a bogus int. | |
589 if ( is_compiled_frame() && locs->at(i)->type() == T_CONFLICT) continue; | |
590 if (other->is_compiled_frame() && other_locs->at(i)->type() == T_CONFLICT) continue; | |
591 | |
592 if (!locs->at(i)->equal(other_locs->at(i))) | |
593 return false; | |
594 } | |
595 | |
596 // Check expressions | |
597 StackValueCollection* exprs = expressions(); | |
598 StackValueCollection* other_exprs = other->expressions(); | |
599 assert(exprs->size() == other_exprs->size(), "sanity check"); | |
600 for(i = 0; i < exprs->size(); i++) { | |
601 if (!exprs->at(i)->equal(other_exprs->at(i))) | |
602 return false; | |
603 } | |
604 | |
605 return true; | |
606 } | |
607 | |
608 | |
609 void javaVFrame::print_activation(int index) const { | |
610 // frame number and method | |
611 tty->print("%2d - ", index); | |
612 ((vframe*)this)->print_value(); | |
613 tty->cr(); | |
614 | |
615 if (WizardMode) { | |
616 ((vframe*)this)->print(); | |
617 tty->cr(); | |
618 } | |
619 } | |
620 | |
621 | |
622 void javaVFrame::verify() const { | |
623 } | |
624 | |
625 | |
626 void interpretedVFrame::verify() const { | |
627 } | |
628 | |
629 | |
630 // ------------- externalVFrame -------------- | |
631 | |
632 void externalVFrame::print() { | |
633 _fr.print_value_on(tty,NULL); | |
634 } | |
635 | |
636 | |
637 void externalVFrame::print_value() const { | |
638 ((vframe*)this)->print(); | |
639 } | |
640 #endif // PRODUCT |