< prev index next >

src/hotspot/cpu/aarch64/frame_aarch64.cpp

Print this page
8248238: Adding Windows support to OpenJDK on AArch64

Summary: LP64 vs LLP64 changes to add Windows support

Contributed-by: Monica Beckwith <monica.beckwith@microsoft.com>, Ludovic Henry <luhenry@microsoft.com>
Reviewed-by:


 636   return NULL;
 637 }
 638 
 639 intptr_t* frame::real_fp() const {
 640   if (_cb != NULL) {
 641     // use the frame size if valid
 642     int size = _cb->frame_size();
 643     if (size > 0) {
 644       return unextended_sp() + size;
 645     }
 646   }
 647   // else rely on fp()
 648   assert(! is_compiled_frame(), "unknown compiled frame size");
 649   return fp();
 650 }
 651 
 652 #undef DESCRIBE_FP_OFFSET
 653 
 654 #define DESCRIBE_FP_OFFSET(name)                                        \
 655   {                                                                     \
 656     unsigned long *p = (unsigned long *)fp;                             \
 657     printf("0x%016lx 0x%016lx %s\n", (unsigned long)(p + frame::name##_offset), \
 658            p[frame::name##_offset], #name);                             \
 659   }
 660 
 661 static __thread unsigned long nextfp;
 662 static __thread unsigned long nextpc;
 663 static __thread unsigned long nextsp;
 664 static __thread RegisterMap *reg_map;
 665 
 666 static void printbc(Method *m, intptr_t bcx) {
 667   const char *name;
 668   char buf[16];
 669   if (m->validate_bci_from_bcp((address)bcx) < 0
 670       || !m->contains((address)bcx)) {
 671     name = "???";
 672     snprintf(buf, sizeof buf, "(bad)");
 673   } else {
 674     int bci = m->bci_from((address)bcx);
 675     snprintf(buf, sizeof buf, "%d", bci);
 676     name = Bytecodes::name(m->code_at(bci));
 677   }
 678   ResourceMark rm;
 679   printf("%s : %s ==> %s\n", m->name_and_sig_as_C_string(), buf, name);
 680 }
 681 
 682 void internal_pf(unsigned long sp, unsigned long fp, unsigned long pc, unsigned long bcx) {
 683   if (! fp)
 684     return;
 685 
 686   DESCRIBE_FP_OFFSET(return_addr);
 687   DESCRIBE_FP_OFFSET(link);
 688   DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
 689   DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
 690   DESCRIBE_FP_OFFSET(interpreter_frame_method);
 691   DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
 692   DESCRIBE_FP_OFFSET(interpreter_frame_cache);
 693   DESCRIBE_FP_OFFSET(interpreter_frame_locals);
 694   DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
 695   DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
 696   unsigned long *p = (unsigned long *)fp;
 697 
 698   // We want to see all frames, native and Java.  For compiled and
 699   // interpreted frames we have special information that allows us to
 700   // unwind them; for everything else we assume that the native frame
 701   // pointer chain is intact.
 702   frame this_frame((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 703   if (this_frame.is_compiled_frame() ||
 704       this_frame.is_interpreted_frame()) {
 705     frame sender = this_frame.sender(reg_map);
 706     nextfp = (unsigned long)sender.fp();
 707     nextpc = (unsigned long)sender.pc();
 708     nextsp = (unsigned long)sender.unextended_sp();
 709   } else {
 710     nextfp = p[frame::link_offset];
 711     nextpc = p[frame::return_addr_offset];
 712     nextsp = (unsigned long)&p[frame::sender_sp_offset];
 713   }
 714 
 715   if (bcx == -1ul)
 716     bcx = p[frame::interpreter_frame_bcp_offset];
 717 
 718   if (Interpreter::contains((address)pc)) {
 719     Method* m = (Method*)p[frame::interpreter_frame_method_offset];
 720     if(m && m->is_method()) {
 721       printbc(m, bcx);
 722     } else
 723       printf("not a Method\n");
 724   } else {
 725     CodeBlob *cb = CodeCache::find_blob((address)pc);
 726     if (cb != NULL) {
 727       if (cb->is_nmethod()) {
 728         ResourceMark rm;
 729         nmethod* nm = (nmethod*)cb;
 730         printf("nmethod %s\n", nm->method()->name_and_sig_as_C_string());
 731       } else if (cb->name()) {
 732         printf("CodeBlob %s\n", cb->name());
 733       }
 734     }
 735   }
 736 }
 737 
 738 extern "C" void npf() {
 739   CodeBlob *cb = CodeCache::find_blob((address)nextpc);
 740   // C2 does not always chain the frame pointers when it can, instead
 741   // preferring to use fixed offsets from SP, so a simple leave() does
 742   // not work.  Instead, it adds the frame size to SP then pops FP and
 743   // LR.  We have to do the same thing to get a good call chain.
 744   if (cb && cb->frame_size())
 745     nextfp = nextsp + wordSize * (cb->frame_size() - 2);
 746   internal_pf (nextsp, nextfp, nextpc, -1);
 747 }
 748 
 749 extern "C" void pf(unsigned long sp, unsigned long fp, unsigned long pc,
 750                    unsigned long bcx, unsigned long thread) {
 751   if (!reg_map) {
 752     reg_map = NEW_C_HEAP_OBJ(RegisterMap, mtNone);
 753     ::new (reg_map) RegisterMap((JavaThread*)thread, false);
 754   } else {
 755     *reg_map = RegisterMap((JavaThread*)thread, false);
 756   }
 757 
 758   {
 759     CodeBlob *cb = CodeCache::find_blob((address)pc);
 760     if (cb && cb->frame_size())
 761       fp = sp + wordSize * (cb->frame_size() - 2);
 762   }
 763   internal_pf(sp, fp, pc, bcx);
 764 }
 765 
 766 // support for printing out where we are in a Java method
 767 // needs to be passed current fp and bcp register values
 768 // prints method name, bc index and bytecode name
 769 extern "C" void pm(unsigned long fp, unsigned long bcx) {
 770   DESCRIBE_FP_OFFSET(interpreter_frame_method);
 771   unsigned long *p = (unsigned long *)fp;
 772   Method* m = (Method*)p[frame::interpreter_frame_method_offset];
 773   printbc(m, bcx);
 774 }
 775 
 776 #ifndef PRODUCT
 777 // This is a generic constructor which is only used by pns() in debug.cpp.
 778 frame::frame(void* sp, void* fp, void* pc) {
 779   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 780 }
 781 
 782 void frame::pd_ps() {}
 783 #endif
 784 
 785 void JavaFrameAnchor::make_walkable(JavaThread* thread) {
 786   // last frame set?
 787   if (last_Java_sp() == NULL) return;
 788   // already walkable?
 789   if (walkable()) return;
 790   vmassert(Thread::current() == (Thread*)thread, "not current thread");
 791   vmassert(last_Java_sp() != NULL, "not called from Java code?");


 636   return NULL;
 637 }
 638 
 639 intptr_t* frame::real_fp() const {
 640   if (_cb != NULL) {
 641     // use the frame size if valid
 642     int size = _cb->frame_size();
 643     if (size > 0) {
 644       return unextended_sp() + size;
 645     }
 646   }
 647   // else rely on fp()
 648   assert(! is_compiled_frame(), "unknown compiled frame size");
 649   return fp();
 650 }
 651 
 652 #undef DESCRIBE_FP_OFFSET
 653 
 654 #define DESCRIBE_FP_OFFSET(name)                                        \
 655   {                                                                     \
 656     uint64_t *p = (uint64_t *)fp;                             \
 657     printf("0x%016lx 0x%016lx %s\n", (uint64_t)(p + frame::name##_offset), \
 658            p[frame::name##_offset], #name);                             \
 659   }
 660 
 661 static __thread uint64_t nextfp;
 662 static __thread uint64_t nextpc;
 663 static __thread uint64_t nextsp;
 664 static __thread RegisterMap *reg_map;
 665 
 666 static void printbc(Method *m, intptr_t bcx) {
 667   const char *name;
 668   char buf[16];
 669   if (m->validate_bci_from_bcp((address)bcx) < 0
 670       || !m->contains((address)bcx)) {
 671     name = "???";
 672     snprintf(buf, sizeof buf, "(bad)");
 673   } else {
 674     int bci = m->bci_from((address)bcx);
 675     snprintf(buf, sizeof buf, "%d", bci);
 676     name = Bytecodes::name(m->code_at(bci));
 677   }
 678   ResourceMark rm;
 679   printf("%s : %s ==> %s\n", m->name_and_sig_as_C_string(), buf, name);
 680 }
 681 
 682 void internal_pf(uint64_t sp, uint64_t fp, uint64_t pc, uint64_t bcx) {
 683   if (! fp)
 684     return;
 685 
 686   DESCRIBE_FP_OFFSET(return_addr);
 687   DESCRIBE_FP_OFFSET(link);
 688   DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
 689   DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
 690   DESCRIBE_FP_OFFSET(interpreter_frame_method);
 691   DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
 692   DESCRIBE_FP_OFFSET(interpreter_frame_cache);
 693   DESCRIBE_FP_OFFSET(interpreter_frame_locals);
 694   DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
 695   DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
 696   uint64_t *p = (uint64_t *)fp;
 697 
 698   // We want to see all frames, native and Java.  For compiled and
 699   // interpreted frames we have special information that allows us to
 700   // unwind them; for everything else we assume that the native frame
 701   // pointer chain is intact.
 702   frame this_frame((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 703   if (this_frame.is_compiled_frame() ||
 704       this_frame.is_interpreted_frame()) {
 705     frame sender = this_frame.sender(reg_map);
 706     nextfp = (uint64_t)sender.fp();
 707     nextpc = (uint64_t)sender.pc();
 708     nextsp = (uint64_t)sender.unextended_sp();
 709   } else {
 710     nextfp = p[frame::link_offset];
 711     nextpc = p[frame::return_addr_offset];
 712     nextsp = (uint64_t)&p[frame::sender_sp_offset];
 713   }
 714 
 715   if (bcx == -1ull)
 716     bcx = p[frame::interpreter_frame_bcp_offset];
 717 
 718   if (Interpreter::contains((address)pc)) {
 719     Method* m = (Method*)p[frame::interpreter_frame_method_offset];
 720     if(m && m->is_method()) {
 721       printbc(m, bcx);
 722     } else
 723       printf("not a Method\n");
 724   } else {
 725     CodeBlob *cb = CodeCache::find_blob((address)pc);
 726     if (cb != NULL) {
 727       if (cb->is_nmethod()) {
 728         ResourceMark rm;
 729         nmethod* nm = (nmethod*)cb;
 730         printf("nmethod %s\n", nm->method()->name_and_sig_as_C_string());
 731       } else if (cb->name()) {
 732         printf("CodeBlob %s\n", cb->name());
 733       }
 734     }
 735   }
 736 }
 737 
 738 extern "C" void npf() {
 739   CodeBlob *cb = CodeCache::find_blob((address)nextpc);
 740   // C2 does not always chain the frame pointers when it can, instead
 741   // preferring to use fixed offsets from SP, so a simple leave() does
 742   // not work.  Instead, it adds the frame size to SP then pops FP and
 743   // LR.  We have to do the same thing to get a good call chain.
 744   if (cb && cb->frame_size())
 745     nextfp = nextsp + wordSize * (cb->frame_size() - 2);
 746   internal_pf (nextsp, nextfp, nextpc, -1);
 747 }
 748 
 749 extern "C" void pf(uint64_t sp, uint64_t fp, uint64_t pc,
 750                    uint64_t bcx, uint64_t thread) {
 751   if (!reg_map) {
 752     reg_map = NEW_C_HEAP_OBJ(RegisterMap, mtNone);
 753     ::new (reg_map) RegisterMap((JavaThread*)thread, false);
 754   } else {
 755     *reg_map = RegisterMap((JavaThread*)thread, false);
 756   }
 757 
 758   {
 759     CodeBlob *cb = CodeCache::find_blob((address)pc);
 760     if (cb && cb->frame_size())
 761       fp = sp + wordSize * (cb->frame_size() - 2);
 762   }
 763   internal_pf(sp, fp, pc, bcx);
 764 }
 765 
 766 // support for printing out where we are in a Java method
 767 // needs to be passed current fp and bcp register values
 768 // prints method name, bc index and bytecode name
 769 extern "C" void pm(uint64_t fp, uint64_t bcx) {
 770   DESCRIBE_FP_OFFSET(interpreter_frame_method);
 771   uint64_t *p = (uint64_t *)fp;
 772   Method* m = (Method*)p[frame::interpreter_frame_method_offset];
 773   printbc(m, bcx);
 774 }
 775 
 776 #ifndef PRODUCT
 777 // This is a generic constructor which is only used by pns() in debug.cpp.
 778 frame::frame(void* sp, void* fp, void* pc) {
 779   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 780 }
 781 
 782 void frame::pd_ps() {}
 783 #endif
 784 
 785 void JavaFrameAnchor::make_walkable(JavaThread* thread) {
 786   // last frame set?
 787   if (last_Java_sp() == NULL) return;
 788   // already walkable?
 789   if (walkable()) return;
 790   vmassert(Thread::current() == (Thread*)thread, "not current thread");
 791   vmassert(last_Java_sp() != NULL, "not called from Java code?");
< prev index next >