virtual void print_method_on(outputStream* st) { int limit; int i; Method* m = method(); Symbol* k = m->klass_name(); // Print the class name with dots instead of slashes limit = k->utf8_length(); for (i = 0 ; i < limit ; i += 1) { char c = (char) k->byte_at(i); if (c == '/') { c = '.'; } st->print("%c", c); } if (limit > 0) { st->print("."); } Symbol* n = m->name(); limit = n->utf8_length(); for (i = 0 ; i < limit ; i += 1) { char c = (char) n->byte_at(i); st->print("%c", c); } if (Verbose || WizardMode) { // Disambiguate overloaded methods Symbol* sig = m->signature(); sig->print_symbol_on(st); } else if (MethodHandles::is_signature_polymorphic(m->intrinsic_id())) // compare with Method::print_short_name MethodHandles::print_as_basic_type_signature_on(st, m->signature(), true); }
void next() { Symbol* sig = _signature; int len = sig->utf8_length(); if (_end >= len) { _end = len + 1; return; } _begin = _end; int t = sig->byte_at(_begin); switch (t) { case 'B': _type = T_BYTE; break; case 'C': _type = T_CHAR; break; case 'D': _type = T_DOUBLE; break; case 'F': _type = T_FLOAT; break; case 'I': _type = T_INT; break; case 'J': _type = T_LONG; break; case 'S': _type = T_SHORT; break; case 'Z': _type = T_BOOLEAN; break; case 'V': _type = T_VOID; break; default : next_non_primitive(t); return; } _end++; }
char* NativeLookup::long_jni_name(methodHandle method) { // Signature ignore the wrapping parenteses and the trailing return type stringStream st; Symbol* signature = method->signature(); st.print("__"); // find ')' int end; for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++); // skip first '(' mangle_name_on(&st, signature, 1, end); return st.as_string(); }
// Check all the formats of native implementation name to see if there is one // for the specified method. address NativeLookup::lookup_critical_entry(methodHandle method) { if (!CriticalJNINatives) return NULL; if (method->is_synchronized() || !method->is_static()) { // Only static non-synchronized methods are allowed return NULL; } ResourceMark rm; address entry = NULL; Symbol* signature = method->signature(); for (int end = 0; end < signature->utf8_length(); end++) { if (signature->byte_at(end) == 'L') { // Don't allow object types return NULL; } } // Compute critical name char* critical_name = critical_jni_name(method); // Compute argument size int args_size = 1 // JNIEnv + (method->is_static() ? 1 : 0) // class for static methods + method->size_of_parameters(); // actual parameters // 1) Try JNI short style entry = lookup_critical_style(method, critical_name, "", args_size, true); if (entry != NULL) return entry; // Compute long name char* long_name = long_jni_name(method); // 2) Try JNI long style entry = lookup_critical_style(method, critical_name, long_name, args_size, true); if (entry != NULL) return entry; // 3) Try JNI short style without os prefix/suffix entry = lookup_critical_style(method, critical_name, "", args_size, false); if (entry != NULL) return entry; // 4) Try JNI long style without os prefix/suffix entry = lookup_critical_style(method, critical_name, long_name, args_size, false); return entry; // NULL indicates not found }
// ------------------------------------------------------------------ // 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); }