jcov_events.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 932 行 · 第 1/3 页
C
932 行
if (jcov_data_type == JCOV_DATA_B && !(crt_met || cov_met) && (caller_filter == NULL || !caller_filt_ok)) { goto cleanupAndFail; } if (filt_ok && jcov_data_type == JCOV_DATA_B && (crt_met || cov_met)) { for (i = 0; i < hooked_class->methods_total; i++) { unsigned char single_item = 0; cov_item_t *cov_item; meth = hooked_class->method_cache[i]; if (meth->covtable != NULL) continue; single_item = (meth->access_flags & JVM_ACC_NATIVE) ? 1 : 0; single_item = single_item || strcmp(meth->name, "<init>"); where_line = meth->covtable_size; /* get remembered line number */ meth->covtable_size = single_item ? 1 : 2; meth->covtable = (cov_item_t*)jcov_calloc(sizeof(cov_item_t) * meth->covtable_size); if (hooked_class->data_type == JCOV_DATA_C) where_line = where_line << CRT_ENTRY_PACK_BITS; cov_item = cov_item_new(0, CT_METHOD, INSTR_ANY, where_line, 0); meth->covtable[0] = *cov_item; jcov_free(cov_item); if (!single_item) { cov_item = cov_item_new(0, CT_BLOCK, INSTR_ANY, where_line, 0); meth->covtable[1] = *cov_item; jcov_free(cov_item); meth->pc_cache = (int*)jcov_calloc(sizeof(int) * meth->pc_cache_size); meth->pc_cache[0] = 2; /* 2 is the index of the last cov_item plus one */ } } } /* read the class' attributes */ READ_AND_CHECK(count, 2, ctx); /* class attrs total */ for (i = 0; i < count; i++) { READ_AND_CHECK(x2, 2, ctx); GET_CP_ENTRY(cp_entry, x2, ctx); /* attr name index */ ASSRT_CP_ENTRY(cp_entry, JVM_CONSTANT_Utf8, 6, ctx); READ_AND_CHECK(attr_len, 4, ctx); /* bytes_count */ if (!filt_ok) { SKIP(attr_len, ctx); continue; } if (!strcmp(cp_entry->u.Utf8.bytes, ABS_SRC_PATH_ATTR_NAME)) { READ_AND_CHECK(x2, 2, ctx); GET_CP_ENTRY(cp_entry, x2, ctx); ASSRT_CP_ENTRY(cp_entry, JVM_CONSTANT_Utf8, 7, ctx); jcov_free(hooked_class->src_name); hooked_class->src_name = jcov_strdup(cp_entry->u.Utf8.bytes); } else if (!strcmp(cp_entry->u.Utf8.bytes, SRC_FILE_ATTR_NAME)) { READ_AND_CHECK(x2, 2, ctx); GET_CP_ENTRY(cp_entry, x2, ctx); ASSRT_CP_ENTRY(cp_entry, JVM_CONSTANT_Utf8, 8, ctx); if (hooked_class->src_name == NULL) { hooked_class->src_name = jcov_strdup(cp_entry->u.Utf8.bytes); } } else if (!strcmp(cp_entry->u.Utf8.bytes, TIMESTAMP_ATTR_NAME)) { union { struct { UINT32 hi; UINT32 lo; } parts; jlong timestamp; } tstamp; READ_AND_CHECK(tstamp.parts.hi, 4, ctx); READ_AND_CHECK(tstamp.parts.lo, 4, ctx); if (hooked_class->timestamp != NULL) continue; hooked_class->timestamp = (char*)jcov_calloc(24 * sizeof(char)); sprintf(hooked_class->timestamp, "%lld", tstamp.timestamp); } else if (!strcmp(cp_entry->u.Utf8.bytes, COMPILATION_ID_ATTR_NAME)) { READ_AND_CHECK(x2, 2, ctx); /* compilation_id_index */ GET_CP_ENTRY(cp_entry, x2, ctx); ASSRT_CP_ENTRY(cp_entry, JVM_CONSTANT_Utf8, 8, ctx); if (hooked_class->timestamp != NULL) { goto cleanupAndFail; } hooked_class->timestamp = jcov_strdup(cp_entry->u.Utf8.bytes); } else { SKIP(attr_len, ctx); } } if (hooked_class->timestamp == NULL) { hooked_class->timestamp = (char*)jcov_calloc(2 * sizeof(char)); sprintf(hooked_class->timestamp, "%c", '0'); } if (jcov_data_type == JCOV_DATA_B && !(crt_met || cov_met)) { for (i = 0; i < hooked_class->methods_total; i++) { hooked_class->method_cache[i]->covtable_size = 0; hooked_class->data_type = JCOV_SKIP_CLASS; } } if (hooked_class->src_name == NULL) { hooked_class->src_name = dummy_src_name(hooked_class->name); } /* constant pool may be freed now */ jcov_free_constant_pool(ctx.cp, ctx.cp_size); put_hooked_class(this_thread->hooked_class_table, &hooked_class); *context = ctx; return TRUE;cleanupAndFail: jcov_free_constant_pool(ctx.cp, ctx.cp_size); jcov_free_hooked_class(hooked_class); return FALSE;}void jcov_class_load_hook_event(JVMPI_Event *event) { bin_class_context_t ctx; Bool res; ctx.class_len = event->u.class_load_hook.class_data_len; ctx.class_data = event->u.class_load_hook.class_data; event->u.class_load_hook.new_class_data = (unsigned char*)event->u.class_load_hook.malloc_f(ctx.class_len); memcpy(event->u.class_load_hook.new_class_data, ctx.class_data, ctx.class_len); event->u.class_load_hook.new_class_data_len = ctx.class_len; res = jcov_parse_class_data(event->env_id, &ctx); cnt_load_hooks++; if (verbose_mode > 1 && res && ctx.hooked_class->name != NULL) { char info[MAX_PATH_LEN]; sprintf(info, "CLASS_LOAD_HOOK : %s", ctx.hooked_class->name); jcov_info(info); }} #undef SKIP#undef ASSRT_CP_ENTRYvoid jcov_class_load_event(JVMPI_Event *event) { char info[MAX_PATH_LEN]; jcov_class_t *class; jcov_hooked_class_t *hooked_class; jcov_class_t *found_class; jcov_method_t *found_method; jcov_method_t **class_methods; JVMPI_Method *meth; jcov_thread_t *this_thread; int i, ind; INT32 mem; char *name, *tmp; int last_matched = 0; JNIEnv *env_id = event->env_id; LOCK(threads); this_thread = find_thread(env_id); UNLOCK(threads); if (this_thread == NULL) { return; } if (!(event->event_type & JVMPI_REQUESTED_EVENT)) { cnt_loads++; } name = jcov_strdup(event->u.class_load.class_name); for (; (tmp = (char*)strchr(name, '.')); *tmp = '/'); hooked_class = lookup_hooked_class(this_thread->hooked_class_table, name); if (hooked_class == NULL) { cnt_skip++; if (verbose_mode > 1) { sprintf(info, "class will not be profiled : %s", name); jcov_info(info); } if (load_early_classes && jcov_java_init_done) { LOCK(cls_flt); if (!lookup_classID(class_filt_table, event->u.class_load.class_id)) { jcov_class_id_t *cid = jcov_class_id_new(event->u.class_load.class_id); put_classID(class_filt_table, &cid); } UNLOCK(cls_flt); } return; } class = (jcov_class_t*)jcov_calloc(sizeof(jcov_class_t)); class->name = name; if (verbose_mode > 1) { char *req = (event->event_type & JVMPI_REQUESTED_EVENT) ? "(requested) " : ""; sprintf(info, "%sCLASS_LOAD : %s", req, name); jcov_info(info); } class->id = event->u.class_load.class_id; class->num_methods = event->u.class_load.num_methods; class->unloaded = 0; mem = class->num_methods * sizeof(JVMPI_Method); class->methods = (JVMPI_Method*)jcov_calloc(mem); memcpy(class->methods, event->u.class_load.methods, mem); class->timestamp = jcov_strdup(hooked_class->timestamp); class->src_name = jcov_strdup(hooked_class->src_name); class->access_flags = hooked_class->access_flags; class->data_type = hooked_class->data_type; for (i = 0; i < event->u.class_load.num_methods; i++) { class->methods[i].method_name = jcov_strdup(class->methods[i].method_name); class->methods[i].method_signature = jcov_strdup(class->methods[i].method_signature); } LOCK(cls_key); found_class = lookup_class_by_key(class_key_table, class); UNLOCK(cls_key); cnt_prof++; if (found_class) { if (!(found_class->unloaded)) { if (verbose_mode > 0) { sprintf(info, "class is loaded twice : %s", found_class->name); jcov_error(info); } return; } CHK(found_class->num_methods != class->num_methods, "jcov_class_load_event: method number mistmatch"); LOCK(cls_id); LOCK(methods); remove_class_by_id(class_id_table, found_class->id); found_class->id = class->id; for (i = 0; i < class->num_methods; i++) { meth = &(class->methods[i]); ind = find_method_in_class(found_class, meth); CHK(ind == -1, "jcov_class_load_event: method def not found"); found_method = lookup_method(method_table, (found_class->methods[ind]).method_id); CHK(!found_method, "jcov_class_load_event: method not found"); remove_method(method_table, found_method->id); found_method->id = meth->method_id; (found_class->methods[ind]).method_id = meth->method_id; put_method(method_table, &found_method); } put_class_by_id(class_id_table, &found_class); UNLOCK(methods); UNLOCK(cls_id); found_class->unloaded = 0; jcov_free(class->methods); jcov_free(class->name); jcov_free(class->src_name); jcov_free(class); return; } LOCK(cls_id); LOCK(cls_key); put_class_by_id(class_id_table, &class); put_class_by_key(class_key_table, &class); UNLOCK(cls_key); UNLOCK(cls_id); class_methods = hooked_class->method_cache; LOCK(methods); for (i = 0; i < class->num_methods; i++) { ind = array_lookup_method(&(class->methods[i]), class_methods, hooked_class->methods_total, last_matched); /* The method could be a miranda method which was not in the initial classfile. If so, just ignore it: */ if (ind != -1) { last_matched = ind; class_methods[ind]->id = class->methods[i].method_id; class_methods[ind]->class = class; if (lookup_method(method_table, class_methods[ind]->id) != NULL) continue; put_method(method_table, &(class_methods[ind])); /* Ownership of this method info is now transferred from the hooked_class to the global method hash table. Remove it from the hooked_class's method cache: */ class_methods[ind] = NULL; } } UNLOCK(methods); remove_hooked_class(this_thread->hooked_class_table, hooked_class); jcov_free_hooked_class(hooked_class);}#define SKIP_CLASS if (verbose_mode > 1) { \ sprintf(info, "class will not be profiled : %s", class.name); \ jcov_info(info); \ } \ cnt_skip++void jcov_req_class_load_event(JVMPI_Event *event) { jcov_class_t *found_class, class; bin_class_context_t ctx = { 0, 0, 0, 0, 0, 0, 0 }; UINT8 *class_buf = NULL; char *tmp; Bool res; char info[MAX_PATH_LEN]; cnt_req_loads++; class.name = jcov_strdup(event->u.class_load.class_name); for (; (tmp = (char*)strchr(class.name, '.')); *tmp = '/'); LOCK(cls_key); found_class = lookup_class_by_key_short(class_key_table, &class); UNLOCK(cls_key); if (found_class) { jcov_free(class.name); SKIP_CLASS; return; } find_or_add_thread(event->env_id); if (!get_class_binary_data(event->env_id, class.name, &class_buf, &ctx.class_len)) { jcov_free(class.name); jcov_free(class_buf);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?