39 //
40 // block X ---+ +-------------------+
41 // | | Virtualspace |
42 // | | |
43 // | | |
44 // | |-------------------|
45 // | || Chunk |
46 // | || |
47 // | ||---------- |
48 // +------>||| block 0 | |
49 // ||---------- |
50 // ||| block 1 | |
51 // ||---------- |
52 // || |
53 // |-------------------|
54 // | |
55 // | |
56 // +-------------------+
57 //
58
59 class ClassLoaderData;
60 class Metablock;
61 class MetaWord;
62 class Mutex;
63 class outputStream;
64 class SpaceManager;
65
66 // Metaspaces each have a SpaceManager and allocations
67 // are done by the SpaceManager. Allocations are done
68 // out of the current Metachunk. When the current Metachunk
69 // is exhausted, the SpaceManager gets a new one from
70 // the current VirtualSpace. When the VirtualSpace is exhausted
71 // the SpaceManager gets a new one. The SpaceManager
72 // also manages freelists of available Chunks.
73 //
74 // Currently the space manager maintains the list of
75 // virtual spaces and the list of chunks in use. Its
76 // allocate() method returns a block for use as a
77 // quantum of metadata.
78
79 class VirtualSpaceList;
80
81 class Metaspace : public CHeapObj<mtClass> {
82 friend class VMStructs;
83 friend class SpaceManager;
84 friend class VM_CollectForMetadataAllocation;
85 friend class MetaspaceGC;
86 friend class MetaspaceAux;
87
88 public:
89 enum MetadataType {ClassType = 0,
90 NonClassType = ClassType + 1,
91 MetadataTypeCount = ClassType + 2
92 };
93 enum MetaspaceType {
94 StandardMetaspaceType,
95 BootMetaspaceType,
96 ROMetaspaceType,
97 ReadWriteMetaspaceType,
98 AnonymousMetaspaceType,
99 ReflectionMetaspaceType
100 };
101
102 private:
103 void initialize(Mutex* lock, MetaspaceType type);
104
105 // Align up the word size to the allocation word size
106 static size_t align_word_size_up(size_t);
107
108 // Aligned size of the metaspace.
109 static size_t _class_metaspace_size;
110
111 static size_t class_metaspace_size() {
112 return _class_metaspace_size;
113 }
114 static void set_class_metaspace_size(size_t metaspace_size) {
115 _class_metaspace_size = metaspace_size;
116 }
117
118 static size_t _first_chunk_word_size;
119 static size_t _first_class_chunk_word_size;
120
121 SpaceManager* _vsm;
122 SpaceManager* vsm() const { return _vsm; }
123
124 SpaceManager* _class_vsm;
125 SpaceManager* class_vsm() const { return _class_vsm; }
126
127 // Allocate space for metadata of type mdtype. This is space
128 // within a Metachunk and is used by
129 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS)
130 // which returns a Metablock.
131 MetaWord* allocate(size_t word_size, MetadataType mdtype);
132
133 // Virtual Space lists for both classes and other metadata
134 static VirtualSpaceList* _space_list;
135 static VirtualSpaceList* _class_space_list;
136
137 static VirtualSpaceList* space_list() { return _space_list; }
138 static VirtualSpaceList* class_space_list() { return _class_space_list; }
139 static VirtualSpaceList* get_space_list(MetadataType mdtype) {
140 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
141 return mdtype == ClassType ? class_space_list() : space_list();
142 }
143
144 // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
145 // maintain a single list for now.
146 void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
147
148 #ifdef _LP64
149 static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
150
151 // Returns true if can use CDS with metaspace allocated as specified address.
152 static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
153
154 static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
155
156 static void initialize_class_space(ReservedSpace rs);
157 #endif
158
159 class AllocRecord : public CHeapObj<mtClass> {
160 public:
161 AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
162 : _next(NULL), _ptr(ptr), _type(type), _byte_size(byte_size) {}
163 AllocRecord *_next;
182
183 char* bottom() const;
184 size_t used_words_slow(MetadataType mdtype) const;
185 size_t free_words_slow(MetadataType mdtype) const;
186 size_t capacity_words_slow(MetadataType mdtype) const;
187
188 size_t used_bytes_slow(MetadataType mdtype) const;
189 size_t capacity_bytes_slow(MetadataType mdtype) const;
190
191 static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size,
192 bool read_only, MetaspaceObj::Type type, TRAPS);
193 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
194
195 MetaWord* expand_and_allocate(size_t size,
196 MetadataType mdtype);
197
198 static bool contains(const void *ptr);
199 void dump(outputStream* const out) const;
200
201 // Free empty virtualspaces
202 static void purge();
203
204 void print_on(outputStream* st) const;
205 // Debugging support
206 void verify();
207
208 class AllocRecordClosure : public StackObj {
209 public:
210 virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0;
211 };
212
213 void iterate(AllocRecordClosure *closure);
214
215 // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False.
216 static bool using_class_space() {
217 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
218 }
219
220 };
221
|
39 //
40 // block X ---+ +-------------------+
41 // | | Virtualspace |
42 // | | |
43 // | | |
44 // | |-------------------|
45 // | || Chunk |
46 // | || |
47 // | ||---------- |
48 // +------>||| block 0 | |
49 // ||---------- |
50 // ||| block 1 | |
51 // ||---------- |
52 // || |
53 // |-------------------|
54 // | |
55 // | |
56 // +-------------------+
57 //
58
59 class ChunkManager;
60 class ClassLoaderData;
61 class Metablock;
62 class Metachunk;
63 class MetaWord;
64 class Mutex;
65 class outputStream;
66 class SpaceManager;
67 class VirtualSpaceList;
68
69 // Metaspaces each have a SpaceManager and allocations
70 // are done by the SpaceManager. Allocations are done
71 // out of the current Metachunk. When the current Metachunk
72 // is exhausted, the SpaceManager gets a new one from
73 // the current VirtualSpace. When the VirtualSpace is exhausted
74 // the SpaceManager gets a new one. The SpaceManager
75 // also manages freelists of available Chunks.
76 //
77 // Currently the space manager maintains the list of
78 // virtual spaces and the list of chunks in use. Its
79 // allocate() method returns a block for use as a
80 // quantum of metadata.
81
82 class Metaspace : public CHeapObj<mtClass> {
83 friend class VMStructs;
84 friend class SpaceManager;
85 friend class VM_CollectForMetadataAllocation;
86 friend class MetaspaceGC;
87 friend class MetaspaceAux;
88
89 public:
90 enum MetadataType {ClassType = 0,
91 NonClassType = ClassType + 1,
92 MetadataTypeCount = ClassType + 2
93 };
94 enum MetaspaceType {
95 StandardMetaspaceType,
96 BootMetaspaceType,
97 ROMetaspaceType,
98 ReadWriteMetaspaceType,
99 AnonymousMetaspaceType,
100 ReflectionMetaspaceType
101 };
102
103 private:
104 void initialize(Mutex* lock, MetaspaceType type);
105
106 Metachunk* get_initialization_chunk(MetadataType mdtype,
107 size_t chunk_word_size,
108 size_t chunk_bunch);
109
110 // Align up the word size to the allocation word size
111 static size_t align_word_size_up(size_t);
112
113 // Aligned size of the metaspace.
114 static size_t _class_metaspace_size;
115
116 static size_t class_metaspace_size() {
117 return _class_metaspace_size;
118 }
119 static void set_class_metaspace_size(size_t metaspace_size) {
120 _class_metaspace_size = metaspace_size;
121 }
122
123 static size_t _first_chunk_word_size;
124 static size_t _first_class_chunk_word_size;
125
126 SpaceManager* _vsm;
127 SpaceManager* vsm() const { return _vsm; }
128
129 SpaceManager* _class_vsm;
130 SpaceManager* class_vsm() const { return _class_vsm; }
131
132 // Allocate space for metadata of type mdtype. This is space
133 // within a Metachunk and is used by
134 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS)
135 // which returns a Metablock.
136 MetaWord* allocate(size_t word_size, MetadataType mdtype);
137
138 // Virtual Space lists for both classes and other metadata
139 static VirtualSpaceList* _space_list;
140 static VirtualSpaceList* _class_space_list;
141
142 static ChunkManager* _chunk_manager_metadata;
143 static ChunkManager* _chunk_manager_class;
144
145 public:
146 static VirtualSpaceList* space_list() { return _space_list; }
147 static VirtualSpaceList* class_space_list() { return _class_space_list; }
148 static VirtualSpaceList* get_space_list(MetadataType mdtype) {
149 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
150 return mdtype == ClassType ? class_space_list() : space_list();
151 }
152
153 static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; }
154 static ChunkManager* chunk_manager_class() { return _chunk_manager_class; }
155 static ChunkManager* get_chunk_manager(MetadataType mdtype) {
156 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
157 return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
158 }
159
160 private:
161 // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
162 // maintain a single list for now.
163 void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
164
165 #ifdef _LP64
166 static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
167
168 // Returns true if can use CDS with metaspace allocated as specified address.
169 static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
170
171 static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
172
173 static void initialize_class_space(ReservedSpace rs);
174 #endif
175
176 class AllocRecord : public CHeapObj<mtClass> {
177 public:
178 AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
179 : _next(NULL), _ptr(ptr), _type(type), _byte_size(byte_size) {}
180 AllocRecord *_next;
199
200 char* bottom() const;
201 size_t used_words_slow(MetadataType mdtype) const;
202 size_t free_words_slow(MetadataType mdtype) const;
203 size_t capacity_words_slow(MetadataType mdtype) const;
204
205 size_t used_bytes_slow(MetadataType mdtype) const;
206 size_t capacity_bytes_slow(MetadataType mdtype) const;
207
208 static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size,
209 bool read_only, MetaspaceObj::Type type, TRAPS);
210 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
211
212 MetaWord* expand_and_allocate(size_t size,
213 MetadataType mdtype);
214
215 static bool contains(const void *ptr);
216 void dump(outputStream* const out) const;
217
218 // Free empty virtualspaces
219 static void purge(MetadataType mdtype);
220 static void purge();
221
222 void print_on(outputStream* st) const;
223 // Debugging support
224 void verify();
225
226 class AllocRecordClosure : public StackObj {
227 public:
228 virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0;
229 };
230
231 void iterate(AllocRecordClosure *closure);
232
233 // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False.
234 static bool using_class_space() {
235 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
236 }
237
238 };
239
|