62 #include "runtime/vmThread.hpp" |
62 #include "runtime/vmThread.hpp" |
63 #include "runtime/vm_operations.hpp" |
63 #include "runtime/vm_operations.hpp" |
64 #include "utilities/align.hpp" |
64 #include "utilities/align.hpp" |
65 #include "utilities/bitMap.hpp" |
65 #include "utilities/bitMap.hpp" |
66 #include "utilities/defaultStream.hpp" |
66 #include "utilities/defaultStream.hpp" |
|
67 #include "utilities/hashtable.inline.hpp" |
67 #if INCLUDE_G1GC |
68 #if INCLUDE_G1GC |
68 #include "gc/g1/g1CollectedHeap.hpp" |
69 #include "gc/g1/g1CollectedHeap.hpp" |
69 #endif |
70 #endif |
70 |
71 |
71 ReservedSpace MetaspaceShared::_shared_rs; |
72 ReservedSpace MetaspaceShared::_shared_rs; |
1065 // This class is the central piece of shared archive compaction -- all metaspace data are |
1066 // This class is the central piece of shared archive compaction -- all metaspace data are |
1066 // initially allocated outside of the shared regions. ArchiveCompactor copies the |
1067 // initially allocated outside of the shared regions. ArchiveCompactor copies the |
1067 // metaspace data into their final location in the shared regions. |
1068 // metaspace data into their final location in the shared regions. |
1068 |
1069 |
1069 class ArchiveCompactor : AllStatic { |
1070 class ArchiveCompactor : AllStatic { |
|
1071 static const int INITIAL_TABLE_SIZE = 8087; |
|
1072 static const int MAX_TABLE_SIZE = 1000000; |
|
1073 |
1070 static DumpAllocStats* _alloc_stats; |
1074 static DumpAllocStats* _alloc_stats; |
1071 static SortedSymbolClosure* _ssc; |
1075 static SortedSymbolClosure* _ssc; |
1072 |
1076 |
1073 static unsigned my_hash(const address& a) { |
1077 typedef KVHashtable<address, address, mtInternal> RelocationTable; |
1074 return primitive_hash<address>(a); |
|
1075 } |
|
1076 static bool my_equals(const address& a0, const address& a1) { |
|
1077 return primitive_equals<address>(a0, a1); |
|
1078 } |
|
1079 typedef ResourceHashtable< |
|
1080 address, address, |
|
1081 ArchiveCompactor::my_hash, // solaris compiler doesn't like: primitive_hash<address> |
|
1082 ArchiveCompactor::my_equals, // solaris compiler doesn't like: primitive_equals<address> |
|
1083 16384, ResourceObj::C_HEAP> RelocationTable; |
|
1084 static RelocationTable* _new_loc_table; |
1078 static RelocationTable* _new_loc_table; |
1085 |
1079 |
1086 public: |
1080 public: |
1087 static void initialize() { |
1081 static void initialize() { |
1088 _alloc_stats = new(ResourceObj::C_HEAP, mtInternal)DumpAllocStats; |
1082 _alloc_stats = new(ResourceObj::C_HEAP, mtInternal)DumpAllocStats; |
1089 _new_loc_table = new(ResourceObj::C_HEAP, mtInternal)RelocationTable; |
1083 _new_loc_table = new RelocationTable(INITIAL_TABLE_SIZE); |
1090 } |
1084 } |
1091 static DumpAllocStats* alloc_stats() { |
1085 static DumpAllocStats* alloc_stats() { |
1092 return _alloc_stats; |
1086 return _alloc_stats; |
1093 } |
1087 } |
1094 |
1088 |
1134 } |
1128 } |
1135 p = _rw_region.allocate(bytes, alignment); |
1129 p = _rw_region.allocate(bytes, alignment); |
1136 newtop = _rw_region.top(); |
1130 newtop = _rw_region.top(); |
1137 } |
1131 } |
1138 memcpy(p, obj, bytes); |
1132 memcpy(p, obj, bytes); |
1139 bool isnew = _new_loc_table->put(obj, (address)p); |
1133 assert(_new_loc_table->lookup(obj) == NULL, "each object can be relocated at most once"); |
|
1134 _new_loc_table->add(obj, (address)p); |
1140 log_trace(cds)("Copy: " PTR_FORMAT " ==> " PTR_FORMAT " %d", p2i(obj), p2i(p), bytes); |
1135 log_trace(cds)("Copy: " PTR_FORMAT " ==> " PTR_FORMAT " %d", p2i(obj), p2i(p), bytes); |
1141 assert(isnew, "must be"); |
1136 if (_new_loc_table->maybe_grow(MAX_TABLE_SIZE)) { |
1142 |
1137 log_info(cds, hashtables)("Expanded _new_loc_table to %d", _new_loc_table->table_size()); |
|
1138 } |
1143 _alloc_stats->record(ref->msotype(), int(newtop - oldtop), read_only); |
1139 _alloc_stats->record(ref->msotype(), int(newtop - oldtop), read_only); |
1144 } |
1140 } |
1145 |
1141 |
1146 static address get_new_loc(MetaspaceClosure::Ref* ref) { |
1142 static address get_new_loc(MetaspaceClosure::Ref* ref) { |
1147 address* pp = _new_loc_table->get(ref->obj()); |
1143 address* pp = _new_loc_table->lookup(ref->obj()); |
1148 assert(pp != NULL, "must be"); |
1144 assert(pp != NULL, "must be"); |
1149 return *pp; |
1145 return *pp; |
1150 } |
1146 } |
1151 |
1147 |
1152 private: |
1148 private: |
1286 vmSymbols::metaspace_pointers_do(it); |
1282 vmSymbols::metaspace_pointers_do(it); |
1287 } |
1283 } |
1288 |
1284 |
1289 static Klass* get_relocated_klass(Klass* orig_klass) { |
1285 static Klass* get_relocated_klass(Klass* orig_klass) { |
1290 assert(DumpSharedSpaces, "dump time only"); |
1286 assert(DumpSharedSpaces, "dump time only"); |
1291 address* pp = _new_loc_table->get((address)orig_klass); |
1287 address* pp = _new_loc_table->lookup((address)orig_klass); |
1292 assert(pp != NULL, "must be"); |
1288 assert(pp != NULL, "must be"); |
1293 Klass* klass = (Klass*)(*pp); |
1289 Klass* klass = (Klass*)(*pp); |
1294 assert(klass->is_klass(), "must be"); |
1290 assert(klass->is_klass(), "must be"); |
1295 return klass; |
1291 return klass; |
1296 } |
1292 } |