src/hotspot/share/classfile/compactHashtable.hpp
author ccheung
Fri, 17 May 2019 08:29:55 -0700
changeset 54927 1512d88b24c6
parent 53244 9807daeb47c4
permissions -rw-r--r--
8207812: Implement Dynamic CDS Archive Summary: Improve the usability of AppCDS Reviewed-by: acorn, jiangli, mseledtsov Contributed-by: ioi.lam@oracle.com, jianglizhou@google.com, calvin.cheung@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     1
/*
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52811
diff changeset
     2
 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     4
 *
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     7
 * published by the Free Software Foundation.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     8
 *
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    13
 * accompanied this code).
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    14
 *
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    18
 *
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    21
 * questions.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    22
 *
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    23
 */
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    24
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52811
diff changeset
    25
#ifndef SHARE_CLASSFILE_COMPACTHASHTABLE_HPP
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52811
diff changeset
    26
#define SHARE_CLASSFILE_COMPACTHASHTABLE_HPP
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    27
46742
24ec8a039c90 8184994: Add Dictionary size logging and jcmd
coleenp
parents: 39713
diff changeset
    28
#include "oops/array.hpp"
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    29
#include "oops/symbol.hpp"
52631
3009ca99de32 8213587: Speed up CDS dump time by using resizable hashtables
iklam
parents: 52601
diff changeset
    30
#include "utilities/growableArray.hpp"
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    31
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    32
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    33
template <
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    34
  typename K,
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    35
  typename V,
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    36
  V (*DECODE)(address base_address, u4 offset),
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    37
  bool (*EQUALS)(V value, K key, int len)
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    38
  >
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    39
class CompactHashtable;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    40
class NumberSeq;
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    41
class SimpleCompactHashtable;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    42
class SerializeClosure;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    43
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    44
// Stats for symbol tables in the CDS archive
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
    45
class CompactHashtableStats {
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    46
public:
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    47
  int hashentry_count;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    48
  int hashentry_bytes;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    49
  int bucket_count;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    50
  int bucket_bytes;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    51
};
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    52
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
    53
#if INCLUDE_CDS
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    54
/////////////////////////////////////////////////////////////////////////
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    55
//
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    56
// The compact hash table writer. Used at dump time for writing out
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    57
// the compact table to the shared archive.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    58
//
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    59
// At dump time, the CompactHashtableWriter obtains all entries from the
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
    60
// symbol/string table and adds them to a new temporary hash table. The hash
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    61
// table size (number of buckets) is calculated using
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    62
// '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    63
// size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    64
// 4 is chosen because it produces smaller sized bucket on average for
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    65
// faster lookup. It also has relatively small number of empty buckets and
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    66
// good distribution of the entries.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    67
//
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
    68
// We use a simple hash function (hash % num_bucket) for the table.
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    69
// The new table is compacted when written out. Please see comments
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    70
// above the CompactHashtable class for the table layout detail. The bucket
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    71
// offsets are written to the archive as part of the compact table. The
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    72
// bucket offset is encoded in the low 30-bit (0-29) and the bucket type
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    73
// (regular or compact) are encoded in bit[31, 30]. For buckets with more
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
    74
// than one entry, both hash and entry offset are written to the
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
    75
// table. For buckets with only one entry, only the entry offset is written
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    76
// to the table and the buckets are tagged as compact in their type bits.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    77
// Buckets without entry are skipped from the table. Their offsets are
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    78
// still written out for faster lookup.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    79
//
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    80
class CompactHashtableWriter: public StackObj {
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    81
public:
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
    82
  class Entry {
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    83
    unsigned int _hash;
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    84
    u4 _value;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    85
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    86
  public:
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    87
    Entry() {}
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    88
    Entry(unsigned int hash, u4 val) : _hash(hash), _value(val) {}
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    89
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    90
    u4 value() {
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    91
      return _value;
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
    92
    }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    93
    unsigned int hash() {
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    94
      return _hash;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
    95
    }
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    96
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    97
    bool operator==(const CompactHashtableWriter::Entry& other) {
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    98
      return (_value == other._value && _hash == other._hash);
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
    99
    }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   100
  }; // class CompactHashtableWriter::Entry
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   101
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   102
private:
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   103
  int _num_entries_written;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   104
  int _num_buckets;
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   105
  int _num_empty_buckets;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   106
  int _num_value_only_buckets;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   107
  int _num_other_buckets;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   108
  GrowableArray<Entry>** _buckets;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   109
  CompactHashtableStats* _stats;
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   110
  Array<u4>* _compact_buckets;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   111
  Array<u4>* _compact_entries;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   112
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   113
public:
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   114
  // This is called at dump-time only
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   115
  CompactHashtableWriter(int num_entries, CompactHashtableStats* stats);
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   116
  ~CompactHashtableWriter();
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   117
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   118
  void add(unsigned int hash, u4 value);
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   119
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   120
private:
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   121
  void allocate_table();
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   122
  void dump_table(NumberSeq* summary);
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   123
  static int calculate_num_buckets(int num_entries) {
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   124
    int num_buckets = num_entries / SharedSymbolTableBucketSize;
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   125
    // calculation of num_buckets can result in zero buckets, we need at least one
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   126
    return (num_buckets < 1) ? 1 : num_buckets;
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   127
  }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   128
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   129
public:
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   130
  void dump(SimpleCompactHashtable *cht, const char* table_name);
52047
7bc8b456e5ac 8210388: Use hash table to store archived subgraph_info records
iklam
parents: 51823
diff changeset
   131
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   132
  static size_t estimate_size(int num_entries);
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   133
};
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   134
#endif // INCLUDE_CDS
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   135
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   136
#define REGULAR_BUCKET_TYPE       0
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   137
#define VALUE_ONLY_BUCKET_TYPE    1
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   138
#define TABLEEND_BUCKET_TYPE      3
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   139
#define BUCKET_OFFSET_MASK        0x3FFFFFFF
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   140
#define BUCKET_OFFSET(info)       ((info) & BUCKET_OFFSET_MASK)
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   141
#define BUCKET_TYPE_SHIFT         30
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   142
#define BUCKET_TYPE(info)         (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   143
#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   144
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   145
/////////////////////////////////////////////////////////////////////////////
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   146
//
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   147
// CompactHashtable is used to store the CDS archive's symbol/string tables.
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   148
//
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   149
// Because these tables are read-only (no entries can be added/deleted) at run-time
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   150
// and tend to have large number of entries, we try to minimize the footprint
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   151
// cost per entry.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   152
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   153
// The CompactHashtable is split into two arrays
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   154
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   155
//   u4 buckets[num_buckets+1]; // bit[31,30]: type; bit[29-0]: offset
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   156
//   u4 entries[<variable size>]
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   157
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   158
// The size of buckets[] is 'num_buckets + 1'. Each entry of
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   159
// buckets[] is a 32-bit encoding of the bucket type and bucket offset,
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   160
// with the type in the left-most 2-bit and offset in the remaining 30-bit.
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   161
// The last entry is a special type. It contains the end of the last
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   162
// bucket.
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   163
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   164
// There are two types of buckets, regular buckets and value_only buckets. The
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   165
// value_only buckets have '01' in their highest 2-bit, and regular buckets have
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   166
// '00' in their highest 2-bit.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   167
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   168
// For normal buckets, each entry is 8 bytes in the entries[]:
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   169
//   u4 hash;    /* symbol/string hash */
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   170
//   union {
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   171
//     u4 offset;  /* Symbol* sym = (Symbol*)(base_address + offset) */
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   172
//     narrowOop str; /* String narrowOop encoding */
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   173
//   }
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   174
//
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   175
//
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   176
// For value_only buckets, each entry has only the 4-byte 'offset' in the entries[].
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   177
//
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   178
// Example -- note that the second bucket is a VALUE_ONLY_BUCKET_TYPE so the hash code
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   179
//            is skipped.
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   180
// buckets[0, 4, 5, ....]
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   181
//         |  |  |
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   182
//         |  |  +---+
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   183
//         |  |      |
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   184
//         |  +----+ |
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   185
//         v       v v
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   186
// entries[H,O,H,O,O,H,O,H,O.....]
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   187
//
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   188
// See CompactHashtable::lookup() for how the table is searched at runtime.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   189
// See CompactHashtableWriter::dump() for how the table is written at CDS
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   190
// dump time.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   191
//
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
   192
class SimpleCompactHashtable {
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   193
protected:
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   194
  address  _base_address;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   195
  u4  _bucket_count;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   196
  u4  _entry_count;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   197
  u4* _buckets;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   198
  u4* _entries;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   199
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   200
public:
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   201
  SimpleCompactHashtable() {
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   202
    _entry_count = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   203
    _bucket_count = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   204
    _buckets = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   205
    _entries = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   206
  }
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   207
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   208
  void reset() {
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   209
    _bucket_count = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   210
    _entry_count = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   211
    _buckets = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   212
    _entries = 0;
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   213
  }
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   214
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   215
  void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries);
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   216
52047
7bc8b456e5ac 8210388: Use hash table to store archived subgraph_info records
iklam
parents: 51823
diff changeset
   217
  // Read/Write the table's header from/to the CDS archive
7bc8b456e5ac 8210388: Use hash table to store archived subgraph_info records
iklam
parents: 51823
diff changeset
   218
  void serialize_header(SerializeClosure* soc) NOT_CDS_RETURN;
51405
8b23aa7cef47 8195100: Use a low latency hashtable for SymbolTable
gziemski
parents: 49364
diff changeset
   219
8b23aa7cef47 8195100: Use a low latency hashtable for SymbolTable
gziemski
parents: 49364
diff changeset
   220
  inline bool empty() {
8b23aa7cef47 8195100: Use a low latency hashtable for SymbolTable
gziemski
parents: 49364
diff changeset
   221
    return (_entry_count == 0);
8b23aa7cef47 8195100: Use a low latency hashtable for SymbolTable
gziemski
parents: 49364
diff changeset
   222
  }
54927
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   223
1512d88b24c6 8207812: Implement Dynamic CDS Archive
ccheung
parents: 53244
diff changeset
   224
  static size_t calculate_header_size();
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   225
};
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   226
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   227
template <
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   228
  typename K,
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   229
  typename V,
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   230
  V (*DECODE)(address base_address, u4 offset),
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   231
  bool (*EQUALS)(V value, K key, int len)
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   232
  >
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   233
class CompactHashtable : public SimpleCompactHashtable {
28822
fa57694ade05 8071962: The SA code needs to be updated to support Symbol lookup from the shared archive.
jiangli
parents: 28615
diff changeset
   234
  friend class VMStructs;
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   235
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   236
  V decode(u4 offset) const {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   237
    return DECODE(_base_address, offset);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   238
  }
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   239
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   240
public:
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   241
  // Lookup a value V from the compact table using key K
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   242
  inline V lookup(K key, unsigned int hash, int len) const {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   243
    if (_entry_count > 0) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   244
      int index = hash % _bucket_count;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   245
      u4 bucket_info = _buckets[index];
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   246
      u4 bucket_offset = BUCKET_OFFSET(bucket_info);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   247
      int bucket_type = BUCKET_TYPE(bucket_info);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   248
      u4* entry = _entries + bucket_offset;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   249
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   250
      if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   251
        V value = decode(entry[0]);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   252
        if (EQUALS(value, key, len)) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   253
          return value;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   254
        }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   255
      } else {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   256
        // This is a regular bucket, which has more than one
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   257
        // entries. Each entry is a pair of entry (hash, offset).
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   258
        // Seek until the end of the bucket.
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   259
        u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   260
        while (entry < entry_max) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   261
          unsigned int h = (unsigned int)(entry[0]);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   262
          if (h == hash) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   263
            V value = decode(entry[1]);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   264
            if (EQUALS(value, key, len)) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   265
              return value;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   266
            }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   267
          }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   268
          entry += 2;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   269
        }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   270
      }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   271
    }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   272
    return NULL;
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   273
  }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   274
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   275
  template <class ITER>
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   276
  inline void iterate(ITER* iter) const {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   277
    for (u4 i = 0; i < _bucket_count; i++) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   278
      u4 bucket_info = _buckets[i];
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   279
      u4 bucket_offset = BUCKET_OFFSET(bucket_info);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   280
      int bucket_type = BUCKET_TYPE(bucket_info);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   281
      u4* entry = _entries + bucket_offset;
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   282
51823
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   283
      if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   284
        iter->do_value(decode(entry[0]));
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   285
      } else {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   286
        u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   287
        while (entry < entry_max) {
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   288
          iter->do_value(decode(entry[1]));
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   289
          entry += 2;
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   290
        }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   291
      }
2a51125b2794 8210875: Refactor CompactHashtable
iklam
parents: 51405
diff changeset
   292
    }
39713
29ece76096cb 8150752: Share Class Data
iklam
parents: 37995
diff changeset
   293
  }
52514
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   294
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   295
  void print_table_statistics(outputStream* st, const char* name) {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   296
    st->print_cr("%s statistics:", name);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   297
    int total_entries = 0;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   298
    int max_bucket = 0;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   299
    for (u4 i = 0; i < _bucket_count; i++) {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   300
      u4 bucket_info = _buckets[i];
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   301
      int bucket_type = BUCKET_TYPE(bucket_info);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   302
      int bucket_size;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   303
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   304
      if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   305
        bucket_size = 1;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   306
      } else {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   307
        bucket_size = (BUCKET_OFFSET(_buckets[i + 1]) - BUCKET_OFFSET(bucket_info)) / 2;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   308
      }
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   309
      total_entries += bucket_size;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   310
      if (max_bucket < bucket_size) {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   311
        max_bucket = bucket_size;
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   312
      }
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   313
    }
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   314
    st->print_cr("Number of buckets       : %9d", _bucket_count);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   315
    st->print_cr("Number of entries       : %9d", total_entries);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   316
    st->print_cr("Maximum bucket size     : %9d", max_bucket);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   317
  }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   318
};
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   319
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   320
////////////////////////////////////////////////////////////////////////
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   321
//
52514
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   322
// OffsetCompactHashtable -- This is used to store many types of objects
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   323
// in the CDS archive. On 64-bit platforms, we save space by using a 32-bit
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   324
// offset from the CDS base address.
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   325
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   326
template <typename V>
52601
d32e5b7100ee 8213948: Solaris-X64 build fails with compact hashtable
iklam
parents: 52514
diff changeset
   327
inline V read_value_from_compact_hashtable(address base_address, u4 offset) {
52514
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   328
  return (V)(base_address + offset);
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   329
}
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   330
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   331
template <
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   332
  typename K,
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   333
  typename V,
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   334
  bool (*EQUALS)(V value, K key, int len)
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   335
  >
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   336
class OffsetCompactHashtable : public CompactHashtable<
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   337
    K, V, read_value_from_compact_hashtable<V>, EQUALS> {
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   338
};
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   339
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   340
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   341
////////////////////////////////////////////////////////////////////////
f4e3900c8d08 8213346: Re-implement shared dictionary using CompactHashtable
iklam
parents: 52047
diff changeset
   342
//
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   343
// Read/Write the contents of a hashtable textual dump (created by
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   344
// SymbolTable::dump and StringTable::dump).
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   345
// Because the dump file may be big (hundred of MB in extreme cases),
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   346
// we use mmap for fast access when reading it.
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   347
//
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
   348
class HashtableTextDump {
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   349
  int _fd;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   350
  const char* _base;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   351
  const char* _p;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   352
  const char* _end;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   353
  const char* _filename;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   354
  size_t      _size;
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   355
  int         _prefix_type;
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   356
  int         _line_no;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   357
public:
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   358
  HashtableTextDump(const char* filename);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   359
  ~HashtableTextDump();
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   360
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   361
  enum {
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   362
    SymbolPrefix = 1 << 0,
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   363
    StringPrefix = 1 << 1,
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   364
    Unknown = 1 << 2
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   365
  };
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   366
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   367
  void quit(const char* err, const char* msg);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   368
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   369
  inline int remain() {
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   370
    return (int)(_end - _p);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   371
  }
52811
ff04b71bf6f1 8214388: CDS dumping fails with java heap fragmentation
iklam
parents: 52631
diff changeset
   372
  int last_line_no() {
ff04b71bf6f1 8214388: CDS dumping fails with java heap fragmentation
iklam
parents: 52631
diff changeset
   373
    return _line_no - 1;
ff04b71bf6f1 8214388: CDS dumping fails with java heap fragmentation
iklam
parents: 52631
diff changeset
   374
  }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   375
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   376
  void corrupted(const char *p, const char *msg);
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   377
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   378
  inline void corrupted_if(bool cond, const char *msg) {
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   379
    if (cond) {
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   380
      corrupted(_p, msg);
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   381
    }
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   382
  }
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   383
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   384
  bool skip_newline();
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   385
  int skip(char must_be_char);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   386
  void skip_past(char c);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   387
  void check_version(const char* ver);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   388
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   389
  inline void get_num(char delim, int *num) {
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   390
    const char* p   = _p;
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   391
    const char* end = _end;
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   392
    u8 n = 0;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   393
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   394
    while (p < end) {
37995
92aec042a43b 8150607: Clean up CompactHashtable
iklam
parents: 35868
diff changeset
   395
      char c = *p++;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   396
      if ('0' <= c && c <= '9') {
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   397
        n = n * 10 + (c - '0');
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   398
        if (n > (u8)INT_MAX) {
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   399
          corrupted(_p, "Num overflow");
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   400
        }
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   401
      } else if (c == delim) {
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   402
        _p = p;
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   403
        *num = (int)n;
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   404
        return;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   405
      } else {
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   406
        // Not [0-9], not 'delim'
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   407
        corrupted(_p, "Unrecognized format");;
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   408
      }
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   409
    }
35868
bf29f15cdf30 8147500: The HashtableTextDump::get_num() should check for integer overflow
jiangli
parents: 34659
diff changeset
   410
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   411
    corrupted(_end, "Incorrect format");
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   412
    ShouldNotReachHere();
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   413
  }
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   414
31345
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   415
  void scan_prefix_type();
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   416
  int scan_prefix(int* utf8_length);
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   417
  int scan_string_prefix();
1bba15125d8d 8015086: add interned strings to the shared archive.
jiangli
parents: 28822
diff changeset
   418
  int scan_symbol_prefix();
28363
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   419
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   420
  jchar unescape(const char* from, const char* end, int count);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   421
  void get_utf8(char* utf8_buffer, int utf8_length);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   422
  static void put_utf8(outputStream* st, const char* utf8_string, int utf8_length);
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   423
};
047115468f16 8059510: Compact symbol table layout inside shared archive.
jiangli
parents:
diff changeset
   424
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52811
diff changeset
   425
#endif // SHARE_CLASSFILE_COMPACTHASHTABLE_HPP