src/cpu/x86/vm/frame_x86.cpp

Print this page
rev 5697 : 8028412: AsyncGetCallTrace() is broken on x86 in JDK7u40
Reviewed-by:


  77     return false;
  78   }
  79 
  80   // an fp must be within the stack and above (but not equal) sp
  81   // second evaluation on fp+ is added to handle situation where fp is -1
  82   bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
  83 
  84   // We know sp/unextended_sp are safe only fp is questionable here
  85 
  86   // If the current frame is known to the code cache then we can attempt to
  87   // to construct the sender and do some validation of it. This goes a long way
  88   // toward eliminating issues when we get in frame construction code
  89 
  90   if (_cb != NULL ) {
  91 
  92     // First check if frame is complete and tester is reliable
  93     // Unfortunately we can only check frame complete for runtime stubs and nmethod
  94     // other generic buffer blobs are more problematic so we just assume they are
  95     // ok. adapter blobs never have a frame complete and are never ok.
  96 
  97     // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
  98 
  99     if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) {
 100       //assert(0, "Invalid frame_size");
 101       return false;
 102     }
 103 
 104     if (!_cb->is_frame_complete_at(_pc)) {
 105       if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
 106         return false;
 107       }
 108     }
 109 
 110     // Could just be some random pointer within the codeBlob
 111     if (!_cb->code_contains(_pc)) {
 112       return false;
 113     }
 114 
 115     // Entry frame checks
 116     if (is_entry_frame()) {
 117       // an entry frame must have a valid fp.
 118 
 119       if (!fp_safe) return false;
 120 
 121       // Validate the JavaCallWrapper an entry frame must have
 122 
 123       address jcw = (address)entry_frame_call_wrapper();


 127       return jcw_safe;
 128 
 129     }
 130 
 131     intptr_t* sender_sp = NULL;
 132     address   sender_pc = NULL;
 133 
 134     if (is_interpreted_frame()) {
 135       // fp must be safe
 136       if (!fp_safe) {
 137         return false;
 138       }
 139 
 140       sender_pc = (address) this->fp()[return_addr_offset];
 141       sender_sp = (intptr_t*) addr_at(sender_sp_offset);
 142 
 143     } else {
 144       // must be some sort of compiled/runtime frame
 145       // fp does not have to be safe (although it could be check for c1?)
 146 





 147       sender_sp = _unextended_sp + _cb->frame_size();
 148       // On Intel the return_address is always the word on the stack
 149       sender_pc = (address) *(sender_sp-1);
 150     }
 151 
 152 
 153     // If the potential sender is the interpreter then we can do some more checking
 154     if (Interpreter::contains(sender_pc)) {
 155 
 156       // ebp is always saved in a recognizable place in any code we generate. However
 157       // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
 158       // is really a frame pointer.
 159 
 160       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
 161       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 162 
 163       if (!saved_fp_safe) {
 164         return false;
 165       }
 166 




  77     return false;
  78   }
  79 
  80   // an fp must be within the stack and above (but not equal) sp
  81   // second evaluation on fp+ is added to handle situation where fp is -1
  82   bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
  83 
  84   // We know sp/unextended_sp are safe only fp is questionable here
  85 
  86   // If the current frame is known to the code cache then we can attempt to
  87   // to construct the sender and do some validation of it. This goes a long way
  88   // toward eliminating issues when we get in frame construction code
  89 
  90   if (_cb != NULL ) {
  91 
  92     // First check if frame is complete and tester is reliable
  93     // Unfortunately we can only check frame complete for runtime stubs and nmethod
  94     // other generic buffer blobs are more problematic so we just assume they are
  95     // ok. adapter blobs never have a frame complete and are never ok.
  96 







  97     if (!_cb->is_frame_complete_at(_pc)) {
  98       if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
  99         return false;
 100       }
 101     }
 102 
 103     // Could just be some random pointer within the codeBlob
 104     if (!_cb->code_contains(_pc)) {
 105       return false;
 106     }
 107 
 108     // Entry frame checks
 109     if (is_entry_frame()) {
 110       // an entry frame must have a valid fp.
 111 
 112       if (!fp_safe) return false;
 113 
 114       // Validate the JavaCallWrapper an entry frame must have
 115 
 116       address jcw = (address)entry_frame_call_wrapper();


 120       return jcw_safe;
 121 
 122     }
 123 
 124     intptr_t* sender_sp = NULL;
 125     address   sender_pc = NULL;
 126 
 127     if (is_interpreted_frame()) {
 128       // fp must be safe
 129       if (!fp_safe) {
 130         return false;
 131       }
 132 
 133       sender_pc = (address) this->fp()[return_addr_offset];
 134       sender_sp = (intptr_t*) addr_at(sender_sp_offset);
 135 
 136     } else {
 137       // must be some sort of compiled/runtime frame
 138       // fp does not have to be safe (although it could be check for c1?)
 139 
 140       // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
 141       if (_cb->frame_size() <= 0) {
 142         return false;
 143       }
 144 
 145       sender_sp = _unextended_sp + _cb->frame_size();
 146       // On Intel the return_address is always the word on the stack
 147       sender_pc = (address) *(sender_sp-1);
 148     }
 149 
 150 
 151     // If the potential sender is the interpreter then we can do some more checking
 152     if (Interpreter::contains(sender_pc)) {
 153 
 154       // ebp is always saved in a recognizable place in any code we generate. However
 155       // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
 156       // is really a frame pointer.
 157 
 158       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
 159       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 160 
 161       if (!saved_fp_safe) {
 162         return false;
 163       }
 164