static unsigned list_hash(LIST * key) { unsigned int hash = 0; LISTITER iter = list_begin( key ), end = list_end( key ); for ( ; iter != end; ++iter ) { hash = hash * 2147059363 + object_hash( list_item( iter ) ); } return hash; }
static bool object_hash_dict(/*const*/ json_object * const d, hash h) { // FIXME: there may be a better way size_t len = 0; { json_object_object_foreach(d, key, val) { ++len; } } byte *hashes = alloca(2 * len * sizeof(hash)); size_t n = 0; json_object_object_foreach(d, key, val) { object_hash_str(key, strlen(key), &hashes[2 * n * sizeof(hash)]); object_hash(val, &hashes[(2 * n + 1) * sizeof(hash)]); ++n; }
static void hashrehash( struct hash * hp ) { int i = ++hp->items.list; hp->items.more = i ? 2 * hp->items.nel : hp->inel; hp->items.next = (char *)BJAM_MALLOC( hp->items.more * hp->items.size ); hp->items.free = 0; hp->items.lists[ i ].nel = hp->items.more; hp->items.lists[ i ].base = hp->items.next; hp->items.nel += hp->items.more; if ( hp->tab.base ) BJAM_FREE( (char *)hp->tab.base ); hp->tab.nel = hp->items.nel * hp->bloat; hp->tab.base = (ITEM * *)BJAM_MALLOC( hp->tab.nel * sizeof( ITEM * * ) ); memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) ); for ( i = 0; i < hp->items.list; ++i ) { int nel = hp->items.lists[ i ].nel; char * next = hp->items.lists[ i ].base; for ( ; nel--; next += hp->items.size ) { ITEM * i = (ITEM *)next; ITEM * * ip = hp->tab.base + object_hash( hash_item_key( i ) ) % hp->tab.nel; /* code currently assumes rehashing only when there are no free * items */ assert( hash_item_key( i ) ); i->next = *ip; *ip = i; } } }
static void hashrehash( register struct hash *hp ) { int i = ++hp->items.list; hp->items.more = i ? 2 * hp->items.nel : hp->inel; hp->items.next = (char *)hash_mem_alloc( hp->items.datalen, hp->items.more * hp->items.size ); hp->items.free = 0; hp->items.lists[i].nel = hp->items.more; hp->items.lists[i].base = hp->items.next; hp->items.nel += hp->items.more; if ( hp->tab.base ) hash_mem_free( hp->items.datalen, (char *)hp->tab.base ); hp->tab.nel = hp->items.nel * hp->bloat; hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, hp->tab.nel * sizeof(ITEM **) ); memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) ); for ( i = 0; i < hp->items.list; ++i ) { int nel = hp->items.lists[i].nel; char *next = hp->items.lists[i].base; for ( ; nel--; next += hp->items.size ) { register ITEM *i = (ITEM *)next; ITEM **ip = hp->tab.base + object_hash( i->data.key ) % hp->tab.nel; /* code currently assumes rehashing only when there are no free items */ assert( i->data.key != 0 ); i->hdr.next = *ip; *ip = i; } } }
static unsigned int hash_keyval( OBJECT * key ) { return object_hash( key ); }
void print_object(struct Object* oop) { if (oop == NULL) { fprintf(stderr, "<object NULL>\n"); return; } if (oop_is_smallint((word_t)oop)) { fprintf(stderr, "<object int_value: %" PRIdPTR ">\n", object_to_smallint(oop)); } else { const char* typestr=0; switch (object_type(oop)) { case TYPE_OBJECT: typestr = "normal"; break; case TYPE_OOP_ARRAY: typestr = "oop array"; break; case TYPE_BYTE_ARRAY: typestr = "byte array"; break; } fprintf(stderr, "<object at %p, hash: 0x%" PRIxPTR ", size: %" PRIdPTR ", payload size: %" PRIdPTR ", type: %s>\n", (void*)oop, object_hash(oop), object_size(oop), payload_size(oop), typestr); } }
void print_object_with_depth(struct object_heap* oh, struct Object* o, word_t depth, word_t max_depth) { struct Map* map; word_t i; if (depth >= max_depth || object_is_smallint(o)) { fprintf(stderr, "(depth limit reached) "); print_object(o); return; } if (o == oh->cached.nil) { fprintf(stderr, "<object NilObject>\n"); return; } map = o->map; print_object(o); if (object_hash(o) >= ID_HASH_RESERVED) { indent(depth); fprintf(stderr, "<object is free/reserved>\n"); return; } indent(depth); fprintf(stderr, "{\n"); if (object_type(o) == TYPE_BYTE_ARRAY) { indent(depth); fprintf(stderr, "bytes: "); print_byte_array(o); fprintf(stderr, "\n"); } if (object_type(o) == TYPE_OOP_ARRAY) { struct OopArray* array = (struct OopArray*)o; indent(depth); fprintf(stderr, "size(array) = %" PRIdPTR "\n", object_array_size(o)); for (i=0; i < object_array_size(o); i++) { indent(depth); fprintf(stderr, "array[%" PRIdPTR "]: ", i); print_object_with_depth(oh, array->elements[i], depth+1, max_depth); if (object_array_size(o) - i > 10) { indent(depth); fprintf(stderr, "...\n"); i = object_array_size(o) - 2; } } } indent(depth); fprintf(stderr, "map flags: %" PRIdPTR " (%s)\n", object_to_smallint(map->flags), ((((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION)==0)? "delegation not restricted":"delegation restricted")); { /*print if delegate*/ struct OopArray* delegates = map->delegates; word_t offset = object_array_offset((struct Object*)delegates); word_t limit = object_total_size((struct Object*)delegates); for (i = 0; offset != limit; offset += sizeof(word_t), i++) { struct Object* delegate = object_slot_value_at_offset((struct Object*)delegates, offset); indent(depth); fprintf(stderr, "delegate[%" PRIdPTR "] = ", i); print_object_with_depth(oh, delegate, (((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION) == 0)? depth+1 : max(max_depth-1, depth+1), max_depth); } } {/*if?*/ struct SlotTable* slotTable = map->slotTable; word_t limit = slot_table_capacity(map->slotTable); indent(depth); fprintf(stderr, "slot count: %" PRIdPTR "\n", object_to_smallint(map->slotCount)); for (i=0; i < limit; i++) { if (slotTable->slots[i].name == (struct Symbol*)oh->cached.nil) continue; indent(depth); fprintf(stderr, "slot[%" PRIdPTR "]['", i); print_symbol(slotTable->slots[i].name); fprintf(stderr, "'] = "); { struct Object* obj = object_slot_value_at_offset(o, object_to_smallint(slotTable->slots[i].offset)); if (object_is_smallint(obj) || object_type(obj) != TYPE_BYTE_ARRAY) { print_object(obj); } else { print_byte_array(obj); fprintf(stderr, "\n"); } } } } /*indent(depth); fprintf(stderr, "map = "); print_object_with_depth(oh, (struct Object*)map, depth+1, max_depth);*/ /*roles */ { struct RoleTable* roleTable = map->roleTable; word_t limit = role_table_capacity(roleTable); indent(depth); fprintf(stderr, "role table capacity: %" PRIdPTR "\n", limit); for (i = 0; i < limit; i++) { if (roleTable->roles[i].name == (struct Symbol*)oh->cached.nil) {continue;} else { indent(depth); fprintf(stderr, "role[%" PRIdPTR "]['", i); print_symbol(roleTable->roles[i].name); fprintf(stderr, "'] @ 0x%04" PRIxPTR "\n", object_to_smallint(roleTable->roles[i].rolePositions)); #if 0 print_object_with_depth(oh, (struct Object*)roleTable->roles[i].methodDefinition, max_depth, max_depth); #endif if (limit - i > 50 && depth >= 2) { indent(depth); fprintf(stderr, "...\n"); i = limit - 3; } } } } indent(depth); fprintf(stderr, "}\n"); }