// ------------------------------------------------------------------ // ciMethod::resolve_vtable_index // // Given a known receiver klass, find the vtable index for the call. // Return methodOopDesc::invalid_vtable_index if the vtable_index is unknown. int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) { check_is_loaded(); int vtable_index = methodOopDesc::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_klassOop()); KlassHandle h_recv (THREAD, receiver->get_klassOop()); symbolHandle h_name (THREAD, name()->get_symbolOop()); symbolHandle h_signature (THREAD, signature()->get_symbolOop()); vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { // A statically bound method. Return "no such index". vtable_index = methodOopDesc::invalid_vtable_index; } } return vtable_index; }
// This version creates handles and calls the other version void Exceptions::_throw_msg(Thread* thread, const char* file, int line, symbolOop name, const char* message) { symbolHandle h_name(thread, name); Handle h_loader(thread, NULL); Handle h_protection_domain(thread, NULL); Exceptions::_throw_msg(thread, file, line, h_name, message, h_loader, h_protection_domain); }
// Another convenience method that creates handles for null class loaders and // protection domains and null causes. // If the last parameter 'to_utf8_mode' is safe_to_utf8, // it means we can safely ignore the encoding scheme of the message string and // convert it directly to a java UTF8 string. Otherwise, we need to take the // encoding scheme of the string into account. One thing we should do at some // point is to push this flag down to class java_lang_String since other // classes may need similar functionalities. Handle Exceptions::new_exception(Thread* thread, symbolOop name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe) { symbolHandle h_name(thread, name); Handle h_loader(thread, NULL); Handle h_prot(thread, NULL); Handle h_cause(thread, NULL); return Exceptions::new_exception(thread, h_name, message, h_cause, h_loader, h_prot, to_utf8_safe); }
// ------------------------------------------------------------------ // 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_klassOop()); KlassHandle h_recv (THREAD, exact_receiver->get_klassOop()); KlassHandle h_resolved (THREAD, holder()->get_klassOop()); symbolHandle h_name (THREAD, name()->get_symbolOop()); symbolHandle h_signature (THREAD, signature()->get_symbolOop()); 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_javaArray() || 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_methodOop()) { result = CURRENT_THREAD_ENV->get_object(m())->as_method(); } // Don't return abstract methods because they aren't // optimizable or interesting. if (result->is_abstract()) { return NULL; } else { return result; } }
void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) { klassKlass::oop_verify_on(obj, st); if (!obj->partially_loaded()) { Thread *thread = Thread::current(); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); // Avoid redundant verifies if (ik->_verify_count == Universe::verify_count()) return; ik->_verify_count = Universe::verify_count(); // Verify that klass is present in SystemDictionary if (ik->is_loaded()) { symbolHandle h_name (thread, ik->name()); Handle h_loader (thread, ik->class_loader()); SystemDictionary::verify_obj_klass_present(obj, h_name, h_loader); } // Verify static fields VerifyFieldClosure blk; ik->iterate_static_fields(&blk); // Verify vtables if (ik->is_linked()) { ResourceMark rm(thread); // $$$ This used to be done only for m/s collections. Doing it // always seemed a valid generalization. (DLD -- 6/00) ik->vtable()->verify(st); } // Verify oop map cache if (ik->oop_map_cache() != NULL) { ik->oop_map_cache()->verify(); } // Verify first subklass if (ik->subklass_oop() != NULL) { guarantee(ik->subklass_oop()->is_perm(), "should be in permspace"); guarantee(ik->subklass_oop()->is_klass(), "should be klass"); } // Verify siblings klassOop super = ik->super(); Klass* sib = ik->next_sibling(); int sib_count = 0; while (sib != NULL) { if (sib == ik) { fatal1("subclass cycle of length %d", sib_count); } if (sib_count >= 100000) { fatal1("suspiciously long subclass list %d", sib_count); } guarantee(sib->as_klassOop()->is_klass(), "should be klass"); guarantee(sib->as_klassOop()->is_perm(), "should be in permspace"); guarantee(sib->super() == super, "siblings should have same superklass"); sib = sib->next_sibling(); } // Verify implementor field if (ik->implementor() != NULL) { guarantee(ik->is_interface(), "only interfaces should have implementor set"); guarantee(ik->nof_implementors() == 1, "should only have one implementor"); klassOop im = ik->implementor(); guarantee(im->is_perm(), "should be in permspace"); guarantee(im->is_klass(), "should be klass"); guarantee(!Klass::cast(klassOop(im))->is_interface(), "implementors cannot be interfaces"); } // Verify local interfaces objArrayOop local_interfaces = ik->local_interfaces(); guarantee(local_interfaces->is_perm(), "should be in permspace"); guarantee(local_interfaces->is_objArray(), "should be obj array"); int j; for (j = 0; j < local_interfaces->length(); j++) { oop e = local_interfaces->obj_at(j); guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid local interface"); } // Verify transitive interfaces objArrayOop transitive_interfaces = ik->transitive_interfaces(); guarantee(transitive_interfaces->is_perm(), "should be in permspace"); guarantee(transitive_interfaces->is_objArray(), "should be obj array"); for (j = 0; j < transitive_interfaces->length(); j++) { oop e = transitive_interfaces->obj_at(j); guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid transitive interface"); } // Verify methods objArrayOop methods = ik->methods(); guarantee(methods->is_perm(), "should be in permspace"); guarantee(methods->is_objArray(), "should be obj array"); for (j = 0; j < methods->length(); j++) { guarantee(methods->obj_at(j)->is_method(), "non-method in methods array"); } for (j = 0; j < methods->length() - 1; j++) { methodOop m1 = methodOop(methods->obj_at(j)); methodOop m2 = methodOop(methods->obj_at(j + 1)); guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly"); } // Verify method ordering typeArrayOop method_ordering = ik->method_ordering(); guarantee(method_ordering->is_perm(), "should be in permspace"); guarantee(method_ordering->is_typeArray(), "should be type array"); int length = method_ordering->length(); if (jvmdi::enabled()) { guarantee(length == methods->length(), "invalid method ordering length"); jlong sum = 0; for (j = 0; j < length; j++) { int original_index = method_ordering->int_at(j); guarantee(original_index >= 0 && original_index < length, "invalid method ordering index"); sum += original_index; } // Verify sum of indices 0,1,...,length-1 guarantee(sum == ((jlong)length*(length-1))/2, "invalid method ordering sum"); } else { guarantee(length == 0, "invalid method ordering length"); } // Verify JNI static field/method identifiers if (ik->jni_ids() != NULL) { ik->jni_ids()->verify(ik->as_klassOop()); } // Verify other fields if (ik->array_klasses() != NULL) { guarantee(ik->array_klasses()->is_perm(), "should be in permspace"); guarantee(ik->array_klasses()->is_klass(), "should be klass"); } guarantee(ik->fields()->is_perm(), "should be in permspace"); guarantee(ik->fields()->is_typeArray(), "should be type array"); guarantee(ik->constants()->is_perm(), "should be in permspace"); guarantee(ik->constants()->is_constantPool(), "should be constant pool"); guarantee(ik->inner_classes()->is_perm(), "should be in permspace"); guarantee(ik->inner_classes()->is_typeArray(), "should be type array"); if (ik->source_file_name() != NULL) { guarantee(ik->source_file_name()->is_perm(), "should be in permspace"); guarantee(ik->source_file_name()->is_symbol(), "should be symbol"); } if (ik->source_debug_extension() != NULL) { guarantee(ik->source_debug_extension()->is_perm(), "should be in permspace"); guarantee(ik->source_debug_extension()->is_symbol(), "should be symbol"); } if (ik->protection_domain() != NULL) { guarantee(ik->protection_domain()->is_oop(), "should be oop"); } if (ik->signers() != NULL) { guarantee(ik->signers()->is_objArray(), "should be obj array"); } } }