symbolOop symbolTable::basic_add(symbolOop s, int hashValue) { assert(s->is_symbol(), "adding something that's not a symbol to the symbol table"); assert(s->is_old(), "all symbols should be tenured"); // Add the indentity hash for the new symbol s->hash_value(); assert(!s->mark()->has_valid_hash(), "should not have a hash yet"); s->set_mark(s->mark()->set_hash(s->hash_value())); assert(s->mark()->has_valid_hash(), "should have a hash now"); symbolTableEntry* bucket = bucketFor(hashValue); if (bucket->is_empty()) { bucket->set_symbol(s); } else { symbolTableLink* old_link; if (bucket->is_symbol()) { old_link = Universe::symbol_table->new_link(bucket->get_symbol()); } else { old_link = bucket->get_link(); } bucket->set_link(Universe::symbol_table->new_link(s, old_link)); } return s; }
/** call this to check a page has been seen yet. */ inline bool seen(Data* data, size_t ptr) { resetIfNeeded(data); // A bucket contains 4 superpages each containing 16 contiguous pages // See above for a more detailed explanation of superpages size_t* bucket = data->_table[bucketFor(ptr)]; for (int i = 0; i < bucketSize; i++) { if (superpageOf(ptr) == superpageOf(bucket[i])) { if (haveSeenPage(bucket[i], ptr)) return true; markPageSeen(bucket[i], ptr); return false; } } // superpage isn't in thread-local cache // slide bucket forward and add new superpage at front for (int i = bucketSize-1; i > 0; i--) bucket[i] = bucket[i-1]; bucket[0] = superpageOf(ptr); markPageSeen(bucket[0], ptr); return false; }
nmethod* codeTable::lookup(MethodLookupKey &k) { nmln* bucket = bucketFor(k.hash()); for (nmln* p = bucket->next; p != bucket; p = p->next) { codeTableEntry *e= entryForLink(p); if (e->key.EQ(k)) { return e->nm; } } return NULL; }
bool symbolTable::is_present(symbolOop sym) { char* name = (char*) sym->bytes(); int len = sym->length(); int hashValue = hash(name, len); symbolTableEntry* bucket = bucketFor(hashValue); if (bucket->is_empty()) return false; if (bucket->is_symbol()) return bucket->get_symbol()->equals(name, len); for (symbolTableLink* l = bucket->get_link(); l; l = l->next) if (l->symbol->equals(name, len)) return true; return false; }
symbolOop symbolTable::lookup(char* name, int len) { int hashValue = hash(name, len); symbolTableEntry* bucket = bucketFor(hashValue); if (!bucket->is_empty()) { if (bucket->is_symbol()) { if (bucket->get_symbol()->equals(name, len)) return bucket->get_symbol(); } else { for (symbolTableLink* l = bucket->get_link(); l; l = l->next) if (l->symbol->equals(name, len)) return l->symbol; } } return basic_add(name, len, hashValue); }
stringOop stringTable::lookup(const char* name, int32 len, bool mustAllocate) { int32 hashValue = hash(name, len); stringTableEntry* bucket = bucketFor(hashValue); if (bucket->is_string()) { if (bucket->get_string()->equals(name, len)) return bucket->get_string(); return basic_add(name, len, hashValue, mustAllocate); } else { if (!bucket->get_link()) return basic_add(name, len, hashValue, mustAllocate); for (stringTableLink* l = bucket->get_link(); l; l = l->next) { if (l->string->equals(name, len)) { return l->string; } } } return basic_add(name, len, hashValue, mustAllocate); }
bool codeTable::verify() { bool flag = true; for (nmln* p = buckets; p < &buckets[tableSize]; ++p) { flag = flag && p->verify_list_integrity(); for (nmln* q = p->next; q != p; q = q->next) { codeTableEntry *e= entryForLink(q); nmethod* nm= e->nm; if (!nmethod::isNMethod(nm)) { error2("bad nmethod 0x%lx in bucket 0x%lx", nm, p); flag = false; } if (bucketFor(e->key.hash()) != p) { error2("code table entry 0x%lx not in bucket 0x%lx", e, p); flag = false; } } } return flag; }
void codeTable::add(nmethod* nm, MethodLookupKey* k) { if (k == NULL) k= &nm->key; k->init_hash(); # if GENERATE_DEBUGGING_AIDS if (CheckAssertions) { if (nm == (nmethod*)catchThisOne) warning("caught nmethod"); if ( nm->isDebug() && this == Memory->code->table) warning("wrong table"); if (!nm->isDebug() && this != Memory->code->table) warning("wrong table"); if (lookup(*k)) { k->print(); fatal2("adding duplicate key to code table: %#lx and new %#lx", lookup(*k), nm); } } # endif nmln* b = bucketFor(k->hash()); codeTableEntry *e= new codeTableEntry(nm, k); if (e->key.is_new()) nm->remember(); b->add(&e->next_hash); }
stringOop stringTable::basic_add(stringOop s, int32 hashValue) { assert(s->is_string(), "adding something that's not a string to the string table"); assert(s->is_old(), "all strings should be tenured"); // Canonical strings must have a hash value (for _IdentityHash) that // is a pure function of the chars in the string. Otherwise, their // hash value would change when they are discarded by a GC and re- // created later. assert(s->mark()->hash() == no_hash, "should not have a hash yet"); s->set_mark(s->mark()->set_hash(hashValue)); assert(s->mark()->hash() != no_hash, "should have a hash now"); stringTableEntry* bucket = bucketFor(hashValue); stringTableLink* old_link; if (bucket->is_string()) { old_link = Memory->string_table->new_link(bucket->get_string()); } else { old_link = bucket->get_link(); } bucket->set_link(Memory->string_table->new_link(s, old_link)); return s; }