3200N/A * Copyright (c) 2001, 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. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A _ageTable(
false),
// false ==> not the global age table, no perf data. 0N/A // A non-null SCA implies that we want the PLAB data recorded. 0N/A // Process ParGCArrayScanChunk elements now 0N/A // and push the remainder back onto queue 0N/A // Test above combines last partial chunk with a full chunk 0N/A // Restore length so that it can be used if there 0N/A // is a promotion failure and forwarding pointers 0N/A // process our set of indices (include header in first chunk) 113N/A // should make sure end is even (aligned to HeapWord in case of compressed oops) 0N/A // object is in to_space 0N/A // object is in old generation 679N/A // object is in to_space 679N/A // object is in old generation 679N/A // For the case of compressed oops, we have a private, non-shared 679N/A // overflow stack, so we eagerly drain it so as to more evenly 679N/A // distribute load early. Note: this may be good to do in 679N/A // general rather than delay for the final stealing phase. 679N/A // If applicable, we'll transfer a set of objects over to our 679N/A // work queue, allowing them to be stolen and draining our 679N/A // private overflow stack. 679N/A // Transfer the most recent num_take_elems from the overflow 679N/A // stack to our work queue. 0N/A // Otherwise, if the object is small enough, try to reallocate the 0N/A // Is small enough; abandon this buffer and start a new one. 0N/A // Note that we cannot compare buf_size < word_sz below 0N/A // because of AlignmentReserve (see ParGCAllocBuffer::allocate()). 0N/A "Else should have been able to allocate");
0N/A // It's conceivable that we may be able to use the 0N/A // buffer we just grabbed for subsequent small requests 0N/A // even if not for this one. 0N/A // Too large; allocate the object individually. 0N/A // Is the alloc in the current alloc buffer? 0N/A "Should contain whole object.");
0N/A // Initializes states for the specified number of threads; 1756N/A "overflow_stack allocation mismatch");
0N/A // Initialize states. 1630N/A "-------termination-------");
1630N/A "--------- ------ --------");
1630N/A// Print stats related to work queue activity. 1145N/A // Work in this loop should be kept as lightweight as 1145N/A // possible since this might otherwise become a bottleneck 1145N/A // to scaling. Should we add heavy-weight work into this 1145N/A // loop, consider parallelizing the loop into the worker threads. 0N/A // Flush stats related to To-space PLAB activity and 0N/A // retire the last buffer. 0N/A // Every thread has its own age table. We need to merge 0N/A // them all into one. 0N/A // Inform old gen that we're done. 1145N/A // We need to call this even when ResizeOldPLAB is disabled 1145N/A // so as to avoid breaking some asserts. While we may be able 1145N/A // to avoid this by reorganizing the code a bit, I am loathe 1145N/A // to do that unless we find cases where ergo leads to bad 0N/A#
pragma warning(
disable:
4786)
/* identifier was truncated to '255' characters in the browser information */ 0N/A // Scan to-space and old-gen objs until we run out of both. 0N/A // We have no local work, attempt to steal from other threads. 0N/A // attempt to steal work from promoted. 0N/A // if successful, goto Start. 0N/A // try global overflow list. 0N/A // Otherwise, offer termination. 534N/A "Broken overflow list?");
0N/A // Finish the last termination pause. 2941N/A// Reset the terminator for the given number of 2941N/A // Should the heap be passed in? There's only 1 for now so 2941N/A// The "i" passed to this method is the part of the work for 2941N/A// this thread. It is not the worker ID. The "i" is derived 2941N/A// from _started_workers which is incremented in internal_note_start() 2941N/A// called in GangWorker loop() and which is called under the 2941N/A// which is called under the protection of the gang monitor and is 2941N/A// called after a task is started. So "i" is based on 0N/A // Since this is being done in a separate thread, need new resource 0N/A // and handle marks. 0N/A // We would need multiple old-gen queues otherwise. 989N/A true,
// Process younger gens, if any, 989N/A false,
// no scope; this is parallel code 989N/A false,
// not collecting perm generation. 989N/A true,
// walk *all* scavengable nmethods 0N/A // "evacuate followers". 3863N/A // typedef to workaround NEW_C_HEAP_ARRAY macro, which can not deal 0N/A// ParNewGeneration:: 113N/A // We never expect to see a null reference being processed 113N/A // as a weak reference. 0N/A// ParNewGeneration:: 113N/A // We never expect to see a null reference being processed 113N/A // as a weak reference. 0N/A // If p points to a younger generation, mark the card. 0N/A "not a generational heap");
0N/A // Beware: this call will lead to closure applications via virtual 4302N/A// A Generation that does parallel young-gen collection. 0N/A // Set the desired survivor size to half the real survivor space 4302N/A // All the spaces are in play for mark-sweep. 4302N/A // Inform the next generation that a promotion failure occurred. 4302N/A // Trace promotion failure in the parallel GC threads 4302N/A // Single threaded code may have reported promotion failure to the global state 4302N/A // Reset the PromotionFailureALot counters. 0N/A "not a CMS generational heap");
0N/A "This must be the youngest gen, and not the only gen");
0N/A "Par collection currently only works with single older gen.");
0N/A // Do we have to avoid promotion_undo? 4302N/A // If the next generation is too full to accommodate worst-case promotion 0N/A // from this generation, pass on collection; let the next generation 0N/A // Capture heap used before collection (for printing). 2941N/A // Set the correct parallelism (number of queues) in the reference processor 2941N/A // Always set the terminator for the active number of workers 2941N/A // because only those workers go through the termination protocol. 0N/A // It turns out that even when we're using 1 thread, doing the work in a 0N/A // separate thread causes wide variance in run times. We can't help this 0N/A // in the multi-threaded case, but we special-case n=1 here to get 0N/A // repeatable measurements of the 1-thread overhead of the parallel code. 0N/A // Process (weak) reference objects found during scavenge. 2941N/A // Can the mt_degree be set later (at run_task() time would be best)? 0N/A // Swap the survivor spaces. 263N/A // This is now done here because of the piece-meal mangling which 263N/A // can check for valid mangling at intermediate points in the 263N/A // collection(s). When a minor collection fails to collect 263N/A // sufficient space resizing of the young generation can occur 263N/A // an redistribute the spaces in the young generation. Mangle 263N/A // here so that unzapped regions don't get distributed to 1387N/A // A successful scavenge should restart the GC time limit count which is 0N/A // set new iteration safe limit for the survivor spaces 3200N/A // We need to use a monotonically non-deccreasing time in ms 3200N/A // or we will see time-warp warnings and os::javaTimeMillis() 3200N/A // does not guarantee monotonicity. 0N/A for (
int i = 0; i <
100; i++) {
0N/A// Because of concurrency, there are times where an object for which 0N/A// "is_forwarded()" is true contains an "interim" forwarding pointer 0N/A// value. Such a value will soon be overwritten with a real value. 0N/A// This method requires "obj" to have a forwarding pointer, and waits, if 0N/A// necessary for a real one to be inserted, and returns it. 0N/A // Spin-read if it is claimed but not yet written by another thread. 1945N/A // We should really have separate per-worker stacks, rather 1945N/A // than use locking of a common pair of stacks. 0N/A// Multiple GC threads may try to promote an object. If the object 0N/A// is successfully promoted, a forwarding pointer will be installed in 0N/A// the object in the young generation. This method claims the right 0N/A// to install the forwarding pointer before it copies the object, 0N/A// thus avoiding the need to undo the copy as in 0N/A// copy_to_survivor_space_avoiding_with_undo. 0N/A // In the sequential version, this assert also says that the object is 0N/A // not forwarded. That might not be the case here. It is the case that 0N/A // the caller observed it to be not forwarded at some time in the past. 0N/A // The sequential code read "old->age()" below. That doesn't work here, 0N/A // since the age is in the mark word, and that might be overwritten with 0N/A // a forwarding pointer by a parallel thread. So we must save the mark 0N/A // word in a local and then analyze it. 0N/A "should not be called with forwarding pointer mark word.");
0N/A // Try allocating obj in to-space (unless too old) 0N/A // Either to-space is full or we decided to promote 0N/A // try allocating obj tenured 0N/A // Attempt to install a null forwarding pointer (atomically), 0N/A // to claim the right to install the real forwarding pointer. 0N/A // someone else beat us to it. 0N/A // promotion failed, forward to self 0N/A // Is in to-space; do copying ourselves. 0N/A // Restore the mark word copied above. 0N/A // Increment age if obj still in new generation 0N/A // Length field used as index of next element to be scanned. 0N/A // Real length can be obtained from real_forwardee() 0N/A "push forwarded object");
0N/A // Push it on one of the queues of to-be-scanned objects. 534N/A // simulate a stack overflow 0N/A // Add stats for overflow pushes. 0N/A // Oops. Someone beat us to it. Undo the allocation. Where did we 0N/A // Must be in to_space. 0N/A // Wait to get the real forwarding pointer value. 0N/A// Multiple GC threads may try to promote the same object. If two 0N/A// or more GC threads copy the object, only one wins the race to install 0N/A// the forwarding pointer. The other threads have to undo their copy. 0N/A // In the sequential version, this assert also says that the object is 0N/A // not forwarded. That might not be the case here. It is the case that 0N/A // the caller observed it to be not forwarded at some time in the past. 0N/A // The sequential code read "old->age()" below. That doesn't work here, 0N/A // since the age is in the mark word, and that might be overwritten with 0N/A // a forwarding pointer by a parallel thread. So we must save the mark 0N/A // word here, install it in a local oopDesc, and then analyze it. 0N/A "should not be called with forwarding pointer mark word.");
0N/A // Try allocating obj in to-space (unless too old) 0N/A // Either to-space is full or we decided to promote 0N/A // try allocating obj tenured 0N/A // promotion failed, forward to self 0N/A // Is in to-space; do copying ourselves. 0N/A // Restore the mark word copied above. 0N/A // Increment age if new_obj still in new generation 0N/A // Now attempt to install the forwarding pointer (atomically). 0N/A // We have to copy the mark word before overwriting with forwarding 0N/A // ptr, so we can restore it below in the copy. 0N/A // Length field used as index of next element to be scanned. 0N/A // Real length can be obtained from real_forwardee() 0N/A "push forwarded object");
0N/A // Push it on one of the queues of to-be-scanned objects. 534N/A // simulate a stack overflow 0N/A // Add stats for overflow pushes. 0N/A // Oops. Someone beat us to it. Undo the allocation. Where did we 0N/A // Must be in to_space. 534N/A// It's OK to call this multi-threaded; the worst thing 534N/A// that can happen is that we'll get a bunch of closely 534N/A// spaced simulated oveflows, but that's OK, in fact 534N/A// probably good as it would exercise the overflow code 679N/A// In case we are using compressed oops, we need to be careful. 679N/A// If the object being pushed is an object array, then its length 679N/A// field keeps track of the "grey boundary" at which the next 679N/A// incremental scan will be done (see ParGCArrayScanChunk). 679N/A// When using compressed oops, this length field is kept in the 679N/A// lower 32 bits of the erstwhile klass word and cannot be used 679N/A// for the overflow chaining pointer (OCP below). As such the OCP 679N/A// would itself need to be compressed into the top 32-bits in this 679N/A// case. Unfortunately, see below, in the event that we have a 679N/A// promotion failure, the node to be pushed on the list can be 679N/A// outside of the Java heap, so the heap-based pointer compression 679N/A// would not work (we would have potential aliasing between C-heap 679N/A// and Java-heap pointers). For this reason, when using compressed 679N/A// oops, we simply use a worker-thread-local, non-shared overflow 679N/A// list in the form of a growable array, with a slightly different 679N/A// overflow stack draining strategy. If/when we start using fat 679N/A// stacks here, we can go back to using (fat) pointer chains 679N/A// (although some performance comparisons would be useful since 679N/A// single global lists have their own performance disadvantages 679N/A// as we were made painfully aware not long ago, see 6786503). 679N/A // In the case of compressed oops, we use a private, not-shared 679N/A // if the object has been forwarded to itself, then we cannot 679N/A // use the klass pointer for the linked list. Instead we have 679N/A // to allocate an oopDesc in the C-Heap and use that for the linked list. 679N/A // XXX This is horribly inefficient when a promotion failure occurs 679N/A // and should be fixed. XXX FIX ME !!! 534N/A// *NOTE*: The overflow list manipulation code here and 534N/A// in CMSCollector:: are very similar in shape, 534N/A// except that in the CMS case we thread the objects 534N/A// directly into the list via their mark word, and do 534N/A// not need to deal with special cases below related 534N/A// to chunking of object arrays and promotion failure 534N/A// CR 6797058 has been filed to attempt consolidation of 534N/A// Because of the common code, if you make any changes in 534N/A// the code below, please check the CMS version to see if 534N/A// similar changes might be needed. 534N/A// See CMSCollector::par_take_from_overflow_list() for 534N/A// more extensive documentation comments. 0N/A // How many to take? 0N/A // Otherwise, there was something there; try claiming the list. 534N/A // Trim off a prefix of at most objsFromOverflow items 534N/A // someone grabbed it before we did ... 534N/A // ... we spin for a short while... 534N/A // nothing left to take 534N/A // try and grab the prefix 534N/A // Nothing to take or waited long enough 534N/A // Write back the NULL in case we overwrote it with BUSY above 534N/A // and it is still the same value. 0N/A // Reattach remaining (suffix) to overflow list 534N/A // Write back the NULL in lieu of the BUSY we wrote 534N/A // above and it is still the same value. 534N/A // It's possible that the list is still in the empty(busy) state 534N/A // we left it in a short while ago; in that case we may be 534N/A // able to place back the suffix. 534N/A // Too bad, someone else got in in between; we'll need to do a splice. 534N/A // Find the last item of suffix list 534N/A // Atomically prepend suffix to current overflow list 534N/A }
else {
// cur_overflow_list == BUSY 0N/A // Push objects on prefix list onto this thread's work queue 534N/A // This may be an array object that is self-forwarded. In that case, the list pointer 534N/A // space, cur, is not in the Java heap, but rather in the C-heap and should be freed. 534N/A // This can become a scaling bottleneck when there is work queue overflow coincident 534N/A // with promotion failure. 0N/A // Allocate and initialize a reference processor 2216N/A false);
// write barrier for next field updates 0N/A return "par new generation";