< prev index next >

src/share/vm/classfile/compactHashtable.cpp

Print this page

        

*** 30,44 **** ///////////////////////////////////////////////////// // // The compact hash table writer implementations // ! CompactHashtableWriter::CompactHashtableWriter(const char* table_name, int num_entries, CompactHashtableStats* stats) { assert(DumpSharedSpaces, "dump-time only"); ! _table_name = table_name; _num_entries = num_entries; _num_buckets = number_of_buckets(_num_entries); _buckets = NEW_C_HEAP_ARRAY(Entry*, _num_buckets, mtSymbol); memset(_buckets, 0, sizeof(Entry*) * _num_buckets); --- 30,44 ---- ///////////////////////////////////////////////////// // // The compact hash table writer implementations // ! CompactHashtableWriter::CompactHashtableWriter(int table_type, int num_entries, CompactHashtableStats* stats) { assert(DumpSharedSpaces, "dump-time only"); ! _type = table_type; _num_entries = num_entries; _num_buckets = number_of_buckets(_num_entries); _buckets = NEW_C_HEAP_ARRAY(Entry*, _num_buckets, mtSymbol); memset(_buckets, 0, sizeof(Entry*) * _num_buckets);
*** 97,107 **** // Write the compact table's bucket infos juint* CompactHashtableWriter::dump_table(juint* p, juint** first_bucket, NumberSeq* summary) { int index; juint* compact_table = p; ! // Find the start of the buckets, skip 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++) { --- 97,107 ---- // 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++) {
*** 128,141 **** } // Write the compact table's entries juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p, NumberSeq* summary) { ! uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); ! uintx max_delta = uintx(MetaspaceShared::shared_rs()->size()); ! assert(max_delta <= 0x7fffffff, "range check"); int num_compact_buckets = 0; assert(p != NULL, "sanity"); for (int index = 0; index < _num_buckets; index++) { juint count = 0; int bucket_size = _bucket_sizes[index]; --- 128,148 ---- } // Write the compact table's entries juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p, NumberSeq* summary) { ! uintx base_address = 0; ! uintx max_delta = 0; int num_compact_buckets = 0; + if (_type == CompactHashtable<Symbol*, char>::_symbol_table) { + base_address = uintx(MetaspaceShared::shared_rs()->base()); + max_delta = uintx(MetaspaceShared::shared_rs()->size()); + assert(max_delta <= 0x7fffffff, "range check"); + } else { + assert((_type == CompactHashtable<oop, char>::_string_table), "unknown table"); + assert(UseCompressedOops, "UseCompressedOops is required"); + } assert(p != NULL, "sanity"); for (int index = 0; index < _num_buckets; index++) { juint count = 0; int bucket_size = _bucket_sizes[index];
*** 146,161 **** num_compact_buckets ++; } for (Entry* tent = _buckets[index]; tent; tent = tent->next()) { if (bucket_type == REGULAR_BUCKET_TYPE) { ! *p++ = juint(tent->hash()); // write symbol hash } uintx deltax = uintx(tent->value()) - base_address; assert(deltax < max_delta, "range check"); juint delta = juint(deltax); ! *p++ = delta; // write symbol offset count ++; } assert(count == _bucket_sizes[index], "sanity"); } --- 153,172 ---- num_compact_buckets ++; } for (Entry* tent = _buckets[index]; tent; tent = tent->next()) { if (bucket_type == REGULAR_BUCKET_TYPE) { ! *p++ = juint(tent->hash()); // write entry hash } + if (_type == CompactHashtable<Symbol*, char>::_symbol_table) { uintx deltax = uintx(tent->value()) - base_address; assert(deltax < max_delta, "range check"); juint delta = juint(deltax); ! *p++ = delta; // write entry offset ! } else { ! *p++ = oopDesc::encode_heap_oop(tent->string()); ! } count ++; } assert(count == _bucket_sizes[index], "sanity"); }
*** 172,181 **** --- 183,196 ---- char* old_top = *top; juint* p = (juint*)(*top); uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); + // Now write the following at the beginning of the table: + // base_address (uintx) + // num_entries (juint) + // num_buckets (juint) *p++ = high(base_address); *p++ = low (base_address); // base address *p++ = _num_entries; // number of entries in the table *p++ = _num_buckets; // number of buckets in the table
*** 189,215 **** if (PrintSharedSpaces) { double avg_cost = 0.0; if (_num_entries > 0) { avg_cost = double(_required_bytes)/double(_num_entries); } ! tty->print_cr("Shared %s table stats -------- base: " PTR_FORMAT, _table_name, (intptr_t)base_address); tty->print_cr("Number of entries : %9d", _num_entries); tty->print_cr("Total bytes used : %9d", (int)((*top) - old_top)); tty->print_cr("Average bytes per entry : %9.3f", avg_cost); tty->print_cr("Average bucket size : %9.3f", summary.avg()); tty->print_cr("Variance of bucket size : %9.3f", summary.variance()); tty->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); tty->print_cr("Maximum bucket size : %9d", (int)summary.maximum()); } } ///////////////////////////////////////////////////////////// // // The CompactHashtable implementation // ! template <class T, class N> const char* CompactHashtable<T, N>::init(const char* buffer) { assert(!DumpSharedSpaces, "run-time only"); juint*p = (juint*)buffer; juint upper = *p++; juint lower = *p++; _base_address = uintx(jlong_from(upper, lower)); _entry_count = *p++; --- 204,243 ---- if (PrintSharedSpaces) { double avg_cost = 0.0; if (_num_entries > 0) { avg_cost = double(_required_bytes)/double(_num_entries); } ! tty->print_cr("Shared %s table stats -------- base: " PTR_FORMAT, ! table_name(), (intptr_t)base_address); tty->print_cr("Number of entries : %9d", _num_entries); tty->print_cr("Total bytes used : %9d", (int)((*top) - old_top)); tty->print_cr("Average bytes per entry : %9.3f", avg_cost); tty->print_cr("Average bucket size : %9.3f", summary.avg()); tty->print_cr("Variance of bucket size : %9.3f", summary.variance()); tty->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); tty->print_cr("Maximum bucket size : %9d", (int)summary.maximum()); } } + const char* CompactHashtableWriter::table_name() { + switch (_type) { + case CompactHashtable<Symbol*, char>::_symbol_table: return "symbol"; + case CompactHashtable<oop, char>::_string_table: return "string"; + default: + ; + } + return "unknown"; + } + ///////////////////////////////////////////////////////////// // // The CompactHashtable implementation // ! template <class T, class N> const char* CompactHashtable<T, N>::init( ! CompactHashtableType type, const char* buffer) { assert(!DumpSharedSpaces, "run-time only"); + _type = type; juint*p = (juint*)buffer; juint upper = *p++; juint lower = *p++; _base_address = uintx(jlong_from(upper, lower)); _entry_count = *p++;
*** 243,254 **** --- 271,308 ---- } } } } + template <class T, class N> void CompactHashtable<T, N>::oops_do(OopClosure* f) { + assert(!DumpSharedSpaces, "run-time only"); + assert(_type == _string_table, "sanity"); + for (juint i = 0; i < _bucket_count; i ++) { + juint bucket_info = _buckets[i]; + juint bucket_offset = BUCKET_OFFSET(bucket_info); + int bucket_type = BUCKET_TYPE(bucket_info); + juint* bucket = _buckets + bucket_offset; + juint* bucket_end = _buckets; + + narrowOop o; + if (bucket_type == COMPACT_BUCKET_TYPE) { + o = (narrowOop)bucket[0]; + f->do_oop(&o); + } else { + bucket_end += BUCKET_OFFSET(_buckets[i + 1]); + while (bucket < bucket_end) { + o = (narrowOop)bucket[1]; + f->do_oop(&o); + bucket += 2; + } + } + } + } + // Explicitly instantiate these types template class CompactHashtable<Symbol*, char>; + template class CompactHashtable<oop, char>; #ifndef O_BINARY // if defined (Win32) use binary files. #define O_BINARY 0 // otherwise do nothing. #endif
*** 271,280 **** --- 325,336 ---- quit("Unable to map hashtable dump file", filename); } _p = _base; _end = _base + st.st_size; _filename = filename; + _prefix_type = Unknown; + _line_no = 1; } HashtableTextDump::~HashtableTextDump() { os::unmap_memory((char*)_base, _size); if (_fd >= 0) {
*** 284,307 **** void HashtableTextDump::quit(const char* err, const char* msg) { vm_exit_during_initialization(err, msg); } ! void HashtableTextDump::corrupted(const char *p) { char info[60]; ! sprintf(info, "corrupted at pos %d", (int)(p - _base)); quit(info, _filename); } bool HashtableTextDump::skip_newline() { if (_p[0] == '\r' && _p[1] == '\n') { _p += 2; } else if (_p[0] == '\n') { _p += 1; } else { ! corrupted(_p); } return true; } int HashtableTextDump::skip(char must_be_char) { corrupted_if(remain() < 1); --- 340,364 ---- void HashtableTextDump::quit(const char* err, const char* msg) { vm_exit_during_initialization(err, msg); } ! void HashtableTextDump::corrupted(const char *p, const char* msg) { char info[60]; ! sprintf(info, "%s. Corrupted at line %d (file pos %d)", msg, _line_no, (int)(p - _base)); quit(info, _filename); } bool HashtableTextDump::skip_newline() { if (_p[0] == '\r' && _p[1] == '\n') { _p += 2; } else if (_p[0] == '\n') { _p += 1; } else { ! corrupted(_p, "Unexpected character"); } + _line_no ++; return true; } int HashtableTextDump::skip(char must_be_char) { corrupted_if(remain() < 1);
*** 326,355 **** } _p += len; skip_newline(); } ! int HashtableTextDump::scan_prefix() { // Expect /[0-9]+: / ! int utf8_length = get_num(':'); if (*_p != ' ') { ! corrupted(_p); } _p++; return utf8_length; } ! int HashtableTextDump::scan_prefix2() { // Expect /[0-9]+ (-|)[0-9]+: / ! int utf8_length = get_num(' '); if (*_p == '-') { _p++; } ! (void)get_num(':'); if (*_p != ' ') { ! corrupted(_p); } _p++; return utf8_length; } --- 383,446 ---- } _p += len; skip_newline(); } + void HashtableTextDump::scan_prefix_type() { + _p ++; + if (strncmp(_p, "SECTION: String", 15) == 0) { + _p += 15; + _prefix_type = StringPrefix; + } else if (strncmp(_p, "SECTION: Symbol", 15) == 0) { + _p += 15; + _prefix_type = SymbolPrefix; + } else { + _prefix_type = Unknown; + } + skip_newline(); + } + + int HashtableTextDump::scan_prefix(int* utf8_length) { + if (*_p == '@') { + scan_prefix_type(); + } + + switch (_prefix_type) { + case SymbolPrefix: + *utf8_length = scan_symbol_prefix(); break; + case StringPrefix: + *utf8_length = scan_string_prefix(); break; + default: + tty->print_cr("Shared input data type: Unknown."); + corrupted(_p, "Unknown data type"); + } ! return _prefix_type; ! } ! ! int HashtableTextDump::scan_string_prefix() { // Expect /[0-9]+: / ! int utf8_length; ! get_num(':', &utf8_length); if (*_p != ' ') { ! corrupted(_p, "Wrong prefix format for string"); } _p++; return utf8_length; } ! int HashtableTextDump::scan_symbol_prefix() { // Expect /[0-9]+ (-|)[0-9]+: / ! int utf8_length; ! get_num(' ', &utf8_length); if (*_p == '-') { _p++; } ! int ref_num; ! (void)get_num(':', &ref_num); if (*_p != ' ') { ! corrupted(_p, "Wrong prefix format for symbol"); } _p++; return utf8_length; }
*** 406,416 **** case 't': *to++ = '\t'; break; case 'n': *to++ = '\n'; break; case 'r': *to++ = '\r'; break; case '\\': *to++ = '\\'; break; default: ! ShouldNotReachHere(); } } } corrupted_if(n > 0); // expected more chars but file has ended _p = from; --- 497,507 ---- case 't': *to++ = '\t'; break; case 'n': *to++ = '\n'; break; case 'r': *to++ = '\r'; break; case '\\': *to++ = '\\'; break; default: ! corrupted(_p, "Unsupported character"); } } } corrupted_if(n > 0); // expected more chars but file has ended _p = from;
< prev index next >