src/hotspot/cpu/arm/frame_arm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File open Sdiff src/hotspot/cpu/arm

src/hotspot/cpu/arm/frame_arm.cpp

Print this page




 287 
 288 
 289 // monitor elements
 290 
 291 BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
 292   return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset);
 293 }
 294 
 295 BasicObjectLock* frame::interpreter_frame_monitor_end() const {
 296   BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset);
 297   // make sure the pointer points inside the frame
 298   assert((intptr_t) fp() >  (intptr_t) result, "result must <  than frame pointer");
 299   assert((intptr_t) sp() <= (intptr_t) result, "result must >= than stack pointer");
 300   return result;
 301 }
 302 
 303 void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
 304   *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
 305 }
 306 
 307 #ifdef AARCH64
 308 
 309 // Used by template based interpreter deoptimization
 310 void frame::interpreter_frame_set_stack_top(intptr_t* stack_top) {
 311   *((intptr_t**)addr_at(interpreter_frame_stack_top_offset)) = stack_top;
 312 }
 313 
 314 // Used by template based interpreter deoptimization
 315 void frame::interpreter_frame_set_extended_sp(intptr_t* sp) {
 316   *((intptr_t**)addr_at(interpreter_frame_extended_sp_offset)) = sp;
 317 }
 318 
 319 #else
 320 
 321 // Used by template based interpreter deoptimization
 322 void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
 323     *((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
 324 }
 325 
 326 #endif // AARCH64
 327 
 328 frame frame::sender_for_entry_frame(RegisterMap* map) const {
 329   assert(map != NULL, "map must be set");
 330   // Java frame called from C; skip all C frames and return top C
 331   // frame of that chunk as the sender
 332   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
 333   assert(!entry_frame_is_first(), "next Java fp must be non zero");
 334   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
 335   map->clear();
 336   assert(map->include_argument_oops(), "should be set by clear");
 337 #ifdef AARCH64
 338   assert (jfa->last_Java_pc() != NULL, "pc should be stored");
 339   frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
 340   return fr;
 341 #else
 342   if (jfa->last_Java_pc() != NULL) {
 343     frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
 344     return fr;
 345   }
 346   frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
 347   return fr;
 348 #endif // AARCH64
 349 }
 350 
 351 //------------------------------------------------------------------------------
 352 // frame::verify_deopt_original_pc
 353 //
 354 // Verifies the calculated original PC of a deoptimization PC for the
 355 // given unextended SP.  The unextended SP might also be the saved SP
 356 // for MethodHandle call sites.
 357 #ifdef ASSERT
 358 void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
 359   frame fr;
 360 
 361   // This is ugly but it's better than to change {get,set}_original_pc
 362   // to take an SP value as argument.  And it's only a debugging
 363   // method anyway.
 364   fr._unextended_sp = unextended_sp;
 365 
 366   address original_pc = nm->get_original_pc(&fr);
 367   assert(nm->insts_contains_inclusive(original_pc),
 368          "original PC must be in the main code section of the the compiled method (or must be immediately following it)");


 386     // PC.  For MethodHandle call site the unextended_sp is stored in
 387     // saved_fp.
 388     if (sender_cm->is_deopt_mh_entry(_pc)) {
 389       DEBUG_ONLY(verify_deopt_mh_original_pc(sender_cm, _fp));
 390       _unextended_sp = _fp;
 391     }
 392     else if (sender_cm->is_deopt_entry(_pc)) {
 393       DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp));
 394     }
 395     else if (sender_cm->is_method_handle_return(_pc)) {
 396       _unextended_sp = _fp;
 397     }
 398   }
 399 }
 400 
 401 //------------------------------------------------------------------------------
 402 // frame::update_map_with_saved_link
 403 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
 404   // see x86 for comments
 405   map->set_location(FP->as_VMReg(), (address) link_addr);
 406 #ifdef AARCH64
 407   // also adjust a high part of register
 408   map->set_location(FP->as_VMReg()->next(), (address) link_addr);
 409 #endif // AARCH64
 410 }
 411 
 412 frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
 413   // SP is the raw SP from the sender after adapter or interpreter
 414   // extension.
 415   intptr_t* sender_sp = this->sender_sp();
 416 
 417   // This is the sp before any possible extension (adapter/locals).
 418   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 419 
 420 #ifdef COMPILER2
 421   if (map->update_map()) {
 422     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
 423   }
 424 #endif // COMPILER2
 425 
 426   return frame(sender_sp, unextended_sp, link(), sender_pc());
 427 }
 428 
 429 frame frame::sender_for_compiled_frame(RegisterMap* map) const {


 522   // validate locals
 523 
 524   address locals =  (address) *interpreter_frame_locals_addr();
 525 
 526   if (locals > thread->stack_base() || locals < (address) fp()) return false;
 527 
 528   // We'd have to be pretty unlucky to be mislead at this point
 529 
 530   return true;
 531 }
 532 
 533 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
 534   assert(is_interpreted_frame(), "interpreted frame expected");
 535   Method* method = interpreter_frame_method();
 536   BasicType type = method->result_type();
 537 
 538   intptr_t* res_addr;
 539   if (method->is_native()) {
 540     // Prior to calling into the runtime to report the method_exit both of
 541     // the possible return value registers are saved.
 542 #ifdef AARCH64
 543     // Return value registers are saved into the frame
 544     if (type == T_FLOAT || type == T_DOUBLE) {
 545       res_addr = addr_at(interpreter_frame_fp_saved_result_offset);
 546     } else {
 547       res_addr = addr_at(interpreter_frame_gp_saved_result_offset);
 548     }
 549 #else
 550     // Return value registers are pushed to the native stack
 551     res_addr = (intptr_t*)sp();
 552 #ifdef __ABI_HARD__
 553     // FP result is pushed onto a stack along with integer result registers
 554     if (type == T_FLOAT || type == T_DOUBLE) {
 555       res_addr += 2;
 556     }
 557 #endif // __ABI_HARD__
 558 #endif // AARCH64
 559   } else {
 560     res_addr = (intptr_t*)interpreter_frame_tos_address();
 561   }
 562 
 563   switch (type) {
 564     case T_OBJECT  :
 565     case T_ARRAY   : {
 566       oop obj;
 567       if (method->is_native()) {
 568         obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
 569       } else {
 570         obj = *(oop*)res_addr;
 571       }
 572       assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
 573       *oop_result = obj;
 574       break;
 575     }
 576     case T_BOOLEAN : value_result->z = *(jboolean*)res_addr; break;
 577     case T_BYTE    : value_result->b = *(jbyte*)res_addr; break;
 578     case T_CHAR    : value_result->c = *(jchar*)res_addr; break;


 585     default        : ShouldNotReachHere();
 586   }
 587 
 588   return type;
 589 }
 590 
 591 
 592 intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
 593   int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
 594   return &interpreter_frame_tos_address()[index];
 595 }
 596 
 597 #ifndef PRODUCT
 598 
 599 #define DESCRIBE_FP_OFFSET(name) \
 600   values.describe(frame_no, fp() + frame::name##_offset, #name)
 601 
 602 void frame::describe_pd(FrameValues& values, int frame_no) {
 603   if (is_interpreted_frame()) {
 604     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
 605 #ifdef AARCH64
 606     DESCRIBE_FP_OFFSET(interpreter_frame_stack_top);
 607     DESCRIBE_FP_OFFSET(interpreter_frame_extended_sp);
 608 #else
 609     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
 610 #endif // AARCH64
 611     DESCRIBE_FP_OFFSET(interpreter_frame_method);
 612     DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
 613     DESCRIBE_FP_OFFSET(interpreter_frame_cache);
 614     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
 615     DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
 616     DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
 617   }
 618 }
 619 
 620 // This is a generic constructor which is only used by pns() in debug.cpp.
 621 frame::frame(void* sp, void* fp, void* pc) {
 622   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 623 }
 624 
 625 void frame::pd_ps() {}
 626 #endif
 627 
 628 intptr_t *frame::initial_deoptimization_info() {
 629   // used to reset the saved FP
 630   return fp();
 631 }
 632 
 633 intptr_t* frame::real_fp() const {
 634 #ifndef AARCH64
 635   if (is_entry_frame()) {
 636     // Work-around: FP (currently) does not conform to the ABI for entry
 637     // frames (see generate_call_stub). Might be worth fixing as another CR.
 638     // Following code assumes (and asserts) this has not yet been fixed.
 639     assert(frame::entry_frame_call_wrapper_offset == 0, "adjust this code");
 640     intptr_t* new_fp = fp();
 641     new_fp += 5; // saved R0,R1,R2,R4,R10
 642 #ifndef __SOFTFP__
 643     new_fp += 8*2; // saved D8..D15
 644 #endif
 645     return new_fp;
 646   }
 647 #endif // !AARCH64
 648   if (_cb != NULL) {
 649     // use the frame size if valid
 650     int size = _cb->frame_size();
 651     if (size > 0) {
 652       return unextended_sp() + size;
 653     }
 654   }
 655   // else rely on fp()
 656   assert(! is_compiled_frame(), "unknown compiled frame size");
 657   return fp();
 658 }


 287 
 288 
 289 // monitor elements
 290 
 291 BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
 292   return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset);
 293 }
 294 
 295 BasicObjectLock* frame::interpreter_frame_monitor_end() const {
 296   BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset);
 297   // make sure the pointer points inside the frame
 298   assert((intptr_t) fp() >  (intptr_t) result, "result must <  than frame pointer");
 299   assert((intptr_t) sp() <= (intptr_t) result, "result must >= than stack pointer");
 300   return result;
 301 }
 302 
 303 void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
 304   *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
 305 }
 306 













 307 
 308 // Used by template based interpreter deoptimization
 309 void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
 310     *((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
 311 }
 312 

 313 
 314 frame frame::sender_for_entry_frame(RegisterMap* map) const {
 315   assert(map != NULL, "map must be set");
 316   // Java frame called from C; skip all C frames and return top C
 317   // frame of that chunk as the sender
 318   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
 319   assert(!entry_frame_is_first(), "next Java fp must be non zero");
 320   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
 321   map->clear();
 322   assert(map->include_argument_oops(), "should be set by clear");





 323   if (jfa->last_Java_pc() != NULL) {
 324     frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
 325     return fr;
 326   }
 327   frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
 328   return fr;

 329 }
 330 
 331 //------------------------------------------------------------------------------
 332 // frame::verify_deopt_original_pc
 333 //
 334 // Verifies the calculated original PC of a deoptimization PC for the
 335 // given unextended SP.  The unextended SP might also be the saved SP
 336 // for MethodHandle call sites.
 337 #ifdef ASSERT
 338 void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
 339   frame fr;
 340 
 341   // This is ugly but it's better than to change {get,set}_original_pc
 342   // to take an SP value as argument.  And it's only a debugging
 343   // method anyway.
 344   fr._unextended_sp = unextended_sp;
 345 
 346   address original_pc = nm->get_original_pc(&fr);
 347   assert(nm->insts_contains_inclusive(original_pc),
 348          "original PC must be in the main code section of the the compiled method (or must be immediately following it)");


 366     // PC.  For MethodHandle call site the unextended_sp is stored in
 367     // saved_fp.
 368     if (sender_cm->is_deopt_mh_entry(_pc)) {
 369       DEBUG_ONLY(verify_deopt_mh_original_pc(sender_cm, _fp));
 370       _unextended_sp = _fp;
 371     }
 372     else if (sender_cm->is_deopt_entry(_pc)) {
 373       DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp));
 374     }
 375     else if (sender_cm->is_method_handle_return(_pc)) {
 376       _unextended_sp = _fp;
 377     }
 378   }
 379 }
 380 
 381 //------------------------------------------------------------------------------
 382 // frame::update_map_with_saved_link
 383 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
 384   // see x86 for comments
 385   map->set_location(FP->as_VMReg(), (address) link_addr);




 386 }
 387 
 388 frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
 389   // SP is the raw SP from the sender after adapter or interpreter
 390   // extension.
 391   intptr_t* sender_sp = this->sender_sp();
 392 
 393   // This is the sp before any possible extension (adapter/locals).
 394   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 395 
 396 #ifdef COMPILER2
 397   if (map->update_map()) {
 398     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
 399   }
 400 #endif // COMPILER2
 401 
 402   return frame(sender_sp, unextended_sp, link(), sender_pc());
 403 }
 404 
 405 frame frame::sender_for_compiled_frame(RegisterMap* map) const {


 498   // validate locals
 499 
 500   address locals =  (address) *interpreter_frame_locals_addr();
 501 
 502   if (locals > thread->stack_base() || locals < (address) fp()) return false;
 503 
 504   // We'd have to be pretty unlucky to be mislead at this point
 505 
 506   return true;
 507 }
 508 
 509 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
 510   assert(is_interpreted_frame(), "interpreted frame expected");
 511   Method* method = interpreter_frame_method();
 512   BasicType type = method->result_type();
 513 
 514   intptr_t* res_addr;
 515   if (method->is_native()) {
 516     // Prior to calling into the runtime to report the method_exit both of
 517     // the possible return value registers are saved.








 518     // Return value registers are pushed to the native stack
 519     res_addr = (intptr_t*)sp();
 520 #ifdef __ABI_HARD__
 521     // FP result is pushed onto a stack along with integer result registers
 522     if (type == T_FLOAT || type == T_DOUBLE) {
 523       res_addr += 2;
 524     }
 525 #endif // __ABI_HARD__

 526   } else {
 527     res_addr = (intptr_t*)interpreter_frame_tos_address();
 528   }
 529 
 530   switch (type) {
 531     case T_OBJECT  :
 532     case T_ARRAY   : {
 533       oop obj;
 534       if (method->is_native()) {
 535         obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
 536       } else {
 537         obj = *(oop*)res_addr;
 538       }
 539       assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
 540       *oop_result = obj;
 541       break;
 542     }
 543     case T_BOOLEAN : value_result->z = *(jboolean*)res_addr; break;
 544     case T_BYTE    : value_result->b = *(jbyte*)res_addr; break;
 545     case T_CHAR    : value_result->c = *(jchar*)res_addr; break;


 552     default        : ShouldNotReachHere();
 553   }
 554 
 555   return type;
 556 }
 557 
 558 
 559 intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
 560   int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
 561   return &interpreter_frame_tos_address()[index];
 562 }
 563 
 564 #ifndef PRODUCT
 565 
 566 #define DESCRIBE_FP_OFFSET(name) \
 567   values.describe(frame_no, fp() + frame::name##_offset, #name)
 568 
 569 void frame::describe_pd(FrameValues& values, int frame_no) {
 570   if (is_interpreted_frame()) {
 571     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);




 572     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);

 573     DESCRIBE_FP_OFFSET(interpreter_frame_method);
 574     DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
 575     DESCRIBE_FP_OFFSET(interpreter_frame_cache);
 576     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
 577     DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
 578     DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
 579   }
 580 }
 581 
 582 // This is a generic constructor which is only used by pns() in debug.cpp.
 583 frame::frame(void* sp, void* fp, void* pc) {
 584   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 585 }
 586 
 587 void frame::pd_ps() {}
 588 #endif
 589 
 590 intptr_t *frame::initial_deoptimization_info() {
 591   // used to reset the saved FP
 592   return fp();
 593 }
 594 
 595 intptr_t* frame::real_fp() const {

 596   if (is_entry_frame()) {
 597     // Work-around: FP (currently) does not conform to the ABI for entry
 598     // frames (see generate_call_stub). Might be worth fixing as another CR.
 599     // Following code assumes (and asserts) this has not yet been fixed.
 600     assert(frame::entry_frame_call_wrapper_offset == 0, "adjust this code");
 601     intptr_t* new_fp = fp();
 602     new_fp += 5; // saved R0,R1,R2,R4,R10
 603 #ifndef __SOFTFP__
 604     new_fp += 8*2; // saved D8..D15
 605 #endif
 606     return new_fp;
 607   }

 608   if (_cb != NULL) {
 609     // use the frame size if valid
 610     int size = _cb->frame_size();
 611     if (size > 0) {
 612       return unextended_sp() + size;
 613     }
 614   }
 615   // else rely on fp()
 616   assert(! is_compiled_frame(), "unknown compiled frame size");
 617   return fp();
 618 }
src/hotspot/cpu/arm/frame_arm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File