예제 #1
0
// ------------------------------------------------------------------
// ciMethod::uses_balanced_monitors
//
// Does this method use monitors in a strict stack-disciplined manner?
bool ciMethod::has_balanced_monitors() {
  check_is_loaded();
  if (_balanced_monitors) return true;

  // Analyze the method to see if monitors are used properly.
  VM_ENTRY_MARK;
  methodHandle method(THREAD, get_Method());
  assert(method->has_monitor_bytecodes(), "should have checked this");

  // Check to see if a previous compilation computed the
  // monitor-matching analysis.
  if (method->guaranteed_monitor_matching()) {
    _balanced_monitors = true;
    return true;
  }

  {
    EXCEPTION_MARK;
    ResourceMark rm(THREAD);
    GeneratePairingInfo gpi(method);
    gpi.compute_map(CATCH);
    if (!gpi.monitor_safe()) {
      return false;
    }
    method->set_guaranteed_monitor_matching();
    _balanced_monitors = true;
  }
  return true;
}
예제 #2
0
// ------------------------------------------------------------------
// ciMethod::resolve_vtable_index
//
// Given a known receiver klass, find the vtable index for the call.
// Return Method::invalid_vtable_index if the vtable_index is unknown.
int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
   check_is_loaded();

   int vtable_index = Method::invalid_vtable_index;
   // Only do lookup if receiver klass has been linked.  Otherwise,
   // the vtable has not been setup, and the LinkResolver will fail.
   if (!receiver->is_interface()
       && (!receiver->is_instance_klass() ||
           receiver->as_instance_klass()->is_linked())) {
     VM_ENTRY_MARK;

     KlassHandle caller_klass (THREAD, caller->get_Klass());
     KlassHandle h_recv       (THREAD, receiver->get_Klass());
     Symbol* h_name = name()->get_symbol();
     Symbol* h_signature = signature()->get_symbol();

     vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
     if (vtable_index == Method::nonvirtual_vtable_index) {
       // A statically bound method.  Return "no such index".
       vtable_index = Method::invalid_vtable_index;
     }
   }

   return vtable_index;
}
예제 #3
0
// ------------------------------------------------------------------
// ciMethod::itable_index
//
// Get the position of this method's entry in the itable, if any.
int ciMethod::itable_index() {
  check_is_loaded();
  assert(holder()->is_linked(), "must be linked");
  VM_ENTRY_MARK;
  Method* m = get_Method();
  if (!m->has_itable_index())
    return Method::nonvirtual_vtable_index;
  return m->itable_index();
}
예제 #4
0
// ------------------------------------------------------------------
// ciMethod::native_entry
//
// Get the address of this method's native code, if any.
address ciMethod::native_entry() {
  check_is_loaded();
  assert(flags().is_native(), "must be native method");
  VM_ENTRY_MARK;
  Method* method = get_Method();
  address entry = method->native_function();
  assert(entry != NULL, "must be valid entry point");
  return entry;
}
예제 #5
0
// ------------------------------------------------------------------
// ciMethod::raw_liveness_at_bci
//
// Which local variables are live at a specific bci?
MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {
  check_is_loaded();
  if (_liveness == NULL) {
    // Create the liveness analyzer.
    Arena* arena = CURRENT_ENV->arena();
    _liveness = new (arena) MethodLiveness(arena, this);
    _liveness->compute_liveness();
  }
  return _liveness->get_liveness_at(bci);
}
예제 #6
0
// ------------------------------------------------------------------
// ciMethod::bci_block_start
//
// Marks all bcis where a new basic block starts
const BitMap ciMethod::bci_block_start() {
  check_is_loaded();
  if (_liveness == NULL) {
    // Create the liveness analyzer.
    Arena* arena = CURRENT_ENV->arena();
    _liveness = new (arena) MethodLiveness(arena, this);
    _liveness->compute_liveness();
  }

  return _liveness->get_bci_block_start();
}
예제 #7
0
// ------------------------------------------------------------------
// invokedynamic support
//
bool ciMethod::is_method_handle_invoke() const {
  check_is_loaded();
  bool flag = ((flags().as_int() & JVM_MH_INVOKE_BITS) == JVM_MH_INVOKE_BITS);
#ifdef ASSERT
  {
    VM_ENTRY_MARK;
    bool flag2 = get_methodOop()->is_method_handle_invoke();
    assert(flag == flag2, "consistent");
  }
#endif //ASSERT
  return flag;
}
예제 #8
0
// ------------------------------------------------------------------
// ciMethod::resolve_invoke
//
// Given a known receiver klass, find the target for the call.
// Return NULL if the call has no target or the target is abstract.
ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) {
   check_is_loaded();
   VM_ENTRY_MARK;

   KlassHandle caller_klass (THREAD, caller->get_Klass());
   KlassHandle h_recv       (THREAD, exact_receiver->get_Klass());
   KlassHandle h_resolved   (THREAD, holder()->get_Klass());
   Symbol* h_name      = name()->get_symbol();
   Symbol* h_signature = signature()->get_symbol();

   methodHandle m;
   // Only do exact lookup if receiver klass has been linked.  Otherwise,
   // the vtable has not been setup, and the LinkResolver will fail.
   if (h_recv->oop_is_array()
        ||
       InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
     if (holder()->is_interface()) {
       m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass);
     } else {
       m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass);
     }
   }

   if (m.is_null()) {
     // Return NULL only if there was a problem with lookup (uninitialized class, etc.)
     return NULL;
   }

   ciMethod* result = this;
   if (m() != get_Method()) {
     result = CURRENT_THREAD_ENV->get_method(m());
   }

   // Don't return abstract methods because they aren't
   // optimizable or interesting.
   if (result->is_abstract()) {
     return NULL;
   } else {
     return result;
   }
}
예제 #9
0
// ------------------------------------------------------------------
// ciMethod::itable_index
//
// Get the position of this method's entry in the itable, if any.
int ciMethod::itable_index() {
  check_is_loaded();
  assert(holder()->is_linked(), "must be linked");
  VM_ENTRY_MARK;
  return klassItable::compute_itable_index(get_methodOop());
}
예제 #10
0
ciInstance* ciMethod::method_handle_type() {
  check_is_loaded();
  VM_ENTRY_MARK;
  oop mtype = get_methodOop()->method_handle_type();
  return CURRENT_THREAD_ENV->get_object(mtype)->as_instance();
}
예제 #11
0
// ------------------------------------------------------------------
// ciMethod::interpreter_entry
//
// Get the entry point for running this method in the interpreter.
address ciMethod::interpreter_entry() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return Interpreter::entry_for_method(mh);
}
예제 #12
0
// ------------------------------------------------------------------
// ciMethod::vtable_index
//
// Get the position of this method's entry in the vtable, if any.
int ciMethod::vtable_index() {
  check_is_loaded();
  assert(holder()->is_linked(), "must be linked");
  VM_ENTRY_MARK;
  return get_Method()->vtable_index();
}
 // Basic method information.
 ciFlags flags() const                          { check_is_loaded(); return _flags; }
예제 #14
0
// ------------------------------------------------------------------
// ciMethod::find_monomorphic_target
//
// Given a certain calling environment, find the monomorphic target
// for the call.  Return NULL if the call is not monomorphic in
// its calling environment, or if there are only abstract methods.
// The returned method is never abstract.
// Note: If caller uses a non-null result, it must inform dependencies
// via assert_unique_concrete_method or assert_leaf_type.
ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
                                            ciInstanceKlass* callee_holder,
                                            ciInstanceKlass* actual_recv) {
  check_is_loaded();

  if (actual_recv->is_interface()) {
    // %%% We cannot trust interface types, yet.  See bug 6312651.
    return NULL;
  }

  ciMethod* root_m = resolve_invoke(caller, actual_recv);
  if (root_m == NULL) {
    // Something went wrong looking up the actual receiver method.
    return NULL;
  }
  assert(!root_m->is_abstract(), "resolve_invoke promise");

  // Make certain quick checks even if UseCHA is false.

  // Is it private or final?
  if (root_m->can_be_statically_bound()) {
    return root_m;
  }

  if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) {
    // Easy case.  There is no other place to put a method, so don't bother
    // to go through the VM_ENTRY_MARK and all the rest.
    return root_m;
  }

  // Array methods (clone, hashCode, etc.) are always statically bound.
  // If we were to see an array type here, we'd return root_m.
  // However, this method processes only ciInstanceKlasses.  (See 4962591.)
  // The inline_native_clone intrinsic narrows Object to T[] properly,
  // so there is no need to do the same job here.

  if (!UseCHA)  return NULL;

  VM_ENTRY_MARK;

  methodHandle target;
  {
    MutexLocker locker(Compile_lock);
    Klass* context = actual_recv->get_Klass();
    target = Dependencies::find_unique_concrete_method(context,
                                                       root_m->get_Method());
    // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.
  }

#ifndef PRODUCT
  if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) {
    tty->print("found a non-root unique target method");
    tty->print_cr("  context = %s", InstanceKlass::cast(actual_recv->get_Klass())->external_name());
    tty->print("  method  = ");
    target->print_short_name(tty);
    tty->cr();
  }
#endif //PRODUCT

  if (target() == NULL) {
    return NULL;
  }
  if (target() == root_m->get_Method()) {
    return root_m;
  }
  if (!root_m->is_public() &&
      !root_m->is_protected()) {
    // If we are going to reason about inheritance, it's easiest
    // if the method in question is public, protected, or private.
    // If the answer is not root_m, it is conservatively correct
    // to return NULL, even if the CHA encountered irrelevant
    // methods in other packages.
    // %%% TO DO: Work out logic for package-private methods
    // with the same name but different vtable indexes.
    return NULL;
  }
  return CURRENT_THREAD_ENV->get_method(target());
}
 int max_stack() const                          { check_is_loaded(); return _max_stack; }
예제 #16
0
bool ciMethod::is_method_handle_adapter() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_methodOop()->is_method_handle_adapter();
}
예제 #17
0
// ------------------------------------------------------------------
// ciMethod::has_linenumber_table
//
// length unknown until decompression
bool    ciMethod::has_linenumber_table() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->has_linenumber_table();
}
 int exception_table_length() const             { check_is_loaded(); return _handler_count; }
 // Can only be used on loaded ciMethods
 int          arg_size() const                  {
   check_is_loaded();
   return _signature->size() + (_flags.is_static() ? 0 : 1);
 }
 bool has_exception_handlers() const            { check_is_loaded(); return _handler_count > 0; }
 vmIntrinsics::ID intrinsic_id() const          { check_is_loaded(); return _intrinsic_id; }
 int max_locals() const                         { check_is_loaded(); return _max_locals; }
예제 #23
0
 int nmethod_age() const                        { check_is_loaded(); return _nmethod_age; }
예제 #24
0
// ------------------------------------------------------------------
// ciMethod::compressed_linenumber_table
u_char* ciMethod::compressed_linenumber_table() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->compressed_linenumber_table();
}
예제 #25
0
 int size_of_parameters() const                 { check_is_loaded(); return _size_of_parameters; }
예제 #26
0
// ------------------------------------------------------------------
// ciMethod::line_number_from_bci
int ciMethod::line_number_from_bci(int bci) const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->line_number_from_bci(bci);
}
 int interpreter_invocation_count() const       { check_is_loaded(); return _interpreter_invocation_count; }
 int code_size() const                          { check_is_loaded(); return _code_size; }
예제 #29
0
// ------------------------------------------------------------------
// ciMethod::is_special_get_caller_class_method
//
bool ciMethod::is_ignored_by_security_stack_walk() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->is_ignored_by_security_stack_walk();
}
 int interpreter_throwout_count() const         { check_is_loaded(); return _interpreter_throwout_count; }