// Write the compact table's bucket infos juint* CompactHashtableWriter::dump_table(juint* p, juint** first_bucket, NumberSeq* summary) { int index; juint* compact_table = p; // Compute the start of the buckets, include the compact_bucket_infos table // and the table end offset. juint offset = _num_buckets + 1; *first_bucket = compact_table + offset; for (index = 0; index < _num_buckets; index++) { int bucket_size = _bucket_sizes[index]; if (bucket_size == 1) { // bucket with one entry is compacted and only has the symbol offset compact_table[index] = BUCKET_INFO(offset, COMPACT_BUCKET_TYPE); offset += bucket_size; // each entry contains symbol offset only } else { // regular bucket, each entry is a symbol (hash, offset) pair compact_table[index] = BUCKET_INFO(offset, REGULAR_BUCKET_TYPE); offset += bucket_size * 2; // each hash entry is 2 juints } if (offset & ~BUCKET_OFFSET_MASK) { vm_exit_during_initialization("CompactHashtableWriter::dump_table: Overflow! " "Too many symbols."); } summary->add(bucket_size); } // Mark the end of the table compact_table[_num_buckets] = BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE); return compact_table; }
// Write the compact table's buckets void CompactHashtableWriter::dump_table(NumberSeq* summary) { u4 offset = 0; for (int index = 0; index < _num_buckets; index++) { GrowableArray<Entry>* bucket = _buckets[index]; int bucket_size = bucket->length(); if (bucket_size == 1) { // bucket with one entry is compacted and only has the symbol offset _compact_buckets->at_put(index, BUCKET_INFO(offset, VALUE_ONLY_BUCKET_TYPE)); Entry ent = bucket->at(0); _compact_entries->at_put(offset++, ent.value()); _num_value_only_buckets++; } else { // regular bucket, each entry is a symbol (hash, offset) pair _compact_buckets->at_put(index, BUCKET_INFO(offset, REGULAR_BUCKET_TYPE)); for (int i=0; i<bucket_size; i++) { Entry ent = bucket->at(i); _compact_entries->at_put(offset++, u4(ent.hash())); // write entry hash _compact_entries->at_put(offset++, ent.value()); } if (bucket_size == 0) { _num_empty_buckets++; } else { _num_other_buckets++; } } summary->add(bucket_size); } // Mark the end of the buckets _compact_buckets->at_put(_num_buckets, BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE)); assert(offset == (u4)_compact_entries->length(), "sanity"); }