annotate src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp @ 20543:e7d0505c8a30

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
author tschatzl
date Fri, 10 Oct 2014 15:51:58 +0200
parents 7b2fc3129653
children ae52ee069062
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
1 /*
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
4 *
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
7 * published by the Free Software Foundation.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
8 *
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
13 * accompanied this code).
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
14 *
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
18 *
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
21 * questions.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
22 *
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
23 */
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
24
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
25 #include "precompiled.hpp"
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
26 #include "gc_implementation/g1/g1BiasedArray.hpp"
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
27 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
20339
7b2fc3129653 8055635: Missing include in g1RegionToSpaceMapper.hpp results in unresolved symbol of fastdebug build without precompiled headers
tschatzl
parents: 20337
diff changeset
28 #include "memory/allocation.inline.hpp"
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
29 #include "runtime/virtualspace.hpp"
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
30 #include "services/memTracker.hpp"
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
31 #include "utilities/bitMap.inline.hpp"
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
32
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
33 G1RegionToSpaceMapper::G1RegionToSpaceMapper(ReservedSpace rs,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
34 size_t commit_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
35 size_t region_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
36 MemoryType type) :
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
37 _storage(),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
38 _commit_granularity(commit_granularity),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
39 _region_granularity(region_granularity),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
40 _listener(NULL),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
41 _commit_map() {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
42 guarantee(is_power_of_2(commit_granularity), "must be");
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
43 guarantee(is_power_of_2(region_granularity), "must be");
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
44 _storage.initialize_with_granularity(rs, commit_granularity);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
45
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
46 MemTracker::record_virtual_memory_type((address)rs.base(), type);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
47 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
48
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
49 // G1RegionToSpaceMapper implementation where the region granularity is larger than
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
50 // or the same as the commit granularity.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
51 // Basically, the space corresponding to one region region spans several OS pages.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
52 class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
53 private:
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
54 size_t _pages_per_region;
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
55
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
56 public:
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
57 G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
58 size_t os_commit_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
59 size_t alloc_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
60 size_t commit_factor,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
61 MemoryType type) :
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
62 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
63 _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
64
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
65 guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity");
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
66 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
67 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
68
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
69 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
70 _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
71 _commit_map.set_range(start_idx, start_idx + num_regions);
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
72 fire_on_commit(start_idx, num_regions, true);
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
73 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
74
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
75 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
76 _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
77 _commit_map.clear_range(start_idx, start_idx + num_regions);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
78 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
79 };
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
80
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
81 // G1RegionToSpaceMapper implementation where the region granularity is smaller
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
82 // than the commit granularity.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
83 // Basically, the contents of one OS page span several regions.
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
84 class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
85 private:
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
86 class CommitRefcountArray : public G1BiasedMappedArray<uint> {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
87 protected:
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
88 virtual uint default_value() const { return 0; }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
89 };
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
90
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
91 size_t _regions_per_page;
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
92
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
93 CommitRefcountArray _refcounts;
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
94
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
95 uintptr_t region_idx_to_page_idx(uint region) const {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
96 return region / _regions_per_page;
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
97 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
98
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
99 public:
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
100 G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
101 size_t os_commit_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
102 size_t alloc_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
103 size_t commit_factor,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
104 MemoryType type) :
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
105 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
106 _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
107
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
108 guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
109 _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
110 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
111 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
112
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
113 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
114 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
115 assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
116 uintptr_t idx = region_idx_to_page_idx(i);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
117 uint old_refcount = _refcounts.get_by_index(idx);
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
118 bool zero_filled = false;
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
119 if (old_refcount == 0) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
120 _storage.commit(idx, 1);
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
121 zero_filled = true;
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
122 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
123 _refcounts.set_by_index(idx, old_refcount + 1);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
124 _commit_map.set_bit(i);
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
125 fire_on_commit(i, 1, zero_filled);
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
126 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
127 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
128
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
129 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
130 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
131 assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i));
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
132 uintptr_t idx = region_idx_to_page_idx(i);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
133 uint old_refcount = _refcounts.get_by_index(idx);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
134 assert(old_refcount > 0, "must be");
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
135 if (old_refcount == 1) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
136 _storage.uncommit(idx, 1);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
137 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
138 _refcounts.set_by_index(idx, old_refcount - 1);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
139 _commit_map.clear_bit(i);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
140 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
141 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
142 };
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
143
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
144 void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
145 if (_listener != NULL) {
20543
e7d0505c8a30 8059758: Footprint regressions with JDK-8038423
tschatzl
parents: 20339
diff changeset
146 _listener->on_commit(start_idx, num_regions, zero_filled);
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
147 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
148 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
149
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
150 G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
151 size_t os_commit_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
152 size_t region_granularity,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
153 size_t commit_factor,
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
154 MemoryType type) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
155
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
156 if (region_granularity >= (os_commit_granularity * commit_factor)) {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
157 return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
158 } else {
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
159 return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
160 }
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents:
diff changeset
161 }