Exemple #1
0
static void
da_relocate_base   (DArray         *d,
                    TrieIndex       s,
                    TrieIndex       new_base)
{
    TrieIndex   old_base;
    Symbols    *symbols;
    int         i;

    old_base = da_get_base (d, s);
    symbols = da_output_symbols (d, s);

    for (i = 0; i < symbols_num (symbols); i++) {
        TrieIndex   old_next, new_next, old_next_base;

        old_next = old_base + symbols_get (symbols, i);
        new_next = new_base + symbols_get (symbols, i);
        old_next_base = da_get_base (d, old_next);

        /* allocate new next node and copy BASE value */
        da_alloc_cell (d, new_next);
        da_set_check (d, new_next, s);
        da_set_base (d, new_next, old_next_base);

        /* old_next node is now moved to new_next
         * so, all cells belonging to old_next
         * must be given to new_next
         */
        /* preventing the case of TAIL pointer */
        if (old_next_base > 0) {
            TrieIndex   c, max_c;

            max_c = MIN_VAL (TRIE_CHAR_MAX, TRIE_INDEX_MAX - old_next_base);
            for  (c = 0; c < max_c; c++) {
                if (da_get_check (d, old_next_base + c) == old_next)
                    da_set_check (d, old_next_base + c, new_next);
            }
        }

        /* free old_next node */
        da_free_cell (d, old_next);
    }

    symbols_free (symbols);

    /* finally, make BASE[s] point to new_base */
    da_set_base (d, s, new_base);
}
Exemple #2
0
static Bool
da_enumerate_recursive (const DArray   *d,
                        TrieIndex       state,
                        DAEnumFunc      enum_func,
                        void           *user_data)
{
    Bool        ret;
    TrieIndex   base;

    base = da_get_base (d, state);

    if (base < 0) {
        TrieChar   *key;

        key = da_get_state_key (d, state);
        ret = (*enum_func) (key, state, user_data);
        free (key);
    } else {
        Symbols *symbols;
        int      i;

        ret = TRUE;
        symbols = da_output_symbols (d, state);
        for (i = 0; ret && i < symbols_num (symbols); i++) {
            ret = da_enumerate_recursive (d, base + symbols_get (symbols, i),
                                          enum_func, user_data);
        }

        symbols_free (symbols);
    }

    return ret;
}
Exemple #3
0
/**
 * @brief Get all walkable characters from state
 *
 * @param s     : the state to get
 * @param chars : the storage for the result
 * @param chars_nelm : the size of @a chars[] in number of elements
 *
 * @return total walkable characters
 *
 * Get the list of all walkable characters from state @a s. At most
 * @a chars_nelm walkable characters are stored in @a chars[] on return.
 *
 * The function returns the actual number of walkable characters from @a s.
 * Note that this may not equal the number of characters stored in @a chars[]
 * if @a chars_nelm is less than the actual number.
 *
 * Available since: 0.2.6
 */
int
trie_state_walkable_chars (const TrieState  *s,
                           AlphaChar         chars[],
                           int               chars_nelm)
{
    int syms_num = 0;

    if (!s->is_suffix) {
        Symbols *syms = da_output_symbols (s->trie->da, s->index);
        int i;

        syms_num = symbols_num (syms);
        for (i = 0; i < syms_num && i < chars_nelm; i++) {
            TrieChar tc = symbols_get (syms, i);
            chars[i] = alpha_map_trie_to_char (s->trie->alpha_map, tc);
        }

        symbols_free (syms);
    } else {
        const TrieChar *suffix = tail_get_suffix (s->trie->tail, s->index);
        chars[0] = alpha_map_trie_to_char (s->trie->alpha_map,
                                           suffix[s->suffix_idx]);
        syms_num = 1;
    }

    return syms_num;
}
Exemple #4
0
void frame_dump_stack(FILE *out, uint16 fp) {
    char buf[10];
    char *funcname;
    int lastpc = pc;
    int i;
    thread_info *thread;
    thread = fp == GET_REG16(7) ? current_thread : hash_get(&threads, fp);
    
    if (!thread)
	return;

    for (i = thread->num_frames; i >= 0; i--) {
	int fpc = thread->frames[i].pc & ~1;
	int fp = thread->frames[i].fp;
	funcname = symbols_get(fpc, 0);
	if (!funcname) {
	    snprintf(buf, 10, "0x%04x", fpc);
	    funcname=buf;
	}
	fprintf(out, "    %04x: %30s [%04x+%04x]\n", 
	       fp, funcname, fpc, lastpc - fpc);
	lastpc = (memory[fp] << 8 | memory[fp+1]);
    }
    return;
}
Exemple #5
0
static void frame_dump_function(unsigned int key, void *param) {
    char buf[10];
    char *funcname;
    profile_info *prof = param;

	
    funcname =  symbols_get(key, 0);

    if (!funcname) {
	snprintf(buf, 10, "0x%04x", key);
	funcname=buf;
    }
    
    if (prof->calls) {
	fprintf(proffile, "%2s%30s: %11ld %11lu %11lu %11lu %11lu %11lu %11lu %11lu\n",
		prof->isIRQ ? "I:" : "  ",
		funcname, prof->calls, prof->local_cycles, 
		prof->total_cycles,
		prof->local_cycles / prof->calls, 
		prof->total_cycles / prof->calls,
		prof->max_local_cycles, prof->max_total_cycles,
		prof->irq_cycles);
    } else {
	fprintf(proffile, "%2s%30s: never finished\n", 
		prof->isIRQ ? "I:" : "  ", funcname);
    }
    hash_enumerate(&prof->callees, frame_dump_callee);
    fprintf(proffile, "\n");
}
Exemple #6
0
static void frame_dump_callee(unsigned int key, void *param) {
    char buf[10];
    char *funcname;
    callee_info *callee = param;

    funcname =  symbols_get(key & ~1, 0);

    if (!funcname) {
	snprintf(buf, 10, "0x%04x", key & ~1);
	funcname=buf;
    }


    fprintf(proffile, "    %2s%30s: %6ld calls %11ld cycles\n",
	    key & 1 ? "I:" : "  ",
	    funcname, callee->calls, callee->cycles);
}    
Exemple #7
0
static Bool
da_fit_symbols     (DArray         *d,
                    TrieIndex       base,
                    const Symbols  *symbols)
{
    int         i;

    for (i = 0; i < symbols_num (symbols); i++) {
        TrieChar    sym = symbols_get (symbols, i);

        /* if (base + sym) > TRIE_INDEX_MAX which means it's overflow,
         * or cell [base + sym] is not free, the symbol is not fit.
         */
        if (base > TRIE_INDEX_MAX - sym || !da_check_free_cell (d, base + sym))
            return FALSE;
    }
    return TRUE;
}
Exemple #8
0
static TrieIndex
da_find_free_base  (DArray         *d,
                    const Symbols  *symbols)
{
    TrieChar        first_sym;
    TrieIndex       s;

    /* find first free cell that is beyond the first symbol */
    first_sym = symbols_get (symbols, 0);
    s = -da_get_check (d, da_get_free_list (d));
    while (s != da_get_free_list (d)
           && s < (TrieIndex) first_sym + DA_POOL_BEGIN)
    {
        s = -da_get_check (d, s);
    }
    if (s == da_get_free_list (d)) {
        for (s = first_sym + DA_POOL_BEGIN; ; ++s) {
            if (!da_extend_pool (d, s))
                return TRIE_INDEX_ERROR;
            if (da_get_check (d, s) < 0)
                break;
        }
    }

    /* search for next free cell that fits the symbols set */
    while (!da_fit_symbols (d, s - first_sym, symbols)) {
        /* extend pool before getting exhausted */
        if (-da_get_check (d, s) == da_get_free_list (d)) {
            if (!da_extend_pool (d, d->num_cells))
                return TRIE_INDEX_ERROR;
        }

        s = -da_get_check (d, s);
    }

    return s - first_sym;
}
Exemple #9
0
/**
 * Handle a call instruction and add profile information for the
 * called and calling function.
 */
void frame_begin(uint16 fp, int in_irq) {
    frame_info *frame, *pframe;
    profile_info *pprof;

    /* If we there is no current thread, just return.  The current thread
     * will be created by the opcode that initializes the stack pointer. 
     * So there should be always a current thread at the moment we call
     * a function.
     */
    if (!current_thread)
	return;

    if (fp < current_thread->minfp)
	current_thread->minfp = fp;

    /* Add a new frame to the current thread.  Resize the stack structure
     * if necessary.
     */
    frame_grow_num_frames();
    
    /* Initialize the new frame.
     */
    frame = &current_thread->frames[current_thread->num_frames];
    frame->startcycle = cycles;
    frame->childcycles = 0;
    frame->irqcycles = 0;
    frame->threadcycles = 0;
    frame->pc = pc | (in_irq ? 1 : 0);
    frame->fp = fp;

#ifdef LOG_CALLS
#ifndef LOG_CALLS_IRQ
    int i, rec_in_irq = 0;
    /* Check if this frame was directly or indirectly called by interrupt. */
    for (i = current_thread->num_frames; i >= 0; i--) {
	if (current_thread->frames[i].pc & 1) {
	    rec_in_irq = 1;
	    break;
	}
    }
    /* Log the call to framelog, unless called from interrupt. */
    if (!rec_in_irq)
#endif
    {
	char* funcname, buf[10];
	funcname = symbols_get(pc, 0);
	if (!funcname) {
	    snprintf(buf, 10, "0x%04x", pc);
	    funcname=buf;
	}
	fprintf(framelog, "%*s%s(%04x,%04x,%04x,%04x) fp: %04x klock: %d inirq: %d\n",
		current_thread->num_frames * 3, "", funcname,
		pc < 0x8000 ? GET_REG16(6) : GET_REG16(0), 
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+2) : GET_REG16(1),
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+4) : GET_REG16(2),
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+6) : GET_REG16(3),
		GET_REG16(7),
		memory[symbols_getaddr("_kernel_lock")], in_irq);
    }
#endif

    /* get parent frame and add a new callee to its profile information. */
    pframe = frame - 1;
#ifdef HASH_PROFILES
    pprof = hash_get(&profiles, pframe->pc & ~1);
#else
    pprof = profiles[pframe->pc & ~1];
#endif
    if (!pprof) {
#ifdef HASH_PROFILES
       pprof = hash_create(&profiles, pframe->pc & ~1, sizeof(profile_info));
#else
       pprof = profiles[pframe->pc & ~1] = malloc(sizeof(profile_info));
#endif
       memset(pprof, 0, sizeof(profile_info));
       hash_init(&pprof->callees, 5);
    }
}
Exemple #10
0
void frame_switch(uint16 oldframe, uint16 newframe) {
    if (oldframe == newframe)
	return;

#ifdef LOG_CALLS
    if (current_thread) {
	int lastpc = pc;
	int i;
	char buf[10];
	char *funcname;
	for (i = current_thread->num_frames; i >= 0; i--) {
	    int fpc = current_thread->frames[i].pc & ~1;
	    int fp = current_thread->frames[i].fp;
	    funcname = symbols_get(fpc, 0);
	    if (!funcname) {
		snprintf(buf, 10, "0x%04x", fpc);
		funcname=buf;
	    }
	    fprintf(framelog, "    %04x: %30s%s [%04x+%04x]\n", 
		    fp, funcname, 
		    current_thread->frames[i].pc & 1 ? "(I)" : "   ",
		    fpc, lastpc - fpc);
	    lastpc = (memory[fp] << 8 | memory[fp+1]);
	}
    }
#endif

#ifdef VERBOSE_FRAME
    printf("Frame switch: %04x --> %04x    cycles: %11ld\n", 
	   oldframe, newframe, cycles);
#endif
    if (current_thread) {
	current_thread->switchcycle = cycles;
	current_thread->savefp = oldframe;
	hash_move(&threads, 0, oldframe);
    }
    
    current_thread = hash_move(&threads, newframe, 0);
#ifdef LOG_CALLS
    fprintf(framelog, "Frame switch: %04x --> %04x\n", oldframe, newframe);
    if (current_thread) {
	int lastpc = pc;
	int i;
	char buf[10];
	char *funcname;
	for (i = current_thread->num_frames; i >= 0; i--) {
	    int fpc = current_thread->frames[i].pc & ~1;
	    int fp = current_thread->frames[i].fp;
	    funcname = symbols_get(fpc, 0);
	    if (!funcname) {
		snprintf(buf, 10, "0x%04x", fpc);
		funcname=buf;
	    }
	    fprintf(framelog, "    %04x: %30s%s [%04x+%04x]\n", 
		    fp, funcname, 
		    current_thread->frames[i].pc & 1 ? "(I)" : "   ",
		    fpc, lastpc - fpc);
	    lastpc = (memory[fp] << 8 | memory[fp+1]);
	}
    }
#endif
    if (!current_thread) {
	current_thread = hash_create(&threads, 0, 
				     sizeof(thread_info) + 
				     2* sizeof(frame_info));
	current_thread->minfp = newframe;
	current_thread->size_frames = 2;
	current_thread->num_frames = 0;
	current_thread->switchcycle = cycles;
	memset(&current_thread->frames[0], 0, sizeof(frame_info));
	current_thread->frames[0].startcycle = cycles;
	current_thread->frames[0].pc = pc;
    }
    current_thread->frames[current_thread->num_frames].threadcycles
	+= cycles - current_thread->switchcycle;
}