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 + -
显示快捷键?