bool SaveARGB(const char *fileName, BYTE *data, int width, int height) { bool result = false; if (!data) return result; ARGBPixel *input = (ARGBPixel *)data; BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)]; memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel)); for(int row = 0; row < height; ++row) { for(int col = 0; col < width; ++col) { int outputIdx = BITMAP_INDEX(col, row, width); int inputIdx = ((height - row - 1) * width) + col; output[outputIdx].red = input[inputIdx].red; output[outputIdx].green = input[inputIdx].green; output[outputIdx].blue = input[inputIdx].blue; } } result = SaveBitmap(fileName, (BYTE *)output, width, height); delete [] output; return result; }
static int _irqext_expand(void) { unsigned int old_size = iectrl.count; unsigned int new_size = iectrl.count + HOST_IRQEXT_CHUNK; struct vmm_host_irq **irqs = NULL; unsigned long *bitmap = NULL; irqs = realloc(iectrl.irqs, old_size * sizeof (struct vmm_host_irq *), new_size * sizeof (struct vmm_host_irq *)); if (!irqs) { vmm_printf("%s: Failed to reallocate extended IRQ array from " "%d to %d bytes\n", __func__, old_size, new_size); return VMM_ENOMEM; } old_size = BITMAP_SIZE(old_size); new_size = BITMAP_SIZE(new_size); bitmap = realloc(iectrl.bitmap, old_size, new_size); if (!bitmap) { vmm_printf("%s: Failed to reallocate extended IRQ bitmap from " "%d to %d bytes\n", __func__, old_size, new_size); vmm_free(irqs); return VMM_ENOMEM; } iectrl.irqs = irqs; iectrl.bitmap = bitmap; iectrl.count += HOST_IRQEXT_CHUNK; return VMM_OK; }
bool SaveBGR(const char *fileName, BYTE *data, int width, int height) { bool result = false; if (!data) return false; RGBPixel *input = (RGBPixel *)data; BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)]; // Pad bytes need to be set to zero, it's easier to just set the entire chunk of memory memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel)); for(int row = 0; row < height; ++row) { for(int col = 0; col < width; ++col) { // In a bitmap (0,0) is at the bottom left, in the frame buffer it is the top left. int outputIdx = BITMAP_INDEX(col, row, width); int inputIdx = ((height - row - 1) * width) + col; output[outputIdx].red = input[inputIdx].blue; output[outputIdx].green = input[inputIdx].green; output[outputIdx].blue = input[inputIdx].red; } } result = SaveBitmap(fileName, (BYTE *)output, width, height); delete [] output; return result; }
STATIC_INLINE StgPtr thread_arg_block (StgFunInfoTable *fun_info, StgClosure **args) { StgPtr p; StgWord bitmap; nat size; p = (StgPtr)args; switch (fun_info->f.fun_type) { case ARG_GEN: bitmap = BITMAP_BITS(fun_info->f.b.bitmap); size = BITMAP_SIZE(fun_info->f.b.bitmap); goto small_bitmap; case ARG_GEN_BIG: size = GET_FUN_LARGE_BITMAP(fun_info)->size; thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size); p += size; break; default: bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]); size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]); small_bitmap: while (size > 0) { if ((bitmap & 1) == 0) { thread((StgClosure **)p); } p++; bitmap = bitmap >> 1; size--; } break; } return p; }
bool SaveRGBPlanar(const char *fileName, BYTE *data, int width, int height) { if (!data) return false; const char *nameExt[] = {"red", "green", "blue"}; BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)]; memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel)); for(int color = 0; color < 3; ++color) { for(int row = 0; row < height; ++row) { for(int col = 0; col < width; ++col) { int outputIdx = BITMAP_INDEX(col, row, width); int inputIdx = ((height - row - 1) * width) + col; output[outputIdx].blue = 0; output[outputIdx].green = 0; output[outputIdx].red = 0; switch(color) { case 0: output[outputIdx].red = data[inputIdx]; break; case 1: output[outputIdx].green = data[inputIdx + (width * height)]; break; case 2: output[outputIdx].blue = data[inputIdx + 2 * (width * height)]; break; default: break; } } } std::string outputFile = fileName; size_t find = outputFile.find_last_of("."); outputFile.insert(find, "-"); outputFile.insert(find+1, nameExt[color]); if(!SaveBitmap(outputFile.c_str(), (BYTE *)output, width, height)) { delete [] output; return false; } } delete [] output; return true; }
/* *************************************************************************** * Determine if a stat header line has to be displayed. * * RETURNS: * TRUE if a header line has to be displayed. *************************************************************************** */ int check_line_hdr(void) { int i, rc = FALSE; /* Get number of options entered on the command line */ if (get_activity_nr(act, AO_SELECTED, COUNT_OUTPUTS) > 1) return TRUE; for (i = 0; i < NR_ACT; i++) { if (IS_SELECTED(act[i]->options)) { /* Special processing for activities using a bitmap */ if (act[i]->bitmap) { if (count_bits(act[i]->bitmap->b_array, BITMAP_SIZE(act[i]->bitmap->b_size)) > 1) { rc = TRUE; } } else if (act[i]->nr > 1) { rc = TRUE; } /* Stop now since we have only one selected activity */ break; } } return rc; }
an_icon *IconResourceToIcon( FILE *fp, an_icon_file *icon_file, unsigned i ) { an_icon_resource *res; BITMAPINFO *bm; BITMAPINFOHEADER *h; an_icon *icon; if( i >= icon_file->count ) return( NULL ); res = &icon_file->resources[ i ]; fseek( fp, res->DIB_offset, SEEK_SET ); bm = ReadIconBitmap( fp ); if( bm ) { icon = UtilMalloc( sizeof( an_icon ) ); icon->bm = bm; h = &bm->bmiHeader; // h->biHeight /= 2; /* code gen bug */ h->biHeight = res->height; /* they have height * 2 in this field */ h->biSizeImage = BITS_TO_BYTES( h->biWidth * h->biBitCount, h->biHeight ); icon->xor_size = h->biSizeImage; icon->and_size = BITS_TO_BYTES( h->biWidth, h->biHeight ); icon->xor_mask = UtilMalloc( icon->xor_size + icon->and_size ); icon->and_mask = (char *)icon->xor_mask + icon->xor_size; fseek( fp, res->DIB_offset + BITMAP_SIZE( h ), SEEK_SET ); fread( icon->xor_mask, icon->xor_size + icon->and_size, 1, fp ); return( icon ); } return( NULL ); } /* IconResourceToIcon */
static CodeSpaceArena * alloc_arena(size_t aloclogsiz, CodeSpaceArena *prev_csa) { uint64_t rbitmap; CodeSpaceArena *arena; int allocsiz; int bitmap_size; int allff_size; int rest_size; arena = raw_alloc_arena(CODE_SPACE_SIZE); arena->next_and_size = ((uintptr_t)prev_csa) | aloclogsiz; /* fill bitmap: 1 means free */ allocsiz = 16 << aloclogsiz; bitmap_size = BITMAP_SIZE(allocsiz); allff_size = (bitmap_size / 64) * 8; memset(arena->bitmap, 0xff, allff_size); /* rest of bit */ rest_size = bitmap_size - allff_size * 8; rbitmap = (1 << (rest_size)) - 1; //fprintf(stderr, "%x %x \n", csarena_allocarea_tab[aloclogsiz], bitmap_size); arena->bitmap[csarena_allocarea_tab[aloclogsiz] - 2] = rbitmap; /* gatekeeper bit */ arena->bitmap[csarena_allocarea_tab[aloclogsiz] - 1] = 0xff; return arena; }
struct page_allocator *page_allocator_init(char *start, size_t len, size_t page_size) { char *pages_start; struct page_allocator *allocator; unsigned int pages; size_t bitmap_len; if (len < page_size) { return NULL; } start = (char *) binalign_bound((uintptr_t) start, 16); pages = len / page_size; pages_start = (char *) binalign_bound((uintptr_t) start, page_size); bitmap_len = sizeof(unsigned long) * BITMAP_SIZE(pages + 1); /* one for guardbit */ while (sizeof(struct page_allocator) + bitmap_len > pages_start - start) { pages_start += page_size; pages --; assert(pages > 0); } allocator = (struct page_allocator *) start; allocator->pages_start = pages_start; allocator->pages_n = pages; allocator->page_size = page_size; allocator->free = pages * page_size; allocator->bitmap_len = bitmap_len; allocator->bitmap = (unsigned long *)((uintptr_t)&allocator->bitmap + sizeof(allocator->bitmap)); memset(allocator->bitmap, 0, bitmap_len); bitmap_set_bit(allocator->bitmap, pages); return allocator; }
/* * Inicializa el Buddy Allocator * * Aca lo que hacemos es inicializar las listas de bloques libres * de tamano 2^n. Tambien le asignamos memoria a los bitmaps * que van a representar el estado de cada bloque de paginas. * Los bitmaps en realidad no son necesarios. En un futuro los voy * a sacar y voy a implementarlo de la forma que esta en el kernel * 2.6 */ void init_buddy(void) { int i; buddy_list_t *freelist = buddy.free_lists; /* * No aseguramos que corremos en un sistema de al menos 2^MAX_ORDER * paginas. MAX_ORDER = 10 asi que el minimo de memoria seria 4Mbytes */ assert(sys_info.sys_pages >= (1 << MAX_ORDER)); size_t nbytes = 0; for (i = 0; i < MAX_ORDER; i++) nbytes += BITMAP_SIZE(sys_info.sys_pages, i); char *memory = (char *) bootmem_alloc(nbytes); if (!memory) panic("Error alocando bitmap para el buddy allocator"); /* Inicializar los bitmap con los buddies */ for (i = 0; i < MAX_ORDER; i++) { /* Inicializamos la lista en vacio */ INIT_LIST_HEAD(&freelist->head); freelist->free_pages = 0; freelist->page_bitmap = (bitmap_t) memory; /* * Las paginas en un principio las ponemos como todas en uso * asi cuando llamamos a bootmem_retire liberamos solo * las paginas que no estaban en uso y no tenemos que marcar * puntualmente las que estaban siendo usadas. */ bitmap_zero(freelist->page_bitmap, sys_info.sys_pages); memory += BITMAP_SIZE(sys_info.sys_pages, i); freelist++; } return; }
/* *************************************************************************** * Parse string containing a set of coma-separated values or ranges of * values (e.g. "0,2-5,10-"). The ALL keyword is allowed and indicate that * all possible values are selected. * * IN: * @strargv Current argument in list to parse. * @bitmap Bitmap whose contents will indicate which values have been * selected. * @max_val Upper limit that value should not reach. * @__K_VALUE0 Keyword corresponding to the first bit in bitmap (e.g "all", * "SUM"...) * * OUT: * @bitmap Bitmap updated with selected values. * * RETURNS: * 0 on success, 1 otherwise. *************************************************************************** */ int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char *__K_VALUE0) { int i, val_low, val; char *t, *s, *valstr, range[16]; if (!strcmp(strargv, K_ALL)) { /* Set bit for every possible values (CPU, IRQ, etc.) */ memset(bitmap, ~0, BITMAP_SIZE(max_val)); return 0; } for (t = strtok(strargv, ","); t; t = strtok(NULL, ",")) { if (!strcmp(t, __K_VALUE0)) { /* * Set bit 0 in bitmap. This may correspond * to CPU "all" or IRQ "SUM" for example. */ bitmap[0] |= 1; } else { /* Parse value or range of values */ strncpy(range, t, 16); range[15] = '\0'; valstr = t; if ((s = index(range, '-')) != NULL) { /* Possible range of values */ *s = '\0'; if (parse_valstr(range, max_val, &val_low) || (val_low < 0)) return 1; valstr = s + 1; } if (parse_valstr(valstr, max_val, &val)) return 1; if (s && val < 0) { /* Range of values with no upper limit (e.g. "3-") */ val = max_val - 1; } if ((!s && (val < 0)) || (s && (val < val_low))) /* * Individual value: string cannot be empty. * Range of values: n-m: m can be empty (e.g. "3-") but * cannot be lower than n. */ return 1; if (!s) { val_low = val; } for (i = val_low; i <= val; i++) { bitmap[(i + 1) >> 3] |= 1 << ((i + 1) & 0x07); } } } return 0; }
static BITMAPINFO *ReadIconBitmap( FILE *fp ) { BITMAPINFO *bm; BITMAPINFOHEADER *header; long DIB_offset, bitmap_size; header = UtilMalloc( sizeof( BITMAPINFOHEADER ) ); DIB_offset = ftell( fp ); fread( header, sizeof( BITMAPINFOHEADER ), 1, fp ); fseek( fp, DIB_offset, SEEK_SET ); bitmap_size = BITMAP_SIZE( header ); bm = realloc( header, bitmap_size ); if( !bm ) return( NULL ); fread( bm, bitmap_size, 1, fp ); return( bm ); } /* ReadIconBitmap */
struct draw * draw_new (int width, int height) { struct draw *draw; draw = xmalloc (_ALIGN (sizeof (struct draw), 4)); draw->width = width; draw->height = height; draw->total_size = BITMAP_SIZE (width, height, 24); draw->pixels = xmalloc (draw->total_size + 4); printf ("Total size: %d\n", draw->total_size); memset (draw->pixels, 0, draw->total_size); return draw; }
bool SaveBitmap(const char *fileName, BYTE *data, int width, int height) { BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; FILE *outputFile; bool bRet = false; if (data) { if(outputFile = fopen(fileName, "wb")) { width = (width + 3) & (~3); int size = width * height * 3; // 24 bits per pixel fileHeader.bfType = 0x4D42; fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size; fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); infoHeader.biSize = sizeof(BITMAPINFOHEADER); infoHeader.biWidth = width; infoHeader.biHeight = height; infoHeader.biPlanes = 1; infoHeader.biBitCount = 24; infoHeader.biCompression = BI_RGB; infoHeader.biSizeImage = BITMAP_SIZE(width, height); infoHeader.biXPelsPerMeter = 0; infoHeader.biYPelsPerMeter = 0; infoHeader.biClrUsed = 0; infoHeader.biClrImportant = 0; fwrite((unsigned char *)&fileHeader, 1, sizeof(BITMAPFILEHEADER), outputFile); fwrite((unsigned char *)&infoHeader, 1, sizeof(BITMAPINFOHEADER), outputFile); fwrite(data, 1, size, outputFile); bRet = true; fclose(outputFile); } } return bRet; }
/* *************************************************************************** * Read stats for current activity from file and display them. * * IN: * @ifd Input file descriptor. * @fpos Position in file where reading must start. * @curr Index in array for current sample statistics. * @rows Number of rows of screen. * @act_id Activity to display. * @file_actlst List of activities in file. * @file Name of file being read. * @file_magic file_magic structure filled with file magic header data. * * OUT: * @curr Index in array for next sample statistics. * @cnt Number of remaining lines of stats to write. * @eosaf Set to TRUE if EOF (end of file) has been reached. * @reset Set to TRUE if last_uptime variable should be * reinitialized (used in next_slice() function). *************************************************************************** */ void handle_curr_act_stats(int ifd, off_t fpos, int *curr, long *cnt, int *eosaf, int rows, unsigned int act_id, int *reset, struct file_activity *file_actlst, char *file, struct file_magic *file_magic) { int p; unsigned long lines = 0; unsigned char rtype; int davg = 0, next, inc = -2; if (lseek(ifd, fpos, SEEK_SET) < fpos) { perror("lseek"); exit(2); } /* * Restore the first stats collected. * Used to compute the rate displayed on the first line. */ copy_structures(act, id_seq, record_hdr, !*curr, 2); *cnt = count; /* Assess number of lines printed */ if ((p = get_activity_position(act, act_id)) >= 0) { if (act[p]->bitmap) { inc = count_bits(act[p]->bitmap->b_array, BITMAP_SIZE(act[p]->bitmap->b_size)); } else { inc = act[p]->nr; } } if (inc < 0) { /* Should never happen */ PANIC(inc); } do { /* Display count lines of stats */ *eosaf = sa_fread(ifd, &record_hdr[*curr], RECORD_HEADER_SIZE, SOFT_SIZE); rtype = record_hdr[*curr].record_type; if (!*eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { /* Read the extra fields since it's not a special record */ read_file_stat_bunch(act, *curr, ifd, file_hdr.sa_act_nr, file_actlst); } if ((lines >= rows) || !lines) { lines = 0; dis = 1; } else dis = 0; if (!*eosaf && (rtype != R_RESTART)) { if (rtype == R_COMMENT) { /* Display comment */ next = sar_print_special(*curr, tm_start.use, tm_end.use, R_COMMENT, ifd, file, file_magic); if (next) { /* A line of comment was actually displayed */ lines++; } continue; } /* next is set to 1 when we were close enough to desired interval */ next = write_stats(*curr, USE_SA_FILE, cnt, tm_start.use, tm_end.use, *reset, act_id); if (next && (*cnt > 0)) { (*cnt)--; } if (next) { davg++; *curr ^=1; lines += inc; } *reset = FALSE; } } while (*cnt && !*eosaf && (rtype != R_RESTART)); if (davg) { write_stats_avg(!*curr, USE_SA_FILE, act_id); } *reset = TRUE; }
void printStackChunk( StgPtr sp, StgPtr spBottom ) { StgWord bitmap; const StgInfoTable *info; ASSERT(sp <= spBottom); for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { info = get_itbl((StgClosure *)sp); switch (info->type) { case UPDATE_FRAME: case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: printObj((StgClosure*)sp); continue; case RET_DYN: { StgRetDyn* r; StgPtr p; StgWord dyn; nat size; r = (StgRetDyn *)sp; dyn = r->liveness; debugBelch("RET_DYN (%p)\n", r); p = (P_)(r->payload); printSmallBitmap(spBottom, sp, RET_DYN_LIVENESS(r->liveness), RET_DYN_BITMAP_SIZE); p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE; for (size = RET_DYN_NONPTRS(dyn); size > 0; size--) { debugBelch(" stk[%ld] (%p) = ", (long)(spBottom-p), p); debugBelch("Word# %ld\n", (long)*p); p++; } for (size = RET_DYN_PTRS(dyn); size > 0; size--) { debugBelch(" stk[%ld] (%p) = ", (long)(spBottom-p), p); printPtr(p); p++; } continue; } case RET_SMALL: debugBelch("RET_SMALL (%p)\n", info); bitmap = info->layout.bitmap; printSmallBitmap(spBottom, sp+1, BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap)); continue; case RET_BCO: { StgBCO *bco; bco = ((StgBCO *)sp[1]); debugBelch("RET_BCO (%p)\n", sp); printLargeBitmap(spBottom, sp+2, BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco)); continue; } case RET_BIG: barf("todo"); case RET_FUN: { StgFunInfoTable *fun_info; StgRetFun *ret_fun; ret_fun = (StgRetFun *)sp; fun_info = get_fun_itbl(ret_fun->fun); debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type); switch (fun_info->f.fun_type) { case ARG_GEN: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(fun_info->f.b.bitmap), BITMAP_SIZE(fun_info->f.b.bitmap)); break; case ARG_GEN_BIG: printLargeBitmap(spBottom, sp+2, GET_FUN_LARGE_BITMAP(fun_info), GET_FUN_LARGE_BITMAP(fun_info)->size); break; default: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type])); break; } continue; } default: debugBelch("unknown object %d\n", (int)info->type); barf("printStackChunk"); } } }
// check an individual stack object StgOffset checkStackFrame( StgPtr c ) { nat size; const StgRetInfoTable* info; info = get_ret_itbl((StgClosure *)c); /* All activation records have 'bitmap' style layout info. */ switch (info->i.type) { case UPDATE_FRAME: ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgUpdateFrame*)c)->updatee)); case ATOMICALLY_FRAME: case CATCH_RETRY_FRAME: case CATCH_STM_FRAME: case CATCH_FRAME: // small bitmap cases (<= 32 entries) case UNDERFLOW_FRAME: case STOP_FRAME: case RET_SMALL: size = BITMAP_SIZE(info->i.layout.bitmap); checkSmallBitmap((StgPtr)c + 1, BITMAP_BITS(info->i.layout.bitmap), size); return 1 + size; case RET_BCO: { StgBCO *bco; nat size; bco = (StgBCO *)*(c+1); size = BCO_BITMAP_SIZE(bco); checkLargeBitmap((StgPtr)c + 2, BCO_BITMAP(bco), size); return 2 + size; } case RET_BIG: // large bitmap (> 32 entries) size = GET_LARGE_BITMAP(&info->i)->size; checkLargeBitmap((StgPtr)c + 1, GET_LARGE_BITMAP(&info->i), size); return 1 + size; case RET_FUN: { StgFunInfoTable *fun_info; StgRetFun *ret_fun; ret_fun = (StgRetFun *)c; fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun)); size = ret_fun->size; switch (fun_info->f.fun_type) { case ARG_GEN: checkSmallBitmap((StgPtr)ret_fun->payload, BITMAP_BITS(fun_info->f.b.bitmap), size); break; case ARG_GEN_BIG: checkLargeBitmap((StgPtr)ret_fun->payload, GET_FUN_LARGE_BITMAP(fun_info), size); break; default: checkSmallBitmap((StgPtr)ret_fun->payload, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), size); break; } return sizeofW(StgRetFun) + size; } default: barf("checkStackFrame: weird activation record found on stack (%p %d).",c,info->i.type); } }
// check an individual stack object StgOffset checkStackFrame( StgPtr c ) { nat size; const StgRetInfoTable* info; info = get_ret_itbl((StgClosure *)c); /* All activation records have 'bitmap' style layout info. */ switch (info->i.type) { case RET_DYN: /* Dynamic bitmap: the mask is stored on the stack */ { StgWord dyn; StgPtr p; StgRetDyn* r; r = (StgRetDyn *)c; dyn = r->liveness; p = (P_)(r->payload); checkSmallBitmap(p,RET_DYN_LIVENESS(r->liveness),RET_DYN_BITMAP_SIZE); p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE; // skip over the non-pointers p += RET_DYN_NONPTRS(dyn); // follow the ptr words for (size = RET_DYN_PTRS(dyn); size > 0; size--) { checkClosureShallow((StgClosure *)*p); p++; } return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE + RET_DYN_NONPTRS(dyn) + RET_DYN_PTRS(dyn); } case UPDATE_FRAME: ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgUpdateFrame*)c)->updatee)); case ATOMICALLY_FRAME: case CATCH_RETRY_FRAME: case CATCH_STM_FRAME: case CATCH_FRAME: // small bitmap cases (<= 32 entries) case UNDERFLOW_FRAME: case STOP_FRAME: case RET_SMALL: size = BITMAP_SIZE(info->i.layout.bitmap); checkSmallBitmap((StgPtr)c + 1, BITMAP_BITS(info->i.layout.bitmap), size); return 1 + size; case RET_BCO: { StgBCO *bco; nat size; bco = (StgBCO *)*(c+1); size = BCO_BITMAP_SIZE(bco); checkLargeBitmap((StgPtr)c + 2, BCO_BITMAP(bco), size); return 2 + size; } case RET_BIG: // large bitmap (> 32 entries) size = GET_LARGE_BITMAP(&info->i)->size; checkLargeBitmap((StgPtr)c + 1, GET_LARGE_BITMAP(&info->i), size); return 1 + size; case RET_FUN: { StgFunInfoTable *fun_info; StgRetFun *ret_fun; ret_fun = (StgRetFun *)c; fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun)); size = ret_fun->size; switch (fun_info->f.fun_type) { case ARG_GEN: checkSmallBitmap((StgPtr)ret_fun->payload, BITMAP_BITS(fun_info->f.b.bitmap), size); break; case ARG_GEN_BIG: checkLargeBitmap((StgPtr)ret_fun->payload, GET_FUN_LARGE_BITMAP(fun_info), size); break; default: checkSmallBitmap((StgPtr)ret_fun->payload, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), size); break; } return sizeofW(StgRetFun) + size; } default: barf("checkStackFrame: weird activation record found on stack (%p %d).",c,info->i.type); } }
static void scavenge_stack(StgPtr p, StgPtr stack_end) { const StgRetInfoTable* info; StgWord bitmap; nat size; /* * Each time around this loop, we are looking at a chunk of stack * that starts with an activation record. */ while (p < stack_end) { info = get_ret_itbl((StgClosure *)p); switch (info->i.type) { case UPDATE_FRAME: // In SMP, we can get update frames that point to indirections // when two threads evaluate the same thunk. We do attempt to // discover this situation in threadPaused(), but it's // possible that the following sequence occurs: // // A B // enter T // enter T // blackhole T // update T // GC // // Now T is an indirection, and the update frame is already // marked on A's stack, so we won't traverse it again in // threadPaused(). We could traverse the whole stack again // before GC, but that seems like overkill. // // Scavenging this update frame as normal would be disastrous; // the updatee would end up pointing to the value. So we // check whether the value after evacuation is a BLACKHOLE, // and if not, we change the update frame to an stg_enter // frame that simply returns the value. Hence, blackholing is // compulsory (otherwise we would have to check for thunks // too). // // Note [upd-black-hole] // One slight hiccup is that the THUNK_SELECTOR machinery can // overwrite the updatee with an IND. In parallel GC, this // could even be happening concurrently, so we can't check for // the IND. Fortunately if we assume that blackholing is // happening (either lazy or eager), then we can be sure that // the updatee is never a THUNK_SELECTOR and we're ok. // NB. this is a new invariant: blackholing is not optional. { StgUpdateFrame *frame = (StgUpdateFrame *)p; StgClosure *v; evacuate(&frame->updatee); v = frame->updatee; if (GET_CLOSURE_TAG(v) != 0 || (get_itbl(v)->type != BLACKHOLE)) { // blackholing is compulsory, see above. frame->header.info = (const StgInfoTable*)&stg_enter_checkbh_info; } ASSERT(v->header.info != &stg_TSO_info); p += sizeofW(StgUpdateFrame); continue; } // small bitmap (< 32 entries, or 64 on a 64-bit machine) case CATCH_STM_FRAME: case CATCH_RETRY_FRAME: case ATOMICALLY_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: case CATCH_FRAME: case RET_SMALL: bitmap = BITMAP_BITS(info->i.layout.bitmap); size = BITMAP_SIZE(info->i.layout.bitmap); // NOTE: the payload starts immediately after the info-ptr, we // don't have an StgHeader in the same sense as a heap closure. p++; p = scavenge_small_bitmap(p, size, bitmap); follow_srt: if (major_gc) scavenge_srt((StgClosure **)GET_SRT(info), info->i.srt_bitmap); continue; case RET_BCO: { StgBCO *bco; nat size; p++; evacuate((StgClosure **)p); bco = (StgBCO *)*p; p++; size = BCO_BITMAP_SIZE(bco); scavenge_large_bitmap(p, BCO_BITMAP(bco), size); p += size; continue; } // large bitmap (> 32 entries, or > 64 on a 64-bit machine) case RET_BIG: { nat size; size = GET_LARGE_BITMAP(&info->i)->size; p++; scavenge_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size); p += size; // and don't forget to follow the SRT goto follow_srt; } // Dynamic bitmap: the mask is stored on the stack, and // there are a number of non-pointers followed by a number // of pointers above the bitmapped area. (see StgMacros.h, // HEAP_CHK_GEN). case RET_DYN: { StgWord dyn; dyn = ((StgRetDyn *)p)->liveness; // traverse the bitmap first bitmap = RET_DYN_LIVENESS(dyn); p = (P_)&((StgRetDyn *)p)->payload[0]; size = RET_DYN_BITMAP_SIZE; p = scavenge_small_bitmap(p, size, bitmap); // skip over the non-ptr words p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE; // follow the ptr words for (size = RET_DYN_PTRS(dyn); size > 0; size--) { evacuate((StgClosure **)p); p++; } continue; } case RET_FUN: { StgRetFun *ret_fun = (StgRetFun *)p; StgFunInfoTable *fun_info; evacuate(&ret_fun->fun); fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun)); p = scavenge_arg_block(fun_info, ret_fun->payload); goto follow_srt; } default: barf("scavenge_stack: weird activation record found on stack: %d", (int)(info->i.type)); } } }
void printStackChunk( StgPtr sp, StgPtr spBottom ) { StgWord bitmap; const StgInfoTable *info; ASSERT(sp <= spBottom); for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { info = get_itbl((StgClosure *)sp); switch (info->type) { case UPDATE_FRAME: case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: printObj((StgClosure*)sp); continue; case RET_SMALL: debugBelch("RET_SMALL (%p)\n", info); bitmap = info->layout.bitmap; printSmallBitmap(spBottom, sp+1, BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap)); continue; case RET_BCO: { StgBCO *bco; bco = ((StgBCO *)sp[1]); debugBelch("RET_BCO (%p)\n", sp); printLargeBitmap(spBottom, sp+2, BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco)); continue; } case RET_BIG: barf("todo"); case RET_FUN: { StgFunInfoTable *fun_info; StgRetFun *ret_fun; ret_fun = (StgRetFun *)sp; fun_info = get_fun_itbl(ret_fun->fun); debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type); switch (fun_info->f.fun_type) { case ARG_GEN: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(fun_info->f.b.bitmap), BITMAP_SIZE(fun_info->f.b.bitmap)); break; case ARG_GEN_BIG: printLargeBitmap(spBottom, sp+2, GET_FUN_LARGE_BITMAP(fun_info), GET_FUN_LARGE_BITMAP(fun_info)->size); break; default: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type])); break; } continue; } default: debugBelch("unknown object %d\n", (int)info->type); barf("printStackChunk"); } } }
bool SaveYUV(const char *fileName, BYTE *data, int width, int height) { if (!data) return false; int hWidth = width >> 1; int hHeight = height >> 1; size_t find = -1; std::string outputFile; BitmapPixel *luma = new BitmapPixel[BITMAP_SIZE(width, height)]; BitmapPixel *chrom = new BitmapPixel[BITMAP_SIZE(width, height)]; memset(luma, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel)); memset(chrom, 0, BITMAP_SIZE(hWidth, hHeight) * sizeof(BitmapPixel)); for(int row = 0; row < height; ++row) { for(int col = 0; col < width; ++col) { int outputIdx = BITMAP_INDEX(col, row, width); int inputIdx = ((height - row - 1) * width) + col; luma[outputIdx].red = data[inputIdx]; luma[outputIdx].green = data[inputIdx]; luma[outputIdx].blue = data[inputIdx]; } } data += width * height; outputFile = fileName; find = outputFile.find_last_of("."); outputFile.insert(find, "-"); outputFile.insert(find+1, "y"); if(!SaveBitmap(outputFile.c_str(), (BYTE *)luma, width, height)) { delete [] luma; delete [] chrom; return false; } for(int row = 0; row < hHeight; ++row) { for(int col = 0; col < hWidth; ++col) { int outputIdx = BITMAP_INDEX(col, row, hWidth); int inputIdx = ((hHeight - row - 1) * hWidth) + col; chrom[outputIdx].red = data[inputIdx]; chrom[outputIdx].green = 255 - data[inputIdx]; chrom[outputIdx].blue = 0; } } data += hWidth * hHeight; outputFile = fileName; find = outputFile.find_last_of("."); outputFile.insert(find, "-"); outputFile.insert(find+1, "u"); if(!SaveBitmap(outputFile.c_str(), (BYTE *)chrom, hWidth, hHeight)) { delete [] luma; delete [] chrom; return false; } for(int row = 0; row < hHeight; ++row) { for(int col = 0; col < hWidth; ++col) { int outputIdx = BITMAP_INDEX(col, row, hWidth); int inputIdx = ((hHeight - row - 1) * hWidth) + col; chrom[outputIdx].red = 0; chrom[outputIdx].green = 255 - data[inputIdx]; chrom[outputIdx].blue = data[inputIdx]; } } data += hWidth * hHeight; outputFile = fileName; find = outputFile.find_last_of("."); outputFile.insert(find, "-"); outputFile.insert(find+1, "v"); if(!SaveBitmap(outputFile.c_str(), (BYTE *)chrom, hWidth, hHeight)) { delete [] luma; delete [] chrom; return false; } delete [] luma; delete [] chrom; return true; }
static void thread_stack(StgPtr p, StgPtr stack_end) { const StgRetInfoTable* info; StgWord bitmap; nat size; // highly similar to scavenge_stack, but we do pointer threading here. while (p < stack_end) { // *p must be the info pointer of an activation // record. All activation records have 'bitmap' style layout // info. // info = get_ret_itbl((StgClosure *)p); switch (info->i.type) { // Dynamic bitmap: the mask is stored on the stack case RET_DYN: { StgWord dyn; dyn = ((StgRetDyn *)p)->liveness; // traverse the bitmap first bitmap = RET_DYN_LIVENESS(dyn); p = (P_)&((StgRetDyn *)p)->payload[0]; size = RET_DYN_BITMAP_SIZE; while (size > 0) { if ((bitmap & 1) == 0) { thread((StgClosure **)p); } p++; bitmap = bitmap >> 1; size--; } // skip over the non-ptr words p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE; // follow the ptr words for (size = RET_DYN_PTRS(dyn); size > 0; size--) { thread((StgClosure **)p); p++; } continue; } // small bitmap (<= 32 entries, or 64 on a 64-bit machine) case UPDATE_FRAME: case STOP_FRAME: case CATCH_FRAME: case RET_SMALL: bitmap = BITMAP_BITS(info->i.layout.bitmap); size = BITMAP_SIZE(info->i.layout.bitmap); p++; // NOTE: the payload starts immediately after the info-ptr, we // don't have an StgHeader in the same sense as a heap closure. while (size > 0) { if ((bitmap & 1) == 0) { thread((StgClosure **)p); } p++; bitmap = bitmap >> 1; size--; } continue; #ifdef ALLOW_INTERPRETER case RET_BCO: { StgBCO *bco; nat size; p++; bco = (StgBCO *)*p; thread((StgClosure **)p); p++; size = BCO_BITMAP_SIZE(bco); thread_large_bitmap(p, BCO_BITMAP(bco), size); p += size; continue; } #endif // ALLOW_INTERPRETER // large bitmap (> 32 entries, or 64 on a 64-bit machine) case RET_BIG: p++; size = GET_LARGE_BITMAP(&info->i)->size; thread_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size); p += size; continue; case RET_FUN: { StgRetFun *ret_fun = (StgRetFun *)p; StgFunInfoTable *fun_info; fun_info = FUN_INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure *) get_threaded_info((StgPtr)ret_fun->fun))); // *before* threading it! thread(&ret_fun->fun); p = thread_arg_block(fun_info, ret_fun->payload); continue; } default: barf("thread_stack: weird activation record found on stack: %d", (int)(info->i.type)); } } }
void printStackChunk( StgPtr sp, StgPtr spBottom ) { StgWord bitmap; const StgInfoTable *info; ASSERT(sp <= spBottom); for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { info = get_itbl((StgClosure *)sp); switch (info->type) { case UPDATE_FRAME: case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: printClosure((StgClosure*)sp); continue; case RET_SMALL: { StgWord c = *sp; if (c == (StgWord)&stg_ctoi_R1p_info) { debugBelch("tstg_ctoi_ret_R1p_info\n" ); } else if (c == (StgWord)&stg_ctoi_R1n_info) { debugBelch("stg_ctoi_ret_R1n_info\n" ); } else if (c == (StgWord)&stg_ctoi_F1_info) { debugBelch("stg_ctoi_ret_F1_info\n" ); } else if (c == (StgWord)&stg_ctoi_D1_info) { debugBelch("stg_ctoi_ret_D1_info\n" ); } else if (c == (StgWord)&stg_ctoi_V_info) { debugBelch("stg_ctoi_ret_V_info\n" ); } else if (c == (StgWord)&stg_ap_v_info) { debugBelch("stg_ap_v_info\n" ); } else if (c == (StgWord)&stg_ap_f_info) { debugBelch("stg_ap_f_info\n" ); } else if (c == (StgWord)&stg_ap_d_info) { debugBelch("stg_ap_d_info\n" ); } else if (c == (StgWord)&stg_ap_l_info) { debugBelch("stg_ap_l_info\n" ); } else if (c == (StgWord)&stg_ap_n_info) { debugBelch("stg_ap_n_info\n" ); } else if (c == (StgWord)&stg_ap_p_info) { debugBelch("stg_ap_p_info\n" ); } else if (c == (StgWord)&stg_ap_pp_info) { debugBelch("stg_ap_pp_info\n" ); } else if (c == (StgWord)&stg_ap_ppp_info) { debugBelch("stg_ap_ppp_info\n" ); } else if (c == (StgWord)&stg_ap_pppp_info) { debugBelch("stg_ap_pppp_info\n" ); } else if (c == (StgWord)&stg_ap_ppppp_info) { debugBelch("stg_ap_ppppp_info\n" ); } else if (c == (StgWord)&stg_ap_pppppp_info) { debugBelch("stg_ap_pppppp_info\n" ); #ifdef PROFILING } else if (c == (StgWord)&stg_restore_cccs_info) { debugBelch("stg_restore_cccs_info\n" ); fprintCCS(stderr, (CostCentreStack*)sp[1]); debugBelch("\n" ); continue; #endif } else { debugBelch("RET_SMALL (%p)\n", info); } bitmap = info->layout.bitmap; printSmallBitmap(spBottom, sp+1, BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap)); continue; } case RET_BCO: { StgBCO *bco; bco = ((StgBCO *)sp[1]); debugBelch("RET_BCO (%p)\n", sp); printLargeBitmap(spBottom, sp+2, BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco)); continue; } case RET_BIG: barf("todo"); case RET_FUN: { const StgFunInfoTable *fun_info; StgRetFun *ret_fun; ret_fun = (StgRetFun *)sp; fun_info = get_fun_itbl(ret_fun->fun); debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type); switch (fun_info->f.fun_type) { case ARG_GEN: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(fun_info->f.b.bitmap), BITMAP_SIZE(fun_info->f.b.bitmap)); break; case ARG_GEN_BIG: printLargeBitmap(spBottom, sp+2, GET_FUN_LARGE_BITMAP(fun_info), GET_FUN_LARGE_BITMAP(fun_info)->size); break; default: printSmallBitmap(spBottom, sp+2, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type])); break; } continue; } default: debugBelch("unknown object %d\n", (int)info->type); barf("printStackChunk"); } } }
int draw_to_bmp (const char *file, struct draw *draw) { FILE *fp; BITMAPFILEHEADER header; BITMAPINFOHEADER info; if ((fp = fopen (file, "wb")) == NULL) { ERROR ("Couldn't open %s for writing: %s\n", file, strerror (errno)); return -1; } header.bfType = BM_MAGIC; header.bfSize = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + BITMAP_SIZE (draw->width, draw->height, 24); header.bfReserved1 = header.bfReserved2 = 0; header.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER); if (fwrite (&header, sizeof (BITMAPFILEHEADER), 1, fp) < 1) { ERROR ("Couldn't store header in %s: %s\n", file, strerror (errno)); fclose (fp); return -1; } info.biSize = sizeof (BITMAPINFOHEADER); info.biWidth = draw->width; info.biHeight = draw->height; info.biPlanes = 1; /* It's ONE f*****g plane, no zero, you dumbass */ info.biBitCount = 24; info.biCompression = 0; info.biSizeImage = 0; info.biXPelsPerMeter = 0; info.biYPelsPerMeter = 0; info.biClrUsed = 0; info.biClrImportant = 0; if (fwrite (&info, sizeof (BITMAPINFOHEADER), 1, fp) < 1) { ERROR ("Couldn't store header in %s: %s\n", file, strerror (errno)); fclose (fp); return -1; } if (fwrite (draw->pixels, draw->total_size, 1, fp) < 1) { ERROR ("Couldn't store data in %s: %s\n", file, strerror (errno)); fclose (fp); return -1; } fclose (fp); return 0; }