Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/frame_x86.cpp @ 3363:167b70ff3abc
6939861: JVM should handle more conversion operations
Reviewed-by: twisti, jrose
author | never |
---|---|
date | Fri, 06 May 2011 16:33:13 -0700 |
parents | 2e038ad0c1d0 |
children | 3cfb240033d1 |
comparison
equal
deleted
inserted
replaced
3362:d4c1fbc3de95 | 3363:167b70ff3abc |
---|---|
337 } | 337 } |
338 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); | 338 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); |
339 return fr; | 339 return fr; |
340 } | 340 } |
341 | 341 |
342 | |
343 //------------------------------------------------------------------------------ | 342 //------------------------------------------------------------------------------ |
344 // frame::verify_deopt_original_pc | 343 // frame::verify_deopt_original_pc |
345 // | 344 // |
346 // Verifies the calculated original PC of a deoptimization PC for the | 345 // Verifies the calculated original PC of a deoptimization PC for the |
347 // given unextended SP. The unextended SP might also be the saved SP | 346 // given unextended SP. The unextended SP might also be the saved SP |
359 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); | 358 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); |
360 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); | 359 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); |
361 } | 360 } |
362 #endif | 361 #endif |
363 | 362 |
363 //------------------------------------------------------------------------------ | |
364 // frame::adjust_unextended_sp | |
365 void frame::adjust_unextended_sp() { | |
366 // If we are returning to a compiled MethodHandle call site, the | |
367 // saved_fp will in fact be a saved value of the unextended SP. The | |
368 // simplest way to tell whether we are returning to such a call site | |
369 // is as follows: | |
370 | |
371 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null(); | |
372 if (sender_nm != NULL) { | |
373 // If the sender PC is a deoptimization point, get the original | |
374 // PC. For MethodHandle call site the unextended_sp is stored in | |
375 // saved_fp. | |
376 if (sender_nm->is_deopt_mh_entry(_pc)) { | |
377 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp)); | |
378 _unextended_sp = _fp; | |
379 } | |
380 else if (sender_nm->is_deopt_entry(_pc)) { | |
381 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp)); | |
382 } | |
383 else if (sender_nm->is_method_handle_return(_pc)) { | |
384 _unextended_sp = _fp; | |
385 } | |
386 } | |
387 } | |
388 | |
389 //------------------------------------------------------------------------------ | |
390 // frame::update_map_with_saved_link | |
391 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) { | |
392 // The interpreter and compiler(s) always save EBP/RBP in a known | |
393 // location on entry. We must record where that location is | |
394 // so this if EBP/RBP was live on callout from c2 we can find | |
395 // the saved copy no matter what it called. | |
396 | |
397 // Since the interpreter always saves EBP/RBP if we record where it is then | |
398 // we don't have to always save EBP/RBP on entry and exit to c2 compiled | |
399 // code, on entry will be enough. | |
400 map->set_location(rbp->as_VMReg(), (address) link_addr); | |
401 #ifdef AMD64 | |
402 // this is weird "H" ought to be at a higher address however the | |
403 // oopMaps seems to have the "H" regs at the same address and the | |
404 // vanilla register. | |
405 // XXXX make this go away | |
406 if (true) { | |
407 map->set_location(rbp->as_VMReg()->next(), (address) link_addr); | |
408 } | |
409 #endif // AMD64 | |
410 } | |
411 | |
364 | 412 |
365 //------------------------------------------------------------------------------ | 413 //------------------------------------------------------------------------------ |
366 // frame::sender_for_interpreter_frame | 414 // frame::sender_for_interpreter_frame |
367 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { | 415 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { |
368 // SP is the raw SP from the sender after adapter or interpreter | 416 // SP is the raw SP from the sender after adapter or interpreter |
370 intptr_t* sender_sp = this->sender_sp(); | 418 intptr_t* sender_sp = this->sender_sp(); |
371 | 419 |
372 // This is the sp before any possible extension (adapter/locals). | 420 // This is the sp before any possible extension (adapter/locals). |
373 intptr_t* unextended_sp = interpreter_frame_sender_sp(); | 421 intptr_t* unextended_sp = interpreter_frame_sender_sp(); |
374 | 422 |
375 // Stored FP. | |
376 intptr_t* saved_fp = link(); | |
377 | |
378 address sender_pc = this->sender_pc(); | |
379 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); | |
380 assert(sender_cb, "sanity"); | |
381 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); | |
382 | |
383 if (sender_nm != NULL) { | |
384 // If the sender PC is a deoptimization point, get the original | |
385 // PC. For MethodHandle call site the unextended_sp is stored in | |
386 // saved_fp. | |
387 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
388 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
389 unextended_sp = saved_fp; | |
390 } | |
391 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
392 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
393 } | |
394 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
395 unextended_sp = saved_fp; | |
396 } | |
397 } | |
398 | |
399 // The interpreter and compiler(s) always save EBP/RBP in a known | |
400 // location on entry. We must record where that location is | |
401 // so this if EBP/RBP was live on callout from c2 we can find | |
402 // the saved copy no matter what it called. | |
403 | |
404 // Since the interpreter always saves EBP/RBP if we record where it is then | |
405 // we don't have to always save EBP/RBP on entry and exit to c2 compiled | |
406 // code, on entry will be enough. | |
407 #ifdef COMPILER2 | 423 #ifdef COMPILER2 |
408 if (map->update_map()) { | 424 if (map->update_map()) { |
409 map->set_location(rbp->as_VMReg(), (address) addr_at(link_offset)); | 425 update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); |
410 #ifdef AMD64 | |
411 // this is weird "H" ought to be at a higher address however the | |
412 // oopMaps seems to have the "H" regs at the same address and the | |
413 // vanilla register. | |
414 // XXXX make this go away | |
415 if (true) { | |
416 map->set_location(rbp->as_VMReg()->next(), (address)addr_at(link_offset)); | |
417 } | |
418 #endif // AMD64 | |
419 } | 426 } |
420 #endif // COMPILER2 | 427 #endif // COMPILER2 |
421 | 428 |
422 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); | 429 return frame(sender_sp, unextended_sp, link(), sender_pc()); |
423 } | 430 } |
424 | 431 |
425 | 432 |
426 //------------------------------------------------------------------------------ | 433 //------------------------------------------------------------------------------ |
427 // frame::sender_for_compiled_frame | 434 // frame::sender_for_compiled_frame |
428 frame frame::sender_for_compiled_frame(RegisterMap* map) const { | 435 frame frame::sender_for_compiled_frame(RegisterMap* map) const { |
429 assert(map != NULL, "map must be set"); | 436 assert(map != NULL, "map must be set"); |
437 assert(!is_ricochet_frame(), "caller must handle this"); | |
430 | 438 |
431 // frame owned by optimizing compiler | 439 // frame owned by optimizing compiler |
432 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); | 440 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); |
433 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); | 441 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); |
434 intptr_t* unextended_sp = sender_sp; | 442 intptr_t* unextended_sp = sender_sp; |
436 // On Intel the return_address is always the word on the stack | 444 // On Intel the return_address is always the word on the stack |
437 address sender_pc = (address) *(sender_sp-1); | 445 address sender_pc = (address) *(sender_sp-1); |
438 | 446 |
439 // This is the saved value of EBP which may or may not really be an FP. | 447 // This is the saved value of EBP which may or may not really be an FP. |
440 // It is only an FP if the sender is an interpreter frame (or C1?). | 448 // It is only an FP if the sender is an interpreter frame (or C1?). |
441 intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); | 449 intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset); |
442 | |
443 // If we are returning to a compiled MethodHandle call site, the | |
444 // saved_fp will in fact be a saved value of the unextended SP. The | |
445 // simplest way to tell whether we are returning to such a call site | |
446 // is as follows: | |
447 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); | |
448 assert(sender_cb, "sanity"); | |
449 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); | |
450 | |
451 if (sender_nm != NULL) { | |
452 // If the sender PC is a deoptimization point, get the original | |
453 // PC. For MethodHandle call site the unextended_sp is stored in | |
454 // saved_fp. | |
455 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
456 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
457 unextended_sp = saved_fp; | |
458 } | |
459 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
460 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
461 } | |
462 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
463 unextended_sp = saved_fp; | |
464 } | |
465 } | |
466 | 450 |
467 if (map->update_map()) { | 451 if (map->update_map()) { |
468 // 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. |
469 // 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 |
470 // outside of update_register_map. | 454 // outside of update_register_map. |
471 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())); |
472 if (_cb->oop_maps() != NULL) { | 456 if (_cb->oop_maps() != NULL) { |
473 OopMapSet::update_register_map(this, map); | 457 OopMapSet::update_register_map(this, map); |
474 } | 458 } |
459 | |
475 // Since the prolog does the save and restore of EBP there is no oopmap | 460 // Since the prolog does the save and restore of EBP there is no oopmap |
476 // for it so we must fill in its location as if there was an oopmap entry | 461 // for it so we must fill in its location as if there was an oopmap entry |
477 // since if our caller was compiled code there could be live jvm state in it. | 462 // since if our caller was compiled code there could be live jvm state in it. |
478 map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset)); | 463 update_map_with_saved_link(map, saved_fp_addr); |
479 #ifdef AMD64 | |
480 // this is weird "H" ought to be at a higher address however the | |
481 // oopMaps seems to have the "H" regs at the same address and the | |
482 // vanilla register. | |
483 // XXXX make this go away | |
484 if (true) { | |
485 map->set_location(rbp->as_VMReg()->next(), (address) (sender_sp - frame::sender_sp_offset)); | |
486 } | |
487 #endif // AMD64 | |
488 } | 464 } |
489 | 465 |
490 assert(sender_sp != sp(), "must have changed"); | 466 assert(sender_sp != sp(), "must have changed"); |
491 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); | 467 return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc); |
492 } | 468 } |
493 | 469 |
494 | 470 |
495 //------------------------------------------------------------------------------ | 471 //------------------------------------------------------------------------------ |
496 // frame::sender | 472 // frame::sender |
500 map->set_include_argument_oops(false); | 476 map->set_include_argument_oops(false); |
501 | 477 |
502 if (is_entry_frame()) return sender_for_entry_frame(map); | 478 if (is_entry_frame()) return sender_for_entry_frame(map); |
503 if (is_interpreted_frame()) return sender_for_interpreter_frame(map); | 479 if (is_interpreted_frame()) return sender_for_interpreter_frame(map); |
504 assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); | 480 assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); |
481 if (is_ricochet_frame()) return sender_for_ricochet_frame(map); | |
505 | 482 |
506 if (_cb != NULL) { | 483 if (_cb != NULL) { |
507 return sender_for_compiled_frame(map); | 484 return sender_for_compiled_frame(map); |
508 } | 485 } |
509 // Must be native-compiled frame, i.e. the marshaling code for native | 486 // Must be native-compiled frame, i.e. the marshaling code for native |