< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page




  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/symbolTable.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "logging/log.hpp"
  30 #include "logging/logMessage.hpp"
  31 #include "logging/logStream.hpp"
  32 #include "memory/heapShared.hpp"
  33 #include "memory/iterator.inline.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/metaspaceClosure.hpp"
  36 #include "memory/metaspaceShared.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "oops/compressedOops.inline.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "runtime/fieldDescriptor.inline.hpp"

  41 
  42 #if INCLUDE_CDS_JAVA_HEAP
  43 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
  44 int HeapShared::_num_archived_subgraph_info_records = 0;
  45 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
  46 
  47 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
  48 // sub-graphs.
  49 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
  50   KlassSubGraphInfo* info = _subgraph_info_list;
  51   while (info != NULL) {
  52     if (info->klass() == k) {
  53       return info;
  54     }
  55     info = info->next();
  56   }
  57   return NULL;
  58 }
  59 
  60 // Get the subgraph_info for Klass k. A new subgraph_info is created if
  61 // there is no existing one for k. The subgraph_info records the relocated
  62 // Klass* of the original k.
  63 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
  64   Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
  65   KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
  66   if (info != NULL) {
  67     return info;
  68   }
  69 
  70   info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
  71   _subgraph_info_list = info;
  72   return info;
  73 }
  74 



  75 int HeapShared::num_of_subgraph_infos() {
  76   int num = 0;
  77   KlassSubGraphInfo* info = _subgraph_info_list;
  78   while (info != NULL) {
  79     num ++;
  80     info = info->next();
  81   }
  82   return num;
  83 }
  84 
  85 // Add an entry field to the current KlassSubGraphInfo.
  86 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
  87   assert(DumpSharedSpaces, "dump time only");
  88   if (_subgraph_entry_fields == NULL) {
  89     _subgraph_entry_fields =
  90       new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
  91   }
  92   _subgraph_entry_fields->append((juint)static_field_offset);
  93   _subgraph_entry_fields->append(CompressedOops::encode(v));
  94 }


 303         CLEAR_PENDING_EXCEPTION;
 304         // None of the field value will be set if there was an exception.
 305         // The java code will not see any of the archived objects in the
 306         // subgraphs referenced from k in this case.
 307         return;
 308       }
 309 
 310       // Load the subgraph entry fields from the record and store them back to
 311       // the corresponding fields within the mirror.
 312       oop m = k->java_mirror();
 313       Array<juint>* entry_field_records = record->entry_field_records();
 314       if (entry_field_records != NULL) {
 315         int efr_len = entry_field_records->length();
 316         assert(efr_len % 2 == 0, "sanity");
 317         for (i = 0; i < efr_len;) {
 318           int field_offset = entry_field_records->at(i);
 319           // The object refereced by the field becomes 'known' by GC from this
 320           // point. All objects in the subgraph reachable from the object are
 321           // also 'known' by GC.
 322           oop v = MetaspaceShared::materialize_archived_object(
 323             CompressedOops::decode(entry_field_records->at(i+1)));
 324           m->obj_field_put(field_offset, v);
 325           i += 2;
 326         }
 327       }
 328 
 329       // Done. Java code can see the archived sub-graphs referenced from k's
 330       // mirror after this point.
 331       return;
 332     }
 333   }
 334 }
 335 
 336 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
 337   int _level;
 338   KlassSubGraphInfo* _subgraph_info;
 339   oop _orig_referencing_obj;
 340   oop _archived_referencing_obj;
 341  public:
 342   WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
 343            oop orig, oop archived) : _level(level),


 584     Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
 585     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
 586     InstanceKlass* ik = InstanceKlass::cast(k);
 587 
 588     ArchivableStaticFieldFinder finder(ik, field_name);
 589     ik->do_local_static_fields(&finder);
 590     assert(finder.found(), "field must exist");
 591 
 592     info->klass = ik;
 593     info->offset = finder.offset();
 594     info->type = finder.type();
 595   }
 596 }
 597 
 598 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
 599   for (int i = 0; i < num_archivable_static_fields; i++) {
 600     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
 601     archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
 602   }
 603 }




























































































 604 #endif // INCLUDE_CDS_JAVA_HEAP


  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/symbolTable.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "logging/log.hpp"
  30 #include "logging/logMessage.hpp"
  31 #include "logging/logStream.hpp"
  32 #include "memory/heapShared.inline.hpp"
  33 #include "memory/iterator.inline.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/metaspaceClosure.hpp"
  36 #include "memory/metaspaceShared.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "oops/compressedOops.inline.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "runtime/fieldDescriptor.inline.hpp"
  41 #include "utilities/bitMap.inline.hpp"
  42 
  43 #if INCLUDE_CDS_JAVA_HEAP
  44 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
  45 int HeapShared::_num_archived_subgraph_info_records = 0;
  46 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
  47 
  48 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
  49 // sub-graphs.
  50 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
  51   KlassSubGraphInfo* info = _subgraph_info_list;
  52   while (info != NULL) {
  53     if (info->klass() == k) {
  54       return info;
  55     }
  56     info = info->next();
  57   }
  58   return NULL;
  59 }
  60 
  61 // Get the subgraph_info for Klass k. A new subgraph_info is created if
  62 // there is no existing one for k. The subgraph_info records the relocated
  63 // Klass* of the original k.
  64 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
  65   Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
  66   KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
  67   if (info != NULL) {
  68     return info;
  69   }
  70 
  71   info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
  72   _subgraph_info_list = info;
  73   return info;
  74 }
  75 
  76 address   HeapShared::_narrow_oop_base;
  77 int       HeapShared::_narrow_oop_shift;
  78 
  79 int HeapShared::num_of_subgraph_infos() {
  80   int num = 0;
  81   KlassSubGraphInfo* info = _subgraph_info_list;
  82   while (info != NULL) {
  83     num ++;
  84     info = info->next();
  85   }
  86   return num;
  87 }
  88 
  89 // Add an entry field to the current KlassSubGraphInfo.
  90 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
  91   assert(DumpSharedSpaces, "dump time only");
  92   if (_subgraph_entry_fields == NULL) {
  93     _subgraph_entry_fields =
  94       new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
  95   }
  96   _subgraph_entry_fields->append((juint)static_field_offset);
  97   _subgraph_entry_fields->append(CompressedOops::encode(v));
  98 }


 307         CLEAR_PENDING_EXCEPTION;
 308         // None of the field value will be set if there was an exception.
 309         // The java code will not see any of the archived objects in the
 310         // subgraphs referenced from k in this case.
 311         return;
 312       }
 313 
 314       // Load the subgraph entry fields from the record and store them back to
 315       // the corresponding fields within the mirror.
 316       oop m = k->java_mirror();
 317       Array<juint>* entry_field_records = record->entry_field_records();
 318       if (entry_field_records != NULL) {
 319         int efr_len = entry_field_records->length();
 320         assert(efr_len % 2 == 0, "sanity");
 321         for (i = 0; i < efr_len;) {
 322           int field_offset = entry_field_records->at(i);
 323           // The object refereced by the field becomes 'known' by GC from this
 324           // point. All objects in the subgraph reachable from the object are
 325           // also 'known' by GC.
 326           oop v = MetaspaceShared::materialize_archived_object(
 327             entry_field_records->at(i+1));
 328           m->obj_field_put(field_offset, v);
 329           i += 2;
 330         }
 331       }
 332 
 333       // Done. Java code can see the archived sub-graphs referenced from k's
 334       // mirror after this point.
 335       return;
 336     }
 337   }
 338 }
 339 
 340 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
 341   int _level;
 342   KlassSubGraphInfo* _subgraph_info;
 343   oop _orig_referencing_obj;
 344   oop _archived_referencing_obj;
 345  public:
 346   WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
 347            oop orig, oop archived) : _level(level),


 588     Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
 589     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
 590     InstanceKlass* ik = InstanceKlass::cast(k);
 591 
 592     ArchivableStaticFieldFinder finder(ik, field_name);
 593     ik->do_local_static_fields(&finder);
 594     assert(finder.found(), "field must exist");
 595 
 596     info->klass = ik;
 597     info->offset = finder.offset();
 598     info->type = finder.type();
 599   }
 600 }
 601 
 602 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
 603   for (int i = 0; i < num_archivable_static_fields; i++) {
 604     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
 605     archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
 606   }
 607 }
 608 
 609 // At dump-time, find the location of all the non-null oop pointers in an archived heap
 610 // region. This way we can quickly relocate all the pointers without using
 611 // BasicOopIterateClosure at runtime.
 612 class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
 613   narrowOop* _start;
 614   BitMap *_oopmap;
 615   int _num_total_oops;
 616   int _num_null_oops;
 617  public:
 618   FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap)
 619     : _start(start), _oopmap(oopmap), _num_total_oops(0),  _num_null_oops(0) {}
 620 
 621   virtual bool should_verify_oops(void) {
 622     return false;
 623   }
 624   virtual void do_oop(narrowOop* p) {
 625     _num_total_oops ++;
 626     narrowOop v = *p;
 627     if (!CompressedOops::is_null(v)) {
 628       size_t idx = p - _start;
 629       _oopmap->set_bit(idx);
 630     } else {
 631       _num_null_oops ++;
 632     }
 633   }
 634   virtual void do_oop(oop *p) {
 635     ShouldNotReachHere();
 636   }
 637   int num_total_oops() const { return _num_total_oops; }
 638   int num_null_oops()  const { return _num_null_oops; }
 639 };
 640 
 641 ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
 642   assert(UseCompressedOops, "must be");
 643   size_t num_bits = region.byte_size() / sizeof(narrowOop);
 644   ResourceBitMap oopmap(num_bits);
 645 
 646   HeapWord* p   = region.start();
 647   HeapWord* end = region.end();
 648   FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap);
 649 
 650   int num_objs = 0;
 651   while (p < end) {
 652     oop o = (oop)p;
 653     o->oop_iterate(&finder);
 654     p += o->size();
 655     ++ num_objs;
 656   }
 657 
 658   log_info(cds, heap)("calculate_oopmap: objects = %6d, embedded oops = %7d, nulls = %7d",
 659                       num_objs, finder.num_total_oops(), finder.num_null_oops());
 660   return oopmap;
 661 }
 662 
 663 void HeapShared::init_narrow_oop_decoding(address base, int shift) {
 664   _narrow_oop_base = base;
 665   _narrow_oop_shift = shift;
 666 }
 667 
 668 // Patch all the embedded oop pointers inside an archived heap region,
 669 // to be consistent with the runtime oop encoding.
 670 class PatchEmbeddedPointers: public BitMapClosure {
 671   narrowOop* _start;
 672 
 673  public:
 674   PatchEmbeddedPointers(narrowOop* start) : _start(start) {}
 675 
 676   bool do_bit(size_t offset) {
 677     narrowOop* p = _start + offset;
 678     narrowOop v = *p;
 679     assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time");
 680     oop o = HeapShared::decode_with_archived_oop_encoding_mode(v);
 681     RawAccess<IS_NOT_NULL>::oop_store(p, o);
 682     return true;
 683   }
 684 };
 685 
 686 void HeapShared::patch_archived_heap_embedded_pointers(MemRegion region, address oopmap,
 687                                                        size_t oopmap_size_in_bits) {
 688   BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits);
 689 
 690 #ifndef PRODUCT
 691   ResourceMark rm;
 692   ResourceBitMap checkBm = calculate_oopmap(region);
 693   assert(bm.is_same(checkBm), "sanity");
 694 #endif
 695 
 696   PatchEmbeddedPointers patcher((narrowOop*)region.start());
 697   bm.iterate(&patcher);
 698 }
 699 
 700 #endif // INCLUDE_CDS_JAVA_HEAP
< prev index next >