src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 6969
02e61cf08ab3
child 7535
7ae4e26cb1e0
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

ysr@777 1 /*
stefank@6969 2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
stefank@2314 27
stefank@6969 28 #include "memory/iterator.hpp"
stefank@6969 29 #include "oops/oopsHierarchy.hpp"
stefank@2314 30 #include "runtime/os.hpp"
stefank@6969 31 #include "utilities/debug.hpp"
stefank@2314 32
ysr@777 33 // A BufferingOops closure tries to separate out the cost of finding roots
ysr@777 34 // from the cost of applying closures to them. It maintains an array of
ysr@777 35 // ref-containing locations. Until the array is full, applying the closure
ysr@777 36 // to an oop* merely records that location in the array. Since this
ysr@777 37 // closure app cost is small, an elapsed timer can approximately attribute
ysr@777 38 // all of this cost to the cost of finding the roots. When the array fills
ysr@777 39 // up, the wrapped closure is applied to all elements, keeping track of
ysr@777 40 // this elapsed time of this process, and leaving the array empty.
ysr@777 41 // The caller must be sure to call "done" to process any unprocessed
ysr@777 42 // buffered entriess.
ysr@777 43
stefank@6969 44 class BufferingOopClosure: public OopClosure {
stefank@6969 45 friend class TestBufferingOopClosure;
stefank@6969 46 protected:
stefank@6969 47 static const size_t BufferLength = 1024;
ysr@777 48
stefank@6969 49 // We need to know if the buffered addresses contain oops or narrowOops.
stefank@6969 50 // We can't tag the addresses the way StarTask does, because we need to
stefank@6969 51 // be able to handle unaligned addresses coming from oops embedded in code.
stefank@6969 52 //
stefank@6969 53 // The addresses for the full-sized oops are filled in from the bottom,
stefank@6969 54 // while the addresses for the narrowOops are filled in from the top.
stefank@6969 55 OopOrNarrowOopStar _buffer[BufferLength];
stefank@6969 56 OopOrNarrowOopStar* _oop_top;
stefank@6969 57 OopOrNarrowOopStar* _narrowOop_bottom;
ysr@777 58
ysr@1280 59 OopClosure* _oc;
ysr@1280 60 double _closure_app_seconds;
ysr@777 61
stefank@6969 62
stefank@6969 63 bool is_buffer_empty() {
stefank@6969 64 return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);
stefank@6969 65 }
stefank@6969 66
stefank@6969 67 bool is_buffer_full() {
stefank@6969 68 return _narrowOop_bottom < _oop_top;
stefank@6969 69 }
stefank@6969 70
stefank@6969 71 // Process addresses containing full-sized oops.
stefank@6969 72 void process_oops() {
stefank@6969 73 for (OopOrNarrowOopStar* curr = _buffer; curr < _oop_top; ++curr) {
stefank@6969 74 _oc->do_oop((oop*)(*curr));
stefank@6969 75 }
stefank@6969 76 _oop_top = _buffer;
stefank@6969 77 }
stefank@6969 78
stefank@6969 79 // Process addresses containing narrow oops.
stefank@6969 80 void process_narrowOops() {
stefank@6969 81 for (OopOrNarrowOopStar* curr = _buffer + BufferLength - 1; curr > _narrowOop_bottom; --curr) {
stefank@6969 82 _oc->do_oop((narrowOop*)(*curr));
stefank@6969 83 }
stefank@6969 84 _narrowOop_bottom = _buffer + BufferLength - 1;
stefank@6969 85 }
stefank@6969 86
stefank@6969 87 // Apply the closure to all oops and clear the buffer.
stefank@6969 88 // Accumulate the time it took.
stefank@6969 89 void process_buffer() {
ysr@777 90 double start = os::elapsedTime();
stefank@6969 91
stefank@6969 92 process_oops();
stefank@6969 93 process_narrowOops();
stefank@6969 94
ysr@777 95 _closure_app_seconds += (os::elapsedTime() - start);
ysr@777 96 }
ysr@777 97
stefank@6969 98 void process_buffer_if_full() {
stefank@6969 99 if (is_buffer_full()) {
ysr@777 100 process_buffer();
ysr@777 101 }
stefank@6969 102 }
stefank@6969 103
stefank@6969 104 void add_narrowOop(narrowOop* p) {
stefank@6969 105 assert(!is_buffer_full(), "Buffer should not be full");
stefank@6969 106 *_narrowOop_bottom = (OopOrNarrowOopStar)p;
stefank@6969 107 _narrowOop_bottom--;
stefank@6969 108 }
stefank@6969 109
stefank@6969 110 void add_oop(oop* p) {
stefank@6969 111 assert(!is_buffer_full(), "Buffer should not be full");
stefank@6969 112 *_oop_top = (OopOrNarrowOopStar)p;
stefank@6969 113 _oop_top++;
ysr@777 114 }
ysr@1280 115
ysr@1280 116 public:
stefank@6969 117 virtual void do_oop(narrowOop* p) {
stefank@6969 118 process_buffer_if_full();
stefank@6969 119 add_narrowOop(p);
stefank@6969 120 }
ysr@1280 121
stefank@6969 122 virtual void do_oop(oop* p) {
stefank@6969 123 process_buffer_if_full();
stefank@6969 124 add_oop(p);
stefank@6969 125 }
stefank@6969 126
stefank@6969 127 void done() {
stefank@6969 128 if (!is_buffer_empty()) {
ysr@777 129 process_buffer();
ysr@777 130 }
ysr@777 131 }
stefank@6969 132
stefank@6969 133 double closure_app_seconds() {
ysr@777 134 return _closure_app_seconds;
ysr@777 135 }
stefank@6969 136
stefank@6969 137 BufferingOopClosure(OopClosure *oc) :
ysr@777 138 _oc(oc),
stefank@6969 139 _oop_top(_buffer),
stefank@6969 140 _narrowOop_bottom(_buffer + BufferLength - 1),
ysr@777 141 _closure_app_seconds(0.0) { }
ysr@777 142 };
ysr@777 143
stefank@2314 144 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP

mercurial