dump.cpp revision 3726
553N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 553N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A// Closure to set up the fingerprint field for all methods. 0N/A// Closure to set the hash value (String.hash field) in all of the 0N/A// String objects in the heap. Setting the hash value is not required. 0N/A// However, setting the value in advance prevents the value from being 0N/A// written later, increasing the likelihood that the shared page contain 0N/A// the hash can be shared. 0N/A// NOTE THAT the algorithm in StringTable::hash_string() MUST MATCH the // Remove data from objects which should not appear in the shared file // (as it pertains only to the current JVM). // Zap data from the objects which is pertains only to this JVM. We // want that data recreated in new JVMs when the shared file is used. // Don't save compiler related special oops (shouldn't be any yet). // Encode a reference to the copy as a negative distance from _start // When a symbol is being copied to a shared space // during CDS archive creation, the original symbol is marked // as relocated by putting a negative value to its _refcount field, // This value is also used to find where exactly the shared copy is // (see MoveSymbols::get_shared_copy), so that the other references // to this symbol could be changed to point to the shared copy. // Mark the symbol in the shared archive as immortal so it is read only // The symbol has not been relocated yet; copy it to _top address // Make the reference point to the shared copy of the symbol // Closure: mark objects closure. // Closure: mark common read-only objects // Mark all constMethod objects. // Exception tables are needed by ci code during compilation. // Mark objects referenced by klass objects which are read-only. // The METHODS() OBJARRAYS CANNOT BE MADE READ-ONLY, even though // it is never modified. Otherwise, they will be pre-marked; the // GC marking phase will skip them; and by skipping them will fail // to mark the methods objects referenced by the array. // Closure: find symbol references in Java Heap objects // Traverse symbols referenced by method objects. // Traverse symbols referenced by klass objects which are read-only. // Traverse symbols referenced by other constantpool entries. // Closure: mark char arrays used by strings // Character arrays referenced by String objects are read-only. // Closure: Check for objects left in the heap which have not been moved. // Closure: Mark remaining objects read-write, except Strings. // The METHODS() OBJARRAYS CANNOT BE MADE READ-ONLY, even though // it is never modified. Otherwise, they will be pre-marked; the // GC marking phase will skip them; and by skipping them will fail // to mark the methods objects referenced by the array. // Mark constantPool tags and the constantPoolCache. // Mark all method objects. // Closure: Mark String objects read-write. // Mark String objects referenced by constant pool entries. // Move objects matching specified type (ie. lock_bits) to the specified // Readonly objects: set hash value to self pointer and make gc_marked. // Although Java mirrors are marked in MarkReadWriteObjects, // apparently they were never moved into shared spaces since // MoveMarkedObjects skips marked instance oops. This may // be a bug in the original implementation or simply the vestige // of an abandoned experiment. Nevertheless we leave a hint // here in case this capability is ever correctly implemented. // mark_and_move_for_policy(OP_favor_runtime, ik->java_mirror(), _move_rw); // Adjust references in oops to refer to shared spaces. // The methods array must be reordered by Symbol* address. // sorted). The addresses of symbols have been changed as a result // of moving to the shared space. true /* idempotent, slow */);
// Vtable and Itable indices are calculated based on methods array // order (see klassItable::compute_itable_index()). Must reinitialize // after ALL methods of ALL classes have been reordered. // We assume that since checkconstraints is false, this method // cannot throw an exception. An exception here would be // problematic since this is the VMThread, not a JavaThread. // Initialize super vtable first, check if already initialized to avoid // quadradic behavior. The vtable is cleared in remove_unshareable_info. // The vtable for array klasses are that of its super class, // Adjust references in oops to refer to shared spaces. // If the object is a Java object or class which might (in the // future) contain a reference to a young gen object, add it to the // someone added an object we hadn't accounted for. // Empty the young and old generations. // Closure for serializing initialization data out to a data area to be // written to the shared file. "Oop in shared space not pointing into shared space.");
bool reading()
const {
return false; }
// Print a summary of the contents of the read/write spaces to help // identify objects which might be able to be made read-only. At this // point, the objects have been written, and we can trash them as // High level summary of the read-only space: // High level summary of the read-write space: // Lower level summary of the read-only space: // Lower level summary of the read-write space: // Patch C++ vtable pointer in klass oops. // Klass objects contain references to c++ vtables in the JVM library. // Fix them to point to our constructed vtables. However, don't iterate // across the space while doing this, as that causes the vtables to be // patched, undoing our useful work. Instead, iterate to make a list, // then use the list to do the fixing. // Our constructed vtables: // 1. init_self_patching_vtbl_list: table of pointers to current virtual method addrs // 2. generate_vtable_methods: create jump table, appended to above vtbl_list // 3. PatchKlassVtables: for Klass list, patch the vtable entry to point to jump table // rather than to current vtbl // Table layout: NOTE FIXED SIZE // 2. #Klass X #virtual methods per Klass // 1 entry for each, in the order: // Klass1:method1 entry, Klass1:method2 entry, ... Klass1:method<num_virtuals> entry // Klass2:method1 entry, Klass2:method2 entry, ... Klass2:method<num_virtuals> entry // Klass<vtbl_list_size>:method1 entry, Klass<vtbl_list_size>:method2 entry, // ... Klass<vtbl_list_size>:method<num_virtuals> entry // Sample entry: (Sparc): // mov XXX, %L0 %L0 gets: Klass index <<8 + method index (note: max method index 255) // 1. initialize_oops: reserve space for table // 2. init_self_patching_vtbl_list: update pointers to NEW virtual method addrs in text // First virtual method call for any object of these Klass types: // 1. object->klass->klass_part // 2. vtable entry for that klass_part points to the jump table entries // 3. branches to common_code with %O0/klass_part, %L0: Klass index <<8 + method index // Get address of new vtbl pointer for this Klass from updated table // Update new vtbl pointer in the Klass: future virtual calls go direct // Jump to method, using new vtbl pointer and method index for (
int i = 0; i < n; i++) {
// Walk through all symbols and patch their vtable pointers. // Note that symbols have vtable pointers only in non-product builds // Populate the shared space. // The following guarantee is meant to ensure that no loader constraints // exist yet, since the constraints table is not shared. This becomes // shared classes at runtime, where constraints were previously created. "loader constraints are not saved");
// Revisit and implement this if we prelink method handle call sites: "invoke method table is not saved");
// At this point, many classes have been loaded. // Update all the fingerprints in the shared methods. tty->
print(
"Calculating fingerprints ... ");
// Remove all references outside the heap. tty->
print(
"Removing unshareable information ... ");
// Move the objects in three passes. // The SharedOptimizeColdStart VM option governs the new layout // algorithm for promoting classes into the shared archive. // The general idea is to minimize cold start time by laying // out the objects in the order they are accessed at startup time. // By doing this we are trying to eliminate out-of-order accesses // in the shared archive. This benefits cold startup time by making // disk reads as sequential as possible during class loading and // bootstrapping activities. There may also be a small secondary // effect of better "packing" of more commonly used data on a smaller // number of pages, although no direct benefit has been measured from // At the class level of granularity, the promotion order is dictated // by the classlist file whose generation is discussed elsewhere. // At smaller granularity, optimal ordering was determined by an // offline analysis of object access order in the shared archive. // The dbx watchpoint facility, combined with SA post-processing, // was used to observe common access patterns primarily during // classloading. This information was used to craft the promotion // order seen in the following closures. // The observed access order is mostly governed by what happens // in SystemDictionary::load_shared_class(). NOTE WELL - care // should be taken when making changes to this method, because it // may invalidate assumptions made about access order! // (Ideally, there would be a better way to manage changes to // the access order. Unfortunately a generic in-VM solution for // dynamically observing access order and optimizing shared // archive layout is pretty difficult. We go with the static // analysis because the code is fairly mature at this point // and we're betting that the access order won't change much.) // Set up the share data and shared code segments. // Reserve space for the list of klassOops whose vtables are used // for patching others as needed. // Reserve space for a new dummy vtable for klass objects in the // heap. Generate self-patching vtable entries. // Reserve space for the total size and the number of stored symbols. // Phase 1a: remove symbols with _refcount == 0 // Phase 1b: move commonly used symbols referenced by oop fields. // Phase 1c: move known names and signatures. // Phase 1d: move the remaining symbols by scanning the whole SymbolTable. // Record the total length of all symbols at the beginning of the block. // Advance the pointer to the end of symbol store. // Phase 2: move commonly used read-only objects to the read-only space. // Phase 3: move String character arrays to the read-only space. // Phase 4: move read-write objects to the read-write space, except tty->
print(
"Moving pre-ordered read-write objects to shared space at " PTR_FORMAT " ... ",
// Phase 5: move String objects to the read-write space. // Check: scan for objects which were not moved. // Resolve forwarding in objects and saved C++ structures tty->
print(
"Updating references to shared objects ... ");
// Fix (forward) all of the references in these shared objects (which // are required to point ONLY to objects in the shared spaces). // Also, create a list of all objects which might later contain a // reference to a younger generation object. // Previously method sorting was done concurrently with forwarding // pointer resolution in the shared spaces. This imposed an ordering // before their holder classes. (Because constant pool pointers in // methodKlasses are required to be resolved before their holder class // is visited for sorting, otherwise methods are sorted by incorrect, // pre-forwarding addresses.) // Now, we reorder methods as a separate step after ALL forwarding // pointer resolution, so that methods can be promoted in any order // with respect to their holder classes. // Reorder the system dictionary. (Moving the symbols opps affects // how the hash table indices are calculated.) // Empty the non-shared heap (because most of the objects were // copied out, and the remainder cannot be considered valid oops). // Copy the String table, the symbol table, and the system // dictionary to the shared space in usable form. Copy the hastable // buckets first [read-write], then copy the linked lists of entries // Write the oop data to the output array. // Update the vtable pointers in all of the Klass objects in the // heap. They should point to newly generated vtable. // Update the vtable pointers in all symbols, // but only in non-product builds where symbols DO have virtual methods. // Create and write the archive file that maps the shared spaces. // Pass 1 - update file offsets in header. };
// class VM_PopulateDumpSharedSpace// Populate the shared spaces and dump to a file. // Calculate hash values for all of the (interned) strings to avoid // writes to shared pages in the future. tty->
print(
"Calculating hash values for String objects .. ");
// Link the class to cause the bytecodes to be rewritten and the // cpcache to be created. // Create String objects from string initializer symbols. // Support for a simple checksum of the contents of the class list // file to prevent trivial tampering. The algorithm matches that in // the MakeClassList program used by the J2SE build process. char *p = (
char *)
buf, *e = p +
len;
/* Skip spaces and control characters */ // Preload classes from a list, populate the shared spaces and dump to a // Preload classes to be shared. // Should use some os:: method rather than fopen() here. aB. // Construct the path to the class list (in jre/lib) // Walk up two directories from the location of the VM and // optionally tack on "lib" (depending on platform) for (
int i = 0; i <
3; i++) {
// Preload (and intern) strings which will be used later. tty->
print(
"Loading classes to share ... ");
// Remove trailing newline // Got a class name - load it. // Should be class load order as per -XX:+TraceClassLoadingPreorder // Link the class to cause the bytecodes to be rewritten and the // cpcache to be created. The linking is done as soon as classes // are loaded in order that the related data structures (klass, // cpCache, Sting constants) are located together. // Create String objects from string initializer symbols. file_jsum = 0;
// Checksum must be on last line of file tty->
print_cr(
"Preload failed: checksum of class list was incorrect.");
// Rewrite and unlink classes. tty->
print(
"Rewriting and unlinking classes ... ");
// Link any classes which got missed. (It's not quite clear why // they got missed.) This iteration would be unsafe if we weren't // single-threaded at this point; however we can't do it on the VM // thread because it requires object allocation. // Create and dump the shared spaces. fatal(
"Dumping shared spaces failed.");
// Since various initialization steps have been undone by this process, // it is not reasonable to continue running a java process.