hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
author ysr
Thu, 20 Nov 2008 16:56:09 -0800
changeset 1606 dcf9714addbe
parent 977 b90650e2a9f7
child 1610 5dddd195cc86
permissions -rw-r--r--
6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
670
ddf3e9583f2f 6719955: Update copyright year
xdono
parents: 360
diff changeset
     2
 * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
# include "incls/_psScavenge.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
HeapWord*                  PSScavenge::_to_space_top_before_gc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
int                        PSScavenge::_consecutive_skipped_scavenges = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
ReferenceProcessor*        PSScavenge::_ref_processor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
CardTableExtension*        PSScavenge::_card_table = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
bool                       PSScavenge::_survivor_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
int                        PSScavenge::_tenuring_threshold = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
HeapWord*                  PSScavenge::_young_generation_boundary = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
elapsedTimer               PSScavenge::_accumulated_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
GrowableArray<markOop>*    PSScavenge::_preserved_mark_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
GrowableArray<oop>*        PSScavenge::_preserved_oop_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
CollectorCounters*         PSScavenge::_counters = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// Define before use
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
class PSIsAliveClosure: public BoolObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  void do_object(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    assert(false, "Do not call.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  bool do_object_b(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
PSIsAliveClosure PSScavenge::_is_alive_closure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
class PSKeepAliveClosure: public OopClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  MutableSpace* _to_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  PSPromotionManager* _promotion_manager;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    _to_space = heap->young_gen()->to_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    assert(_promotion_manager != NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    68
  template <class T> void do_oop_work(T* p) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    69
    assert (!oopDesc::is_null(*p), "expected non-null ref");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    70
    assert ((oopDesc::load_decode_heap_oop_not_null(p))->is_oop(),
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    71
            "expected an oop while scanning weak refs");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    // Weak refs may be visited more than once.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    74
    if (PSScavenge::should_scavenge(p, _to_space)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
      PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    78
  virtual void do_oop(oop* p)       { PSKeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    79
  virtual void do_oop(narrowOop* p) { PSKeepAliveClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
class PSEvacuateFollowersClosure: public VoidClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  PSPromotionManager* _promotion_manager;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  PSEvacuateFollowersClosure(PSPromotionManager* pm) : _promotion_manager(pm) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    88
  virtual void do_void() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    assert(_promotion_manager != NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    _promotion_manager->drain_stacks(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    guarantee(_promotion_manager->stacks_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
              "stacks should be empty at this point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
class PSPromotionFailedClosure : public ObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  virtual void do_object(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    if (obj->is_forwarded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
      obj->init_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
class PSRefProcTaskProxy: public GCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  ProcessTask & _rp_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  uint          _work_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    : _rp_task(rp_task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
      _work_id(work_id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  virtual char* name() { return (char *)"Process referents by policy in parallel"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  virtual void do_it(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  PSPromotionManager* promotion_manager =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    PSPromotionManager::gc_thread_promotion_manager(which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  assert(promotion_manager != NULL, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  PSKeepAliveClosure keep_alive(promotion_manager);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  PSEvacuateFollowersClosure evac_followers(promotion_manager);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  PSIsAliveClosure is_alive;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  _rp_task.work(_work_id, is_alive, keep_alive, evac_followers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
class PSRefEnqueueTaskProxy: public GCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  EnqueueTask& _enq_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  uint         _work_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  PSRefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    : _enq_task(enq_task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
      _work_id(work_id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  virtual void do_it(GCTaskManager* manager, uint which)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    _enq_task.work(_work_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  virtual void execute(ProcessTask& task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  virtual void execute(EnqueueTask& task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
void PSRefProcTaskExecutor::execute(ProcessTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  GCTaskQueue* q = GCTaskQueue::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  for(uint i=0; i<ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    q->enqueue(new PSRefProcTaskProxy(task, i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  ParallelTaskTerminator terminator(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    ParallelScavengeHeap::gc_task_manager()->workers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    UseDepthFirstScavengeOrder ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
        (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
      : (TaskQueueSetSuper*) PSPromotionManager::stack_array_breadth());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  if (task.marks_oops_alive() && ParallelGCThreads > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    for (uint j=0; j<ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
      q->enqueue(new StealTask(&terminator));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
void PSRefProcTaskExecutor::execute(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  GCTaskQueue* q = GCTaskQueue::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  for(uint i=0; i<ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    q->enqueue(new PSRefEnqueueTaskProxy(task, i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
// This method contains all heap specific policy for invoking scavenge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// PSScavenge::invoke_no_policy() will do nothing but attempt to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
// scavenge. It will not clean up after failed promotions, bail out if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
// we've exceeded policy time limits, or any other special behavior.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
// All such policy should be placed here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
// Note that this method should only be called from the vm_thread while
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
// at a safepoint!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
void PSScavenge::invoke()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  assert(!Universe::heap()->is_gc_active(), "not reentrant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  PSAdaptiveSizePolicy* policy = heap->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // Before each allocation/collection attempt, find out from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // policy object if GCs are, on the whole, taking too long. If so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  // bail out without attempting a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  if (!policy->gc_time_limit_exceeded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    IsGCActiveMark mark;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    bool scavenge_was_done = PSScavenge::invoke_no_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    if (UsePerfData)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
      counters->update_full_follows_scavenge(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    if (!scavenge_was_done ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
        policy->should_full_GC(heap->old_gen()->free_in_bytes())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
      if (UsePerfData)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
        counters->update_full_follows_scavenge(full_follows_scavenge);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
      GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
      if (UseParallelOldGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
        PSParallelCompact::invoke_no_policy(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        PSMarkSweep::invoke_no_policy(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
// This method contains no policy. You should probably
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
// be calling invoke() instead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
bool PSScavenge::invoke_no_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  TimeStamp scavenge_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  TimeStamp scavenge_midpoint;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  TimeStamp scavenge_exit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  scavenge_entry.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  if (GC_locker::check_active_before_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  GCCause::Cause gc_cause = heap->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  // Check for potential problems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  if (!should_attempt_scavenge()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  bool promotion_failure_occurred = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  PSPermGen* perm_gen = heap->perm_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  PSAdaptiveSizePolicy* size_policy = heap->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  heap->increment_total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  if ((gc_cause != GCCause::_java_lang_system_gc) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
       UseAdaptiveSizePolicyWithSystemGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    // Gather the feedback data for eden occupancy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    young_gen->eden_space()->accumulate_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   268
  if (ZapUnusedHeapArea) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   269
    // Save information needed to minimize mangling
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   270
    heap->record_gen_tops_before_GC();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   271
  }
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   272
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  if (PrintHeapAtGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    Universe::print_heap_before_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  size_t prev_used = heap->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  assert(promotion_failed() == false, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // Fill in TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  heap->accumulate_statistics_all_tlabs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  heap->ensure_parsability(true);  // retire TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    gclog_or_tty->print(" VerifyBeforeGC:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    TraceMemoryManagerStats tms(false /* not full GC */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    if (TraceGen0Time) accumulated_time()->start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    // Let the size policy know we're starting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    size_policy->minor_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    // Verify the object start arrays.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    if (VerifyObjectStartArray &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
        VerifyBeforeGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
      old_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
      perm_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    // Verify no unmarked old->young roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    if (VerifyRememberedSets) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
      CardTableExtension::verify_all_young_refs_imprecise();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    if (!ScavengeWithObjectsInToSpace) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
      assert(young_gen->to_space()->is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
             "Attempt to scavenge with live objects in to_space");
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   323
      young_gen->to_space()->clear(SpaceDecorator::Mangle);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
    } else if (ZapUnusedHeapArea) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      young_gen->to_space()->mangle_unused_area();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    save_to_space_top_before_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    COMPILER2_PRESENT(DerivedPointerTable::clear());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    reference_processor()->enable_discovery();
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 977
diff changeset
   333
    reference_processor()->snap_policy(false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    // We track how much was promoted to the next generation for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    // the AdaptiveSizePolicy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    size_t old_gen_used_before = old_gen->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    // For PrintGCDetails
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    size_t young_gen_used_before = young_gen->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    // Reset our survivor overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    set_survivor_overflow(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    // We need to save the old/perm top values before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
    // creating the promotion_manager. We pass the top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
    // values to the card_table, to prevent it from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    // straying into the promotion labs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
    HeapWord* old_top = old_gen->object_space()->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    HeapWord* perm_top = perm_gen->object_space()->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    // Release all previously held resources
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    gc_task_manager()->release_all_resources();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    PSPromotionManager::pre_scavenge();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    // We'll use the promotion manager again later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
      // TraceTime("Roots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
      GCTaskQueue* q = GCTaskQueue::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
      for(uint i=0; i<ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
        q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
      q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
      // We scan the thread roots in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
      Threads::create_thread_roots_tasks(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
      ParallelTaskTerminator terminator(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
        gc_task_manager()->workers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
        promotion_manager->depth_first() ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
            (TaskQueueSetSuper*) promotion_manager->stack_array_depth()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
          : (TaskQueueSetSuper*) promotion_manager->stack_array_breadth());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      if (ParallelGCThreads>1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
        for (uint j=0; j<ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
          q->enqueue(new StealTask(&terminator));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
      gc_task_manager()->execute_and_wait(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    scavenge_midpoint.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    // Process reference objects discovered during scavenge
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
    {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 977
diff changeset
   398
      reference_processor()->snap_policy(false); // not always_clear
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
      PSKeepAliveClosure keep_alive(promotion_manager);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
      PSEvacuateFollowersClosure evac_followers(promotion_manager);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
      if (reference_processor()->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
        PSRefProcTaskExecutor task_executor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        reference_processor()->process_discovered_references(
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 977
diff changeset
   404
          &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
        reference_processor()->process_discovered_references(
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 977
diff changeset
   407
          &_is_alive_closure, &keep_alive, &evac_followers, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    // Enqueue reference objects discovered during scavenge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    if (reference_processor()->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
      PSRefProcTaskExecutor task_executor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
      reference_processor()->enqueue_discovered_references(&task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
      reference_processor()->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    // Finally, flush the promotion_manager's labs, and deallocate its stacks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
    assert(promotion_manager->claimed_stack_empty(), "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    PSPromotionManager::post_scavenge();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    promotion_failure_occurred = promotion_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    if (promotion_failure_occurred) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
      clean_up_failed_promotion();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
        gclog_or_tty->print("--");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
    // Let the size policy know we're done.  Note that we count promotion
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    // failure cleanup time as part of the collection (otherwise, we're
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
    // implicitly saying it's mutator time).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    size_policy->minor_collection_end(gc_cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    if (!promotion_failure_occurred) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      // Swap the survivor spaces.
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   438
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   439
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   440
      young_gen->eden_space()->clear(SpaceDecorator::Mangle);
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   441
      young_gen->from_space()->clear(SpaceDecorator::Mangle);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      young_gen->swap_spaces();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      size_t survived = young_gen->from_space()->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
      size_t promoted = old_gen->used_in_bytes() - old_gen_used_before;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      size_policy->update_averages(_survivor_overflow, survived, promoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
      if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        // Calculate the new survivor size and tenuring threshold
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
        if (PrintAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
          gclog_or_tty->print("AdaptiveSizeStart: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
          gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
          gclog_or_tty->print_cr(" collection: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
                         heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
          if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
            gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
              " perm_gen_capacity: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
              old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
              perm_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
          PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
          counters->update_old_eden_size(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
            size_policy->calculated_eden_size_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
          counters->update_old_promo_size(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
            size_policy->calculated_promo_size_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
          counters->update_old_capacity(old_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
          counters->update_young_capacity(young_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
          counters->update_survived(survived);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
          counters->update_promoted(promoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
          counters->update_survivor_overflowed(_survivor_overflow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
        size_t survivor_limit =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
          size_policy->max_survivor_size(young_gen->max_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        _tenuring_threshold =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
          size_policy->compute_survivor_space_size_and_threshold(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
                                                           _survivor_overflow,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
                                                           _tenuring_threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
                                                           survivor_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
       if (PrintTenuringDistribution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
         gclog_or_tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
         gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
                                size_policy->calculated_survivor_size_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
                                _tenuring_threshold, MaxTenuringThreshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
       }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
        if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
          PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
          counters->update_tenuring_threshold(_tenuring_threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
          counters->update_survivor_size_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
        // Do call at minor collections?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
        // Don't check if the size_policy is ready at this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
        // level.  Let the size_policy check that internally.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
        if (UseAdaptiveSizePolicy &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
            UseAdaptiveGenerationSizePolicyAtMinorCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
            ((gc_cause != GCCause::_java_lang_system_gc) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
              UseAdaptiveSizePolicyWithSystemGC)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
          // Calculate optimial free space amounts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
          assert(young_gen->max_size() >
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
            young_gen->from_space()->capacity_in_bytes() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
            young_gen->to_space()->capacity_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
            "Sizes of space in young gen are out-of-bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
          size_t max_eden_size = young_gen->max_size() -
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
            young_gen->from_space()->capacity_in_bytes() -
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
            young_gen->to_space()->capacity_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
          size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
                                   young_gen->eden_space()->used_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
                                   old_gen->used_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
                                   perm_gen->used_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
                                   young_gen->eden_space()->capacity_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
                                   old_gen->max_gen_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
                                   max_eden_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
                                   false  /* full gc*/,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
                                   gc_cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
        // Resize the young generation at every collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
        // even if new sizes have not been calculated.  This is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
        // to allow resizes that may have been inhibited by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        // relative location of the "to" and "from" spaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
        // Resizing the old gen at minor collects can cause increases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
        // that don't feed back to the generation sizing policy until
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
        // a major collection.  Don't resize the old gen here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
        heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
                        size_policy->calculated_survivor_size_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
        if (PrintAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
          gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
                         heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
      // cause the change of the heap layout. Make sure eden is reshaped if that's the case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
      // Also update() will case adaptive NUMA chunk resizing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      assert(young_gen->eden_space()->is_empty(), "eden space should be empty now");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
      young_gen->eden_space()->update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
      heap->gc_policy_counters()->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
      heap->resize_all_tlabs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
      assert(young_gen->to_space()->is_empty(), "to space should be empty now");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    // Re-verify object start arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    if (VerifyObjectStartArray &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
        VerifyAfterGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      old_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
      perm_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    // Verify all old -> young cards are now precise
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    if (VerifyRememberedSets) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
      // Precise verification will give false positives. Until this is fixed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
      // use imprecise verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
      // CardTableExtension::verify_all_young_refs_precise();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
      CardTableExtension::verify_all_young_refs_imprecise();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    if (TraceGen0Time) accumulated_time()->stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
        // Don't print a GC timestamp here.  This is after the GC so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
        // would be confusing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
        young_gen->print_used_change(young_gen_used_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
      heap->print_heap_change(prev_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    // Track memory usage and detect low memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    MemoryService::track_memory_usage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    heap->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    gclog_or_tty->print(" VerifyAfterGC:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    Universe::verify(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  if (PrintHeapAtGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    Universe::print_heap_after_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   603
  if (ZapUnusedHeapArea) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   604
    young_gen->eden_space()->check_mangled_unused_area_complete();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   605
    young_gen->from_space()->check_mangled_unused_area_complete();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   606
    young_gen->to_space()->check_mangled_unused_area_complete();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   607
  }
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   608
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  scavenge_exit.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  if (PrintGCTaskTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
                  scavenge_entry.ticks(), scavenge_midpoint.ticks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
                  scavenge_exit.ticks());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    gc_task_manager()->print_task_time_stamps();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  return !promotion_failure_occurred;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
// This method iterates over all objects in the young generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
// unforwarding markOops. It then restores any preserved mark oops,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
// and clears the _preserved_mark_stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
void PSScavenge::clean_up_failed_promotion() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  assert(promotion_failed(), "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    // Unforward all pointers in the young gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    PSPromotionFailedClosure unforward_closure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    young_gen->object_iterate(&unforward_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      gclog_or_tty->print_cr("Restoring %d marks",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
                              _preserved_oop_stack->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    // Restore any saved marks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
    for (int i=0; i < _preserved_oop_stack->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
      oop obj       = _preserved_oop_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
      markOop mark  = _preserved_mark_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
      obj->set_mark(mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    // Deallocate the preserved mark and oop stacks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    // The stacks were allocated as CHeap objects, so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    // we must call delete to prevent mem leaks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    delete _preserved_mark_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    _preserved_mark_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    delete _preserved_oop_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    _preserved_oop_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  // Reset the PromotionFailureALot counters.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
// This method is called whenever an attempt to promote an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
// fails. Some markOops will need preserving, some will not. Note
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// that the entire eden is traversed after a failed promotion, with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// all forwarded headers replaced by the default markOop. This means
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
// it is not neccessary to preserve most markOops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  if (_preserved_mark_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    ThreadCritical tc; // Lock and retest
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
    if (_preserved_mark_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
      assert(_preserved_oop_stack == NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
      _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
      _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  // Because we must hold the ThreadCritical lock before using
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  // the stacks, we should be safe from observing partial allocations,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  // which are also guarded by the ThreadCritical lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    ThreadCritical tc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
    _preserved_oop_stack->push(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    _preserved_mark_stack->push(obj_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
bool PSScavenge::should_attempt_scavenge() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
    counters->update_scavenge_skipped(not_skipped);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  if (!ScavengeWithObjectsInToSpace) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    // Do not attempt to promote unless to_space is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    if (!young_gen->to_space()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
      _consecutive_skipped_scavenges++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
      if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
        counters->update_scavenge_skipped(to_space_not_empty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  // Test to see if the scavenge will likely fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  PSAdaptiveSizePolicy* policy = heap->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  // A similar test is done in the policy's should_full_GC().  If this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  // changed, decide if that test should also be changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  bool result = promotion_estimate < old_gen->free_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
    gclog_or_tty->print(result ? "  do scavenge: " : "  skip scavenge: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
    gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
      " padded_average_promoted " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
      " free in old gen " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      (size_t) policy->average_promoted_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
      (size_t) policy->padded_average_promoted_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
      old_gen->free_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    if (young_gen->used_in_bytes() <
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
        (size_t) policy->padded_average_promoted_in_bytes()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
      gclog_or_tty->print_cr(" padded_promoted_average is greater"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
        " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    _consecutive_skipped_scavenges = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    _consecutive_skipped_scavenges++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
      counters->update_scavenge_skipped(promoted_too_large);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  // Used to add tasks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
GCTaskManager* const PSScavenge::gc_task_manager() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  assert(ParallelScavengeHeap::gc_task_manager() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
   "shouldn't return NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  return ParallelScavengeHeap::gc_task_manager();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
void PSScavenge::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  // Arguments must have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  if (AlwaysTenure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    _tenuring_threshold = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  } else if (NeverTenure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
    _tenuring_threshold = markOopDesc::max_age + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
    // We want to smooth out our startup times for the AdaptiveSizePolicy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
    _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
                                                    MaxTenuringThreshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  PSPermGen* perm_gen = heap->perm_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  // Set boundary between young_gen and old_gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  assert(perm_gen->reserved().end() <= old_gen->object_space()->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
         "perm above old");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
         "old above young");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  _young_generation_boundary = young_gen->eden_space()->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  // Initialize ref handling object for scavenging.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  MemRegion mr = young_gen->reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  _ref_processor = ReferenceProcessor::create_ref_processor(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    mr,                         // span
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    true,                       // atomic_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
    true,                       // mt_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    NULL,                       // is_alive_non_header
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    ParallelGCThreads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
    ParallelRefProcEnabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  // Cache the cardtable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  BarrierSet* bs = Universe::heap()->barrier_set();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
  assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  _card_table = (CardTableExtension*)bs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  _counters = new CollectorCounters("PSScavenge", 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
}