src/share/vm/prims/forte.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8068945-8u-patched Sdiff src/share/vm/prims

src/share/vm/prims/forte.cpp

Print this page
rev 7386 : 8068945: Use RBP register as proper frame pointer in JIT compiled code on x86
Summary: Introduce the PreserveFramePointer flag to control if RBP is used as the frame pointer or as a general purpose register.
Reviewed-by: kvn, roland, dlong, enevill, shade


 155     // the actual pc reported by the frame.
 156     PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
 157 
 158     // Did we find a useful PcDesc?
 159     if (pc_desc != NULL &&
 160         pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {
 161       return true;
 162     }
 163   }
 164 
 165   // We're at some random pc in the nmethod so search for the PcDesc
 166   // whose pc is greater than the current PC.  It's done this way
 167   // because the extra PcDescs that are recorded for improved debug
 168   // info record the end of the region covered by the ScopeDesc
 169   // instead of the beginning.
 170   PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
 171 
 172   // Now do we have a useful PcDesc?
 173   if (pc_desc == NULL ||
 174       pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
 175     // No debug information available for this pc
 176     // vframeStream would explode if we try and walk the frames.



















 177     return false;
 178   }
 179 
 180   // This PcDesc is useful however we must adjust the frame's pc
 181   // so that the vframeStream lookups will use this same pc
 182   fr->set_pc(pc_desc->real_pc(nm));
 183   return true;
 184 }
 185 
 186 
 187 // Determine if 'fr' is a walkable interpreted frame. Returns false
 188 // if it is not. *method_p, and *bci_p are not set when false is
 189 // returned. *method_p is non-NULL if frame was executing a Java
 190 // method. *bci_p is != -1 if a valid BCI in the Java method could
 191 // be found.
 192 // Note: this method returns true when a valid Java method is found
 193 // even if a valid BCI cannot be found.
 194 
 195 static bool is_decipherable_interpreted_frame(JavaThread* thread,
 196                                               frame* fr,


 213                       state == _thread_blocked );
 214 
 215   if (known_valid || fr->is_interpreted_frame_valid(thread)) {
 216 
 217     // The frame code should completely validate the frame so that
 218     // references to Method* and bci are completely safe to access
 219     // If they aren't the frame code should be fixed not this
 220     // code. However since gc isn't locked out the values could be
 221     // stale. This is a race we can never completely win since we can't
 222     // lock out gc so do one last check after retrieving their values
 223     // from the frame for additional safety
 224 
 225     Method* method = fr->interpreter_frame_method();
 226 
 227     // We've at least found a method.
 228     // NOTE: there is something to be said for the approach that
 229     // if we don't find a valid bci then the method is not likely
 230     // a valid method. Then again we may have caught an interpreter
 231     // frame in the middle of construction and the bci field is
 232     // not yet valid.
 233 
 234     *method_p = method;
 235     if (!method->is_valid_method()) return false;



 236 
 237     intptr_t bcx = fr->interpreter_frame_bcx();
 238 
 239     int      bci = method->validate_bci_from_bcx(bcx);
 240 
 241     // note: bci is set to -1 if not a valid bci
 242     *bci_p = bci;
 243     return true;
 244   }
 245 
 246   return false;
 247 }
 248 
 249 
 250 // Determine if 'fr' can be used to find an initial Java frame.
 251 // Return false if it can not find a fully decipherable Java frame
 252 // (in other words a frame that isn't safe to use in a vframe stream).
 253 // Obviously if it can't even find a Java frame false will also be returned.
 254 //
 255 // If we find a Java frame decipherable or not then by definition we have
 256 // identified a method and that will be returned to the caller via method_p.
 257 // If we can determine a bci that is returned also. (Hmm is it possible
 258 // to return a method and bci and still return false? )




 259 //
 260 // The initial Java frame we find (if any) is return via initial_frame_p.
 261 //











 262 
 263 static bool find_initial_Java_frame(JavaThread* thread,
 264                                     frame* fr,
 265                                     frame* initial_frame_p,
 266                                     Method** method_p,
 267                                     int* bci_p) {
 268 
 269   // It is possible that for a frame containing an nmethod
 270   // we can capture the method but no bci. If we get no
 271   // bci the frame isn't walkable but the method is usable.
 272   // Therefore we init the returned Method* to NULL so the
 273   // caller can make the distinction.
 274 
 275   *method_p = NULL;
 276 
 277   // On the initial call to this method the frame we get may not be
 278   // recognizable to us. This should only happen if we are in a JRT_LEAF
 279   // or something called by a JRT_LEAF method.
 280 
 281 
 282 
 283   frame candidate = *fr;
 284 
 285   // If the starting frame we were given has no codeBlob associated with
 286   // it see if we can find such a frame because only frames with codeBlobs
 287   // are possible Java frames.
 288 
 289   if (fr->cb() == NULL) {
 290 
 291     // See if we can find a useful frame
 292     int loop_count;
 293     int loop_max = MaxJavaStackTraceDepth * 2;
 294     RegisterMap map(thread, false);
 295 
 296     for (loop_count = 0; loop_count < loop_max; loop_count++) {
 297       if (!candidate.safe_for_sender(thread)) return false;
 298       candidate = candidate.sender(&map);
 299       if (candidate.cb() != NULL) break;
 300     }
 301     if (candidate.cb() == NULL) return false;
 302   }


 317       if (jcw == NULL || jcw->is_first_frame()) {
 318         return false;
 319       }
 320     }
 321 
 322     if (candidate.is_interpreted_frame()) {
 323       if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {
 324         *initial_frame_p = candidate;
 325         return true;
 326       }
 327 
 328       // Hopefully we got some data
 329       return false;
 330     }
 331 
 332     if (candidate.cb()->is_nmethod()) {
 333 
 334       nmethod* nm = (nmethod*) candidate.cb();
 335       *method_p = nm->method();
 336 
 337       // If the frame isn't fully decipherable then the default
 338       // value for the bci is a signal that we don't have a bci.
 339       // If we have a decipherable frame this bci value will


 340       // not be used.
 341 
 342       *bci_p = -1;
 343 
 344       *initial_frame_p = candidate;
 345 
 346       // Native wrapper code is trivial to decode by vframeStream
 347 
 348       if (nm->is_native_method()) return true;
 349 
 350       // If it isn't decipherable then we have found a pc that doesn't
 351       // have a PCDesc that can get us a bci however we did find
 352       // a method
 353 
 354       if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
 355         return false;
 356       }
 357 
 358       // is_decipherable_compiled_frame may modify candidate's pc
 359       *initial_frame_p = candidate;
 360 
 361       assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid");
 362 
 363       return true;
 364     }
 365 
 366     // Must be some stub frame that we don't care about
 367 
 368     if (!candidate.safe_for_sender(thread)) return false;
 369     candidate = candidate.sender(&map);
 370 
 371     // If it isn't in the code cache something is wrong
 372     // since once we find a frame in the code cache they
 373     // all should be there.
 374 
 375     if (candidate.cb() == NULL) return false;
 376 
 377   }
 378 
 379   return false;
 380 
 381 }
 382 
 383 static void forte_fill_call_trace_given_top(JavaThread* thd,
 384                                             ASGCT_CallTrace* trace,
 385                                             int depth,
 386                                             frame top_frame) {
 387   NoHandleMark nhm;
 388 
 389   frame initial_Java_frame;
 390   Method* method;
 391   int bci;

 392   int count;
 393 
 394   count = 0;
 395   assert(trace->frames != NULL, "trace->frames must be non-NULL");
 396 
 397   bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
 398 
 399   // The frame might not be walkable but still recovered a method
 400   // (e.g. an nmethod with no scope info for the pc)
 401 

 402   if (method == NULL) return;
 403 
 404   if (!method->is_valid_method()) {
 405     trace->num_frames = ticks_GC_active; // -2
 406     return;
 407   }
 408 
 409   // We got a Java frame however it isn't fully decipherable
 410   // so it won't necessarily be safe to use it for the
 411   // initial frame in the vframe stream.
 412 
 413   if (!fully_decipherable) {
 414     // Take whatever method the top-frame decoder managed to scrape up.
 415     // We look further at the top frame only if non-safepoint
 416     // debugging information is available.
 417     count++;
 418     trace->num_frames = count;
 419     trace->frames[0].method_id = method->find_jmethod_id_or_null();
 420     if (!method->is_native()) {
 421       trace->frames[0].lineno = bci;
 422     } else {
 423       trace->frames[0].lineno = -3;
 424     }
 425 
 426     if (!initial_Java_frame.safe_for_sender(thd)) return;
 427 
 428     RegisterMap map(thd, false);
 429     initial_Java_frame = initial_Java_frame.sender(&map);
 430   }
 431 
 432   vframeStreamForte st(thd, initial_Java_frame, false);
 433 
 434   for (; !st.at_end() && count < depth; st.forte_next(), count++) {
 435     bci = st.bci();
 436     method = st.method();
 437 
 438     if (!method->is_valid_method()) {
 439       // we throw away everything we've gathered in this sample since
 440       // none of it is safe
 441       trace->num_frames = ticks_GC_active; // -2
 442       return;
 443     }
 444 
 445     trace->frames[count].method_id = method->find_jmethod_id_or_null();
 446     if (!method->is_native()) {
 447       trace->frames[count].lineno = bci;
 448     } else {
 449       trace->frames[count].lineno = -3;




 155     // the actual pc reported by the frame.
 156     PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
 157 
 158     // Did we find a useful PcDesc?
 159     if (pc_desc != NULL &&
 160         pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {
 161       return true;
 162     }
 163   }
 164 
 165   // We're at some random pc in the nmethod so search for the PcDesc
 166   // whose pc is greater than the current PC.  It's done this way
 167   // because the extra PcDescs that are recorded for improved debug
 168   // info record the end of the region covered by the ScopeDesc
 169   // instead of the beginning.
 170   PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
 171 
 172   // Now do we have a useful PcDesc?
 173   if (pc_desc == NULL ||
 174       pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
 175     // No debug information is available for this PC.
 176     //
 177     // vframeStreamCommon::fill_from_frame() will decode the frame depending
 178     // on the state of the thread.
 179     //
 180     // Case #1: If the thread is in Java (state == _thread_in_Java), then
 181     // the vframeStreamCommon object will be filled as if the frame were a native
 182     // compiled frame. Therefore, no debug information is needed.
 183     //
 184     // Case #2: If the thread is in any other state, then two steps will be performed:
 185     // - if asserts are enabled, found_bad_method_frame() will be called and
 186     //   the assert in found_bad_method_frame() will be triggered;
 187     // - if asserts are disabled, the vframeStreamCommon object will be filled
 188     //   as if it were a native compiled frame.
 189     //
 190     // Case (2) is similar to the way interpreter frames are processed in
 191     // vframeStreamCommon::fill_from_interpreter_frame in case no valid BCI
 192     // was found for an interpreted frame. If asserts are enabled, the assert
 193     // in found_bad_method_frame() will be triggered. If asserts are disabled,
 194     // the vframeStreamCommon object will be filled afterwards as if the
 195     // interpreter were at the point of entering into the method.
 196     return false;
 197   }
 198 
 199   // This PcDesc is useful however we must adjust the frame's pc
 200   // so that the vframeStream lookups will use this same pc
 201   fr->set_pc(pc_desc->real_pc(nm));
 202   return true;
 203 }
 204 
 205 
 206 // Determine if 'fr' is a walkable interpreted frame. Returns false
 207 // if it is not. *method_p, and *bci_p are not set when false is
 208 // returned. *method_p is non-NULL if frame was executing a Java
 209 // method. *bci_p is != -1 if a valid BCI in the Java method could
 210 // be found.
 211 // Note: this method returns true when a valid Java method is found
 212 // even if a valid BCI cannot be found.
 213 
 214 static bool is_decipherable_interpreted_frame(JavaThread* thread,
 215                                               frame* fr,


 232                       state == _thread_blocked );
 233 
 234   if (known_valid || fr->is_interpreted_frame_valid(thread)) {
 235 
 236     // The frame code should completely validate the frame so that
 237     // references to Method* and bci are completely safe to access
 238     // If they aren't the frame code should be fixed not this
 239     // code. However since gc isn't locked out the values could be
 240     // stale. This is a race we can never completely win since we can't
 241     // lock out gc so do one last check after retrieving their values
 242     // from the frame for additional safety
 243 
 244     Method* method = fr->interpreter_frame_method();
 245 
 246     // We've at least found a method.
 247     // NOTE: there is something to be said for the approach that
 248     // if we don't find a valid bci then the method is not likely
 249     // a valid method. Then again we may have caught an interpreter
 250     // frame in the middle of construction and the bci field is
 251     // not yet valid.


 252     if (!method->is_valid_method()) return false;
 253     *method_p = method; // If the Method* found is invalid, it is
 254                         // ignored by forte_fill_call_trace_given_top().
 255                         // So set method_p only if the Method is valid.
 256 
 257     intptr_t bcx = fr->interpreter_frame_bcx();
 258 
 259     int      bci = method->validate_bci_from_bcx(bcx);
 260 
 261     // note: bci is set to -1 if not a valid bci
 262     *bci_p = bci;
 263     return true;
 264   }
 265 
 266   return false;
 267 }
 268 
 269 
 270 // Determine if a Java frame can be found starting with the frame 'fr'.
 271 //
 272 // Check the return value of find_initial_Java_frame and the value of
 273 // 'method_p' to decide on how use the results returned by this method.
 274 //
 275 // If 'method_p' is not NULL, an initial Java frame has been found and
 276 // the stack can be walked starting from that initial frame. In this case,
 277 // 'method_p' points to the Method that the initial frame belongs to and
 278 // the initial Java frame is returned in initial_frame_p.
 279 //
 280 // find_initial_Java_frame() returns true if a Method has been found (i.e.,
 281 // 'method_p' is not NULL) and the initial frame that belongs to that Method
 282 // is decipherable.
 283 //
 284 // A frame is considered to be decipherable:
 285 //
 286 // - if the frame is a compiled frame and a PCDesc is available;
 287 //
 288 // - if the frame is an interpreter frame that is valid or the thread is
 289 //   state (_thread_in_native || state == _thread_in_vm || state == _thread_blocked).
 290 //
 291 // Note that find_initial_Java_frame() can return false even if an initial
 292 // Java method was found (e.g., there is no PCDesc available for the method).
 293 //
 294 // If 'method_p' is NULL, it was not possible to find a Java frame when
 295 // walking the stack starting from 'fr'. In this case find_initial_Java_frame
 296 // returns false.
 297 
 298 static bool find_initial_Java_frame(JavaThread* thread,
 299                                     frame* fr,
 300                                     frame* initial_frame_p,
 301                                     Method** method_p,
 302                                     int* bci_p) {
 303 
 304   // It is possible that for a frame containing an nmethod
 305   // we can capture the method but no bci. If we get no
 306   // bci the frame isn't walkable but the method is usable.
 307   // Therefore we init the returned Method* to NULL so the
 308   // caller can make the distinction.
 309 
 310   *method_p = NULL;
 311 
 312   // On the initial call to this method the frame we get may not be
 313   // recognizable to us. This should only happen if we are in a JRT_LEAF
 314   // or something called by a JRT_LEAF method.
 315 


 316   frame candidate = *fr;
 317 
 318   // If the starting frame we were given has no codeBlob associated with
 319   // it see if we can find such a frame because only frames with codeBlobs
 320   // are possible Java frames.
 321 
 322   if (fr->cb() == NULL) {
 323 
 324     // See if we can find a useful frame
 325     int loop_count;
 326     int loop_max = MaxJavaStackTraceDepth * 2;
 327     RegisterMap map(thread, false);
 328 
 329     for (loop_count = 0; loop_count < loop_max; loop_count++) {
 330       if (!candidate.safe_for_sender(thread)) return false;
 331       candidate = candidate.sender(&map);
 332       if (candidate.cb() != NULL) break;
 333     }
 334     if (candidate.cb() == NULL) return false;
 335   }


 350       if (jcw == NULL || jcw->is_first_frame()) {
 351         return false;
 352       }
 353     }
 354 
 355     if (candidate.is_interpreted_frame()) {
 356       if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {
 357         *initial_frame_p = candidate;
 358         return true;
 359       }
 360 
 361       // Hopefully we got some data
 362       return false;
 363     }
 364 
 365     if (candidate.cb()->is_nmethod()) {
 366 
 367       nmethod* nm = (nmethod*) candidate.cb();
 368       *method_p = nm->method();
 369 
 370       // If the frame is not decipherable, then the value of -1
 371       // for the BCI is used to signal that no BCI is available.
 372       // Furthermore, the method returns false in this case.
 373       //
 374       // If a decipherable frame is available, the BCI value will
 375       // not be used.
 376 
 377       *bci_p = -1;
 378 
 379       *initial_frame_p = candidate;
 380 
 381       // Native wrapper code is trivial to decode by vframeStream
 382 
 383       if (nm->is_native_method()) return true;
 384 
 385       // If the frame is not decipherable, then a PC was found
 386       // that does not have a PCDesc from which a BCI can be obtained.
 387       // Nevertheless, a Method was found.
 388 
 389       if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
 390         return false;
 391       }
 392 
 393       // is_decipherable_compiled_frame may modify candidate's pc
 394       *initial_frame_p = candidate;
 395 
 396       assert(nm->pc_desc_at(candidate.pc()) != NULL, "debug information must be available if the frame is decipherable");
 397 
 398       return true;
 399     }
 400 
 401     // Must be some stub frame that we don't care about
 402 
 403     if (!candidate.safe_for_sender(thread)) return false;
 404     candidate = candidate.sender(&map);
 405 
 406     // If it isn't in the code cache something is wrong
 407     // since once we find a frame in the code cache they
 408     // all should be there.
 409 
 410     if (candidate.cb() == NULL) return false;
 411 
 412   }
 413 
 414   return false;
 415 
 416 }
 417 
 418 static void forte_fill_call_trace_given_top(JavaThread* thd,
 419                                             ASGCT_CallTrace* trace,
 420                                             int depth,
 421                                             frame top_frame) {
 422   NoHandleMark nhm;
 423 
 424   frame initial_Java_frame;
 425   Method* method;
 426   int bci = -1; // assume BCI is not available for method
 427                 // update with correct information if available
 428   int count;
 429 
 430   count = 0;
 431   assert(trace->frames != NULL, "trace->frames must be non-NULL");
 432 
 433   // Walk the stack starting from 'top_frame' and search for an initial Java frame.
 434   find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);


 435 
 436   // Check if a Java Method has been found.
 437   if (method == NULL) return;
 438 
 439   if (!method->is_valid_method()) {
 440     trace->num_frames = ticks_GC_active; // -2
 441     return;























 442   }
 443 
 444   vframeStreamForte st(thd, initial_Java_frame, false);
 445 
 446   for (; !st.at_end() && count < depth; st.forte_next(), count++) {
 447     bci = st.bci();
 448     method = st.method();
 449 
 450     if (!method->is_valid_method()) {
 451       // we throw away everything we've gathered in this sample since
 452       // none of it is safe
 453       trace->num_frames = ticks_GC_active; // -2
 454       return;
 455     }
 456 
 457     trace->frames[count].method_id = method->find_jmethod_id_or_null();
 458     if (!method->is_native()) {
 459       trace->frames[count].lineno = bci;
 460     } else {
 461       trace->frames[count].lineno = -3;


src/share/vm/prims/forte.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File