49
49
// + at run time: we clone the actual contents of the vtables from libjvm.so
50
50
// into our own tables.
51
51
52
- // Currently, the archive contain ONLY the following types of objects that have C++ vtables.
53
- #define CPP_VTABLE_PATCH_TYPES_DO (f ) \
52
+ // Currently, the archive contains ONLY the following types of objects that have C++ vtables.
53
+ #define CPP_VTABLE_TYPES_DO (f ) \
54
54
f (ConstantPool) \
55
55
f(InstanceKlass) \
56
56
f(InstanceClassLoaderKlass) \
@@ -78,60 +78,36 @@ class CppVtableInfo {
78
78
}
79
79
};
80
80
81
- static inline intptr_t * vtable_of (Metadata* m) {
81
+ static inline intptr_t * vtable_of (const Metadata* m) {
82
82
return *((intptr_t **)m);
83
83
}
84
84
85
- static inline DumpRegion* mc_region () {
86
- return MetaspaceShared::misc_code_dump_space ();
87
- }
88
-
89
- template <class T > class CppVtableCloner : public T {
90
- static CppVtableInfo* _info;
91
-
85
+ template <class T > class CppVtableCloner {
92
86
static int get_vtable_length (const char * name);
93
87
94
88
public:
95
- // Allocate and initialize the C++ vtable, starting from top, but do not go past end.
96
- static intptr_t * allocate (const char * name);
89
+ // Allocate a clone of the vtable of T from the shared metaspace;
90
+ // Initialize the contents of this clone.
91
+ static CppVtableInfo* allocate_and_initialize (const char * name);
97
92
98
- // Clone the vtable to ...
99
- static intptr_t * clone_vtable (const char * name, CppVtableInfo* info);
100
-
101
- static void zero_vtable_clone () {
102
- assert (DumpSharedSpaces, " dump-time only" );
103
- _info->zero ();
104
- }
105
-
106
- static bool is_valid_shared_object (const T* obj) {
107
- intptr_t * vptr = *(intptr_t **)obj;
108
- return vptr == _info->cloned_vtable ();
109
- }
93
+ // Copy the contents of the vtable of T into info->_cloned_vtable;
94
+ static void initialize (const char * name, CppVtableInfo* info);
110
95
111
96
static void init_orig_cpp_vtptr (int kind);
112
97
};
113
98
114
- template <class T > CppVtableInfo* CppVtableCloner<T>::_info = NULL ;
115
-
116
99
template <class T >
117
- intptr_t * CppVtableCloner<T>::allocate(const char * name) {
118
- assert (is_aligned (mc_region ()->top (), sizeof (intptr_t )), " bad alignment" );
100
+ CppVtableInfo* CppVtableCloner<T>::allocate_and_initialize(const char * name) {
119
101
int n = get_vtable_length (name);
120
- _info = (CppVtableInfo*)mc_region ()->allocate (CppVtableInfo::byte_size (n));
121
- _info->set_vtable_size (n);
122
-
123
- intptr_t * p = clone_vtable (name, _info);
124
- assert ((char *)p == mc_region ()->top (), " must be" );
125
-
126
- return _info->cloned_vtable ();
102
+ CppVtableInfo* info =
103
+ (CppVtableInfo*)MetaspaceShared::misc_code_dump_space ()->allocate (CppVtableInfo::byte_size (n));
104
+ info->set_vtable_size (n);
105
+ initialize (name, info);
106
+ return info;
127
107
}
128
108
129
109
template <class T >
130
- intptr_t * CppVtableCloner<T>::clone_vtable(const char * name, CppVtableInfo* info) {
131
- if (!DumpSharedSpaces) {
132
- assert (_info == 0 , " _info is initialized only at dump time" );
133
- _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method()
134
- }
110
+ void CppVtableCloner<T>::initialize(const char * name, CppVtableInfo* info) {
135
111
T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
136
112
int n = info->vtable_size ();
137
113
intptr_t * srcvtable = vtable_of (&tmp);
@@ -141,7 +117,6 @@ intptr_t* CppVtableCloner<T>::clone_vtable(const char* name, CppVtableInfo* info
141
117
// safe to do memcpy.
142
118
log_debug (cds, vtables)(" Copying %3d vtable entries for %s" , n, name);
143
119
memcpy (dstvtable, srcvtable, sizeof (intptr_t ) * n);
144
- return dstvtable + n;
145
120
}
146
121
147
122
// To determine the size of the vtable for each type, we use the following
@@ -195,15 +170,12 @@ int CppVtableCloner<T>::get_vtable_length(const char* name) {
195
170
return vtable_len;
196
171
}
197
172
198
- #define ALLOC_CPP_VTABLE_CLONE (c ) \
199
- _cloned_cpp_vtptrs [c##_Kind] = CppVtableCloner<c>::allocate (#c); \
200
- ArchivePtrMarker::mark_pointer (&_cloned_cpp_vtptrs [c##_Kind]);
173
+ #define ALLOCATE_AND_INITIALIZE_VTABLE (c ) \
174
+ _index [c##_Kind] = CppVtableCloner<c>::allocate_and_initialize (#c); \
175
+ ArchivePtrMarker::mark_pointer (&_index [c##_Kind]);
201
176
202
- #define CLONE_CPP_VTABLE (c ) \
203
- p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
204
-
205
- #define ZERO_CPP_VTABLE (c ) \
206
- CppVtableCloner<c>::zero_vtable_clone();
177
+ #define INITIALIZE_VTABLE (c ) \
178
+ CppVtableCloner<c>::initialize(#c, _index[c##_Kind]);
207
179
208
180
#define INIT_ORIG_CPP_VTPTRS (c ) \
209
181
CppVtableCloner<c>::init_orig_cpp_vtptr(c##_Kind);
@@ -212,7 +184,7 @@ int CppVtableCloner<T>::get_vtable_length(const char* name) {
212
184
213
185
enum ClonedVtableKind {
214
186
// E.g., ConstantPool_Kind == 0, InstanceKlass_Kind == 1, etc.
215
- CPP_VTABLE_PATCH_TYPES_DO (DECLARE_CLONED_VTABLE_KIND)
187
+ CPP_VTABLE_TYPES_DO (DECLARE_CLONED_VTABLE_KIND)
216
188
_num_cloned_vtable_kinds
217
189
};
218
190
@@ -235,23 +207,30 @@ void CppVtableCloner<T>::init_orig_cpp_vtptr(int kind) {
235
207
// ConstantPool* cp = ....; // an archived constant pool
236
208
// InstanceKlass* ik = ....;// an archived class
237
209
// the following holds true:
238
- // _cloned_cpp_vtptrs [ConstantPool_Kind] == ((intptr_t**)cp)[0]
239
- // _cloned_cpp_vtptrs [InstanceKlass_Kind] == ((intptr_t**)ik)[0]
240
- static intptr_t ** _cloned_cpp_vtptrs = NULL ;
210
+ // _index [ConstantPool_Kind]->cloned_vtable() == ((intptr_t**)cp)[0]
211
+ // _index [InstanceKlass_Kind]->cloned_vtable() == ((intptr_t**)ik)[0]
212
+ CppVtableInfo ** CppVtables::_index = NULL ;
241
213
242
- void CppVtables::allocate_cloned_cpp_vtptrs () {
214
+ char * CppVtables::dumptime_init () {
243
215
assert (DumpSharedSpaces, " must" );
244
- size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof (intptr_t *);
245
- _cloned_cpp_vtptrs = (intptr_t **)mc_region ()->allocate (vtptrs_bytes);
216
+ size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof (CppVtableInfo*);
217
+ _index = (CppVtableInfo**)MetaspaceShared::misc_code_dump_space ()->allocate (vtptrs_bytes);
218
+
219
+ CPP_VTABLE_TYPES_DO (ALLOCATE_AND_INITIALIZE_VTABLE);
220
+
221
+ return (char *)_index;
246
222
}
247
223
248
- void CppVtables::serialize_cloned_cpp_vtptrs (SerializeClosure* soc) {
249
- soc->do_ptr ((void **)&_cloned_cpp_vtptrs);
224
+ void CppVtables::serialize (SerializeClosure* soc) {
225
+ soc->do_ptr ((void **)&_index);
226
+ if (soc->reading ()) {
227
+ CPP_VTABLE_TYPES_DO (INITIALIZE_VTABLE);
228
+ }
250
229
}
251
230
252
- intptr_t * CppVtables::get_archived_cpp_vtable (MetaspaceObj::Type msotype, address obj) {
231
+ intptr_t * CppVtables::get_archived_vtable (MetaspaceObj::Type msotype, address obj) {
253
232
if (!_orig_cpp_vtptrs_inited) {
254
- CPP_VTABLE_PATCH_TYPES_DO (INIT_ORIG_CPP_VTPTRS);
233
+ CPP_VTABLE_TYPES_DO (INIT_ORIG_CPP_VTPTRS);
255
234
_orig_cpp_vtptrs_inited = true ;
256
235
}
257
236
@@ -283,50 +262,27 @@ intptr_t* CppVtables::get_archived_cpp_vtable(MetaspaceObj::Type msotype, addres
283
262
}
284
263
if (kind >= _num_cloned_vtable_kinds) {
285
264
fatal (" Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added"
286
- " a new subtype of Klass or MetaData without updating CPP_VTABLE_PATCH_TYPES_DO " ,
265
+ " a new subtype of Klass or MetaData without updating CPP_VTABLE_TYPES_DO " ,
287
266
p2i (obj));
288
267
}
289
268
}
290
269
291
270
if (kind >= 0 ) {
292
271
assert (kind < _num_cloned_vtable_kinds, " must be" );
293
- return _cloned_cpp_vtptrs [kind];
272
+ return _index [kind]-> cloned_vtable () ;
294
273
} else {
295
274
return NULL ;
296
275
}
297
276
}
298
277
299
- // This can be called at both dump time and run time:
300
- // - clone the contents of the c++ vtables into the space
301
- // allocated by allocate_cpp_vtable_clones()
302
- void CppVtables::clone_cpp_vtables (intptr_t * p) {
303
- assert (DumpSharedSpaces || UseSharedSpaces, " sanity" );
304
- CPP_VTABLE_PATCH_TYPES_DO (CLONE_CPP_VTABLE);
305
- }
306
-
307
- void CppVtables::zero_cpp_vtable_clones_for_writing () {
278
+ void CppVtables::zero_archived_vtables () {
308
279
assert (DumpSharedSpaces, " dump-time only" );
309
- CPP_VTABLE_PATCH_TYPES_DO (ZERO_CPP_VTABLE);
310
- }
311
-
312
- // Allocate and initialize the C++ vtables, starting from top, but do not go past end.
313
- char * CppVtables::allocate_cpp_vtable_clones () {
314
- char * cloned_vtables = mc_region ()->top (); // This is the beginning of all the cloned vtables
315
-
316
- assert (DumpSharedSpaces, " dump-time only" );
317
- // Layout (each slot is a intptr_t):
318
- // [number of slots in the first vtable = n1]
319
- // [ <n1> slots for the first vtable]
320
- // [number of slots in the first second = n2]
321
- // [ <n2> slots for the second vtable]
322
- // ...
323
- // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro.
324
- CPP_VTABLE_PATCH_TYPES_DO (ALLOC_CPP_VTABLE_CLONE);
325
-
326
- return cloned_vtables;
280
+ for (int kind = 0 ; kind < _num_cloned_vtable_kinds; kind ++) {
281
+ _index[kind]->zero ();
282
+ }
327
283
}
328
284
329
285
bool CppVtables::is_valid_shared_method (const Method* m) {
330
286
assert (MetaspaceShared::is_in_shared_metaspace (m), " must be" );
331
- return CppVtableCloner<Method>:: is_valid_shared_object (m );
287
+ return vtable_of (m) == _index[Method_Kind]-> cloned_vtable ( );
332
288
}
0 commit comments