src/hotspot/share/classfile/compactHashtable.cpp
changeset 54927 1512d88b24c6
parent 54780 f8d182aedc92
child 58447 319173c62caa
equal deleted inserted replaced
54926:d4e7ccaf1445 54927:1512d88b24c6
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "jvm.h"
    26 #include "jvm.h"
    27 #include "classfile/compactHashtable.hpp"
    27 #include "classfile/compactHashtable.hpp"
    28 #include "classfile/javaClasses.hpp"
    28 #include "classfile/javaClasses.hpp"
    29 #include "logging/logMessage.hpp"
    29 #include "logging/logMessage.hpp"
       
    30 #include "memory/dynamicArchive.hpp"
    30 #include "memory/heapShared.inline.hpp"
    31 #include "memory/heapShared.inline.hpp"
    31 #include "memory/metadataFactory.hpp"
    32 #include "memory/metadataFactory.hpp"
    32 #include "memory/metaspaceShared.hpp"
    33 #include "memory/metaspaceShared.hpp"
    33 #include "runtime/vmThread.hpp"
    34 #include "runtime/vmThread.hpp"
    34 #include "utilities/numberSeq.hpp"
    35 #include "utilities/numberSeq.hpp"
    37 #if INCLUDE_CDS
    38 #if INCLUDE_CDS
    38 /////////////////////////////////////////////////////
    39 /////////////////////////////////////////////////////
    39 //
    40 //
    40 // The compact hash table writer implementations
    41 // The compact hash table writer implementations
    41 //
    42 //
    42 CompactHashtableWriter::CompactHashtableWriter(int num_buckets,
    43 CompactHashtableWriter::CompactHashtableWriter(int num_entries,
    43                                                CompactHashtableStats* stats) {
    44                                                CompactHashtableStats* stats) {
    44   assert(DumpSharedSpaces, "dump-time only");
    45   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
    45   assert(num_buckets > 0, "no buckets");
    46   assert(num_entries >= 0, "sanity");
    46   _num_buckets = num_buckets;
    47   _num_buckets = calculate_num_buckets(num_entries);
    47   _num_entries = 0;
    48   assert(_num_buckets > 0, "no buckets");
       
    49 
       
    50   _num_entries_written = 0;
    48   _buckets = NEW_C_HEAP_ARRAY(GrowableArray<Entry>*, _num_buckets, mtSymbol);
    51   _buckets = NEW_C_HEAP_ARRAY(GrowableArray<Entry>*, _num_buckets, mtSymbol);
    49   for (int i=0; i<_num_buckets; i++) {
    52   for (int i=0; i<_num_buckets; i++) {
    50     _buckets[i] = new (ResourceObj::C_HEAP, mtSymbol) GrowableArray<Entry>(0, true, mtSymbol);
    53     _buckets[i] = new (ResourceObj::C_HEAP, mtSymbol) GrowableArray<Entry>(0, true, mtSymbol);
    51   }
    54   }
    52 
    55 
    65   }
    68   }
    66 
    69 
    67   FREE_C_HEAP_ARRAY(GrowableArray<Entry>*, _buckets);
    70   FREE_C_HEAP_ARRAY(GrowableArray<Entry>*, _buckets);
    68 }
    71 }
    69 
    72 
       
    73 size_t CompactHashtableWriter::estimate_size(int num_entries) {
       
    74   int num_buckets = calculate_num_buckets(num_entries);
       
    75   size_t bucket_bytes = MetaspaceShared::ro_array_bytesize<u4>(num_buckets + 1);
       
    76 
       
    77   // In worst case, we have no VALUE_ONLY_BUCKET_TYPE, so each entry takes 2 slots
       
    78   int entries_space = 2 * num_entries;
       
    79   size_t entry_bytes = MetaspaceShared::ro_array_bytesize<u4>(entries_space);
       
    80 
       
    81   return bucket_bytes
       
    82        + entry_bytes
       
    83        + SimpleCompactHashtable::calculate_header_size();
       
    84 }
       
    85 
    70 // Add a symbol entry to the temporary hash table
    86 // Add a symbol entry to the temporary hash table
    71 void CompactHashtableWriter::add(unsigned int hash, u4 value) {
    87 void CompactHashtableWriter::add(unsigned int hash, u4 value) {
    72   int index = hash % _num_buckets;
    88   int index = hash % _num_buckets;
    73   _buckets[index]->append_if_missing(Entry(hash, value));
    89   _buckets[index]->append_if_missing(Entry(hash, value));
    74   _num_entries++;
    90   _num_entries_written++;
    75 }
    91 }
    76 
    92 
    77 void CompactHashtableWriter::allocate_table() {
    93 void CompactHashtableWriter::allocate_table() {
    78   int entries_space = 0;
    94   int entries_space = 0;
    79   for (int index = 0; index < _num_buckets; index++) {
    95   for (int index = 0; index < _num_buckets; index++) {
    80     GrowableArray<Entry>* bucket = _buckets[index];
    96     GrowableArray<Entry>* bucket = _buckets[index];
    81     int bucket_size = bucket->length();
    97     int bucket_size = bucket->length();
    82     if (bucket_size == 1) {
    98     if (bucket_size == 1) {
    83       entries_space++;
    99       entries_space++;
    84     } else {
   100     } else if (bucket_size > 1) {
    85       entries_space += 2 * bucket_size;
   101       entries_space += 2 * bucket_size;
    86     }
   102     }
    87   }
   103   }
    88 
   104 
    89   if (entries_space & ~BUCKET_OFFSET_MASK) {
   105   if (entries_space & ~BUCKET_OFFSET_MASK) {
    94   _compact_buckets = MetaspaceShared::new_ro_array<u4>(_num_buckets + 1);
   110   _compact_buckets = MetaspaceShared::new_ro_array<u4>(_num_buckets + 1);
    95   _compact_entries = MetaspaceShared::new_ro_array<u4>(entries_space);
   111   _compact_entries = MetaspaceShared::new_ro_array<u4>(entries_space);
    96 
   112 
    97   _stats->bucket_count    = _num_buckets;
   113   _stats->bucket_count    = _num_buckets;
    98   _stats->bucket_bytes    = _compact_buckets->size() * BytesPerWord;
   114   _stats->bucket_bytes    = _compact_buckets->size() * BytesPerWord;
    99   _stats->hashentry_count = _num_entries;
   115   _stats->hashentry_count = _num_entries_written;
   100   _stats->hashentry_bytes = _compact_entries->size() * BytesPerWord;
   116   _stats->hashentry_bytes = _compact_entries->size() * BytesPerWord;
   101 }
   117 }
   102 
   118 
   103 // Write the compact table's buckets
   119 // Write the compact table's buckets
   104 void CompactHashtableWriter::dump_table(NumberSeq* summary) {
   120 void CompactHashtableWriter::dump_table(NumberSeq* summary) {
   142   NumberSeq summary;
   158   NumberSeq summary;
   143   allocate_table();
   159   allocate_table();
   144   dump_table(&summary);
   160   dump_table(&summary);
   145 
   161 
   146   int table_bytes = _stats->bucket_bytes + _stats->hashentry_bytes;
   162   int table_bytes = _stats->bucket_bytes + _stats->hashentry_bytes;
   147   address base_address = address(MetaspaceShared::shared_rs()->base());
   163   address base_address = address(SharedBaseAddress);
   148   cht->init(base_address,  _num_entries, _num_buckets,
   164   cht->init(base_address,  _num_entries_written, _num_buckets,
   149             _compact_buckets->data(), _compact_entries->data());
   165             _compact_buckets->data(), _compact_entries->data());
   150 
   166 
   151   LogMessage(cds, hashtables) msg;
   167   LogMessage(cds, hashtables) msg;
   152   if (msg.is_info()) {
   168   if (msg.is_info()) {
   153     double avg_cost = 0.0;
   169     double avg_cost = 0.0;
   154     if (_num_entries > 0) {
   170     if (_num_entries_written > 0) {
   155       avg_cost = double(table_bytes)/double(_num_entries);
   171       avg_cost = double(table_bytes)/double(_num_entries_written);
   156     }
   172     }
   157     msg.info("Shared %s table stats -------- base: " PTR_FORMAT,
   173     msg.info("Shared %s table stats -------- base: " PTR_FORMAT,
   158                          table_name, (intptr_t)base_address);
   174                          table_name, (intptr_t)base_address);
   159     msg.info("Number of entries       : %9d", _num_entries);
   175     msg.info("Number of entries       : %9d", _num_entries_written);
   160     msg.info("Total bytes used        : %9d", table_bytes);
   176     msg.info("Total bytes used        : %9d", table_bytes);
   161     msg.info("Average bytes per entry : %9.3f", avg_cost);
   177     msg.info("Average bytes per entry : %9.3f", avg_cost);
   162     msg.info("Average bucket size     : %9.3f", summary.avg());
   178     msg.info("Average bucket size     : %9.3f", summary.avg());
   163     msg.info("Variance of bucket size : %9.3f", summary.variance());
   179     msg.info("Variance of bucket size : %9.3f", summary.variance());
   164     msg.info("Std. dev. of bucket size: %9.3f", summary.sd());
   180     msg.info("Std. dev. of bucket size: %9.3f", summary.sd());
   172 /////////////////////////////////////////////////////////////
   188 /////////////////////////////////////////////////////////////
   173 //
   189 //
   174 // The CompactHashtable implementation
   190 // The CompactHashtable implementation
   175 //
   191 //
   176 
   192 
       
   193 void SimpleCompactHashtable::init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries) {
       
   194   _bucket_count = bucket_count;
       
   195   _entry_count = entry_count;
       
   196   _base_address = base_address;
       
   197   if (DynamicDumpSharedSpaces) {
       
   198     _buckets = DynamicArchive::buffer_to_target(buckets);
       
   199     _entries = DynamicArchive::buffer_to_target(entries);
       
   200   } else {
       
   201     _buckets = buckets;
       
   202     _entries = entries;
       
   203   }
       
   204 }
       
   205 
       
   206 size_t SimpleCompactHashtable::calculate_header_size() {
       
   207   // We have 5 fields. Each takes up sizeof(intptr_t). See WriteClosure::do_u4
       
   208   size_t bytes = sizeof(intptr_t) * 5;
       
   209   return bytes;
       
   210 }
       
   211 
   177 void SimpleCompactHashtable::serialize_header(SerializeClosure* soc) {
   212 void SimpleCompactHashtable::serialize_header(SerializeClosure* soc) {
       
   213   // NOTE: if you change this function, you MUST change the number 5 in
       
   214   // calculate_header_size() accordingly.
   178   soc->do_ptr((void**)&_base_address);
   215   soc->do_ptr((void**)&_base_address);
   179   soc->do_u4(&_entry_count);
   216   soc->do_u4(&_entry_count);
   180   soc->do_u4(&_bucket_count);
   217   soc->do_u4(&_bucket_count);
   181   soc->do_ptr((void**)&_buckets);
   218   soc->do_ptr((void**)&_buckets);
   182   soc->do_ptr((void**)&_entries);
   219   soc->do_ptr((void**)&_entries);