Exemple #1
0
/*
 * method to upcall into Java to return the value of the specified
 * property as a utf8 string, or NULL if does not exist. The caller
 * is responsible for setting a ResourceMark for proper cleanup of
 * the utf8 strings.
 */
const char* StatSampler::get_system_property(const char* name, TRAPS) {

  // setup the arguments to getProperty
  Handle key_str   = java_lang_String::create_from_str(name, CHECK_NULL);

  // return value
  JavaValue result(T_OBJECT);

  // public static String getProperty(String key, String def);
  JavaCalls::call_static(&result,
                         KlassHandle(THREAD, SystemDictionary::System_klass()),
                         vmSymbolHandles::getProperty_name(),
                         vmSymbolHandles::string_string_signature(),
                         key_str,
                         CHECK_NULL);

  oop value_oop = (oop)result.get_jobject();
  if (value_oop == NULL) {
    return NULL;
  }

  // convert Java String to utf8 string
  char* value = java_lang_String::as_utf8_string(value_oop);

  return value;
}
Exemple #2
0
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");

  // Invoke the method
  JavaCalls::call(result, method, args, CHECK);
}
Exemple #3
0
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");
  //signature->
  // Invoke the method
  printf("%s[%d] [tid: %lu]: 开始调用Java中的静态方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), klass->external_name(), name->as_C_string(), signature->as_C_string());
  JavaCalls::call(result, method, args, CHECK);
}
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
    CallInfo callinfo;
    LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
    LinkResolver::resolve_special_call(callinfo, link_info, CHECK);
    methodHandle method = callinfo.selected_method();
    assert(method.not_null(), "should have thrown exception");

    // Invoke the method
    JavaCalls::call(result, method, args, CHECK);
}
Exemple #5
0
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  Handle receiver = args->receiver();
  KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
  LinkResolver::resolve_virtual_call(
          callinfo, receiver, recvrKlass, spec_klass, name, signature,
          KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");

  // Invoke the method
  JavaCalls::call(result, method, args, CHECK);
}
Exemple #6
0
Metadata* AOTCompiledMethod::metadata_at(int index) const {
  if (index == 0) { // 0 is reserved
    return NULL;
  }
  assert(index - 1 < _metadata_size, "");
  {
    Metadata** entry = _metadata_got + (index - 1);
    intptr_t meta = (intptr_t)*entry;
    if ((meta & 1) == 1) {
      // already resolved
      Metadata *m = (Metadata*)(meta & ~1);
      return m;
    }
    // The entry is string which we need to resolve.
    const char* meta_name = _heap->get_name_at((int)meta);
    int klass_len = build_u2_from((address)meta_name);
    const char* klass_name = meta_name + 2;
    // Quick check the current method's holder.
    Klass* k = _method->method_holder();
    bool klass_matched = true;

    ResourceMark rm; // for signature_name() and find_method()
    if (strncmp(k->signature_name(), klass_name, klass_len) != 0) { // Does not match?
      // Search klass in got cells in DSO which have this compiled method.
      k = _heap->get_klass_from_got(klass_name, klass_len, _method);
      klass_matched = false;
    }
    int method_name_len = build_u2_from((address)klass_name + klass_len);
    if (method_name_len == 0) { // Array or Klass name only?
      meta = ((intptr_t)k) | 1;
      *entry = (Metadata*)meta; // Should be atomic on x64
      return (Metadata*)k;
    } else { // Method
      // Quick check the current method's name.
      Method* m = _method;
      int signature_len = build_u2_from((address)klass_name + klass_len + 2 + method_name_len);
      int full_len = 2 + klass_len + 2 + method_name_len + 2 + signature_len;
      if (!klass_matched || memcmp(_name, meta_name, full_len) != 0) { // Does not match?
        Thread* thread = Thread::current();
        KlassHandle klass = KlassHandle(thread, k);
        const char* method_name = klass_name + klass_len;
        m = AOTCodeHeap::find_method(klass, thread, method_name);
      }
      meta = ((intptr_t)m) | 1;
      *entry = (Metadata*)meta; // Should be atomic on x64
      return (Metadata*)m;
    }
  }
  ShouldNotReachHere(); return NULL;
}
Exemple #7
0
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  Handle receiver = args->receiver();
  KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass());

  LinkResolver::resolve_virtual_call(
          callinfo, receiver, recvrKlass, spec_klass, name, signature,
          KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");

  printf("%s[%d] [tid: %lu]: 开始调用Java中的方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), spec_klass->external_name(), name->as_C_string(), signature->as_C_string());

  // Invoke the method
  JavaCalls::call(result, method, args, CHECK);
}
Exemple #8
0
 static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) {
   Klass* refk_oop = NULL;
   BasicType result = as_BasicType(java_class, &refk_oop);
   (*reference_klass) = KlassHandle(refk_oop);
   return result;
 }
Exemple #9
0
KlassHandle Klass::base_create_klass(KlassHandle& klass, int size,
                                     const Klass_vtbl& vtbl, TRAPS) {
  klassOop ek = base_create_klass_oop(klass, size, vtbl, THREAD);
  return KlassHandle(THREAD, ek);
}
// ------------------------------------------------------------------
// ciEnv::get_klass_by_name_impl
ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
                                       constantPoolHandle cpool,
                                       ciSymbol* name,
                                       bool require_local) {
  ASSERT_IN_VM;
  EXCEPTION_CONTEXT;

  // Now we need to check the SystemDictionary
  Symbol* sym = name->get_symbol();
  if (sym->byte_at(0) == 'L' &&
    sym->byte_at(sym->utf8_length()-1) == ';') {
    // This is a name from a signature.  Strip off the trimmings.
    // Call recursive to keep scope of strippedsym.
    TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
                    sym->utf8_length()-2,
                    KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
    ciSymbol* strippedname = get_symbol(strippedsym);
    return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);
  }

  // Check for prior unloaded klass.  The SystemDictionary's answers
  // can vary over time but the compiler needs consistency.
  ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name);
  if (unloaded_klass != NULL) {
    if (require_local)  return NULL;
    return unloaded_klass;
  }

  Handle loader(THREAD, (oop)NULL);
  Handle domain(THREAD, (oop)NULL);
  if (accessing_klass != NULL) {
    loader = Handle(THREAD, accessing_klass->loader());
    domain = Handle(THREAD, accessing_klass->protection_domain());
  }

  // setup up the proper type to return on OOM
  ciKlass* fail_type;
  if (sym->byte_at(0) == '[') {
    fail_type = _unloaded_ciobjarrayklass;
  } else {
    fail_type = _unloaded_ciinstance_klass;
  }
  KlassHandle found_klass;
  {
    ttyUnlocker ttyul;  // release tty lock to avoid ordering problems
    MutexLocker ml(Compile_lock);
    Klass* kls;
    if (!require_local) {
      kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader,
                                                                       KILL_COMPILE_ON_FATAL_(fail_type));
    } else {
      kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain,
                                                           KILL_COMPILE_ON_FATAL_(fail_type));
    }
    found_klass = KlassHandle(THREAD, kls);
  }

  // If we fail to find an array klass, look again for its element type.
  // The element type may be available either locally or via constraints.
  // In either case, if we can find the element type in the system dictionary,
  // we must build an array type around it.  The CI requires array klasses
  // to be loaded if their element klasses are loaded, except when memory
  // is exhausted.
  if (sym->byte_at(0) == '[' &&
      (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {
    // We have an unloaded array.
    // Build it on the fly if the element class exists.
    TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
                                                 sym->utf8_length()-1,
                                                 KILL_COMPILE_ON_FATAL_(fail_type));

    // Get element ciKlass recursively.
    ciKlass* elem_klass =
      get_klass_by_name_impl(accessing_klass,
                             cpool,
                             get_symbol(elem_sym),
                             require_local);
    if (elem_klass != NULL && elem_klass->is_loaded()) {
      // Now make an array for it
      return ciObjArrayKlass::make_impl(elem_klass);
    }
  }

  if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) {
    // Look inside the constant pool for pre-resolved class entries.
    for (int i = cpool->length() - 1; i >= 1; i--) {
      if (cpool->tag_at(i).is_klass()) {
        Klass* kls = cpool->resolved_klass_at(i);
        if (kls->name() == sym) {
          found_klass = KlassHandle(THREAD, kls);
          break;
        }
      }
    }
  }

  if (found_klass() != NULL) {
    // Found it.  Build a CI handle.
    return get_klass(found_klass());
  }

  if (require_local)  return NULL;

  // Not yet loaded into the VM, or not governed by loader constraints.
  // Make a CI representative for it.
  return get_unloaded_klass(accessing_klass, name);
}