1 /* |
1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
176 // Note: this method returns true when a valid Java method is found |
176 // Note: this method returns true when a valid Java method is found |
177 // even if a valid BCI cannot be found. |
177 // even if a valid BCI cannot be found. |
178 |
178 |
179 static bool is_decipherable_interpreted_frame(JavaThread* thread, |
179 static bool is_decipherable_interpreted_frame(JavaThread* thread, |
180 frame* fr, |
180 frame* fr, |
181 methodOop* method_p, |
181 Method** method_p, |
182 int* bci_p) { |
182 int* bci_p) { |
183 assert(fr->is_interpreted_frame(), "just checking"); |
183 assert(fr->is_interpreted_frame(), "just checking"); |
184 |
184 |
185 // top frame is an interpreted frame |
185 // top frame is an interpreted frame |
186 // check if it is walkable (i.e. valid methodOop and valid bci) |
186 // check if it is walkable (i.e. valid Method* and valid bci) |
187 |
187 |
188 // Because we may be racing a gc thread the method and/or bci |
188 // Because we may be racing a gc thread the method and/or bci |
189 // of a valid interpreter frame may look bad causing us to |
189 // of a valid interpreter frame may look bad causing us to |
190 // fail the is_interpreted_frame_valid test. If the thread |
190 // fail the is_interpreted_frame_valid test. If the thread |
191 // is in any of the following states we are assured that the |
191 // is in any of the following states we are assured that the |
197 state == _thread_blocked ); |
197 state == _thread_blocked ); |
198 |
198 |
199 if (known_valid || fr->is_interpreted_frame_valid(thread)) { |
199 if (known_valid || fr->is_interpreted_frame_valid(thread)) { |
200 |
200 |
201 // The frame code should completely validate the frame so that |
201 // The frame code should completely validate the frame so that |
202 // references to methodOop and bci are completely safe to access |
202 // references to Method* and bci are completely safe to access |
203 // If they aren't the frame code should be fixed not this |
203 // If they aren't the frame code should be fixed not this |
204 // code. However since gc isn't locked out the values could be |
204 // code. However since gc isn't locked out the values could be |
205 // stale. This is a race we can never completely win since we can't |
205 // stale. This is a race we can never completely win since we can't |
206 // lock out gc so do one last check after retrieving their values |
206 // lock out gc so do one last check after retrieving their values |
207 // from the frame for additional safety |
207 // from the frame for additional safety |
208 |
208 |
209 methodOop method = fr->interpreter_frame_method(); |
209 Method* method = fr->interpreter_frame_method(); |
210 |
210 |
211 // We've at least found a method. |
211 // We've at least found a method. |
212 // NOTE: there is something to be said for the approach that |
212 // NOTE: there is something to be said for the approach that |
213 // if we don't find a valid bci then the method is not likely |
213 // if we don't find a valid bci then the method is not likely |
214 // a valid method. Then again we may have caught an interpreter |
214 // a valid method. Then again we may have caught an interpreter |
248 // |
248 // |
249 |
249 |
250 static bool find_initial_Java_frame(JavaThread* thread, |
250 static bool find_initial_Java_frame(JavaThread* thread, |
251 frame* fr, |
251 frame* fr, |
252 frame* initial_frame_p, |
252 frame* initial_frame_p, |
253 methodOop* method_p, |
253 Method** method_p, |
254 int* bci_p) { |
254 int* bci_p) { |
255 |
255 |
256 // It is possible that for a frame containing an nmethod |
256 // It is possible that for a frame containing an nmethod |
257 // we can capture the method but no bci. If we get no |
257 // we can capture the method but no bci. If we get no |
258 // bci the frame isn't walkable but the method is usable. |
258 // bci the frame isn't walkable but the method is usable. |
259 // Therefore we init the returned methodOop to NULL so the |
259 // Therefore we init the returned Method* to NULL so the |
260 // caller can make the distinction. |
260 // caller can make the distinction. |
261 |
261 |
262 *method_p = NULL; |
262 *method_p = NULL; |
263 |
263 |
264 // On the initial call to this method the frame we get may not be |
264 // On the initial call to this method the frame we get may not be |
400 |
400 |
401 CollectedHeap* ch = Universe::heap(); |
401 CollectedHeap* ch = Universe::heap(); |
402 |
402 |
403 // The method is not stored GC safe so see if GC became active |
403 // The method is not stored GC safe so see if GC became active |
404 // after we entered AsyncGetCallTrace() and before we try to |
404 // after we entered AsyncGetCallTrace() and before we try to |
405 // use the methodOop. |
405 // use the Method*. |
406 // Yes, there is still a window after this check and before |
406 // Yes, there is still a window after this check and before |
407 // we use methodOop below, but we can't lock out GC so that |
407 // we use Method* below, but we can't lock out GC so that |
408 // has to be an acceptable risk. |
408 // has to be an acceptable risk. |
409 if (!ch->is_valid_method(method)) { |
409 if (!ch->is_valid_method(method)) { |
410 trace->num_frames = ticks_GC_active; // -2 |
410 trace->num_frames = ticks_GC_active; // -2 |
411 return; |
411 return; |
412 } |
412 } |
440 bci = st.bci(); |
440 bci = st.bci(); |
441 method = st.method(); |
441 method = st.method(); |
442 |
442 |
443 // The method is not stored GC safe so see if GC became active |
443 // The method is not stored GC safe so see if GC became active |
444 // after we entered AsyncGetCallTrace() and before we try to |
444 // after we entered AsyncGetCallTrace() and before we try to |
445 // use the methodOop. |
445 // use the Method*. |
446 // Yes, there is still a window after this check and before |
446 // Yes, there is still a window after this check and before |
447 // we use methodOop below, but we can't lock out GC so that |
447 // we use Method* below, but we can't lock out GC so that |
448 // has to be an acceptable risk. |
448 // has to be an acceptable risk. |
449 if (!ch->is_valid_method(method)) { |
449 if (!ch->is_valid_method(method)) { |
450 // we throw away everything we've gathered in this sample since |
450 // we throw away everything we've gathered in this sample since |
451 // none of it is safe |
451 // none of it is safe |
452 trace->num_frames = ticks_GC_active; // -2 |
452 trace->num_frames = ticks_GC_active; // -2 |