Mercurial > hg > graal-jvmci-8
comparison src/share/vm/oops/klassVtable.cpp @ 23905:cb4af293fe70 jdk8u101-b07
8153312: Constrain AppCDS behavior
Reviewed-by: iklam, acorn, mschoene
author | jiangli |
---|---|
date | Wed, 27 Apr 2016 14:41:55 -0400 |
parents | 8cd2e2834c8f |
children | f13e777eb255 |
comparison
equal
deleted
inserted
replaced
23902:432c2a4b018e | 23905:cb4af293fe70 |
---|---|
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | 26 #include "classfile/systemDictionary.hpp" |
27 #include "classfile/vmSymbols.hpp" | 27 #include "classfile/vmSymbols.hpp" |
28 #include "gc_implementation/shared/markSweep.inline.hpp" | 28 #include "gc_implementation/shared/markSweep.inline.hpp" |
29 #include "memory/gcLocker.hpp" | 29 #include "memory/gcLocker.hpp" |
30 #include "memory/metaspaceShared.hpp" | |
30 #include "memory/resourceArea.hpp" | 31 #include "memory/resourceArea.hpp" |
31 #include "memory/universe.inline.hpp" | 32 #include "memory/universe.inline.hpp" |
32 #include "oops/instanceKlass.hpp" | 33 #include "oops/instanceKlass.hpp" |
33 #include "oops/klassVtable.hpp" | 34 #include "oops/klassVtable.hpp" |
34 #include "oops/method.hpp" | 35 #include "oops/method.hpp" |
43 | 44 |
44 inline InstanceKlass* klassVtable::ik() const { | 45 inline InstanceKlass* klassVtable::ik() const { |
45 Klass* k = _klass(); | 46 Klass* k = _klass(); |
46 assert(k->oop_is_instance(), "not an InstanceKlass"); | 47 assert(k->oop_is_instance(), "not an InstanceKlass"); |
47 return (InstanceKlass*)k; | 48 return (InstanceKlass*)k; |
49 } | |
50 | |
51 bool klassVtable::is_preinitialized_vtable() { | |
52 return _klass->is_shared() && !MetaspaceShared::remapped_readwrite(); | |
48 } | 53 } |
49 | 54 |
50 | 55 |
51 // this function computes the vtable size (including the size needed for miranda | 56 // this function computes the vtable size (including the size needed for miranda |
52 // methods) and the number of miranda methods in this class. | 57 // methods) and the number of miranda methods in this class. |
126 // and return the number of entries copied. Expects that 'super' is the Java | 131 // and return the number of entries copied. Expects that 'super' is the Java |
127 // super class (arrays can have "array" super classes that must be skipped). | 132 // super class (arrays can have "array" super classes that must be skipped). |
128 int klassVtable::initialize_from_super(KlassHandle super) { | 133 int klassVtable::initialize_from_super(KlassHandle super) { |
129 if (super.is_null()) { | 134 if (super.is_null()) { |
130 return 0; | 135 return 0; |
136 } else if (is_preinitialized_vtable()) { | |
137 // A shared class' vtable is preinitialized at dump time. No need to copy | |
138 // methods from super class for shared class, as that was already done | |
139 // during archiving time. However, if Jvmti has redefined a class, | |
140 // copy super class's vtable in case the super class has changed. | |
141 return super->vtable()->length(); | |
131 } else { | 142 } else { |
132 // copy methods from superKlass | 143 // copy methods from superKlass |
133 // can't inherit from array class, so must be InstanceKlass | 144 // can't inherit from array class, so must be InstanceKlass |
134 assert(super->oop_is_instance(), "must be instance klass"); | 145 assert(super->oop_is_instance(), "must be instance klass"); |
135 InstanceKlass* sk = (InstanceKlass*)super(); | 146 InstanceKlass* sk = (InstanceKlass*)super(); |
155 | 166 |
156 // Note: Arrays can have intermediate array supers. Use java_super to skip them. | 167 // Note: Arrays can have intermediate array supers. Use java_super to skip them. |
157 KlassHandle super (THREAD, klass()->java_super()); | 168 KlassHandle super (THREAD, klass()->java_super()); |
158 int nofNewEntries = 0; | 169 int nofNewEntries = 0; |
159 | 170 |
171 bool is_shared = _klass->is_shared(); | |
172 | |
160 if (PrintVtables && !klass()->oop_is_array()) { | 173 if (PrintVtables && !klass()->oop_is_array()) { |
161 ResourceMark rm(THREAD); | 174 ResourceMark rm(THREAD); |
162 tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); | 175 tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); |
163 } | 176 } |
164 | 177 |
167 oop* end_of_vtable = (oop*)&table()[_length]; | 180 oop* end_of_vtable = (oop*)&table()[_length]; |
168 assert(end_of_vtable <= end_of_obj, "vtable extends beyond end"); | 181 assert(end_of_vtable <= end_of_obj, "vtable extends beyond end"); |
169 #endif | 182 #endif |
170 | 183 |
171 if (Universe::is_bootstrapping()) { | 184 if (Universe::is_bootstrapping()) { |
185 assert(!is_shared, "sanity"); | |
172 // just clear everything | 186 // just clear everything |
173 for (int i = 0; i < _length; i++) table()[i].clear(); | 187 for (int i = 0; i < _length; i++) table()[i].clear(); |
174 return; | 188 return; |
175 } | 189 } |
176 | 190 |
206 if (default_methods != NULL) { | 220 if (default_methods != NULL) { |
207 len = default_methods->length(); | 221 len = default_methods->length(); |
208 if (len > 0) { | 222 if (len > 0) { |
209 Array<int>* def_vtable_indices = NULL; | 223 Array<int>* def_vtable_indices = NULL; |
210 if ((def_vtable_indices = ik()->default_vtable_indices()) == NULL) { | 224 if ((def_vtable_indices = ik()->default_vtable_indices()) == NULL) { |
225 assert(!is_shared, "shared class def_vtable_indices does not exist"); | |
211 def_vtable_indices = ik()->create_new_default_vtable_indices(len, CHECK); | 226 def_vtable_indices = ik()->create_new_default_vtable_indices(len, CHECK); |
212 } else { | 227 } else { |
213 assert(def_vtable_indices->length() == len, "reinit vtable len?"); | 228 assert(def_vtable_indices->length() == len, "reinit vtable len?"); |
214 } | 229 } |
215 for (int i = 0; i < len; i++) { | 230 for (int i = 0; i < len; i++) { |
220 bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, i, checkconstraints, CHECK); | 235 bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, i, checkconstraints, CHECK); |
221 | 236 |
222 // needs new entry | 237 // needs new entry |
223 if (needs_new_entry) { | 238 if (needs_new_entry) { |
224 put_method_at(mh(), initialized); | 239 put_method_at(mh(), initialized); |
225 def_vtable_indices->at_put(i, initialized); //set vtable index | 240 if (is_preinitialized_vtable()) { |
241 // At runtime initialize_vtable is rerun for a shared class | |
242 // (loaded by the non-boot loader) as part of link_class_impl(). | |
243 // The dumptime vtable index should be the same as the runtime index. | |
244 assert(def_vtable_indices->at(i) == initialized, | |
245 "dump time vtable index is different from runtime index"); | |
246 } else { | |
247 def_vtable_indices->at_put(i, initialized); //set vtable index | |
248 } | |
226 initialized++; | 249 initialized++; |
227 } | 250 } |
228 } | 251 } |
229 } | 252 } |
230 } | 253 } |
363 target_method()->set_vtable_index(Method::pending_itable_index); | 386 target_method()->set_vtable_index(Method::pending_itable_index); |
364 } | 387 } |
365 } | 388 } |
366 | 389 |
367 // we need a new entry if there is no superclass | 390 // we need a new entry if there is no superclass |
368 if (klass->super() == NULL) { | 391 Klass* super = klass->super(); |
392 if (super == NULL) { | |
369 return allocate_new; | 393 return allocate_new; |
370 } | 394 } |
371 | 395 |
372 // private methods in classes always have a new entry in the vtable | 396 // private methods in classes always have a new entry in the vtable |
373 // specification interpretation since classic has | 397 // specification interpretation since classic has |
392 | 416 |
393 Handle target_loader(THREAD, target_klass->class_loader()); | 417 Handle target_loader(THREAD, target_klass->class_loader()); |
394 | 418 |
395 Symbol* target_classname = target_klass->name(); | 419 Symbol* target_classname = target_klass->name(); |
396 for(int i = 0; i < super_vtable_len; i++) { | 420 for(int i = 0; i < super_vtable_len; i++) { |
397 Method* super_method = method_at(i); | 421 Method* super_method; |
422 if (is_preinitialized_vtable()) { | |
423 // If this is a shared class, the vtable is already in the final state (fully | |
424 // initialized). Need to look at the super's vtable. | |
425 klassVtable* superVtable = super->vtable(); | |
426 super_method = superVtable->method_at(i); | |
427 } else { | |
428 super_method = method_at(i); | |
429 } | |
398 // Check if method name matches | 430 // Check if method name matches |
399 if (super_method->name() == name && super_method->signature() == signature) { | 431 if (super_method->name() == name && super_method->signature() == signature) { |
400 | 432 |
401 // get super_klass for method_holder for the found method | 433 // get super_klass for method_holder for the found method |
402 InstanceKlass* super_klass = super_method->method_holder(); | 434 InstanceKlass* super_klass = super_method->method_holder(); |
456 put_method_at(target_method(), i); | 488 put_method_at(target_method(), i); |
457 if (!is_default) { | 489 if (!is_default) { |
458 target_method()->set_vtable_index(i); | 490 target_method()->set_vtable_index(i); |
459 } else { | 491 } else { |
460 if (def_vtable_indices != NULL) { | 492 if (def_vtable_indices != NULL) { |
461 def_vtable_indices->at_put(default_index, i); | 493 if (is_preinitialized_vtable()) { |
494 // At runtime initialize_vtable is rerun as part of link_class_impl() | |
495 // for a shared class loaded by the non-boot loader. | |
496 // The dumptime vtable index should be the same as the runtime index. | |
497 assert(def_vtable_indices->at(default_index) == i, | |
498 "dump time vtable index is different from runtime index"); | |
499 } else { | |
500 def_vtable_indices->at_put(default_index, i); | |
501 } | |
462 } | 502 } |
463 assert(super_method->is_default_method() || super_method->is_overpass() | 503 assert(super_method->is_default_method() || super_method->is_overpass() |
464 || super_method->is_abstract(), "default override error"); | 504 || super_method->is_abstract(), "default override error"); |
465 } | 505 } |
466 | 506 |
521 } | 561 } |
522 return allocate_new; | 562 return allocate_new; |
523 } | 563 } |
524 | 564 |
525 void klassVtable::put_method_at(Method* m, int index) { | 565 void klassVtable::put_method_at(Method* m, int index) { |
566 if (is_preinitialized_vtable()) { | |
567 // At runtime initialize_vtable is rerun as part of link_class_impl() | |
568 // for shared class loaded by the non-boot loader to obtain the loader | |
569 // constraints based on the runtime classloaders' context. The dumptime | |
570 // method at the vtable index should be the same as the runtime method. | |
571 assert(table()[index].method() == m, | |
572 "archived method is different from the runtime method"); | |
573 } else { | |
526 #ifndef PRODUCT | 574 #ifndef PRODUCT |
527 if (PrintVtables && Verbose) { | 575 if (PrintVtables && Verbose) { |
528 ResourceMark rm; | 576 ResourceMark rm; |
529 const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; | 577 const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
530 tty->print("adding %s at index %d, flags: ", sig, index); | 578 tty->print("adding %s at index %d, flags: ", sig, index); |
531 if (m != NULL) { | 579 if (m != NULL) { |
532 m->access_flags().print_on(tty); | 580 m->access_flags().print_on(tty); |
533 if (m->is_default_method()) { | 581 if (m->is_default_method()) { |
534 tty->print("default "); | 582 tty->print("default "); |
535 } | 583 } |
536 if (m->is_overpass()) { | 584 if (m->is_overpass()) { |
537 tty->print("overpass"); | 585 tty->print("overpass"); |
538 } | 586 } |
539 } | 587 } |
540 tty->cr(); | 588 tty->cr(); |
541 } | 589 } |
542 #endif | 590 #endif |
543 table()[index].set(m); | 591 table()[index].set(m); |
592 } | |
544 } | 593 } |
545 | 594 |
546 // Find out if a method "m" with superclass "super", loader "classloader" and | 595 // Find out if a method "m" with superclass "super", loader "classloader" and |
547 // name "classname" needs a new vtable entry. Let P be a class package defined | 596 // name "classname" needs a new vtable entry. Let P be a class package defined |
548 // by "classloader" and "classname". | 597 // by "classloader" and "classname". |
969 | 1018 |
970 // Initialize a itableMethodEntry | 1019 // Initialize a itableMethodEntry |
971 void itableMethodEntry::initialize(Method* m) { | 1020 void itableMethodEntry::initialize(Method* m) { |
972 if (m == NULL) return; | 1021 if (m == NULL) return; |
973 | 1022 |
974 _method = m; | 1023 if (MetaspaceShared::is_in_shared_space((void*)&_method) && |
1024 !MetaspaceShared::remapped_readwrite()) { | |
1025 // At runtime initialize_itable is rerun as part of link_class_impl() | |
1026 // for a shared class loaded by the non-boot loader. | |
1027 // The dumptime itable method entry should be the same as the runtime entry. | |
1028 assert(_method == m, "sanity"); | |
1029 } else { | |
1030 _method = m; | |
1031 } | |
975 } | 1032 } |
976 | 1033 |
977 klassItable::klassItable(instanceKlassHandle klass) { | 1034 klassItable::klassItable(instanceKlassHandle klass) { |
978 _klass = klass; | 1035 _klass = klass; |
979 | 1036 |
1079 } | 1136 } |
1080 } | 1137 } |
1081 tty->cr(); | 1138 tty->cr(); |
1082 } | 1139 } |
1083 if (!m->has_vtable_index()) { | 1140 if (!m->has_vtable_index()) { |
1084 assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); | 1141 // A shared method could have an initialized itable_index that |
1142 // is < 0. | |
1143 assert(m->vtable_index() == Method::pending_itable_index || | |
1144 m->is_shared(), | |
1145 "set by initialize_vtable"); | |
1085 m->set_itable_index(ime_num); | 1146 m->set_itable_index(ime_num); |
1086 // Progress to next itable entry | 1147 // Progress to next itable entry |
1087 ime_num++; | 1148 ime_num++; |
1088 } | 1149 } |
1089 } | 1150 } |
1275 ime++; | 1336 ime++; |
1276 } | 1337 } |
1277 } | 1338 } |
1278 #endif // INCLUDE_JVMTI | 1339 #endif // INCLUDE_JVMTI |
1279 | 1340 |
1280 | |
1281 // Setup | 1341 // Setup |
1282 class InterfaceVisiterClosure : public StackObj { | 1342 class InterfaceVisiterClosure : public StackObj { |
1283 public: | 1343 public: |
1284 virtual void doit(Klass* intf, int method_count) = 0; | 1344 virtual void doit(Klass* intf, int method_count) = 0; |
1285 }; | 1345 }; |