void CHA::process_interface(instanceKlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, symbolHandle name, symbolHandle signature) { // recursively add non-abstract implementors of interface r to receivers list assert(r->is_interface(), "should call process_class instead"); // We only store the implementors for an interface, if there is exactly one implementor klassOop k = r->implementor(); assert(k == NULL || r->nof_implementors() == 1, "inconsistent implementor list"); if (k != NULL && !methods->is_full()) { instanceKlass* kl = instanceKlass::cast(k); assert(kl->oop_is_instance(), "primitive klasses don't implement interfaces"); assert(!kl->is_interface(), "must be a real klass"); process_class(kl, receivers, methods, name, signature); } // now process all subinterfaces for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) { assert(s->is_interface(), "must be an interface"); instanceKlassHandle sub(s->as_klassOop()); process_interface(sub, receivers, methods, name, signature); if (methods->is_full()) break; // give up -- too many overriding methods } }
void CHA::process_class(KlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, symbolHandle name, symbolHandle signature) { // recursively add non-abstract subclasses of r to receivers list assert(!r->is_interface(), "should call process_interface instead"); for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) { // preorder traversal, so check subclasses first if (s->is_interface()) { // can only happen if r == Object assert(r->superklass() == NULL, "must be klass Object"); } else { process_class(s, receivers, methods, name, signature); } } // now check r itself (after subclasses because of preorder) if (!methods->is_full()) { // don't add abstract classes to receivers list // (but still consider their methods -- they may be non-abstract) if (!receivers->is_full() && !r->is_abstract()) receivers->push(r); methodOop m = NULL; if (r->oop_is_instance()) m = instanceKlass::cast(r())->find_method(name(), signature()); if (m != NULL && !m->is_abstract()) { if (!methods->contains(m)) methods->push(m); } } }
int main (int argc, char** argv) { JCF jcf[1]; int argi, opt; /* Unlock the stdio streams. */ unlock_std_streams (); gcc_init_libintl (); if (argc <= 1) { fprintf (stderr, _("jcf-dump: no classes specified\n")); usage (); } jcf_path_init (); /* We use getopt_long_only to allow single `-' long options. For some of our options this is more natural. */ while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1) { switch (opt) { case 0: /* Already handled. */ break; case 'o': output_file = optarg; break; case 'I': jcf_path_include_arg (optarg); break; case 'v': verbose++; break; case 'c': flag_disassemble_methods = 1; break; case OPT_classpath: jcf_path_classpath_arg (optarg); break; case OPT_bootclasspath: jcf_path_bootclasspath_arg (optarg); break; case OPT_extdirs: jcf_path_extdirs_arg (optarg); break; case OPT_HELP: help (); break; case OPT_VERSION: version (); break; case OPT_JAVAP: flag_javap_compatible++; flag_print_constant_pool = 0; flag_print_attributes = 0; break; default: usage (); } } if (verbose && ! flag_javap_compatible) flag_print_constant_pool = 1; if (optind == argc) { fprintf (stderr, _("jcf-dump: no classes specified\n")); usage (); } jcf_path_seal (verbose); if (flag_print_main) { flag_print_fields = 0; flag_print_methods = 0; flag_print_constant_pool = 0; flag_print_attributes = 0; flag_print_class_info = 0; } if (output_file) { out = fopen (output_file, "w"); if (! out) { fprintf (stderr, _("Cannot open '%s' for output.\n"), output_file); return FATAL_EXIT_CODE; } } else out = stdout; if (optind >= argc) { fprintf (out, "Reading .class from <standard input>.\n"); open_class ("<stdio>", jcf, 0, NULL); process_class (jcf); } else { for (argi = optind; argi < argc; argi++) { char *arg = argv[argi]; const char *class_filename = find_class (arg, strlen (arg), jcf, 0); if (class_filename == NULL) class_filename = find_classfile (arg, jcf, NULL); if (class_filename == NULL) { perror ("Could not find class"); return FATAL_EXIT_CODE; } JCF_FILL (jcf, 4); if (GET_u4 (jcf->read_ptr) == ZIPMAGIC) { long compressed_size, member_size; int compression_method, filename_length, extra_length; int general_purpose_bits; const char *filename; int total_length; if (flag_print_class_info) fprintf (out, "Reading classes from archive %s.\n", class_filename); for (;;) { int skip = 0; jcf_filbuf_t save_filbuf = jcf->filbuf; long magic = JCF_readu4_le (jcf); if (magic == 0x02014b50 || magic == 0x06054b50) break; /* got to central directory */ if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */ { fprintf (stderr, _("bad format of .zip/.jar archive\n")); return FATAL_EXIT_CODE; } JCF_FILL (jcf, 26); JCF_SKIP (jcf, 2); general_purpose_bits = JCF_readu2_le (jcf); compression_method = JCF_readu2_le (jcf); JCF_SKIP (jcf, 8); compressed_size = JCF_readu4_le (jcf); member_size = JCF_readu4_le (jcf); filename_length = JCF_readu2_le (jcf); extra_length = JCF_readu2_le (jcf); total_length = filename_length + extra_length + compressed_size; if (jcf->read_end - jcf->read_ptr < total_length) jcf_trim_old_input (jcf); JCF_FILL (jcf, total_length); filename = (const char *) jcf->read_ptr; JCF_SKIP (jcf, filename_length); JCF_SKIP (jcf, extra_length); if (filename_length > 0 && filename[filename_length-1] == '/') { if (flag_print_class_info) fprintf (out, "[Skipping directory %.*s]\n", filename_length, filename); skip = 1; } else if (compression_method != 0) { if (flag_print_class_info) fprintf (out, "[Skipping compressed file %.*s]\n", filename_length, filename); skip = 1; } else if (member_size < 4 || GET_u4 (jcf->read_ptr) != 0xcafebabe) { if (flag_print_class_info) fprintf (out, "[Skipping non-.class member %.*s]\n", filename_length, filename); skip = 1; } else { if (flag_print_class_info) fprintf (out, "Reading class member: %.*s.\n", filename_length, filename); } if (skip) { JCF_SKIP (jcf, compressed_size); } else { unsigned char *save_end; jcf->filbuf = jcf_unexpected_eof; save_end = jcf->read_end; jcf->read_end = jcf->read_ptr + compressed_size; process_class (jcf); jcf->filbuf = save_filbuf; jcf->read_end = save_end; } } } else { if (flag_print_class_info) fprintf (out, "Reading .class from %s.\n", class_filename); process_class (jcf); } JCF_FINISH(jcf); } } return SUCCESS_EXIT_CODE; }
void report_process_update_display(void) { unsigned int i, lines = 0; unsigned int total; int show_power; if ((!reportout.csv_report)&&(!reportout.http_report)) return; sort(all_power.begin(), all_power.end(), power_cpu_sort); show_power = global_power_valid(); if (reporttype){ fprintf(reportout.http_report, "<div id=\"software\"><h2>%s</h2>\n <table width=\"100%%\">\n",_("Overview of Software Power Consumers")); if (show_power) fprintf(reportout.http_report, "<tr><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\" class=\"process\">%s</th><th class=\"process\">%s</th></tr>\n",_("Power est."), _("Usage"), _("Wakeups/s"),_("GPU ops/s"),_("Disk IO/s"), _("GFX Wakeups/s"),_("Category"),_("Description")); else fprintf(reportout.http_report, "<tr><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\" class=\"process\">%s</th><th class=\"process\">%s</th></tr>\n",_("Usage"), _("Wakeups/s"),_("GPU ops/s"),_("Disk IO/s"), _("GFX Wakeups/s"),_("Category"),_("Description")); }else { fprintf(reportout.csv_report,"**Overview of Software Power Consumers**, \n\n"); if (show_power) fprintf(reportout.csv_report, "Power est., Usage, Wakeups, GPU ops, Disk IO, GFX Wakeups, Category, Description, \n"); else fprintf(reportout.csv_report, "Usage, Wakeups, GPU ops, Disk IO, GFX Wakeups, Category, Description, \n"); } total = all_power.size(); if (total > 100) total = 100; for (i = 0; i < total; i++) { char power[16]; char name[20]; char usage[20]; char wakes[20]; char gpus[20]; char disks[20]; char xwakes[20]; char descr[128]; format_watts(all_power[i]->Witts(), power, 10); if (!show_power) strcpy(power, " "); sprintf(name, "%s", all_power[i]->type()); if (strcmp(name, "Device") == 0) continue; lines++; if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && all_power[i]->Witts() == 0) break; usage[0] = 0; if (all_power[i]->usage_units()) { if (all_power[i]->usage() < 1000) sprintf(usage, "%5.1f%s", all_power[i]->usage(), all_power[i]->usage_units()); else sprintf(usage, "%5i%s", (int)all_power[i]->usage(), all_power[i]->usage_units()); } sprintf(wakes, "%5.1f", all_power[i]->wake_ups / measurement_time); if (all_power[i]->wake_ups / measurement_time <= 0.3) sprintf(wakes, "%5.2f", all_power[i]->wake_ups / measurement_time); sprintf(gpus, "%5.1f", all_power[i]->gpu_ops / measurement_time); sprintf(disks, "%5.1f (%5.1f)", all_power[i]->hard_disk_hits / measurement_time, all_power[i]->disk_hits / measurement_time); sprintf(xwakes, "%5.1f", all_power[i]->xwakes / measurement_time); if (!all_power[i]->show_events()) { wakes[0] = 0; gpus[0] = 0; disks[0] = 0; } if (all_power[i]->gpu_ops == 0) gpus[0] = 0; if (all_power[i]->wake_ups == 0) wakes[0] = 0; if (all_power[i]->disk_hits == 0) disks[0] = 0; if (all_power[i]->xwakes == 0) xwakes[0] = 0; if (show_power) { if (reporttype) fprintf(reportout.http_report,"<tr class=\"%s\"><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td>%s</td><td>%s</td></tr>\n", process_class(lines), power, usage, wakes, gpus, disks, xwakes, name, pretty_print(all_power[i]->description(), descr, 128)); else fprintf(reportout.csv_report,"%s, %s, %s, %s, %s, %s, %s, %s,\n", power, usage, wakes, gpus, disks, xwakes, name, pretty_print(all_power[i]->description(), descr, 128)); } else { if (reporttype) fprintf(reportout.http_report,"<tr class=\"%s\"><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td>%s</td><td>%s</td></tr>\n", process_class(lines), usage, wakes, gpus, disks, xwakes, name, pretty_print(all_power[i]->description(), descr, 128)); else fprintf(reportout.csv_report,"%s, %s, %s, %s, %s, %s, %s, \n", usage, wakes, gpus, disks, xwakes, name, pretty_print(all_power[i]->description(), descr, 128)); } } if (reporttype) fprintf(reportout.http_report,"</table></div>\n"); else fprintf(reportout.csv_report,"\n"); }
void report_summary(void) { unsigned int i, lines = 0; unsigned int total; int show_power; if ((!reportout.csv_report)&&(!reportout.http_report)) return; sort(all_power.begin(), all_power.end(), power_cpu_sort); show_power = global_power_valid(); if (reporttype) { fprintf(reportout.http_report, "<div id=\"summary\"><h2>%s</h2>\n",_("Power Consumption Summary")); fprintf(reportout.http_report, "<p>%3.1f %s, %3.1f %s, %3.1f %s, %3.1f %s %3.1f%% %s</p>\n <table width=\"100%%\">\n", total_wakeups(), _("wakeups/second"), total_gpu_ops(),_("GPU ops/second"), total_disk_hits(), _("VFS ops/sec"), total_xwakes(),_("GFX wakes/sec and"), total_cpu_time()*100, _("CPU use")); if (show_power) fprintf(reportout.http_report, "<tr><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\" class=\"process\">%s</th><th class=\"process\">%s</th></tr>\n", _("Power est."), _("Usage"), _("Events/s"),_("Category"),_("Description")); else fprintf(reportout.http_report, "<tr><th width=\"10%%\">%s</th><th width=\"10%%\">%s</th><th width=\"10%%\" class=\"process\">%s</th><th class=\"process\">%s</th></tr>\n", _("Usage"), _("Events/s"),_("Category"),_("Description")); }else { fprintf(reportout.csv_report, "**Power Consumption Summary** \n"); fprintf(reportout.csv_report, "%3.1f wakeups/second, %3.1f GPU ops/second, %3.1f VFS ops/sec, %3.1f GFX wakes/sec and %3.1f%% CPU use \n\n", total_wakeups(), total_gpu_ops(), total_disk_hits(), total_xwakes(), total_cpu_time()*100); if (show_power) fprintf(reportout.csv_report,"Power est., Usage, Events/s, Category, Description, \n"); else fprintf(reportout.csv_report,"Usage, Events/s, Category, Description, \n"); } total = all_power.size(); if (total > 10) total = 10; for (i = 0; i < all_power.size(); i++) { char power[16]; char name[20]; char usage[20]; char events[20]; char descr[128]; format_watts(all_power[i]->Witts(), power, 10); if (!show_power) strcpy(power, " "); sprintf(name, "%s", all_power[i]->type()); lines++; if (lines > total) break; if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && all_power[i]->Witts() == 0) break; usage[0] = 0; if (all_power[i]->usage_units()) { if (all_power[i]->usage() < 1000) sprintf(usage, "%5.1f%s", all_power[i]->usage_summary(), all_power[i]->usage_units_summary()); else sprintf(usage, "%5i%s", (int)all_power[i]->usage_summary(), all_power[i]->usage_units_summary()); } sprintf(events, "%5.1f", all_power[i]->events()); if (!all_power[i]->show_events()) events[0] = 0; else if (all_power[i]->events() <= 0.3) sprintf(events, "%5.2f", all_power[i]->events()); if (show_power) { if (reporttype) fprintf(reportout.http_report,"<tr class=\"%s\"><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td>%s</td><td>%s</td></tr>\n", process_class(lines), power, usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); else fprintf(reportout.csv_report,"%s,%s,%s,%s,%s \n", power, usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); } else { if (reporttype) fprintf(reportout.http_report, "<tr class=\"%s\"><td class=\"process_power\">%s</td><td class=\"process_power\">%s</td><td>%s</td><td>%s</td></tr>\n", process_class(lines),usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); else fprintf(reportout.csv_report,"%s,%s,%s,%s, \n", usage, events, name, pretty_print(all_power[i]->description(), descr, 128)); } } if (reporttype) fprintf(reportout.http_report,"</table></div>\n"); else fprintf(reportout.csv_report,"\n"); }
/* * boot_compact_db - compact specified classes * HEAP_CACHE_ATTRINFO structure * return: error status * class_oids(in): the classes list * n_classes(in): the class_oids length * hfids(in): the hfid list * space_to_process(in): the space to process * instance_lock_timeout(in): the lock timeout for instances * class_lock_timeout(in): the lock timeout for instances * delete_old_repr(in): whether to delete the old class representation * last_processed_class_oid(in,out): last processed class oid * last_processed_oid(in,out): last processed oid * total_objects(out): count processed objects for each class * failed_objects(out): count failed objects for each class * modified_objects(out): count modified objects for each class * big_objects(out): count big objects for each class * initial_last_repr_id(in, out): the list of initial last class * representation */ int boot_compact_db (THREAD_ENTRY * thread_p, OID * class_oids, int n_classes, int space_to_process, int instance_lock_timeout, int class_lock_timeout, bool delete_old_repr, OID * last_processed_class_oid, OID * last_processed_oid, int *total_objects, int *failed_objects, int *modified_objects, int *big_objects, int *initial_last_repr_id) { int result = NO_ERROR; int i, j, start_index = -1; int max_space_to_process, current_tran_index = -1; int lock_ret; HFID hfid; if (boot_can_compact (thread_p) == false) { return ER_COMPACTDB_ALREADY_STARTED; } if (class_oids == NULL || n_classes <= 0 || space_to_process <= 0 || last_processed_class_oid == NULL || last_processed_oid == NULL || total_objects == NULL || failed_objects == NULL || modified_objects == NULL || big_objects == NULL || initial_last_repr_id == NULL) { return ER_QPROC_INVALID_PARAMETER; } for (start_index = 0; start_index < n_classes; start_index++) { if (OID_EQ (class_oids + start_index, last_processed_class_oid)) { break; } } if (start_index == n_classes) { return ER_QPROC_INVALID_PARAMETER; } for (i = 0; i < n_classes; i++) { total_objects[i] = 0; failed_objects[i] = 0; modified_objects[i] = 0; big_objects[i] = 0; } max_space_to_process = space_to_process; for (i = start_index; i < n_classes; i++) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret != LK_GRANTED) { total_objects[i] = COMPACTDB_LOCKED_CLASS; OID_SET_NULL (last_processed_oid); continue; } if (heap_get_hfid_from_class_oid (thread_p, class_oids + i, &hfid) != NO_ERROR) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (HFID_IS_NULL (&hfid)) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (OID_ISNULL (last_processed_oid)) { initial_last_repr_id[i] = heap_get_class_repr_id (thread_p, class_oids + i); if (initial_last_repr_id[i] <= 0) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } } if (process_class (thread_p, class_oids + i, &hfid, max_space_to_process, &instance_lock_timeout, &space_to_process, last_processed_oid, total_objects + i, failed_objects + i, modified_objects + i, big_objects + i) != NO_ERROR) { OID_SET_NULL (last_processed_oid); for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; break; } if (delete_old_repr && OID_ISNULL (last_processed_oid) && failed_objects[i] == 0 && heap_get_class_repr_id (thread_p, class_oids + i) == initial_last_repr_id[i]) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, X_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret == LK_GRANTED) { if (catalog_drop_old_representations (thread_p, class_oids + i) != NO_ERROR) { for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; } else { initial_last_repr_id[i] = COMPACTDB_REPR_DELETED; } break; } } if (space_to_process == 0) { break; } } if (OID_ISNULL (last_processed_oid)) { if (i < n_classes - 1) { COPY_OID (last_processed_class_oid, class_oids + i + 1); } else { OID_SET_NULL (last_processed_class_oid); } } else { COPY_OID (last_processed_class_oid, class_oids + i); } return result; }
CHAResult* CHA::analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, KlassHandle actual_receiver, symbolHandle name, symbolHandle signature) { assert(static_receiver->oop_is_instance(), "must be instance klass"); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, // the vtables has not been setup, and the LinkResolver will fail. if (instanceKlass::cast(static_receiver())->is_linked() && instanceKlass::cast(actual_receiver())->is_linked()) { if (static_receiver->is_interface()) { // no point trying to resolve unless actual receiver is a klass if (!actual_receiver->is_interface()) { m = LinkResolver::resolve_interface_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); } } else { m = LinkResolver::resolve_virtual_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); } if (m.is_null()) { // didn't find method (e.g., could be abstract method) return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); } if( Klass::can_be_statically_bound(m()) || m()->is_private() || actual_receiver->subklass() == NULL ) { // always optimize final methods, private methods or methods with no // subclasses. return new CHAResult(actual_receiver, name, signature, NULL, NULL, m); } if (!UseCHA) { // don't optimize this call return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); } } // If the method is abstract then each non-abstract subclass must implement // the method and inlining is not possible. If there is exactly 1 subclass // then there can be only 1 implementation and we are OK. if( !m.is_null() && m()->is_abstract() ) {// Method is abstract? Klass *sr = Klass::cast(static_receiver()); if( sr == sr->up_cast_abstract() ) return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); // Fall into the next code; it will find the one implementation // and that implementation is correct. } _used = true; GrowableArray<methodHandle>* methods = new GrowableArray<methodHandle>(CHA::max_result()); GrowableArray<KlassHandle>* receivers = new GrowableArray<KlassHandle>(CHA::max_result()); // Since 'm' is visible from the actual receiver we can call it if the // runtime receiver class does not override 'm'. if( !m.is_null() && m()->method_holder() != actual_receiver() && !m->is_abstract() ) { receivers->push(actual_receiver); methods->push(m); } if (static_receiver->is_interface()) { instanceKlassHandle sr = static_receiver(); process_interface(sr, receivers, methods, name, signature); } else { process_class(static_receiver, receivers, methods, name, signature); } methodHandle dummy; CHAResult* res = new CHAResult(actual_receiver, name, signature, receivers, methods, dummy); //res->print(); return res; }