예제 #1
0
void frame::describe_pd(FrameValues& values, int frame_no) {
  for (int w = 0; w < frame::register_save_words; w++) {
    values.describe(frame_no, sp() + w, err_msg("register save area word %d", w), 1);
  }

  if (is_ricochet_frame()) {
    MethodHandles::RicochetFrame::describe(this, values, frame_no);
  } else if (is_interpreted_frame()) {
    DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
    DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
    DESCRIBE_FP_OFFSET(interpreter_frame_padding);
    DESCRIBE_FP_OFFSET(interpreter_frame_oop_temp);

    // esp, according to Lesp (e.g. not depending on bci), if seems valid
    intptr_t* esp = *interpreter_frame_esp_addr();
    if ((esp >= sp()) && (esp < fp())) {
      values.describe(-1, esp, "*Lesp");
    }
  }

  if (!is_compiled_frame()) {
    if (frame::callee_aggregate_return_pointer_words != 0) {
      values.describe(frame_no, sp() + frame::callee_aggregate_return_pointer_sp_offset, "callee_aggregate_return_pointer_word");
    }
    for (int w = 0; w < frame::callee_register_argument_save_area_words; w++) {
      values.describe(frame_no, sp() + frame::callee_register_argument_save_area_sp_offset + w,
                      err_msg("callee_register_argument_save_area_words %d", w));
    }
  }
}
예제 #2
0
GrowableArray<MonitorInfo*>* javaVFrame::locked_monitors() {
  assert(SafepointSynchronize::is_at_safepoint() || JavaThread::current() == thread(),
         "must be at safepoint or it's a java frame of the current thread");

  GrowableArray<MonitorInfo*>* mons = monitors();
  GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(mons->length());
  if (mons->is_empty()) return result;

  bool found_first_monitor = false;
  ObjectMonitor *pending_monitor = thread()->current_pending_monitor();
  ObjectMonitor *waiting_monitor = thread()->current_waiting_monitor();
  oop pending_obj = (pending_monitor != NULL ? (oop) pending_monitor->object() : (oop) NULL);
  oop waiting_obj = (waiting_monitor != NULL ? (oop) waiting_monitor->object() : (oop) NULL);

  for (int index = (mons->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = mons->at(index);
    if (monitor->eliminated() && is_compiled_frame()) continue; // skip eliminated monitor
    oop obj = monitor->owner();
    if (obj == NULL) continue; // skip unowned monitor
    //
    // Skip the monitor that the thread is blocked to enter or waiting on
    //
    if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) {
      continue;
    }
    found_first_monitor = true;
    result->append(monitor);
  }
  return result;
}
예제 #3
0
void javaVFrame::print() {
  ResourceMark rm;
  vframe::print();
  tty->print("\t");
  method()->print_value();
  tty->cr();
  tty->print_cr("\tbci:    %d", bci());

  print_stack_values("locals",      locals());
  print_stack_values("expressions", expressions());

  GrowableArray<MonitorInfo*>* list = monitors();
  if (list->is_empty()) return;
  tty->print_cr("\tmonitor list:");
  for (int index = (list->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = list->at(index);
    tty->print("\t  obj\t");
    if (monitor->owner_is_scalar_replaced()) {
      Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
      tty->print("( is scalar replaced %s)", k->external_name());
    } else if (monitor->owner() == NULL) {
      tty->print("( null )");
    } else {
      monitor->owner()->print_value();
      tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
    }
    if (monitor->eliminated() && is_compiled_frame())
      tty->print(" ( lock is eliminated )");
    tty->cr();
    tty->print("\t  ");
    monitor->lock()->print_on(tty);
    tty->cr();
  }
}
예제 #4
0
bool javaVFrame::structural_compare(javaVFrame* other) {
  // Check static part
  if (method() != other->method()) return false;
  if (bci()    != other->bci())    return false;

  // Check locals
  StackValueCollection *locs = locals();
  StackValueCollection *other_locs = other->locals();
  assert(locs->size() == other_locs->size(), "sanity check");
  int i;
  for(i = 0; i < locs->size(); i++) {
    // it might happen the compiler reports a conflict and
    // the interpreter reports a bogus int.
    if (       is_compiled_frame() &&       locs->at(i)->type() == T_CONFLICT) continue;
    if (other->is_compiled_frame() && other_locs->at(i)->type() == T_CONFLICT) continue;

    if (!locs->at(i)->equal(other_locs->at(i)))
      return false;
  }

  // Check expressions
  StackValueCollection* exprs = expressions();
  StackValueCollection* other_exprs = other->expressions();
  assert(exprs->size() == other_exprs->size(), "sanity check");
  for(i = 0; i < exprs->size(); i++) {
    if (!exprs->at(i)->equal(other_exprs->at(i)))
      return false;
  }

  return true;
}
예제 #5
0
void frame::follow_roots() {
  if (is_interpreted_frame()) {
    if (has_interpreted_float_marker() && follow_roots_interpreted_float_frame()) return;

    // Follow the roots of the frame
    for (oop* p = sp(); p <= temp_addr(0); p++) {
      MarkSweep::follow_root(p);
    }
    MarkSweep::follow_root((oop*)hp_addr());
    MarkSweep::follow_root(receiver_addr());
    return;
  } 
  
  if (is_compiled_frame()) {
    if (has_compiled_float_marker() && follow_roots_compiled_float_frame()) return;

    for (oop* p = sp(); p < (oop*)fp(); p++) MarkSweep::follow_root(p);
    return;
  }
    
  if (is_entry_frame()) {
    for (oop* p = sp(); p < (oop*)fp(); p++) MarkSweep::follow_root(p);
    return;
  }

  if (is_deoptimized_frame()) {
    // Expression stack
    oop* end = (oop*)fp() + frame_real_sender_sp_offset;
    for (oop* p = sp(); p < end; p++) MarkSweep::follow_root(p);
    MarkSweep::follow_root((oop*)frame_array_addr());
    return;
  }
}
예제 #6
0
void frame::adjust_unextended_sp() {
  // If we are returning to a compiled MethodHandle call site, the
  // saved_fp will in fact be a saved value of the unextended SP. The
  // simplest way to tell whether we are returning to such a call site
  // is as follows:

  if (is_compiled_frame() && false /*is_at_mh_callsite()*/) {  // TODO PPC port
    // If the sender PC is a deoptimization point, get the original
    // PC. For MethodHandle call site the unextended_sp is stored in
    // saved_fp.
    _unextended_sp = _fp - _cb->frame_size();

#ifdef ASSERT
    nmethod *sender_nm = _cb->as_nmethod_or_null();
    assert(sender_nm && *_sp == *_unextended_sp, "backlink changed");

    intptr_t* sp = _unextended_sp;  // check if stack can be walked from here
    for (int x = 0; x < 5; ++x) {   // check up to a couple of backlinks
      intptr_t* prev_sp = *(intptr_t**)sp;
      if (prev_sp == 0) break;      // end of stack
      assert(prev_sp>sp, "broken stack");
      sp = prev_sp;
    }

    if (sender_nm->is_deopt_mh_entry(_pc)) { // checks for deoptimization
      address original_pc = sender_nm->get_original_pc(this);
      assert(sender_nm->insts_contains(original_pc), "original PC must be in nmethod");
      assert(sender_nm->is_method_handle_return(original_pc), "must be");
    }
#endif
  }
}
예제 #7
0
bool frame::should_be_deoptimized() const {
  if (!is_compiled_frame()) return false;
  nmethod* nm = code();
  if (TraceApplyChange) {
    std->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false"); 
    nm->print_value_on(std);
    std->cr();
  }
  return nm->is_marked_for_deoptimization();
}
예제 #8
0
intptr_t* frame::real_fp() const {
  if (_cb != NULL) {
    // use the frame size if valid
    int size = _cb->frame_size();
    if (size > 0) {
      return unextended_sp() + size;
    }
  }
  // else rely on fp()
  assert(! is_compiled_frame(), "unknown compiled frame size");
  return fp();
}
예제 #9
0
void frame::print() const {
  std->print("[%s frame: fp = %#lx, sp = %#lx, pc = %#lx", print_name(), fp(), sp(), pc());
  if (is_compiled_frame()) {
    std->print(", nm = %#x", findNMethod(pc()));
  } else if (is_interpreted_frame()) {
    std->print(", hp = %#x, method = %#x", hp(), method());
  }
  std->print_cr("]");

  if (PrintLongFrames) {
    for (oop* p = sp(); p < (oop*)fp(); p++)
      std->print_cr("  - 0x%lx: 0x%lx", p, *p);
  }
}
예제 #10
0
void frame::oop_iterate(OopClosure* blk) {
  if (is_interpreted_frame()) {
    if (has_interpreted_float_marker() && oop_iterate_interpreted_float_frame(blk)) return;
 
    // lprintf("Frame: fp = %#lx, sp = %#lx]\n", fp(), sp());
    for (oop* p = sp(); p <= temp_addr(0); p++) {
      // lprintf("\t[%#lx]: ", p);
      // (*p)->short_print();
      // lprintf("\n");
      blk->do_oop(p);
    }
    // lprintf("\t{%#lx}: ", receiver_addr());
    // (*receiver_addr())->short_print();
    // lprintf("\n");
    blk->do_oop(receiver_addr());
    return;
  }
  
  if (is_compiled_frame()) {
    if (has_compiled_float_marker() && oop_iterate_compiled_float_frame(blk)) return;

     // All oops are [sp..fp[
    for (oop* p = sp(); p < (oop*)fp(); p++) {
      blk->do_oop(p);
    }
    return;
  }

  if (is_entry_frame()) {
    // All oops are [sp..fp[
    for (oop* p = sp(); p < (oop*)fp(); p++) {
      blk->do_oop(p);
    }
    return;
  }
  
  if (is_deoptimized_frame()) {
    // Expression stack
    oop* end = (oop*)fp() + frame_real_sender_sp_offset;
    // All oops are [sp..end[
    for (oop* p = sp(); p < end; p++) {
      blk->do_oop(p);
    }
    blk->do_oop((oop*)frame_array_addr());
    return;
  }
}
예제 #11
0
IC_Iterator* frame::current_ic_iterator() const {

  if (is_interpreted_frame()) {
    InterpretedIC* ic = current_interpretedIC();
    if (ic && !Bytecodes::is_send_code(ic->send_code())) return NULL;
    return ic ? new InterpretedIC_Iterator(ic) : NULL;
  }

  if (is_compiled_frame()) {
    CompiledIC* ic = current_compiledIC();
    return  ic->inlineCache() 
          ? new CompiledIC_Iterator(ic)
	  : NULL; // a perform, not a send
  }

  // entry or deoptimized frame
  return NULL;
}
예제 #12
0
nmethod* frame::code() const {
  assert(is_compiled_frame(), "no code");
  return findNMethod(pc());
}
예제 #13
0
CompiledIC* frame::current_compiledIC() const {
  return is_compiled_frame()
       ? CompiledIC_from_return_addr(pc())  // may fail if current frame isn't at a send -- caller must know
       : NULL;
}
예제 #14
0
char* frame::print_name() const {
  if (is_interpreted_frame()) return "interpreted";
  if (is_compiled_frame())    return "compiled";
  if (is_deoptimized_frame()) return "deoptimized";
  return "C";
}
예제 #15
0
void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
  ResourceMark rm;

  // If this is the first frame, and java.lang.Object.wait(...) then print out the receiver.
  if (frame_count == 0) {
    if (method()->name() == vmSymbols::wait_name() &&
        method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
      StackValueCollection* locs = locals();
      if (!locs->is_empty()) {
        StackValue* sv = locs->at(0);
        if (sv->type() == T_OBJECT) {
          Handle o = locs->at(0)->get_obj();
          print_locked_object_class_name(st, o, "waiting on");
        }
      }
    } else if (thread()->current_park_blocker() != NULL) {
      oop obj = thread()->current_park_blocker();
      Klass* k = obj->klass();
      st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", (address)obj, k->external_name());
    }
  }


  // Print out all monitors that we have locked or are trying to lock
  GrowableArray<MonitorInfo*>* mons = monitors();
  if (!mons->is_empty()) {
    bool found_first_monitor = false;
    for (int index = (mons->length()-1); index >= 0; index--) {
      MonitorInfo* monitor = mons->at(index);
      if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code
        if (monitor->owner_is_scalar_replaced()) {
          Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
          st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name());
        } else {
          oop obj = monitor->owner();
          if (obj != NULL) {
            print_locked_object_class_name(st, obj, "eliminated");
          }
        }
        continue;
      }
      if (monitor->owner() != NULL) {

        // First, assume we have the monitor locked. If we haven't found an
        // owned monitor before and this is the first frame, then we need to
        // see if we have completed the lock or we are blocked trying to
        // acquire it - we can only be blocked if the monitor is inflated

        const char *lock_state = "locked"; // assume we have the monitor locked
        if (!found_first_monitor && frame_count == 0) {
          markOop mark = monitor->owner()->mark();
          if (mark->has_monitor() &&
              mark->monitor() == thread()->current_pending_monitor()) {
            lock_state = "waiting to lock";
          }
        }

        found_first_monitor = true;
        print_locked_object_class_name(st, monitor->owner(), lock_state);
      }
    }
  }
}
예제 #16
0
void frame::print_for_deoptimization(outputStream* st) {
 ResourceMark rm;
 st->print(" - ");
 if (is_interpreted_frame()) {
   st->print("I ");
   interpretedVFrame* vf = (interpretedVFrame*) vframe::new_vframe(this);
   vf->method()->print_value_on(st);
   if (ActivationShowBCI) {
     st->print(" bci=%d ", vf->bci());
   }
   std->print_cr(" @ 0x%lx", fp());
   print_context_chain(vf->interpreter_context(), st);
   if (ActivationShowExpressionStack) {
     GrowableArray<oop>* stack = vf->expression_stack();
     for (int index = 0; index < stack->length(); index++) {
       st->print("    %3d: ", index);
       stack->at(index)->print_value_on(st);
       st->cr();
     }
   }
   return;
 } 

 if (is_compiled_frame()) {
   st->print("C ");
   compiledVFrame* vf = (compiledVFrame*) vframe::new_vframe(this);
   assert(vf->is_compiled_frame(), "should be compiled vframe");
   vf->code()->print_value_on(st);
   std->print_cr(" @ 0x%lx", fp());

   while (true) {
     st->print("    ");
     vf->method()->print_value_on(st);
     std->print_cr(" @ %d", vf->scope()->offset());
     print_context_chain(vf->compiled_context(), st);
     if (vf->is_top()) break;
     vf = (compiledVFrame*) vf->sender();
     assert(vf->is_compiled_frame(), "should be compiled vframe");
   }
   return;
 }

 if (is_deoptimized_frame()) {
   st->print("D "); 
   frame_array()->print_value();
   std->print_cr(" @ 0x%lx", fp());

   deoptimizedVFrame* vf = (deoptimizedVFrame*) vframe::new_vframe(this);
   assert(vf->is_deoptimized_frame(), "should be deoptimized vframe");
   while (true) {
     st->print("    ");
     vf->method()->print_value_on(st);
     std->cr();
     print_context_chain(vf->deoptimized_context(), st);
     if (vf->is_top()) break;
     vf = (deoptimizedVFrame*) vf->sender();
     assert(vf->is_deoptimized_frame(), "should be deoptimized vframe");
   }
   return;
 }

 st->print("E foreign frame @ 0x%lx", fp());
}
inline bool frame::is_known_frame() const { return is_interpreted_frame() || is_native_frame() || is_compiled_frame(); }
inline bool frame::is_java_frame() const { return is_interpreted_frame() || is_compiled_frame(); }
예제 #19
0
 bool is_delta_frame()       const	{ return is_interpreted_frame() || is_compiled_frame(); }