STATIC int rawSampCmp( const void *_d1, const void *_d2 ) /*******************************************************/ { const pointer *d1 = _d1; const pointer *d2 = _d2; address *data1; address *data2; data1 = *d1; data2 = *d2; return( AddrCmp( data1, data2 ) ); }
STATIC void calcAggregates( void ) /********************************/ { unsigned index; unsigned index2; int cmp_result; unsigned *sorted_idx; address ***sorted_vect; massgd_sample_addr **massgd_data; // unsigned mbuckets; unsigned curr_mbucket; unsigned curr_midx; thread_data *thd; unsigned buckets; unsigned base; unsigned best; unsigned end; massgd_sample_addr *curr; ClearMassaged( CurrSIOData ); buckets = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { buckets += RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; } sorted_idx = ProfCAlloc( buckets * sizeof( *sorted_idx ) ); sorted_vect = ProfAlloc( buckets * sizeof(*thd->raw_bucket) ); base = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { end = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; for( index = 0; index < end; ++index, ++base ) { sorted_vect[base] = ProfAlloc( MAX_RAW_BUCKET_INDEX * sizeof( **sorted_vect ) ); for( index2 = 0; index2 < MAX_RAW_BUCKET_INDEX; ++index2 ) { sorted_vect[base][index2] = &thd->raw_bucket[index][index2]; } qsort( sorted_vect[base], MAX_RAW_BUCKET_INDEX, sizeof(**sorted_vect), rawSampCmp ); } } /* skip over all the 0:0 samples */ for( index = 0; index < buckets; ++index ) { index2 = 0; for( ;; ) { if( index2 >= MAX_RAW_BUCKET_INDEX ) break; if( !(sorted_vect[index][index2]->mach.segment == 0 && sorted_vect[index][index2]->mach.offset == 0) ) break; ++index2; } sorted_idx[index] = index2; } curr = NULL; curr_mbucket = 0; curr_midx = -1; // mbuckets = 1; massgd_data = ProfAlloc( sizeof( *massgd_data ) ); massgd_data[0] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); for( ;; ) { best = -1U; for( index = 0; index < buckets; ++index ) { index2 = sorted_idx[index]; if( index2 >= MAX_RAW_BUCKET_INDEX ) continue; if( best == -1U ) best = index; cmp_result = AddrCmp( sorted_vect[index][index2], sorted_vect[best][sorted_idx[best]] ); if( cmp_result < 0 ) best = index; } if( best == -1U ) break; if( curr == NULL || AddrCmp( sorted_vect[best][sorted_idx[best]], curr->raw ) != 0 ) { if( ++curr_midx >= MAX_MASSGD_BUCKET_INDEX ) { ++curr_mbucket; massgd_data = ProfRealloc( massgd_data, (curr_mbucket+1) * sizeof(*massgd_data) ); massgd_data[curr_mbucket] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); curr_midx = 0; } curr = &massgd_data[curr_mbucket][curr_midx]; curr->raw = sorted_vect[best][sorted_idx[best]]; } curr->hits++; sorted_idx[best]++; } CurrSIOData->massaged_sample = massgd_data; CurrSIOData->number_massaged = 1 + curr_midx + (curr_mbucket * (unsigned long)MAX_MASSGD_BUCKET_INDEX); CurrSIOData->massaged_mapped = true; for( index = 0; index < buckets; ++index ) { ProfFree( sorted_vect[index] ); } ProfFree( sorted_vect ); ProfFree( sorted_idx ); }
wp_asmfile *WPAsmOpen( sio_data * curr_sio, int src_row, bool quiet ) /*******************************************************************/ { wp_asmfile * wpasm_file; cue_handle * ch; cue_handle * ch2; mod_info * curr_mod; file_info * curr_file; massgd_sample_addr * samp_data; wp_asmline * asm_line; mod_handle mh; file_handle fh; address addr; cue_fileid fid; search_result cue_find; int rows; int asm_group; int asm_row; int file_index; int addr_cmp; clicks_t addr_tick_index; quiet=quiet; ch = alloca( DIPHandleSize( HK_CUE ) ); ch2 = alloca( DIPHandleSize( HK_CUE ) ); curr_file = curr_sio->curr_file; curr_mod = curr_sio->curr_mod; if( curr_file->fid == 0 || LineCue( curr_mod->mh, curr_sio->curr_file->fid, src_row, 0, ch2 ) == SR_NONE ) { ch2 = NULL; } fh = ExeOpen( curr_sio->curr_image->name ); if( fh == -1 ) { ErrorMsg( LIT( Exe_Not_Found ), curr_sio->curr_image->name ); return( NULL ); } wpasm_file = ProfCAlloc( sizeof(wp_asmfile) ); curr_sio->asm_file = wpasm_file; wpasm_file->asm_buff = ProfAlloc( MAX_ASM_BUFF_LEN ); wpasm_file->asm_buff_len = MAX_ASM_BUFF_LEN; SetNumBytes( 0 ); SetExeFile( fh, false ); wpasm_file->fh = fh; addr = ModAddr( curr_mod->mh ); SetExeOffset( addr ); wpasm_file->max_time = 0; addr_tick_index = curr_mod->first_tick_index - 1; samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ ); wpasm_file->asm_data = ProfAlloc( sizeof(wp_asm_groups) ); wpasm_file->asm_data[0].asm_lines = ProfAlloc( MAX_ASM_LINE_SIZE ); wpasm_file->asm_groups = 0; rows = 0; for( ;; ) { mh = curr_mod->mh; if( EndOfSegment() || AddrMod( addr, &mh ) == SR_NONE || mh != curr_mod->mh ) break; cue_find = (AddrCue( curr_mod->mh, addr, ch ) == SR_EXACT); if( ch2 != NULL && CueCmp( ch, ch2 ) == 0 ) { wpasm_file->entry_line = rows; ch2 = NULL; } asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); if( cue_find ) { asm_line->source_line = true; asm_line->u.src.line = CueLine( ch ); asm_line->u.src.src_file = NULL; if( !curr_file->unknown_file ) { fid = CueFileId( ch ); file_index = 0; while( file_index < curr_mod->file_count ) { curr_file = curr_mod->mod_file[file_index]; if( curr_file->fid == fid ) { asm_line->u.src.src_file = FOpenSource( curr_file->name, mh, fid ); break; } file_index++; } } rows++; asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); } asm_line = &wpasm_file->asm_data[asm_group].asm_lines[asm_row]; asm_line->source_line = false; asm_line->u.asm_line.addr = addr; asm_line->u.asm_line.tick_count = 0; for( ;; ) { if( samp_data == NULL ) break; addr_cmp = AddrCmp( &addr, samp_data->raw ); if( addr_cmp < 0 ) break; if( addr_cmp == 0 ) { asm_line->u.asm_line.tick_count = samp_data->hits; if( asm_line->u.asm_line.tick_count > wpasm_file->max_time ) { wpasm_file->max_time = asm_line->u.asm_line.tick_count; } } samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ ); } rows++; CodeAdvance( &addr ); } WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); wpasm_file->asm_data[asm_group].asm_lines = ProfRealloc( wpasm_file->asm_data[asm_group].asm_lines, sizeof(wp_asmline)*(asm_row+1) ); wpasm_file->asm_rows = rows; return( wpasm_file ); }