Exemplo n.º 1
0
//
// Count the number of objects for a lightweight monitor. The hobj
// parameter is object that owns the monitor so this routine will
// count the number of times the same object was locked by frames
// in java_thread.
//
jint
JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
  jint ret = 0;
  if (!java_thread->has_last_Java_frame()) {
    return ret;  // no Java frames so no monitors
  }

  ResourceMark rm;
  HandleMark   hm;
  RegisterMap  reg_map(java_thread);

  for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL;
                                                 jvf = jvf->java_sender()) {
    GrowableArray<MonitorInfo*>* mons = jvf->monitors();
    if (!mons->is_empty()) {
      for (int i = 0; i < mons->length(); i++) {
        MonitorInfo *mi = mons->at(i);
        if (mi->owner_is_scalar_replaced()) continue;

        // see if owner of the monitor is our object
        if (mi->owner() != NULL && mi->owner() == hobj()) {
          ret++;
        }
      }
    }
  }
  return ret;
}
Exemplo n.º 2
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();
  }
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
void ConcurrentLocksDump::print_locks_on(JavaThread* t, outputStream* st) {
  st->print_cr("   Locked ownable synchronizers:");
  ThreadConcurrentLocks* tcl = thread_concurrent_locks(t);
  GrowableArray<instanceOop>* locks = (tcl != NULL ? tcl->owned_locks() : NULL);
  if (locks == NULL || locks->is_empty()) {
    st->print_cr("\t- None");
    st->cr();
    return;
  }

  for (int i = 0; i < locks->length(); i++) {
    instanceOop obj = locks->at(i);
    st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", p2i(obj), obj->klass()->external_name());
  }
  st->cr();
}
Exemplo n.º 5
0
void javaVFrame::print_lock_info(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 && method()->name() == vmSymbols::wait_name() && 
      instanceKlass::cast(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();    
        if (o.not_null()) {
          instanceKlass* ik = instanceKlass::cast(o->klass());
          tty->print_cr("\t- waiting on <" INTPTR_FORMAT "> (a %s)", o(), ik->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->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 the thread is blocked.
        //
        const char *lock_state = "locked"; // assume we have the monitor locked
        if (!found_first_monitor && frame_count == 0) {
          switch (thread()->thread_state()) {
          case _thread_blocked:
          case _thread_blocked_trans:
            lock_state = "waiting to lock";
            break;
          }
        }
        found_first_monitor = true;
        instanceKlass* ik = instanceKlass::cast(monitor->owner()->klass());
        tty->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", lock_state, monitor->owner(), ik->external_name());
      }
    }  
  }
}
Exemplo n.º 6
0
//
// Count the number of entries for a lightweight monitor. The hobj
// parameter is object that owns the monitor so this routine will
// count the number of times the same object was locked by this
// frame.
//
jint javaVFrame::count_lock_entries(Handle hobj) {
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = monitors();
  if (mons->is_empty()) {
    return 0;  // this javaVFrame holds no monitors
  }

  jint ret = 0;
  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);

    // see if owner of the monitor is our object
    if (mi->owner() != NULL && mi->owner() == hobj()) {
      ret++;
    }
  }

  return ret;
}
Exemplo n.º 7
0
void LoopFinder::gather_loop_blocks(LoopList* loops) {
  int lng = loops->length();
  BitMap blocks_in_loop(max_blocks());
  for (int i = 0; i < lng; i++) {
    // for each loop do the following
    blocks_in_loop.clear();
    Loop* loop = loops->at(i);
    BlockList* ends = loop->ends();
    if (!loop->is_end(loop->start())) {
      GrowableArray<BlockBegin*>* stack = new GrowableArray<BlockBegin*>();
      blocks_in_loop.at_put(loop->start()->block_id(), true);
      
      // insert all the ends into the list
      for (int i = 0; i < ends->length(); i++) {
        blocks_in_loop.at_put(ends->at(i)->block_id()  , true);
        stack->push(ends->at(i));
      }
      
      while (!stack->is_empty()) {
        BlockBegin* bb = stack->pop();
        BlockLoopInfo* bli = get_block_info(bb);
        // push all predecessors that are not yet in loop
        int npreds = bli->nof_preds();
        for (int m = 0; m < npreds; m++) {
          BlockBegin* pred = bli->pred_no(m);
          if (!blocks_in_loop.at(pred->block_id())) {
            blocks_in_loop.at_put(pred->block_id(), true);
            loop->append_node(pred);
            stack->push(pred);
          }
        }
      }
      loop->append_node(loop->start());
    }
    // insert all the ends into the loop
    for (int i = 0; i < ends->length(); i++) {
      loop->append_node(ends->at(i));
    }
  }
}
Exemplo n.º 8
0
//
// Fabricate heavyweight monitor information for each lightweight monitor
// found in the Java VFrame.
//
void javaVFrame::jvmpi_fab_heavy_monitors(bool query, int* fab_index, int frame_count, GrowableArray<ObjectMonitor*>* fab_list) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  ResourceMark rm;

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

  bool found_first_monitor = false;
  for (int index = (mons->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = mons->at(index);
    if (monitor->owner() == NULL) continue; // skip unowned monitor
    //
    // If we haven't found a monitor before, this is the first frame, and
    // the thread is blocked, then we are trying to enter this monitor.
    // We skip it because we have already seen it before from the monitor 
    // cache walk.
    //
    if (!found_first_monitor && frame_count == 0) {
      switch (thread()->thread_state()) {
      case _thread_blocked:
      case _thread_blocked_trans:
        continue;
      }
    }
    found_first_monitor = true;

    markOop mark = monitor->owner()->mark();
    if (mark->has_locker()) {
      if (!query) {   // not just counting so create and store at the current element
        // fabricate the heavyweight monitor from lightweight info
        ObjectMonitor *heavy = new ObjectMonitor();
        heavy->set_object(monitor->owner());  // use the owning object
        heavy->set_owner(thread());           // use thread instead of stack address for speed
        fab_list->at_put(*fab_index, heavy);
      }
      (*fab_index)++;
    }
  }
}
Exemplo n.º 9
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"); monitor->owner()->print_value(); 
    tty->print("(" INTPTR_FORMAT ")", monitor->owner());
    tty->cr();
    tty->print("\t  ");
    monitor->lock()->print_on(tty);
    tty->cr(); 
  }
}
Exemplo n.º 10
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);
      }
    }
  }
}
Exemplo n.º 11
0
void vframeArrayElement::fill_in(compiledVFrame* vf) {

// Copy the information from the compiled vframe to the
// interpreter frame we will be creating to replace vf

  _method = vf->method();
  _bci    = vf->raw_bci();
  _reexecute = vf->should_reexecute();

  int index;

  // Get the monitors off-stack

  GrowableArray<MonitorInfo*>* list = vf->monitors();
  if (list->is_empty()) {
    _monitors = NULL;
  } else {

    // Allocate monitor chunk
    _monitors = new MonitorChunk(list->length());
    vf->thread()->add_monitor_chunk(_monitors);

    // Migrate the BasicLocks from the stack to the monitor chunk
    for (index = 0; index < list->length(); index++) {
      MonitorInfo* monitor = list->at(index);
      assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already");
      assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
      BasicObjectLock* dest = _monitors->at(index);
      dest->set_obj(monitor->owner());
      monitor->lock()->move_to(monitor->owner(), dest->lock());
    }
  }

  // Convert the vframe locals and expressions to off stack
  // values. Because we will not gc all oops can be converted to
  // intptr_t (i.e. a stack slot) and we are fine. This is
  // good since we are inside a HandleMark and the oops in our
  // collection would go away between packing them here and
  // unpacking them in unpack_on_stack.

  // First the locals go off-stack

  // FIXME this seems silly it creates a StackValueCollection
  // in order to get the size to then copy them and
  // convert the types to intptr_t size slots. Seems like it
  // could do it in place... Still uses less memory than the
  // old way though

  StackValueCollection *locs = vf->locals();
  _locals = new StackValueCollection(locs->size());
  for(index = 0; index < locs->size(); index++) {
    StackValue* value = locs->at(index);
    switch(value->type()) {
      case T_OBJECT:
        assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
        // preserve object type
        _locals->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
        break;
      case T_CONFLICT:
        // A dead local.  Will be initialized to null/zero.
        _locals->add( new StackValue());
        break;
      case T_INT:
        _locals->add( new StackValue(value->get_int()));
        break;
      default:
        ShouldNotReachHere();
    }
  }

  // Now the expressions off-stack
  // Same silliness as above

  StackValueCollection *exprs = vf->expressions();
  _expressions = new StackValueCollection(exprs->size());
  for(index = 0; index < exprs->size(); index++) {
    StackValue* value = exprs->at(index);
    switch(value->type()) {
      case T_OBJECT:
        assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
        // preserve object type
        _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
        break;
      case T_CONFLICT:
        // A dead stack element.  Will be initialized to null/zero.
        // This can occur when the compiler emits a state in which stack
        // elements are known to be dead (because of an imminent exception).
        _expressions->add( new StackValue());
        break;
      case T_INT:
        _expressions->add( new StackValue(value->get_int()));
        break;
      default:
        ShouldNotReachHere();
    }
  }
}
Exemplo n.º 12
0
 bool has_more_nodes() const { return !_path.is_empty(); }
 bool              has_dependencies() const     { return !_dependencies.is_empty(); }
Exemplo n.º 14
0
// Save JNI local handles for any objects that this frame owns.
jvmtiError
JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) {
  jvmtiError err = JVMTI_ERROR_NONE;
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = jvf->monitors();
  if (mons->is_empty()) {
    return err;  // this javaVFrame holds no monitors
  }

  HandleMark hm;
  oop wait_obj = NULL;
  {
    // save object of current wait() call (if any) for later comparison
    ObjectMonitor *mon = java_thread->current_waiting_monitor();
    if (mon != NULL) {
      wait_obj = (oop)mon->object();
    }
  }
  oop pending_obj = NULL;
  {
    // save object of current enter() call (if any) for later comparison
    ObjectMonitor *mon = java_thread->current_pending_monitor();
    if (mon != NULL) {
      pending_obj = (oop)mon->object();
    }
  }

  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);

    if (mi->owner_is_scalar_replaced()) continue;

    oop obj = mi->owner();
    if (obj == NULL) {
      // this monitor doesn't have an owning object so skip it
      continue;
    }

    if (wait_obj == obj) {
      // the thread is waiting on this monitor so it isn't really owned
      continue;
    }

    if (pending_obj == obj) {
      // the thread is pending on this monitor so it isn't really owned
      continue;
    }

    if (owned_monitors_list->length() > 0) {
      // Our list has at least one object on it so we have to check
      // for recursive object locking
      bool found = false;
      for (int j = 0; j < owned_monitors_list->length(); j++) {
        jobject jobj = ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(j))->monitor;
        oop check = JNIHandles::resolve(jobj);
        if (check == obj) {
          found = true;  // we found the object
          break;
        }
      }

      if (found) {
        // already have this object so don't include it
        continue;
      }
    }

    // add the owning object to our list
    jvmtiMonitorStackDepthInfo *jmsdi;
    err = allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
    if (err != JVMTI_ERROR_NONE) {
        return err;
    }
    Handle hobj(obj);
    jmsdi->monitor = jni_reference(calling_thread, hobj);
    jmsdi->stack_depth = stack_depth;
    owned_monitors_list->append(jmsdi);
  }

  return err;
}
Exemplo n.º 15
0
// Save global JNI handles for any objects that this thread owns.
void javaVFrame::save_lock_entries(GrowableArray<jobject>* handle_list) {
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = monitors();
  if (mons->is_empty()) {
    return;  // this javaVFrame holds no monitors
  }

  HandleMark hm;
  oop wait_obj = NULL;
  {
    // save object of current wait() call (if any) for later comparison
    ObjectMonitor *mon = thread()->current_waiting_monitor();
    if (mon != NULL) {
      wait_obj = (oop)mon->object();
    }
  }
  oop pending_obj = NULL;
  {
    // save object of current enter() call (if any) for later comparison
    ObjectMonitor *mon = thread()->current_pending_monitor();
    if (mon != NULL) {
      pending_obj = (oop)mon->object();
    }
  }

  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);

    oop obj = mi->owner();
    if (obj == NULL) {
      // this monitor doesn't have an owning object so skip it
      continue;
    }

    if (wait_obj == obj) {
      // the thread is waiting on this monitor so it isn't really owned
      continue;
    }

    if (pending_obj == obj) {
      // the thread is pending on this monitor so it isn't really owned
      continue;
    }

    if (handle_list->length() > 0) {
      // Our list has at least one object on it so we have to check
      // for recursive object locking
      bool found = false;
      for (int j = 0; j < handle_list->length(); j++) {
        jobject jobj = handle_list->at(j);
        oop check = JNIHandles::resolve(jobj);
        if (check == obj) {
          found = true;  // we found the object
          break;
        }
      }

      if (found) {
        // already have this object so don't include it
        continue;
      }
    }

    // add the owning object to our list
    Handle hobj(obj);
    jobject jobj = (jobject)JNIHandles::make_global(hobj);
    handle_list->append(jobj);
  }
}