52 class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
53 private:
54 size_t _pages_per_region;
55
56 public:
57 G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs,
58 size_t os_commit_granularity,
59 size_t alloc_granularity,
60 size_t commit_factor,
61 MemoryType type) :
62 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
63 _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) {
64
65 guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity");
66 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
67 }
68
69 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
70 _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
71 _commit_map.set_range(start_idx, start_idx + num_regions);
72 fire_on_commit(start_idx, num_regions);
73 }
74
75 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
76 _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region);
77 _commit_map.clear_range(start_idx, start_idx + num_regions);
78 }
79 };
80
81 // G1RegionToSpaceMapper implementation where the region granularity is smaller
82 // than the commit granularity.
83 // Basically, the contents of one OS page span several regions.
84 class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
85 private:
86 class CommitRefcountArray : public G1BiasedMappedArray<uint> {
87 protected:
88 virtual uint default_value() const { return 0; }
89 };
90
91 size_t _regions_per_page;
92
98
99 public:
100 G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs,
101 size_t os_commit_granularity,
102 size_t alloc_granularity,
103 size_t commit_factor,
104 MemoryType type) :
105 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
106 _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() {
107
108 guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
109 _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity);
110 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
111 }
112
113 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
114 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
115 assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
116 uintptr_t idx = region_idx_to_page_idx(i);
117 uint old_refcount = _refcounts.get_by_index(idx);
118 if (old_refcount == 0) {
119 _storage.commit(idx, 1);
120 }
121 _refcounts.set_by_index(idx, old_refcount + 1);
122 _commit_map.set_bit(i);
123 fire_on_commit(i, 1);
124 }
125 }
126
127 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
128 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
129 assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i));
130 uintptr_t idx = region_idx_to_page_idx(i);
131 uint old_refcount = _refcounts.get_by_index(idx);
132 assert(old_refcount > 0, "must be");
133 if (old_refcount == 1) {
134 _storage.uncommit(idx, 1);
135 }
136 _refcounts.set_by_index(idx, old_refcount - 1);
137 _commit_map.clear_bit(i);
138 }
139 }
140 };
141
142 void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions) {
143 if (_listener != NULL) {
144 _listener->on_commit(start_idx, num_regions);
145 }
146 }
147
148 G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
149 size_t os_commit_granularity,
150 size_t region_granularity,
151 size_t commit_factor,
152 MemoryType type) {
153
154 if (region_granularity >= (os_commit_granularity * commit_factor)) {
155 return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
156 } else {
157 return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
158 }
159 }
|
52 class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
53 private:
54 size_t _pages_per_region;
55
56 public:
57 G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs,
58 size_t os_commit_granularity,
59 size_t alloc_granularity,
60 size_t commit_factor,
61 MemoryType type) :
62 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
63 _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) {
64
65 guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity");
66 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
67 }
68
69 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
70 _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
71 _commit_map.set_range(start_idx, start_idx + num_regions);
72 fire_on_commit(start_idx, num_regions, true);
73 }
74
75 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
76 _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region);
77 _commit_map.clear_range(start_idx, start_idx + num_regions);
78 }
79 };
80
81 // G1RegionToSpaceMapper implementation where the region granularity is smaller
82 // than the commit granularity.
83 // Basically, the contents of one OS page span several regions.
84 class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
85 private:
86 class CommitRefcountArray : public G1BiasedMappedArray<uint> {
87 protected:
88 virtual uint default_value() const { return 0; }
89 };
90
91 size_t _regions_per_page;
92
98
99 public:
100 G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs,
101 size_t os_commit_granularity,
102 size_t alloc_granularity,
103 size_t commit_factor,
104 MemoryType type) :
105 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
106 _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() {
107
108 guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
109 _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity);
110 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
111 }
112
113 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
114 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
115 assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
116 uintptr_t idx = region_idx_to_page_idx(i);
117 uint old_refcount = _refcounts.get_by_index(idx);
118 bool zero_filled = false;
119 if (old_refcount == 0) {
120 _storage.commit(idx, 1);
121 zero_filled = true;
122 }
123 _refcounts.set_by_index(idx, old_refcount + 1);
124 _commit_map.set_bit(i);
125 fire_on_commit(i, 1, zero_filled);
126 }
127 }
128
129 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
130 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
131 assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i));
132 uintptr_t idx = region_idx_to_page_idx(i);
133 uint old_refcount = _refcounts.get_by_index(idx);
134 assert(old_refcount > 0, "must be");
135 if (old_refcount == 1) {
136 _storage.uncommit(idx, 1);
137 }
138 _refcounts.set_by_index(idx, old_refcount - 1);
139 _commit_map.clear_bit(i);
140 }
141 }
142 };
143
144 void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
145 if (_listener != NULL) {
146 _listener->on_commit(start_idx, num_regions, zero_filled);
147 }
148 }
149
150 G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
151 size_t os_commit_granularity,
152 size_t region_granularity,
153 size_t commit_factor,
154 MemoryType type) {
155
156 if (region_granularity >= (os_commit_granularity * commit_factor)) {
157 return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
158 } else {
159 return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
160 }
161 }
|