RFR: 8179302: Pre-resolve constant pool string entries and cache resolved_reference arrays in CDS archive

Ioi Lam ioi.lam at oracle.com
Tue Aug 8 00:45:09 UTC 2017


On 8/4/17 10:19 PM, Jiangli Zhou wrote:

> Hi Ioi,
>
> Thanks for looking again.
>
>> On Aug 4, 2017, at 2:22 PM, Ioi Lam <ioi.lam at oracle.com 
>> <mailto:ioi.lam at oracle.com>> wrote:
>>
>> Hi Jiangli,
>>
>> The code looks good in general. I just have a few pet peeves for 
>> readability:
>>
>>
>> (1) stringTable.cpp and metaspaceShared.cpp have the same asserts
>>
>>  704   assert(UseG1GC, "Only support G1 GC");
>>  705   assert(UseCompressedOops && UseCompressedClassPointers,
>>  706          "Only support UseCompressedOops and 
>> UseCompressedClassPointers enabled");
>>
>> 1615   assert(UseG1GC, "Only support G1 GC");
>> 1616   assert(UseCompressedOops && UseCompressedClassPointers,
>> 1617          "Only support UseCompressedOops and 
>> UseCompressedClassPointers enabled");
>>
>> Maybe it's better to combine them into a single function like 
>> MetaspaceShared::assert_vm_flags() so they don't get out of sync?
>
> There is a MetaspaceShared::allow_archive_heap_object(), which checks 
> for UseG1GC, UseCompressedOops and UseCompressedClassPointers 
> combined. It does not seem to worth add another separate API for 
> asserting the required flags. I’ll use that in the assert.
>
>>
>>
>>
>> (2) FileMapInfo::write_archive_heap_regions()
>>
>> I still find this code very hard to read, especially due to the loop.
>>
>> First, the comments are not consistent with the code:
>>
>>     498   assert(arr_len <= max_num_regions, "number of memory 
>> regions exceeds maximum");
>>
>> but the comments says: "The rest are consecutive full GC regions" 
>> which means there's a chance for max_num_regions to be more than 2 
>> (which will be the case with Calvin's java-loader dumping changes 
>> using very small heap size).So the code is actually wrong.
>
> The max_num_regions is the maximum number of region for each archived 
> heap space (the string space, or open archive space). We only run into 
> the case where the MemRegion array size is larger than max_num_regions 
> with Calvin’s pending change. As part of Calvin’s change, he will 
> change the assert into a check and bail out if the number of 
> MemRegions are larger than max_num_regions due to heap fragmentation.
>
>
Your latest patch assumes that arr_len <= 2, but the implementation of 
G1CollectedHeap::heap()->begin_archive_alloc_range() / 
G1CollectedHeap::heap()->end_archive_alloc_range() actually allows more 
than 2 regions to returned. So simply putting an assert there seems 
risky (unless you have analyzed all possible scenarios to prove that's 
impossible).

Instead of trying to come up with a complicated proof, I think it's much 
safer to disable the archived string region if the arr_len > 2. Also, if 
the string region is disabled, you should also disable the 
open_archive_heap_region

I think this is a general issue with the mapped heap regions, and it 
just happens to be revealed by Calvin's patch. So we should fix it now 
and not wait for Calvin's patch.


>>
>> The word "region" is used in these parameters, but they don't mean 
>> the same thing.
>>
>> GrowableArray<MemRegion> *regions
>>               int first_region, int max_num_regions,
>>
>>
>> How about regions      -> g1_regions_list
>>           first_region -> first_region_in_archive
>
> The GrowableArray above is the MemRegions that GC code gives back to 
> us. The GC code combines multiple G1 regions. The comments probably 
> are over-explaining the details, which are hidden in the GC code. 
> Probably that’s the confusing source. I’ll make the comment more clear.
>
> Using g1_regions_list would also be confusing, since 
> write_archive_heap_regions does not handle G1 regions directly. It 
> processes the MemRegion array that GC code returns. How about changing 
> ‘regions’ to ‘mem_regions’ or ‘archive_regions'?
>
How about heap_regions? These are regions in the active Java heap, which 
current has not mapped anything from the CDS archive.


>>
>>
>> In the comments, I find the phrase 'the current archive heap region' 
>> ambiguous. It could be (erroneously) interpreted as "a region from 
>> the currently mapped archive”
>>
>> To make it unambiguous, how about changing
>>
>>
>>  464 // Write the current archive heap region, which contains one or 
>> multiple GC(G1) regions.
>>
>>
>> to
>>
>>     // Write the given list of G1 memory regions into the archive, 
>> starting at
>>     // first_region_in_archive.
>
>
> Ok. How about the following:
>
> // Write the given list of java heap memory regions into the archive, 
> starting at
> // first_region_in_archive.
>
Sounds good.

Thanks
- Ioi

>>
>>
>> Also, for the explanation of how the G1 regions are written into the 
>> archive, how about:
>>
>>    // The G1 regions in the list are sorted in ascending address 
>> order. When there are more objects
>>    // than the capacity of a single G1 region, the bottom-most G1 
>> region may be partially filled, and the
>>    // remaining G1 region(s) are consecutively allocated and fully 
>> filled.
>>    //
>>    // Thus, the bottom-most G1 region (if not empty) is written into 
>> first_region_in_archive.
>>    // The remaining G1 regions (if exist) are coalesced and written 
>> as a single block
>>    // into (first_region_in_archive + 1)
>>
>>    // Here's the mapping from (g1 regions) -> (archive regions).
>>
>>
>> All this function needs to do is to decide the values for
>>
>>      r0_start, r0_top
>>      r1_start, r1_top
>>
>> I think it would be much better to not use the loop, and not use the 
>> max_num_regions parameter (it's always 2 anyway).
>>
>>      *r0_start = *r0_top = NULL;
>>      *r1_start = *r1_top = NULL;
>>
>>      if (arr_len >= 1) {
>>          *r0_start = regions->at(0).start();
>>          *r0_end = *r0_start + regions->at(0).byte_size();
>>      }
>>      if (arr_len >= 2) {
>>          int last = arr_len - 1;
>>          *r1_start = regions->at(1).start();
>>          *r1_end = regions->at(last).start() + 
>> regions->at(last).byte_size();
>>       }
>>
>> what do you think?
>
> We need to write out all archive regions including the empty ones. The 
> loop using max_num_regions is the easiest way. I’d like to remove the 
> code that deals with r0_* and r1_ explicitly. Let me try that.
>
>>
>>
>>
>> (3) metaspace.cpp
>>
>> 3350         // Map the archived heap regions after compressed pointers
>> 3351         // because it relies on compressed class pointers 
>> setting to work
>>
>> do you mean this?
>>
>>     // Archived heap regions depend on the parameters of compressed 
>> class pointers, so
>>     // they must be mapped after such parameters have been decided in 
>> the above call.
>
> Hmmm, maybe use ‘arguments’ instead of ‘parameters’?
>
>>
>>
>> (4) I found this name not strictly grammatical. How about this:
>>
>>      allow_archive_heap_object -> is_heap_object_archiving_allowed
>
> Ok.
>
>>
>> (5) in most of your code, 'archive' is used as a noun, except in 
>> StringTable::archive_string() where it's used as a verb.
>>
>> archive_string could also be interpreted erroneously as "return a 
>> string that's already in the archive". So to be consistent and 
>> unambiguous, I think it's better to rename it to 
>> StringTable::create_archived_string()
>
> Ok.
>
> Thanks,
> Jiangli
>
>>
>>
>> Thanks
>> - Ioi
>>
>>
>> On 8/3/17 5:15 PM, Jiangli Zhou wrote:
>>> Here are the updated webrevs.
>>>
>>> http://cr.openjdk.java.net/~jiangli/8179302/webrev.hotspot.02/ 
>>> <http://cr.openjdk.java.net/%7Ejiangli/8179302/webrev.hotspot.02/>
>>> http://cr.openjdk.java.net/~jiangli/8179302/webrev.whitebox.02/
>>>
>>> Changes in the updated webrevs include:
>>>
>>>   * Merge with Ioi’s recent shared space auto-sizing change (8072061)
>>>   * Addressed all feedbacks from Ioi and Coleen (Thanks for detailed
>>>     review!)
>>>
>>>
>>> Thanks,
>>> Jiangli
>>>
>>>
>>>> On Aug 1, 2017, at 5:29 PM, Jiangli Zhou <jiangli.zhou at Oracle.COM> 
>>>> wrote:
>>>>
>>>> Hi Ioi,
>>>>
>>>> Thank you so much for reviewing this. I’ve addressed all your 
>>>> feedbacks. Please see details below. I’ll updated the webrev 
>>>> after addressing Coleen’s comments.
>>>>
>>>>> On Jul 30, 2017, at 9:07 PM, Ioi Lam <ioi.lam at oracle.com> wrote:
>>>>>
>>>>> Hi Jiangli,
>>>>>
>>>>> Here are my comments. I've not reviewed the GC code and I'll leave 
>>>>> that to the GC experts :-)
>>>>>
>>>>> stringTable.cpp: StringTable::archive_string
>>>>>
>>>>>    add assert for DumpSharedSpaces only
>>>>
>>>> Ok.
>>>>
>>>>>
>>>>> filemap.cpp
>>>>>
>>>>> 525 void 
>>>>> FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> 
>>>>> *regions,
>>>>> 526  int first_region, int num_regions) {
>>>>>
>>>>> When I first read this function, I found it hard to follow, 
>>>>> especially this part that coalesces the trailing regions:
>>>>>
>>>>> 537         int len = regions->length();
>>>>> 538         if (len > 1) {
>>>>> 539           start = (char*)regions->at(1).start();
>>>>> 540           size = (char*)regions->at(len - 1).end() - start;
>>>>> 541         }
>>>>> 542       }
>>>>>
>>>>> The rest of filemap.cpp always perform identical operations on 
>>>>> MemRegion arrays, which are either 1 or 2 in size. However, 
>>>>> this function doesn't follow that pattern; it also has a very 
>>>>> different notion of "region", and the confusing part is 
>>>>> regions->size() is not the same as num_regions.
>>>>>
>>>>> How about we change the API to something like the following? 
>>>>> Before calling this API, the caller needs to coalesce the trailing 
>>>>> G1 regions into a single MemRegion.
>>>>>
>>>>> FileMapInfo::write_archive_heap_regions(MemRegion *regions, int 
>>>>> first, int num_regions) {
>>>>>        if (first == MetaspaceShared::first_string) {
>>>>>           assert(num_regons <=  MetaspaceShared::max_strings, "...");
>>>>>        } else {
>>>>>           assert(first == 
>>>>> MetaspaceShared::first_open_archive_heap_region, "...");
>>>>>           assert(num_regons <= 
>>>>> MetaspaceShared::max_open_archive_heap_region, "...");
>>>>> }
>>>>>        ....
>>>>>
>>>>>
>>>>
>>>> I’ve reworked the function and simplified the code.
>>>>
>>>>>
>>>>> 756   if (!string_data_mapped) {
>>>>> 757 StringTable::ignore_shared_strings(true);
>>>>> 758     assert(string_ranges == NULL && num_string_ranges == 0, 
>>>>> "sanity");
>>>>> 759   }
>>>>> 760
>>>>> 761   if (open_archive_heap_data_mapped) {
>>>>> 762 MetaspaceShared::set_open_archive_heap_region_mapped();
>>>>> 763   } else {
>>>>> 764     assert(open_archive_heap_ranges == NULL && 
>>>>> num_open_archive_heap_ranges == 0, "sanity");
>>>>> 765   }
>>>>>
>>>>> Maybe the two "if" statements should be more consistent? Instead 
>>>>> of StringTable::ignore_shared_strings, how 
>>>>> about StringTable::set_shared_strings_region_mapped()?
>>>>
>>>> Fixed.
>>>>
>>>>>
>>>>> FileMapInfo::map_heap_data() --
>>>>>
>>>>> 818     char* addr = (char*)regions[i].start();
>>>>> 819     char* base = os::map_memory(_fd, _full_path, si->_file_offset,
>>>>> 820                                 addr, regions[i].byte_size(), 
>>>>> si->_read_only,
>>>>> 821 si->_allow_exec);
>>>>>
>>>>> What happens when the first region succeeds to map but the second 
>>>>> region fails to map? Will both regions be unmapped? I don't see 
>>>>> where you store the return value (base) from os::map_memory(). 
>>>>> Does it mean the code assumes that (addr == base). If so, we need 
>>>>> an assert here.
>>>>
>>>> If any of the region fails to map, we bail out and call 
>>>> dealloc_archive_heap_regions(), which handles the deallocation of 
>>>> any regions specified. If second region fails to map, all memory 
>>>> ranges specified by ‘regions’ array are deallocated. We don’t unmap 
>>>> the memory here since it is part of the java heap. Unmapping of 
>>>> heap memory are handled by GC code. The ‘if’ check below makes sure 
>>>> base == addr.
>>>>
>>>>     if (base == NULL || base != addr) {
>>>>       // dealloc the regions from java heap
>>>>       dealloc_archive_heap_regions(regions, region_num);
>>>>       if (log_is_enabled(Info, cds)) {
>>>>         log_info(cds)("UseSharedSpaces: Unable to map at required 
>>>> address in java heap.");
>>>>       }
>>>>       return false;
>>>>     }
>>>>
>>>>
>>>>>
>>>>> constantPool.cpp
>>>>>
>>>>>     Handle refs_handle;
>>>>>     ...
>>>>>     refs_handle = Handle(THREAD, (oop)archived);
>>>>>
>>>>> This will first create a NULL handle, then construct a temporary 
>>>>> handle, and then assign the temp handle back to the null 
>>>>> handle. This means two handles will be pushed onto 
>>>>> THREAD->metadata_handles()
>>>>>
>>>>> I think it's more efficient if you merge these into a single statement
>>>>>
>>>>>     Handle refs_handle(THREAD, (oop)archived);
>>>>
>>>> Fixed.
>>>>
>>>>>
>>>>> Is this experimental code? Maybe it should be removed?
>>>>>
>>>>> 664     if (tag_at(index).is_unresolved_klass()) {
>>>>> 665 #if 0
>>>>> 666       CPSlot entry = cp->slot_at(index);
>>>>> 667       Symbol* name = entry.get_symbol();
>>>>> 668       Klass* k = SystemDictionary::find(name, NULL, NULL, THREAD);
>>>>> 669       if (k != NULL) {
>>>>> 670         klass_at_put(index, k);
>>>>> 671       }
>>>>> 672 #endif
>>>>> 673     } else
>>>>
>>>> Removed.
>>>>
>>>>>
>>>>> cpCache.hpp:
>>>>>
>>>>>     u8   _archived_references
>>>>>
>>>>> shouldn't this be declared as an narrowOop to avoid the type casts 
>>>>> when it's used?
>>>>
>>>> Ok.
>>>>
>>>>>
>>>>> cpCache.cpp:
>>>>>
>>>>>    add assert so that one of these is used only at dump time and 
>>>>> the other only at run time?
>>>>>
>>>>> 610 oop ConstantPoolCache::archived_references() {
>>>>> 611   return 
>>>>> oopDesc::decode_heap_oop((narrowOop)_archived_references);
>>>>> 612 }
>>>>> 613
>>>>> 614 void ConstantPoolCache::set_archived_references(oop o) {
>>>>> 615   _archived_references = (u8)oopDesc::encode_heap_oop(o);
>>>>> 616 }
>>>>
>>>> Ok.
>>>>
>>>> Thanks!
>>>>
>>>> Jiangli
>>>>
>>>>>
>>>>> Thanks!
>>>>> - Ioi
>>>>>
>>>>> On 7/27/17 1:37 PM, Jiangli Zhou wrote:
>>>>>> Sorry, the mail didn’t handle the rich text well. I fixed the 
>>>>>> format below.
>>>>>>
>>>>>> Please help review the changes for JDK-8179302 (Pre-resolve 
>>>>>> constant pool string entries and cache resolved_reference arrays 
>>>>>> in CDS archive). Currently, the CDS archive can contain cached 
>>>>>> class metadata, interned java.lang.String objects. This RFE adds 
>>>>>> the constant pool ‘resolved_references’ arrays (hotspot specific) 
>>>>>> to the archive for startup/runtime performance enhancement. 
>>>>>> The ‘resolved_references' arrays are used to hold references of 
>>>>>> resolved constant pool entries including Strings, mirrors, etc. 
>>>>>> With the 'resolved_references’ being cached, string constants in 
>>>>>> shared classes can now be resolved to existing interned 
>>>>>> java.lang.Strings at CDS dump time. G1 and 64-bit platforms are 
>>>>>> required.
>>>>>>
>>>>>> The GC changes in the RFE were discussed and guided by Thomas 
>>>>>> Schatzl and GC team. Part of the changes were contributed by 
>>>>>> Thomas himself.
>>>>>> RFE: https://bugs.openjdk.java.net/browse/JDK-8179302
>>>>>> hotspot: 
>>>>>> http://cr.openjdk.java.net/~jiangli/8179302/webrev.hotspot.01/
>>>>>> whitebox: 
>>>>>> http://cr.openjdk.java.net/~jiangli/8179302/webrev.whitebox.01/
>>>>>>
>>>>>> Please see below for details of supporting cached 
>>>>>> ‘resolved_references’ and pre-resolving string constants.
>>>>>>
>>>>>> Types of Pinned G1 Heap Regions
>>>>>>
>>>>>> The pinned region type is a super type of all archive region 
>>>>>> types, which include the open archive type and the closed archive 
>>>>>> type.
>>>>>>
>>>>>> 00100 0 [ 8] Pinned Mask
>>>>>> 01000 0 [16] Old Mask
>>>>>> 10000 0 [32] Archive Mask
>>>>>> 11100 0 [56] Open Archive:   ArchiveMask | PinnedMask | OldMask
>>>>>> 11100 1 [57] Closed Archive: ArchiveMask | PinnedMask | OldMask + 1
>>>>>>
>>>>>>
>>>>>> Pinned Regions
>>>>>>
>>>>>> Objects within the region are 'pinned', which means GC does not 
>>>>>> move any live objects. GC scans and marks objects in the 
>>>>>> pinned region as normal, but skips forwarding live objects. 
>>>>>> Pointers in live objects are updated. Dead objects (unreachable) 
>>>>>> can be collected and freed.
>>>>>>
>>>>>> Archive Regions
>>>>>>
>>>>>> The archive types are sub-types of 'pinned'. There are two types 
>>>>>> of archive region currently, open archive and closed archive. 
>>>>>> Both can support caching java heap objects via the CDS archive.
>>>>>>
>>>>>> An archive region is also an old region by design.
>>>>>>
>>>>>> Open Archive (GC-RW) Regions
>>>>>>
>>>>>> Open archive region is GC writable. GC scans & marks objects 
>>>>>> within the region and adjusts (updates) pointers in live objects 
>>>>>> the same way as a pinned region. Live objects (reachable) are 
>>>>>> pinned and not forwarded by GC.
>>>>>> Open archive region does not have 'dead' objects. Unreachable 
>>>>>> objects are 'dormant' objects. Dormant objects are not 
>>>>>> collected and freed by GC.
>>>>>>
>>>>>> Adjustable Outgoing Pointers
>>>>>>
>>>>>> As GC can adjust pointers within the live objects in open archive 
>>>>>> heap region, objects can have outgoing pointers to another 
>>>>>> java heap region, including closed archive region, open archive 
>>>>>> region, pinned (or humongous) region, and normal generational 
>>>>>> region. When a referenced object is moved by GC, the pointer 
>>>>>> within the open archive region is updated accordingly.
>>>>>>
>>>>>> Closed Archive (GC-RO) Regions
>>>>>>
>>>>>> The closed archive region is GC read-only region. GC cannot write 
>>>>>> into the region. Objects are not scanned and marked by 
>>>>>> GC. Objects are pinned and not forwarded. Pointers are not 
>>>>>> updated by GC either. Hence, objects within the archive region 
>>>>>> cannot have any outgoing pointers to another java heap region. 
>>>>>> Objects however can still have pointers to other objects within 
>>>>>> the closed archive regions (we might allow pointers to open 
>>>>>> archive regions in the future). That restricts the type of java 
>>>>>> objects that can be supported by the archive region.
>>>>>> In JDK 9 we support archive Strings with the archive regions.
>>>>>>
>>>>>> The GC-readonly archive region makes java heap memory sharable 
>>>>>> among different JVM processes. NOTE: synchronization on the 
>>>>>> objects within the archive heap region can still cause writes to 
>>>>>> the memory page.
>>>>>>
>>>>>> Dormant Objects
>>>>>>
>>>>>> Dormant objects are unreachable java objects within the open 
>>>>>> archive heap region.
>>>>>> A java object in the open archive heap region is a live object if 
>>>>>> it can be reached during scanning. Some of the java objects in 
>>>>>> the region may not be reachable during scanning. Those objects 
>>>>>> are considered as dormant, but not dead. For example, a 
>>>>>> constant pool 'resolved_references' array is reachable via the 
>>>>>> klass root if its container klass (shared) is already loaded at 
>>>>>> the time during GC scanning. If a shared klass is not yet loaded, 
>>>>>> the klass root is not scanned and it's constant pool 
>>>>>> 'resolved_reference' array (A) in the open archive region is not 
>>>>>> reachable. Then A is a dormant object.
>>>>>>
>>>>>> Object State Transition
>>>>>>
>>>>>> All java objects are initially dormant objects when open archive 
>>>>>> heap regions are mapped to the runtime java heap. A 
>>>>>> dormant object becomes live object when the associated shared 
>>>>>> class is loaded at runtime. Explicit call 
>>>>>> to G1SATBCardTableModRefBS::enqueue() needs to be made when a 
>>>>>> dormant object becomes live. That should be the case for cached 
>>>>>> objects with strong roots as well, since strong roots are only 
>>>>>> scanned at the start of GC marking (the initial marking) but 
>>>>>> not during Remarking/Final marking. If a cached object becomes 
>>>>>> live during concurrent marking phase, G1 may not find it and mark 
>>>>>> it live unless a call to G1SATBCardTableModRefBS::enqueue() is 
>>>>>> made for the object.
>>>>>>
>>>>>> Currently, a live object in the open archive heap region cannot 
>>>>>> become dormant again. This restriction simplifies GC 
>>>>>> requirement and guarantees all outgoing pointers are updated by 
>>>>>> GC correctly. Only objects for shared classes from the builtin 
>>>>>> class loaders (boot, PlatformClassLoaders, and AppClassLoaders) 
>>>>>> are supported for caching.
>>>>>>
>>>>>> Caching Java Objects at Archive Dump Time
>>>>>>
>>>>>> The closed archive and open archive regions are allocated near 
>>>>>> the top of the dump time java heap. Archived java objects 
>>>>>> are copied into the designated archive heap regions. For example, 
>>>>>> String objects and the underlying 'value' arrays are copied into 
>>>>>> the closed archive regions. All references to the archived 
>>>>>> objects (from shared class metadata, string table, etc) are set 
>>>>>> to the new heap locations. A hash table is used to keep track of 
>>>>>> all archived java objects during the copying process to make sure 
>>>>>> java object is not archived more than once if reached from 
>>>>>> different roots. It also makes sure references to the same 
>>>>>> archived object are updated using the same new address location.
>>>>>>
>>>>>> Caching Constant Pool resolved_references Array
>>>>>>
>>>>>> The 'resolved_references' is an array that holds references of 
>>>>>> resolved constant pool entries including Strings, mirrors 
>>>>>> and methodTypes, etc. Each loaded class has one 
>>>>>> 'resolved_references' array (in ConstantPoolCache). The 
>>>>>> 'resolved_references' arrays are copied into the open archive 
>>>>>> regions during dump process. Prior to copying the 
>>>>>> 'resolved_references' arrays, JVM iterates through constant pool 
>>>>>> entries and resolves all JVM_CONSTANT_String entries to existing 
>>>>>> interned Strings for all archived classes. When resolving, JVM 
>>>>>> only looks up the string table and finds existing interned 
>>>>>> Strings without inserting new ones. If a string entry cannot be 
>>>>>> resolved to an existing interned String, the constant pool entry 
>>>>>> remain as unresolved. That prevents memory waste if a constant 
>>>>>> pool string entry is never used at runtime.
>>>>>>
>>>>>> All String objects referenced by the string table are copied 
>>>>>> first into the closed archive regions. The string table entry is 
>>>>>> updated with the new location when each String object is 
>>>>>> archived. The JVM updates the resolved constant pool string 
>>>>>> entries with the new object locations when copying the 
>>>>>> 'resolved_references' arrays to the open archive regions. 
>>>>>> References to the 'resolved_references' arrays in the 
>>>>>> ConstantPoolCache are also updated.
>>>>>> At runtime as part of ConstantPool::restore_unshareable_info() 
>>>>>> work, call G1SATBCardTableModRefBS::enqueue() to let GC know the 
>>>>>> 'resolved_references' is becoming live. A handle is created for 
>>>>>> the cached object and added to the loader_data's handles.
>>>>>>
>>>>>> Runtime Java Heap With Cached Java Objects
>>>>>>
>>>>>>
>>>>>> The closed archive regions (the string regions) and open archive 
>>>>>> regions are mapped to the runtime java heap at the same 
>>>>>> offsets as the dump time offsets from the runtime java heap base.
>>>>>>
>>>>>> Preliminary test execution and status:
>>>>>>
>>>>>> JPRT: passed
>>>>>> Tier2-rt: passed
>>>>>> Tier2-gc: passed
>>>>>> Tier2-comp: passed
>>>>>> Tier3-rt: passed
>>>>>> Tier3-gc: passed
>>>>>> Tier3-comp: passed
>>>>>> Tier4-rt: passed
>>>>>> Tier4-gc: passed
>>>>>> Tier4-comp:6 jobs timed out, all other tests passed
>>>>>> Tier5-rt: one test failed but passed when running locally, all 
>>>>>> other tests passed
>>>>>> Tier5-gc: passed
>>>>>> Tier5-comp: running
>>>>>> hotspot_gc: two jobs timed out, all other tests passed
>>>>>> hotspot_gc in CDS mode: two jobs timed out, all other tests passed
>>>>>> vm.gc: passed
>>>>>> vm.gc in CDS mode: passed
>>>>>> Kichensink: passed
>>>>>> Kichensink in CDS mode: passed
>>>>>>
>>>>>> Thanks,
>>>>>> Jiangli
>>>>>
>>>>
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20170807/5af76680/attachment.htm>


More information about the hotspot-gc-dev mailing list