Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vframe.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | 16885e702c88 |
children | b9a918201d47 de6a9e811145 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2 * Copyright (c) 1997, 2012, 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()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
149 Klass* target_klass = java_lang_Class::as_Klass(obj()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
150 st->print_cr("(a java.lang.Class for %s)", InstanceKlass::cast(target_klass)->external_name()); |
0 | 151 } else { |
6983 | 152 Klass* k = obj->klass(); |
0 | 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() && | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
164 method()->method_holder()->name() == vmSymbols::java_lang_Object()) { |
0 | 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(); | |
6983 | 175 Klass* k = obj->klass(); |
0 | 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()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
189 Klass* k = java_lang_Class::as_Klass(monitor->owner_klass()); |
818
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 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
252 Method* interpretedVFrame::method() const { |
0 | 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 void vframeStreamCommon::security_get_caller_frame(int depth) { | |
8866
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
395 assert(depth >= 0, err_msg("invalid depth: %d", depth)); |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
396 for (int n = 0; !at_end(); security_next()) { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
397 if (!method()->is_ignored_by_security_stack_walk()) { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
398 if (n == depth) { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
399 // We have reached the desired depth; return. |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
400 return; |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
401 } |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
402 n++; // this is a non-skipped frame; count it against the depth |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
403 } |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
404 } |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
405 // NOTE: At this point there were not enough frames on the stack |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
406 // to walk to depth. Callers of this method have to check for at_end. |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
407 } |
0 | 408 |
8866
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
409 |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
410 void vframeStreamCommon::security_next() { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
411 if (method()->is_prefixed_native()) { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
412 skip_prefixed_method_and_wrappers(); // calls next() |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
413 } else { |
16885e702c88
7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents:
6983
diff
changeset
|
414 next(); |
0 | 415 } |
416 } | |
417 | |
418 | |
419 void vframeStreamCommon::skip_prefixed_method_and_wrappers() { | |
420 ResourceMark rm; | |
421 HandleMark hm; | |
422 | |
423 int method_prefix_count = 0; | |
424 char** method_prefixes = JvmtiExport::get_all_native_method_prefixes(&method_prefix_count); | |
425 KlassHandle prefixed_klass(method()->method_holder()); | |
426 const char* prefixed_name = method()->name()->as_C_string(); | |
427 size_t prefixed_name_len = strlen(prefixed_name); | |
428 int prefix_index = method_prefix_count-1; | |
429 | |
430 while (!at_end()) { | |
431 next(); | |
432 if (method()->method_holder() != prefixed_klass()) { | |
433 break; // classes don't match, can't be a wrapper | |
434 } | |
435 const char* name = method()->name()->as_C_string(); | |
436 size_t name_len = strlen(name); | |
437 size_t prefix_len = prefixed_name_len - name_len; | |
438 if (prefix_len <= 0 || strcmp(name, prefixed_name + prefix_len) != 0) { | |
439 break; // prefixed name isn't prefixed version of method name, can't be a wrapper | |
440 } | |
441 for (; prefix_index >= 0; --prefix_index) { | |
442 const char* possible_prefix = method_prefixes[prefix_index]; | |
443 size_t possible_prefix_len = strlen(possible_prefix); | |
444 if (possible_prefix_len == prefix_len && | |
445 strncmp(possible_prefix, prefixed_name, prefix_len) == 0) { | |
446 break; // matching prefix found | |
447 } | |
448 } | |
449 if (prefix_index < 0) { | |
450 break; // didn't find the prefix, can't be a wrapper | |
451 } | |
452 prefixed_name = name; | |
453 prefixed_name_len = name_len; | |
454 } | |
455 } | |
456 | |
457 | |
458 void vframeStreamCommon::skip_reflection_related_frames() { | |
459 while (!at_end() && | |
460 (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
461 (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || |
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
462 method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { |
0 | 463 next(); |
464 } | |
465 } | |
466 | |
467 | |
468 #ifndef PRODUCT | |
469 void vframe::print() { | |
470 if (WizardMode) _fr.print_value_on(tty,NULL); | |
471 } | |
472 | |
473 | |
474 void vframe::print_value() const { | |
475 ((vframe*)this)->print(); | |
476 } | |
477 | |
478 | |
479 void entryVFrame::print_value() const { | |
480 ((entryVFrame*)this)->print(); | |
481 } | |
482 | |
483 void entryVFrame::print() { | |
484 vframe::print(); | |
485 tty->print_cr("C Chunk inbetween Java"); | |
486 tty->print_cr("C link " INTPTR_FORMAT, _fr.link()); | |
487 } | |
488 | |
489 | |
490 // ------------- javaVFrame -------------- | |
491 | |
492 static void print_stack_values(const char* title, StackValueCollection* values) { | |
493 if (values->is_empty()) return; | |
494 tty->print_cr("\t%s:", title); | |
495 values->print(); | |
496 } | |
497 | |
498 | |
499 void javaVFrame::print() { | |
500 ResourceMark rm; | |
501 vframe::print(); | |
502 tty->print("\t"); | |
503 method()->print_value(); | |
504 tty->cr(); | |
505 tty->print_cr("\tbci: %d", bci()); | |
506 | |
507 print_stack_values("locals", locals()); | |
508 print_stack_values("expressions", expressions()); | |
509 | |
510 GrowableArray<MonitorInfo*>* list = monitors(); | |
511 if (list->is_empty()) return; | |
512 tty->print_cr("\tmonitor list:"); | |
513 for (int index = (list->length()-1); index >= 0; index--) { | |
514 MonitorInfo* monitor = list->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
515 tty->print("\t obj\t"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
516 if (monitor->owner_is_scalar_replaced()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
517 Klass* k = java_lang_Class::as_Klass(monitor->owner_klass()); |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
518 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
|
519 } else if (monitor->owner() == NULL) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
520 tty->print("( null )"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
521 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
522 monitor->owner()->print_value(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
523 tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
524 } |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
525 if (monitor->eliminated() && is_compiled_frame()) |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
793
diff
changeset
|
526 tty->print(" ( lock is eliminated )"); |
0 | 527 tty->cr(); |
528 tty->print("\t "); | |
529 monitor->lock()->print_on(tty); | |
530 tty->cr(); | |
531 } | |
532 } | |
533 | |
534 | |
535 void javaVFrame::print_value() const { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
536 Method* m = method(); |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
537 InstanceKlass* k = m->method_holder(); |
0 | 538 tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", |
539 _fr.sp(), _fr.unextended_sp(), _fr.fp(), _fr.pc()); | |
6983 | 540 tty->print("%s.%s", k->internal_name(), m->name()->as_C_string()); |
0 | 541 |
542 if (!m->is_native()) { | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
543 Symbol* source_name = k->source_file_name(); |
0 | 544 int line_number = m->line_number_from_bci(bci()); |
545 if (source_name != NULL && (line_number != -1)) { | |
546 tty->print("(%s:%d)", source_name->as_C_string(), line_number); | |
547 } | |
548 } else { | |
549 tty->print("(Native Method)"); | |
550 } | |
551 // Check frame size and print warning if it looks suspiciously large | |
552 if (fr().sp() != NULL) { | |
793
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
196
diff
changeset
|
553 RegisterMap map = *register_map(); |
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
196
diff
changeset
|
554 uint size = fr().frame_size(&map); |
0 | 555 #ifdef _LP64 |
556 if (size > 8*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); | |
557 #else | |
558 if (size > 4*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); | |
559 #endif | |
560 } | |
561 } | |
562 | |
563 | |
564 bool javaVFrame::structural_compare(javaVFrame* other) { | |
565 // Check static part | |
566 if (method() != other->method()) return false; | |
567 if (bci() != other->bci()) return false; | |
568 | |
569 // Check locals | |
570 StackValueCollection *locs = locals(); | |
571 StackValueCollection *other_locs = other->locals(); | |
572 assert(locs->size() == other_locs->size(), "sanity check"); | |
573 int i; | |
574 for(i = 0; i < locs->size(); i++) { | |
575 // it might happen the compiler reports a conflict and | |
576 // the interpreter reports a bogus int. | |
577 if ( is_compiled_frame() && locs->at(i)->type() == T_CONFLICT) continue; | |
578 if (other->is_compiled_frame() && other_locs->at(i)->type() == T_CONFLICT) continue; | |
579 | |
580 if (!locs->at(i)->equal(other_locs->at(i))) | |
581 return false; | |
582 } | |
583 | |
584 // Check expressions | |
585 StackValueCollection* exprs = expressions(); | |
586 StackValueCollection* other_exprs = other->expressions(); | |
587 assert(exprs->size() == other_exprs->size(), "sanity check"); | |
588 for(i = 0; i < exprs->size(); i++) { | |
589 if (!exprs->at(i)->equal(other_exprs->at(i))) | |
590 return false; | |
591 } | |
592 | |
593 return true; | |
594 } | |
595 | |
596 | |
597 void javaVFrame::print_activation(int index) const { | |
598 // frame number and method | |
599 tty->print("%2d - ", index); | |
600 ((vframe*)this)->print_value(); | |
601 tty->cr(); | |
602 | |
603 if (WizardMode) { | |
604 ((vframe*)this)->print(); | |
605 tty->cr(); | |
606 } | |
607 } | |
608 | |
609 | |
610 void javaVFrame::verify() const { | |
611 } | |
612 | |
613 | |
614 void interpretedVFrame::verify() const { | |
615 } | |
616 | |
617 | |
618 // ------------- externalVFrame -------------- | |
619 | |
620 void externalVFrame::print() { | |
621 _fr.print_value_on(tty,NULL); | |
622 } | |
623 | |
624 | |
625 void externalVFrame::print_value() const { | |
626 ((vframe*)this)->print(); | |
627 } | |
628 #endif // PRODUCT |