Esempio n. 1
0
// Check if there are any JVM TI prefixes which have been applied to the native method name.
// If any are found, remove them before attemping the look up of the
// native implementation again.
// See SetNativeMethodPrefix in the JVM TI Spec for more details.
address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) {
  ResourceMark rm(THREAD);

  int prefix_count;
  char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
  char* in_name = method->name()->as_C_string();
  char* wrapper_name = in_name;
  // last applied prefix will be first -- go backwards
  for (int i = prefix_count-1; i >= 0; i--) {
    char* prefix = prefixes[i];
    size_t prefix_len = strlen(prefix);
    if (strncmp(prefix, wrapper_name, prefix_len) == 0) {
      // has this prefix remove it
      wrapper_name += prefix_len;
    }
  }
  if (wrapper_name != in_name) {
    // we have a name for a wrapping method
    int wrapper_name_len = (int)strlen(wrapper_name);
    TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len);
    if (wrapper_symbol != NULL) {
      KlassHandle kh(method->method_holder());
      methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol,
                                                                  method->signature());
      if (wrapper_method != NULL && !wrapper_method->is_native()) {
        // we found a wrapper method, use its native entry
        method->set_is_prefixed_native();
        return lookup_entry(wrapper_method, in_base_library, THREAD);
      }
    }
  }
  return NULL;
}
VerificationType StackMapFrame::set_locals_from_arg(
    const methodHandle m, VerificationType thisKlass, TRAPS) {
  SignatureStream ss(m->signature());
  int init_local_num = 0;
  if (!m->is_static()) {
    init_local_num++;
    // add one extra argument for instance method
    if (m->name() == vmSymbols::object_initializer_name() &&
       thisKlass.name() != vmSymbols::java_lang_Object()) {
      _locals[0] = VerificationType::uninitialized_this_type();
      _flags |= FLAG_THIS_UNINIT;
    } else {
      _locals[0] = thisKlass;
    }
  }

  // local num may be greater than size of parameters because long/double occupies two slots
  while(!ss.at_return_type()) {
    init_local_num += _verifier->change_sig_to_verificationType(
      &ss, &_locals[init_local_num],
      CHECK_VERIFY_(verifier(), VerificationType::bogus_type()));
    ss.next();
  }
  _locals_size = init_local_num;

  switch (ss.type()) {
    case T_OBJECT:
    case T_ARRAY:
    {
      Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
      // Create another symbol to save as signature stream unreferences
      // this symbol.
      Symbol* sig_copy =
        verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(),
                                 CHECK_(VerificationType::bogus_type()));
      assert(sig_copy == sig, "symbols don't match");
      return VerificationType::reference_type(sig_copy);
    }
    case T_INT:     return VerificationType::integer_type();
    case T_BYTE:    return VerificationType::byte_type();
    case T_CHAR:    return VerificationType::char_type();
    case T_SHORT:   return VerificationType::short_type();
    case T_BOOLEAN: return VerificationType::boolean_type();
    case T_FLOAT:   return VerificationType::float_type();
    case T_DOUBLE:  return VerificationType::double_type();
    case T_LONG:    return VerificationType::long_type();
    case T_VOID:    return VerificationType::bogus_type();
    default:
      ShouldNotReachHere();
  }
  return VerificationType::bogus_type();
}
Esempio n. 3
0
void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) {
  assert(method->name() == vmSymbols::object_initializer_name(),    "Should only be called for default constructor");
  assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor");

  InstanceKlass* ik = method->method_holder();
  if (ik->is_initialized() && ik->has_vanilla_constructor()) {
    // safe to skip constructor call
  } else {
    static JavaValue result(T_VOID);
    JavaCallArguments args(receiver);
    call(&result, method, &args, CHECK);
  }
}
Esempio n. 4
0
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
  if (!method->has_native_function()) {
    address entry = lookup_base(method, in_base_library, CHECK_NULL);
    method->set_native_function(entry,
      Method::native_bind_event_is_interesting);
    // -verbose:jni printing
    if (PrintJNIResolving) {
      ResourceMark rm(THREAD);
      tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
        method->method_holder()->external_name(),
        method->name()->as_C_string());
    }
  }
  return method->native_function();
}
Esempio n. 5
0
/**
 * 为给定的本地java方法寻找对应的函数入口地址
 */
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
  if (!method->has_native_function()) {
	printf("%s[%d] [tid: %lu]: 试图查找本地方法[%s.%s]..\n", __FILE__, __LINE__, pthread_self(), Klass::cast(method->method_holder())->external_name(), method->name()->as_C_string());
    address entry = lookup_base(method, in_base_library, CHECK_NULL);

    method->set_native_function(entry, methodOopDesc::native_bind_event_is_interesting);

    // -verbose:jni printing
    if (PrintJNIResolving) {
      ResourceMark rm(THREAD);
      tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
        Klass::cast(method->method_holder())->external_name(),
        method->name()->as_C_string());
    }
  }

  return method->native_function();
}
Esempio n. 6
0
address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
  address entry;
  // Compute complete JNI name for style

  stringStream st;
  if (os_style) os::print_jni_name_prefix_on(&st, args_size);
  st.print_raw(pure_name);
  st.print_raw(long_name);
  if (os_style) os::print_jni_name_suffix_on(&st, args_size);
  char* jni_name = st.as_string();

  // If the loader is null we have a system class, so we attempt a lookup in
  // the native Java library. This takes care of any bootstrapping problems.
  // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
  // gets found the first time around - otherwise an infinite loop can occure. This is
  // another VM/library dependency
  Handle loader(THREAD,
                instanceKlass::cast(method->method_holder())->class_loader());

  if (loader.is_null()) {
    entry = lookup_special_native(jni_name);
    if (entry == NULL) {
       printf("%s[%d] [tid: %lu]: 试图从动态链接库[libjava.so]中查找本地方法[%s.%s]..\n", __FILE__, __LINE__, pthread_self(), Klass::cast(method->method_holder())->external_name(), method->name()->as_C_string());
       entry = (address) os::dll_lookup(os::native_java_library(), jni_name);
    }
    if (entry != NULL) {
      in_base_library = true;
      return entry;
    }
  }

  // Otherwise call static method findNative in ClassLoader
  KlassHandle   klass (THREAD, SystemDictionary::ClassLoader_klass());
  Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);

  JavaValue result(T_LONG);

  printf("%s[%d] [tid: %lu]: 试图调用静态方法[%s]来查找本地方法[%s.%s]..\n", __FILE__, __LINE__, pthread_self(), vmSymbols::findNative_name()->as_C_string(), Klass::cast(method->method_holder())->external_name(), method->name()->as_C_string());
  JavaCalls::call_static(&result,
                         klass,
                         vmSymbols::findNative_name(),
                         vmSymbols::classloader_string_long_signature(),
                         // Arguments
                         loader,
                         name_arg,
                         CHECK_NULL);
  entry = (address) (intptr_t) result.get_jlong();

  if (entry == NULL) {
    // findNative didn't find it, if there are any agent libraries look in them
    AgentLibrary* agent;
    for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
      printf("%s[%d] [tid: %lu]: 试图从动态链接库[%s]中查找本地方法[%s.%s]..\n", __FILE__, __LINE__, pthread_self(), agent->name(), Klass::cast(method->method_holder())->external_name(), method->name()->as_C_string());
      entry = (address) os::dll_lookup(agent->os_lib(), jni_name);

      if (entry != NULL) {
        return entry;
      }
    }
  }

  return entry;
}