void do_object(oop obj) { // instanceKlass objects need some adjustment. if (obj->blueprint()->oop_is_instanceKlass()) { instanceKlass* ik = instanceKlass::cast((klassOop)obj); sort_methods(ik, _thread); } }
void CompilerTest::run_tests(JVM_SINGLE_ARG_TRAPS) { UsingFastOops fast_oops; ObjArray::Fast classes; ObjArray::Fast methods; InstanceClass::Fast klass; Method::Fast m; Os::suspend_profiler(); { classes = load_and_sort_classes(JVM_SINGLE_ARG_CHECK); } Os::resume_profiler(); int num_classes = classes().length(); for (int i=0; i<num_classes; i++) { klass = classes().obj_at(i); Os::suspend_profiler(); { methods = sort_methods(&klass JVM_CHECK); } Os::resume_profiler(); if (Verbose) { tty->print("Compiling class: "); klass().print_name_on(tty); tty->cr(); } int num_methods = methods().length(); for (int j=0; j<num_methods; j++) { m = methods().obj_at(j); if (m.not_null() && !m().is_impossible_to_compile() && !m().is_abstract()) { test_compile(&m JVM_CHECK); } } } Os::suspend_profiler(); { print_summary(); } Os::resume_profiler(); }
void sort_methods(instanceKlass* ik, TRAPS) { klassOop super = ik->super(); if (super != NULL) { sort_methods(instanceKlass::cast(super), THREAD); } // The methods array must be ordered by symbolOop address. (See // classFileParser.cpp where methods in a class are originally // sorted.) Since objects have just be reordered, this must be // corrected. methodOopDesc::sort_methods(ik->methods(), ik->methods_annotations(), ik->methods_parameter_annotations(), ik->methods_default_annotations(), true /* idempotent, slow */); // Itable indices are calculated based on methods array order // (see klassItable::compute_itable_index()). Must reinitialize. // We assume that since checkconstraints is false, this method // cannot throw an exception. An exception here would be // problematic since this is the VMThread, not a JavaThread. ik->itable()->initialize_itable(false, THREAD); }
static void merge_in_new_methods(InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) { enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS }; Array<Method*>* original_methods = klass->methods(); Array<int>* original_ordering = klass->method_ordering(); Array<int>* merged_ordering = Universe::the_empty_int_array(); int new_size = klass->methods()->length() + new_methods->length(); Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>( klass->class_loader_data(), new_size, NULL, CHECK); // original_ordering might be empty if this class has no methods of its own if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { merged_ordering = MetadataFactory::new_array<int>( klass->class_loader_data(), new_size, CHECK); } int method_order_index = klass->methods()->length(); sort_methods(new_methods); // Perform grand merge of existing methods and new methods int orig_idx = 0; int new_idx = 0; for (int i = 0; i < new_size; ++i) { Method* orig_method = NULL; Method* new_method = NULL; if (orig_idx < original_methods->length()) { orig_method = original_methods->at(orig_idx); } if (new_idx < new_methods->length()) { new_method = new_methods->at(new_idx); } if (orig_method != NULL && (new_method == NULL || orig_method->name() < new_method->name())) { merged_methods->at_put(i, orig_method); original_methods->at_put(orig_idx, NULL); if (merged_ordering->length() > 0) { assert(original_ordering != NULL && original_ordering->length() > 0, "should have original order information for this method"); merged_ordering->at_put(i, original_ordering->at(orig_idx)); } ++orig_idx; } else { merged_methods->at_put(i, new_method); if (merged_ordering->length() > 0) { merged_ordering->at_put(i, method_order_index++); } ++new_idx; } // update idnum for new location merged_methods->at(i)->set_method_idnum(i); } // Verify correct order #ifdef ASSERT uintptr_t prev = 0; for (int i = 0; i < merged_methods->length(); ++i) { Method* mo = merged_methods->at(i); uintptr_t nv = (uintptr_t)mo->name(); assert(nv >= prev, "Incorrect method ordering"); prev = nv; } #endif // Replace klass methods with new merged lists klass->set_methods(merged_methods); klass->set_initial_method_idnum(new_size); klass->set_method_ordering(merged_ordering); // Free metadata ClassLoaderData* cld = klass->class_loader_data(); if (original_methods->length() > 0) { MetadataFactory::free_array(cld, original_methods); } if (original_ordering != NULL && original_ordering->length() > 0) { MetadataFactory::free_array(cld, original_ordering); } }