static VarEntry * add_private(ClipMachine * ClipMachineMemory, long hash) { long *p; VarEntry *vp, *np; ClipFrame *fp; if (ClipMachineMemory->inMacro) fp = ClipMachineMemory->inMacro; else fp = ClipMachineMemory->fp; if (fp) { p = fp->privates_of_ClipFrame; if (p) { int n; long c; for (n = *p, p++; n >= 0; n--, p++) if (hash == GETLONG(p)) { vp = (VarEntry *) HashTable_fetch(ClipMachineMemory->privates, hash); if (vp) return vp; } p = fp->privates_of_ClipFrame; c = GETLONG(p); p = (long *) realloc(p, (c + 2) * sizeof(long)); SETLONG(p, c + 1); SETLONG(p + c + 1, hash); fp->privates_of_ClipFrame = p; } else { p = fp->privates_of_ClipFrame = (long *) malloc(sizeof(long) * 2); SETLONG(p, 1); SETLONG(p + 1, hash); } } vp = (VarEntry *) HashTable_fetch(ClipMachineMemory->privates, hash); np = new_VarEntry(hash); if (!vp) HashTable_insert(ClipMachineMemory->privates, np, hash); else { np->VarEntry_next_of_VarEntry = vp; HashTable_remove(ClipMachineMemory->privates, hash); HashTable_store(ClipMachineMemory->privates, np, hash); } return np; }
void LexParser_fnBodyEnter(LexParser * self, iVar * fn) { ParamsListItem * param = fn->val.fn->params.First; HashTable * fnSymTable = HashTable__init__(SYMBOL_TABLE_SIZE); if (HashTable_insert(fnSymTable, self->str.buff, fn) != ht_inserted) { Lex_throwError(self, "Error while creating symbol for function recursion"); } fnSymTable->masterTable = self->symbolTable; fnSymTable->masterItem = fn; self->symbolTable = fnSymTable; while (param) { if (HashTable_insert(self->symbolTable, param->name, param->data) != ht_inserted) { Definition_err_throw(self); // redefinition of param } param = param->next; } }
Closure * loadClosure(const char *filename, FILE *f, const StringTabEntry *strings, HashTable *itbls, HashTable *closures) { u4 i; u4 magic = fget_u4(f); assert(magic == CLOSURE_MAGIC); char *clos_name = loadId(f, strings, "."); u4 payloadsize = fget_varuint(f); char *itbl_name = loadId(f, strings, "."); Closure *cl = allocStaticClosure(wordsof(ClosureHeader) + payloadsize); Closure *fwd_ref; InfoTable* info = HashTable_lookup(itbls, itbl_name); LC_ASSERT(info != NULL && info->type != INVALID_OBJECT); // Fill in closure payload. May create forward references to // the current closure. setInfo(cl, info); xfree(itbl_name); for (i = 0; i < payloadsize; i++) { LD_DBG_PR(1, "Loading payload for: %s [%d]\n", clos_name, i); u1 dummy; loadLiteral(filename, f, &dummy, &cl->payload[i], strings, itbls, closures); } fwd_ref = HashTable_lookup(closures, clos_name); if (fwd_ref != NULL) { LD_DBG_PR(2, "Fixing closure forward ref: %s, %p -> %p\n", clos_name, fwd_ref, cl); // fixup forward refs void **p, *next; for (p = (void**)fwd_ref->payload[0]; p != NULL; p = next) { next = *p; *p = (void*)cl; } xfree(fwd_ref); HashTable_update(closures, clos_name, cl); // The key has been allocated by whoever installed the first // forward reference. xfree(clos_name); } else { HashTable_insert(closures, clos_name, cl); } return cl; }
// Postorder traversal void loadModule_aux(const char *moduleName, u4 level) { char *filename; Module *mdl; FILE *f; int i; mdl = (Module*)HashTable_lookup(G_loader->loadedModules, moduleName); if (mdl != NULL) { // Module is either already loaded, or currently in process of // being loaded. return; } filename = findModule(moduleName); for (i = 0; i < level; i++) fputc(' ', stderr); fprintf(stderr, "> Loading %s ...(%s)\n", moduleName, filename); f = fopen(filename, "rb"); if (f == NULL) { fprintf(stderr, "ERROR: Could not open file: %s\n", filename); exit(14); } mdl = loadModuleHeader(f, filename); HashTable_insert(G_loader->loadedModules, moduleName, mdl); // Load dependencies first. This avoids creating many forward // references. The downside is that we keep more file descriptors // open. for (i = 0; i < mdl->numImports; i++) loadModule_aux(mdl->imports[i], level + 1); loadModuleBody(filename, f, mdl); fclose(f); // We now don't need the string table anymore. xfree(mdl->strings); mdl->strings = NULL; for (i = 0; i < level; i++) fputc(' ', stderr); fprintf(stderr, "< DONE (%s)\n", moduleName); }
void L_build_jrg_info (L_JRG_Info *jrg_info, L_Cb *cb, L_Oper *jrg_oper) { L_Oper *op; L_Flow *fl; int case_cnt = 0; double weight = cb->weight; HashTable h; jrg_info->cb = cb; jrg_info->jrg = jrg_oper; jrg_info->jrg_flows = L_find_flow_for_branch (cb, jrg_oper); jrg_info->jrg_default_flow = L_find_last_flow (cb->dest_flow); h = HashTable_create (32); for (op = cb->first_op; op && op != jrg_oper; op = op->next) { if (!L_is_control_oper (op)) continue; weight -= fl->weight; fl = fl->next_flow; } jrg_info->weight = weight; for (; fl; fl = fl->next_flow) { case_cnt++; if ((tgt = HashTable_find_or_null (h, fl->dst_cb->id))) { tgt->weight+=fl->weight; } else { tgt = L_ALLOC (L_JRG_Target); tgt->target = fl->dst_cb; tgt->weight = fl->weight; HashTable_insert (h, (void *)tgt); } } jrg_info->target_hash = h; return; }
void HashTable_rebuild(HashTable *ht) { u4 oldsize = ht->size; HashEntry **old_table = ht->table; int i; ht->size *= 2; ht->entries = 0; ht->table = xmalloc(sizeof(HashEntry*) * ht->size); memset(ht->table, 0, sizeof(HashEntry*) * ht->size); for (i = 0; i < oldsize; ++i) { HashEntry *p, *next; for (p = old_table[i]; p != NULL; p = next) { next = p->next; HashTable_insert(ht, p->key, p->value); xfree(p); } } xfree(old_table); }
static int dbf_create(ClipMachine * ClipMachineMemory, RDD_DATA_VTBL * vtbl, char *name, RDD_STRUCT * stru, int nfields, const char *__PROC__) { RDD_FILE file; DBF_HEADER *hdr = malloc(sizeof(DBF_HEADER)); char *chdr, *s; DBF_FIELD *fld; int i, offs; time_t ltm; struct tm *date; HashTable *hashes; int er; unsigned int recsize; memset(hdr, 0, sizeof(DBF_HEADER)); hdr->version = vtbl->dbfsig; for (i = 0; i < nfields; i++) if (strchr("MPG", stru[i].type) || (stru[i].type == 'V' && stru[i].len != 3 && stru[i].len != 4)) { hdr->version = vtbl->dbfwithmemosig; break; } ltm = time(NULL); date = gmtime(<m); hdr->yy = date->tm_year; hdr->mm = date->tm_mon + 1; hdr->dd = date->tm_mday; _rdd_put_uint(hdr->recs, 0); _rdd_put_ushort(hdr->hdrsize, sizeof(DBF_HEADER) + nfields * sizeof(DBF_FIELD) + 2); recsize = 1; hdr = realloc(hdr, _rdd_ushort(hdr->hdrsize) + 1); hashes = new_HashTable(); offs = 1; for (i = 0; i < nfields; i++) { recsize += stru[i].len; fld = (DBF_FIELD *) ((char *) hdr + sizeof(DBF_HEADER) + i * sizeof(DBF_FIELD)); memset(fld, 0, sizeof(DBF_FIELD)); strncpy(fld->name, stru[i].name, 10); for (s = fld->name; *s && *s != ' '; s++); *s = 0; loc_write(dbf_get_locale(ClipMachineMemory), (unsigned char *) (fld->name), strlen(fld->name)); fld->type = stru[i].type; if (stru[i].type == 'V' && stru[i].len != 3 && stru[i].len != 4 && stru[i].len < 6) { er = rdd_err(ClipMachineMemory, EG_CREATE, 0, __FILE__, __LINE__, __PROC__, er_badstructure); goto err; } _rdd_put_uint(fld->offs, offs); offs += stru[i].len; if (fld->type == 'N') { if (stru[i].dec >= stru[i].len - (stru[i].dec != 0)) { er = rdd_err(ClipMachineMemory, EG_CREATE, 0, __FILE__, __LINE__, __PROC__, er_badstructure); goto err; } fld->len.num.len = stru[i].len; fld->len.num.dec = stru[i].dec; } else if (fld->type == 'X') { if (stru[i].len < 10 || stru[i].len > 127) { er = rdd_err(ClipMachineMemory, EG_CREATE, 0, __FILE__, __LINE__, __PROC__, er_badstructure); goto err; } fld->len.num.len = stru[i].len; fld->len.num.dec = stru[i].dec; } else { _rdd_put_ushort((unsigned char *) (fld->len.len), stru[i].len); } if (!HashTable_insert(hashes, fld, _clip_casehashword(fld->name, strlen(fld->name)))) { er = rdd_err(ClipMachineMemory, EG_CREATE, 0, __FILE__, __LINE__, __PROC__, er_fielduplicate); goto err; } } if (recsize > 0xffff) { er = rdd_err(ClipMachineMemory, EG_CREATE, 0, __FILE__, __LINE__, __PROC__, er_badstructure); goto err; } _rdd_put_ushort(hdr->recsize, recsize); delete_HashTable(hashes); chdr = (char *) hdr; chdr[_rdd_ushort(hdr->hdrsize) - 2] = 0x0D; chdr[_rdd_ushort(hdr->hdrsize) - 1] = 0x00; chdr[_rdd_ushort(hdr->hdrsize)] = 0x1A; memset(&file, 0, sizeof(RDD_FILE)); file.md = (char *) -1; file.fd = _clip_creat(ClipMachineMemory, name, O_RDWR, ClipMachineMemory->fileCreateMode, 1); if (file.fd == -1) goto err_create; if ((er = rdd_write(ClipMachineMemory, &file, 0, _rdd_ushort(hdr->hdrsize) + 1, (char *) hdr, __PROC__))) goto err; if (_clip_close(ClipMachineMemory, _clip_hashstr(name), file.fd) == -1) goto err_create; free(hdr); return 0; err_create: er = rdd_err(ClipMachineMemory, EG_CREATE, errno, __FILE__, __LINE__, __PROC__, name); err: free(hdr); return er; }
IPA_symbol_info_t * IPA_symbol_add (IPA_prog_info_t * info, IPA_funcsymbol_info_t * fninfo, char *sym_name, Key sym_key, int kind, Key type_key) { IPA_symbol_info_t *syminfo; int hash; int size; assert(sym_name); /* Prevent duplicate symbol */ hash = SYM_GETKEY(sym_key); cmp_key = sym_key; syminfo = IPA_htab_find(info->symtab, hash, IPA_symbol_compare); if (syminfo) { syminfo->kind |= kind; return syminfo; } #if 0 printf("SYMBOL [%s:%d in %s] %X -- ", sym_name, info->max_var_id+1, fninfo->func_name, kind); if (PST_IsFunctionType(info->symboltable, type_key)) printf("FUNC "); if (PST_IsPointerType(info->symboltable, type_key)) printf("PTR "); printf("\n"); #endif assert(P_ValidKey(sym_key) || sym_key.file == IPA_TEMPVAR_FILEID); assert(P_ValidKey(type_key) || type_key.file == IPA_TEMPTYPE_FILEID); if (PST_IsFunctionType(info->symboltable, type_key)) kind |= (IPA_VAR_KIND_GLOBAL | IPA_VAR_KIND_FUNC); /* Create new syminfo */ syminfo = IPA_symbol_new (); syminfo->fninfo = fninfo; syminfo->its_fninfo = NULL; syminfo->id = info->max_var_id++; syminfo->kind = kind; syminfo->max_version = 1; syminfo->sym_key = sym_key; syminfo->type_key = type_key; syminfo->symbol_name = strdup(sym_name); IPA_htab_insert(info->symtab, syminfo, hash); HashTable_insert (info->id2sym_htab, syminfo->id, syminfo); size = IPA_Pcode_sizeof(info, type_key); if (size > IPA_max_type_size) IPA_max_type_size = size; while (PST_IsPointerType(info->symboltable, type_key) || PST_IsArrayType(info->symboltable, type_key)) { type_key = PST_GetTypeType(info->symboltable, type_key); } size = IPA_Pcode_sizeof(info, type_key); if (size > IPA_max_type_size) IPA_max_type_size = size; return syminfo; }
void loadLiteral(const char *filename, FILE *f, u1 *littype /*out*/, Word *literal /*out*/, const StringTabEntry *strings, HashTable *itbls, HashTable *closures) { u4 i; *littype = fget_u1(f); switch (*littype) { case LIT_INT: *literal = (Word)fget_varsint(f); break; case LIT_CHAR: *literal = (Word)fget_varuint(f); break; case LIT_WORD: *literal = (Word)fget_varuint(f); break; case LIT_FLOAT: *literal = (Word)fget_u4(f); break; case LIT_STRING: i = fget_varuint(f); *literal = (Word)strings[i].str; break; case LIT_CLOSURE: { char *clname = loadId(f, strings, "."); Closure *cl = HashTable_lookup(closures, clname); if (cl == NULL) { // 1st forward ref, create the link cl = xmalloc(sizeof(ClosureHeader) + sizeof(Word)); setInfo(cl, NULL); cl->payload[0] = (Word)literal; *literal = (Word)NULL; LD_DBG_PR(2, "Creating forward reference %p for `%s', %p\n", cl, clname, literal); HashTable_insert(closures, clname, cl); } else if (getInfo(cl) == NULL) { // forward ref (not the first), insert into linked list LD_DBG_PR(2, "Linking forward reference %p (%s, target: %p)\n", cl, clname, literal); *literal = (Word)cl->payload[0]; cl->payload[0] = (Word)literal; xfree(clname); } else { *literal = (Word)cl; xfree(clname); } } break; case LIT_INFO: { char *infoname = loadId(f, strings, "."); InfoTable *info = HashTable_lookup(itbls, infoname); FwdRefInfoTable *info2; if (info == NULL) { // 1st forward ref info2 = xmalloc(sizeof(FwdRefInfoTable)); info2->i.type = INVALID_OBJECT; info2->next = (void**)literal; *literal = (Word)NULL; HashTable_insert(itbls, infoname, info2); } else if (info->type == INVALID_OBJECT) { // subsequent forward ref info2 = (FwdRefInfoTable*)info; *literal = (Word)info2->next; info2->next = (void**)literal; xfree(infoname); } else { *literal = (Word)info; xfree(infoname); } } break; default: fprintf(stderr, "ERROR: Unknown literal type (%d) " "when loading file: %s\n", *littype, filename); exit(1); } }
InfoTable * loadInfoTable(const char *filename, FILE *f, const StringTabEntry *strings, HashTable *itbls, HashTable *closures) { u4 magic = fget_u4(f); assert(magic == INFO_MAGIC); char *itbl_name = loadId(f, strings, "."); u2 cl_type = fget_varuint(f); InfoTable *new_itbl = NULL; FwdRefInfoTable *old_itbl = HashTable_lookup(itbls, itbl_name); if (old_itbl && old_itbl->i.type != INVALID_OBJECT) { fprintf(stderr, "ERROR: Duplicate info table: %s\n", itbl_name); exit(1); } switch (cl_type) { case CONSTR: // A statically allocated constructor { ConInfoTable *info = allocInfoTable(wordsof(ConInfoTable)); info->i.type = cl_type; info->i.tagOrBitmap = fget_varuint(f); // tag Word sz = fget_varuint(f); assert(sz <= 32); info->i.size = sz; info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0; // info->i.layout.payload.ptrs = fget_varuint(f); // info->i.layout.payload.nptrs = fget_varuint(f); info->name = loadId(f, strings, "."); new_itbl = (InfoTable*)info; } break; case FUN: { FuncInfoTable *info = allocInfoTable(wordsof(FuncInfoTable)); info->i.type = cl_type; info->i.tagOrBitmap = 0; // TODO: anything useful to put in here? Word sz = fget_varuint(f); assert(sz <= 32); info->i.size = sz; info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0; info->name = loadId(f, strings, "."); loadCode(filename, f, &info->code, strings, itbls, closures); new_itbl = (InfoTable*)info; } break; case CAF: case THUNK: { ThunkInfoTable *info = allocInfoTable(wordsof(ThunkInfoTable)); info->i.type = cl_type; info->i.tagOrBitmap = 0; // TODO: anything useful to put in here? Word sz = fget_varuint(f); assert(sz <= 32); info->i.size = sz; info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0; info->name = loadId(f, strings, "."); loadCode(filename, f, &info->code, strings, itbls, closures); new_itbl = (InfoTable*)info; } break; default: fprintf(stderr, "ERROR: Unknown info table type (%d)", cl_type); exit(1); } // new_itbl is the new info table. There may have been forward // references (even during loading the code for this info table). if (old_itbl != NULL) { LD_DBG_PR(1, "Fixing itable forward reference for: %s, %p\n", itbl_name, new_itbl); void **p, *next; LC_ASSERT(old_itbl->i.type == INVALID_OBJECT); for (p = old_itbl->next; p != NULL; p = next) { next = *p; *p = (void*)new_itbl; } // TODO: fixup forward refs xfree(old_itbl); HashTable_update(itbls, itbl_name, new_itbl); xfree(itbl_name); } else { HashTable_insert(itbls, itbl_name, new_itbl); } return new_itbl; }
void testHashTable() { typedef struct { uint64 key; uint64 data; } TestData; int initialCapacity = 1000; int numEntries = 5000; // make hash table HashTable htb = HashTable_make(sizeof(uint64), sizeof(uint64), initialCapacity); // insert data, and some duplicates TestData entries[numEntries]; int i; for (i = 0; i < numEntries; i++) { entries[i].key = rand(); entries[i].data = rand(); HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); // insert a previous duplicate if (i > 10) { HashTable_insert(&htb, &(entries[i-10].key), &(entries[i-10].data)); } assert(HashTable_size(&htb) == i+1); assert(HashTable_capacity(&htb) > i); } // check data for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); // remove and re-insert some elements int numRemoved = 0; for (i = 0; i < numEntries; i = i + 2) { HashTable_delete(&htb, &(entries[i].key)); numRemoved++; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) == NULL); } for (i = 0; i < numEntries; i = i + 2) { HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); numRemoved--; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) != NULL); } // save to file, destroy, and recreate from file char *filename = "/tmp/roomyTestHashTable"; HashTable_fileSave(&htb, filename); HashTable_destroy(&htb); htb = HashTable_makeFromFiles(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); // make using mmap htb = HashTable_makeMapped(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); assert(HashTable_removeFiles(filename) == 0); printf("HASH TABLE PASSED TESTS\n"); }