g1RootClosures.cpp revision 11020:c0ea2e3ebe83
1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "gc/g1/g1OopClosures.inline.hpp"
27#include "gc/g1/g1RootClosures.hpp"
28#include "gc/g1/g1SharedClosures.hpp"
29
30// Closures used for standard G1 evacuation.
31class G1EvacuationClosures : public G1EvacuationRootClosures {
32  G1SharedClosures<G1MarkNone> _closures;
33
34public:
35  G1EvacuationClosures(G1CollectedHeap* g1h,
36                       G1ParScanThreadState* pss,
37                       bool gcs_are_young) :
38      _closures(g1h, pss, gcs_are_young, /* must_claim_cld */ false) {}
39
40  OopClosure* weak_oops()   { return &_closures._buffered_oops; }
41  OopClosure* strong_oops() { return &_closures._buffered_oops; }
42
43  CLDClosure* weak_clds()             { return &_closures._clds; }
44  CLDClosure* strong_clds()           { return &_closures._clds; }
45  CLDClosure* second_pass_weak_clds() { return NULL; }
46
47  CodeBlobClosure* strong_codeblobs()      { return &_closures._codeblobs; }
48  CodeBlobClosure* weak_codeblobs()        { return &_closures._codeblobs; }
49
50  void flush()                 { _closures._buffered_oops.done(); }
51  double closure_app_seconds() { return _closures._buffered_oops.closure_app_seconds(); }
52
53  OopClosure* raw_strong_oops() { return &_closures._oops; }
54
55  bool trace_metadata()         { return false; }
56};
57
58// Closures used during initial mark.
59// The treatment of "weak" roots is selectable through the template parameter,
60// this is usually used to control unloading of classes and interned strings.
61template <G1Mark MarkWeak>
62class G1InitalMarkClosures : public G1EvacuationRootClosures {
63  G1SharedClosures<G1MarkFromRoot> _strong;
64  G1SharedClosures<MarkWeak>       _weak;
65
66  // Filter method to help with returning the appropriate closures
67  // depending on the class template parameter.
68  template <G1Mark Mark, typename T>
69  T* null_if(T* t) {
70    if (Mark == MarkWeak) {
71      return NULL;
72    }
73    return t;
74  }
75
76public:
77  G1InitalMarkClosures(G1CollectedHeap* g1h,
78                       G1ParScanThreadState* pss) :
79      _strong(g1h, pss, /* process_only_dirty_klasses */ false, /* must_claim_cld */ true),
80      _weak(g1h, pss,   /* process_only_dirty_klasses */ false, /* must_claim_cld */ true) {}
81
82  OopClosure* weak_oops()   { return &_weak._buffered_oops; }
83  OopClosure* strong_oops() { return &_strong._buffered_oops; }
84
85  // If MarkWeak is G1MarkPromotedFromRoot then the weak CLDs must be processed in a second pass.
86  CLDClosure* weak_clds()             { return null_if<G1MarkPromotedFromRoot>(&_weak._clds); }
87  CLDClosure* strong_clds()           { return &_strong._clds; }
88
89  // If MarkWeak is G1MarkFromRoot then all CLDs are processed by the weak and strong variants
90  // return a NULL closure for the following specialized versions in that case.
91  CLDClosure* second_pass_weak_clds() { return null_if<G1MarkFromRoot>(&_weak._clds); }
92
93  CodeBlobClosure* strong_codeblobs()      { return &_strong._codeblobs; }
94  CodeBlobClosure* weak_codeblobs()        { return &_weak._codeblobs; }
95
96  void flush() {
97    _strong._buffered_oops.done();
98    _weak._buffered_oops.done();
99  }
100
101  double closure_app_seconds() {
102    return _strong._buffered_oops.closure_app_seconds() +
103           _weak._buffered_oops.closure_app_seconds();
104  }
105
106  OopClosure* raw_strong_oops() { return &_strong._oops; }
107
108  // If we are not marking all weak roots then we are tracing
109  // which metadata is alive.
110  bool trace_metadata()         { return MarkWeak == G1MarkPromotedFromRoot; }
111};
112
113G1EvacuationRootClosures* G1EvacuationRootClosures::create_root_closures(G1ParScanThreadState* pss, G1CollectedHeap* g1h) {
114  G1EvacuationRootClosures* res = create_root_closures_ext(pss, g1h);
115  if (res != NULL) {
116    return res;
117  }
118
119  if (g1h->collector_state()->during_initial_mark_pause()) {
120    if (ClassUnloadingWithConcurrentMark) {
121      res = new G1InitalMarkClosures<G1MarkPromotedFromRoot>(g1h, pss);
122    } else {
123      res = new G1InitalMarkClosures<G1MarkFromRoot>(g1h, pss);
124    }
125  } else {
126    res = new G1EvacuationClosures(g1h, pss, g1h->collector_state()->gcs_are_young());
127  }
128  return res;
129}
130