Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/frame_x86.cpp @ 1204:18a389214829
6921352: JSR 292 needs its own deopt handler
Summary: We need to introduce a new MH deopt handler so we can easily determine if the deopt happened at a MH call site or not.
Reviewed-by: never, jrose
author | twisti |
---|---|
date | Mon, 01 Feb 2010 19:29:46 +0100 |
parents | 24128c2ffa87 |
children | 615a9d95d265 2338d41fbd81 |
comparison
equal
deleted
inserted
replaced
1203:844a9d73ec22 | 1204:18a389214829 |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2010 Sun Microsystems, Inc. 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. |
220 tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", | 220 tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", |
221 &((address *)sp())[-1], ((address *)sp())[-1], pc); | 221 &((address *)sp())[-1], ((address *)sp())[-1], pc); |
222 } | 222 } |
223 ((address *)sp())[-1] = pc; | 223 ((address *)sp())[-1] = pc; |
224 _cb = CodeCache::find_blob(pc); | 224 _cb = CodeCache::find_blob(pc); |
225 if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { | 225 address original_pc = nmethod::get_deopt_original_pc(this); |
226 address orig = (((nmethod*)_cb)->get_original_pc(this)); | 226 if (original_pc != NULL) { |
227 assert(orig == _pc, "expected original to be stored before patching"); | 227 assert(original_pc == _pc, "expected original PC to be stored before patching"); |
228 _deopt_state = is_deoptimized; | 228 _deopt_state = is_deoptimized; |
229 // leave _pc as is | 229 // leave _pc as is |
230 } else { | 230 } else { |
231 _deopt_state = not_deoptimized; | 231 _deopt_state = not_deoptimized; |
232 _pc = pc; | 232 _pc = pc; |
321 } | 321 } |
322 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); | 322 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); |
323 return fr; | 323 return fr; |
324 } | 324 } |
325 | 325 |
326 | |
327 //------------------------------------------------------------------------------ | |
328 // frame::verify_deopt_original_pc | |
329 // | |
330 // Verifies the calculated original PC of a deoptimization PC for the | |
331 // given unextended SP. The unextended SP might also be the saved SP | |
332 // for MethodHandle call sites. | |
333 #if ASSERT | |
334 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { | |
335 frame fr; | |
336 | |
337 // This is ugly but it's better than to change {get,set}_original_pc | |
338 // to take an SP value as argument. And it's only a debugging | |
339 // method anyway. | |
340 fr._unextended_sp = unextended_sp; | |
341 | |
342 address original_pc = nm->get_original_pc(&fr); | |
343 assert(nm->code_contains(original_pc), "original PC must be in nmethod"); | |
344 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); | |
345 } | |
346 #endif | |
347 | |
348 | |
349 //------------------------------------------------------------------------------ | |
350 // frame::sender_for_interpreter_frame | |
326 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { | 351 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { |
327 // sp is the raw sp from the sender after adapter or interpreter extension | 352 // SP is the raw SP from the sender after adapter or interpreter |
328 intptr_t* sp = (intptr_t*) addr_at(sender_sp_offset); | 353 // extension. |
354 intptr_t* sender_sp = this->sender_sp(); | |
329 | 355 |
330 // This is the sp before any possible extension (adapter/locals). | 356 // This is the sp before any possible extension (adapter/locals). |
331 intptr_t* unextended_sp = interpreter_frame_sender_sp(); | 357 intptr_t* unextended_sp = interpreter_frame_sender_sp(); |
358 | |
359 // Stored FP. | |
360 intptr_t* saved_fp = link(); | |
332 | 361 |
333 address sender_pc = this->sender_pc(); | 362 address sender_pc = this->sender_pc(); |
334 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); | 363 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); |
335 assert(sender_cb, "sanity"); | 364 assert(sender_cb, "sanity"); |
336 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); | 365 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); |
337 if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { | 366 |
338 unextended_sp = (intptr_t*) at(link_offset); | 367 if (sender_nm != NULL) { |
368 // If the sender PC is a deoptimization point, get the original | |
369 // PC. For MethodHandle call site the unextended_sp is stored in | |
370 // saved_fp. | |
371 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
372 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
373 unextended_sp = saved_fp; | |
374 } | |
375 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
376 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
377 } | |
378 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
379 unextended_sp = saved_fp; | |
380 } | |
339 } | 381 } |
340 | 382 |
341 // The interpreter and compiler(s) always save EBP/RBP in a known | 383 // The interpreter and compiler(s) always save EBP/RBP in a known |
342 // location on entry. We must record where that location is | 384 // location on entry. We must record where that location is |
343 // so this if EBP/RBP was live on callout from c2 we can find | 385 // so this if EBP/RBP was live on callout from c2 we can find |
357 if (true) { | 399 if (true) { |
358 map->set_location(rbp->as_VMReg()->next(), (address)addr_at(link_offset)); | 400 map->set_location(rbp->as_VMReg()->next(), (address)addr_at(link_offset)); |
359 } | 401 } |
360 #endif // AMD64 | 402 #endif // AMD64 |
361 } | 403 } |
362 #endif /* COMPILER2 */ | 404 #endif // COMPILER2 |
363 return frame(sp, unextended_sp, link(), sender_pc); | 405 |
364 } | 406 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); |
365 | 407 } |
366 | 408 |
367 //------------------------------sender_for_compiled_frame----------------------- | 409 |
410 //------------------------------------------------------------------------------ | |
411 // frame::sender_for_compiled_frame | |
368 frame frame::sender_for_compiled_frame(RegisterMap* map) const { | 412 frame frame::sender_for_compiled_frame(RegisterMap* map) const { |
369 assert(map != NULL, "map must be set"); | 413 assert(map != NULL, "map must be set"); |
370 const bool c1_compiled = _cb->is_compiled_by_c1(); | |
371 | 414 |
372 // frame owned by optimizing compiler | 415 // frame owned by optimizing compiler |
373 intptr_t* sender_sp = NULL; | |
374 | |
375 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); | 416 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); |
376 sender_sp = unextended_sp() + _cb->frame_size(); | 417 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); |
418 intptr_t* unextended_sp = sender_sp; | |
377 | 419 |
378 // On Intel the return_address is always the word on the stack | 420 // On Intel the return_address is always the word on the stack |
379 address sender_pc = (address) *(sender_sp-1); | 421 address sender_pc = (address) *(sender_sp-1); |
380 | 422 |
381 // This is the saved value of ebp which may or may not really be an fp. | 423 // This is the saved value of EBP which may or may not really be an FP. |
382 // it is only an fp if the sender is an interpreter frame (or c1?) | 424 // It is only an FP if the sender is an interpreter frame (or C1?). |
383 | 425 intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); |
384 intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); | 426 |
385 | 427 // If we are returning to a compiled MethodHandle call site, the |
386 intptr_t* unextended_sp = sender_sp; | 428 // saved_fp will in fact be a saved value of the unextended SP. The |
387 // If we are returning to a compiled method handle call site, | 429 // simplest way to tell whether we are returning to such a call site |
388 // the saved_fp will in fact be a saved value of the unextended SP. | 430 // is as follows: |
389 // The simplest way to tell whether we are returning to such a call | |
390 // site is as follows: | |
391 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); | 431 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); |
392 assert(sender_cb, "sanity"); | 432 assert(sender_cb, "sanity"); |
393 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); | 433 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); |
394 if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { | 434 |
395 unextended_sp = saved_fp; | 435 if (sender_nm != NULL) { |
436 // If the sender PC is a deoptimization point, get the original | |
437 // PC. For MethodHandle call site the unextended_sp is stored in | |
438 // saved_fp. | |
439 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
440 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
441 unextended_sp = saved_fp; | |
442 } | |
443 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
444 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
445 } | |
446 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
447 unextended_sp = saved_fp; | |
448 } | |
396 } | 449 } |
397 | 450 |
398 if (map->update_map()) { | 451 if (map->update_map()) { |
399 // Tell GC to use argument oopmaps for some runtime stubs that need it. | 452 // Tell GC to use argument oopmaps for some runtime stubs that need it. |
400 // For C1, the runtime stub might not have oop maps, so set this flag | 453 // For C1, the runtime stub might not have oop maps, so set this flag |
401 // outside of update_register_map. | 454 // outside of update_register_map. |
402 map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); | 455 map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); |
403 if (_cb->oop_maps() != NULL) { | 456 if (_cb->oop_maps() != NULL) { |
404 OopMapSet::update_register_map(this, map); | 457 OopMapSet::update_register_map(this, map); |
405 } | 458 } |
406 // Since the prolog does the save and restore of epb there is no oopmap | 459 // Since the prolog does the save and restore of EBP there is no oopmap |
407 // for it so we must fill in its location as if there was an oopmap entry | 460 // for it so we must fill in its location as if there was an oopmap entry |
408 // since if our caller was compiled code there could be live jvm state in it. | 461 // since if our caller was compiled code there could be live jvm state in it. |
409 map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset)); | 462 map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset)); |
410 #ifdef AMD64 | 463 #ifdef AMD64 |
411 // this is weird "H" ought to be at a higher address however the | 464 // this is weird "H" ought to be at a higher address however the |
420 | 473 |
421 assert(sender_sp != sp(), "must have changed"); | 474 assert(sender_sp != sp(), "must have changed"); |
422 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); | 475 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); |
423 } | 476 } |
424 | 477 |
478 | |
479 //------------------------------------------------------------------------------ | |
480 // frame::sender | |
425 frame frame::sender(RegisterMap* map) const { | 481 frame frame::sender(RegisterMap* map) const { |
426 // Default is we done have to follow them. The sender_for_xxx will | 482 // Default is we done have to follow them. The sender_for_xxx will |
427 // update it accordingly | 483 // update it accordingly |
428 map->set_include_argument_oops(false); | 484 map->set_include_argument_oops(false); |
429 | 485 |