50 assert(contain_region(addr, size), "Not contain this region"); |
53 assert(contain_region(addr, size), "Not contain this region"); |
51 |
54 |
52 if (all_committed()) return true; |
55 if (all_committed()) return true; |
53 |
56 |
54 CommittedMemoryRegion committed_rgn(addr, size, stack); |
57 CommittedMemoryRegion committed_rgn(addr, size, stack); |
55 LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.find_node(committed_rgn); |
58 LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head(); |
56 if (node != NULL) { |
59 |
|
60 while (node != NULL) { |
57 CommittedMemoryRegion* rgn = node->data(); |
61 CommittedMemoryRegion* rgn = node->data(); |
58 if (rgn->same_region(addr, size)) { |
62 if (rgn->same_region(addr, size)) { |
59 return true; |
63 return true; |
60 } |
64 } |
61 |
65 |
62 if (rgn->adjacent_to(addr, size)) { |
66 if (rgn->adjacent_to(addr, size)) { |
63 // check if the next region covers this committed region, |
67 // special case to expand prior region if there is no next region |
64 // the regions may not be merged due to different call stacks |
68 LinkedListNode<CommittedMemoryRegion>* next = node->next(); |
65 LinkedListNode<CommittedMemoryRegion>* next = |
69 if (next == NULL && rgn->call_stack()->equals(stack)) { |
66 node->next(); |
|
67 if (next != NULL && next->data()->contain_region(addr, size)) { |
|
68 if (next->data()->same_region(addr, size)) { |
|
69 next->data()->set_call_stack(stack); |
|
70 } |
|
71 return true; |
|
72 } |
|
73 if (rgn->call_stack()->equals(stack)) { |
|
74 VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag()); |
70 VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag()); |
75 // the two adjacent regions have the same call stack, merge them |
71 // the two adjacent regions have the same call stack, merge them |
76 rgn->expand_region(addr, size); |
72 rgn->expand_region(addr, size); |
77 VirtualMemorySummary::record_committed_memory(rgn->size(), flag()); |
73 VirtualMemorySummary::record_committed_memory(rgn->size(), flag()); |
78 return true; |
74 return true; |
79 } |
75 } |
80 VirtualMemorySummary::record_committed_memory(size, flag()); |
76 } |
81 if (rgn->base() > addr) { |
77 |
82 return _committed_regions.insert_before(committed_rgn, node) != NULL; |
78 if (rgn->overlap_region(addr, size)) { |
83 } else { |
79 // Clear a space for this region in the case it overlaps with any regions. |
84 return _committed_regions.insert_after(committed_rgn, node) != NULL; |
80 remove_uncommitted_region(addr, size); |
85 } |
81 break; // commit below |
86 } |
82 } |
87 assert(rgn->contain_region(addr, size), "Must cover this region"); |
83 if (rgn->end() >= addr + size){ |
88 return true; |
84 break; |
89 } else { |
85 } |
|
86 node = node->next(); |
|
87 } |
|
88 |
90 // New committed region |
89 // New committed region |
91 VirtualMemorySummary::record_committed_memory(size, flag()); |
90 VirtualMemorySummary::record_committed_memory(size, flag()); |
92 return add_committed_region(committed_rgn); |
91 return add_committed_region(committed_rgn); |
93 } |
92 } |
94 } |
|
95 |
93 |
96 void ReservedMemoryRegion::set_all_committed(bool b) { |
94 void ReservedMemoryRegion::set_all_committed(bool b) { |
97 if (all_committed() != b) { |
95 if (all_committed() != b) { |
98 _all_committed = b; |
96 _all_committed = b; |
99 if (b) { |
97 if (b) { |
173 return false; |
171 return false; |
174 } |
172 } |
175 } |
173 } |
176 } |
174 } |
177 } else { |
175 } else { |
178 // we have to walk whole list to remove the committed regions in |
176 CommittedMemoryRegion del_rgn(addr, sz, *call_stack()); |
179 // specified range |
177 address end = addr + sz; |
180 LinkedListNode<CommittedMemoryRegion>* head = |
178 |
181 _committed_regions.head(); |
179 LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head(); |
182 LinkedListNode<CommittedMemoryRegion>* prev = NULL; |
180 LinkedListNode<CommittedMemoryRegion>* prev = NULL; |
183 VirtualMemoryRegion uncommitted_rgn(addr, sz); |
181 CommittedMemoryRegion* crgn; |
184 |
182 |
185 while (head != NULL && !uncommitted_rgn.is_empty()) { |
183 while (head != NULL) { |
186 CommittedMemoryRegion* crgn = head->data(); |
184 crgn = head->data(); |
187 // this committed region overlaps to region to uncommit |
185 |
188 if (crgn->overlap_region(uncommitted_rgn.base(), uncommitted_rgn.size())) { |
186 if (crgn->same_region(addr, sz)) { |
189 if (crgn->same_region(uncommitted_rgn.base(), uncommitted_rgn.size())) { |
187 VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag()); |
190 // find matched region, remove the node will do |
|
191 VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag()); |
|
192 _committed_regions.remove_after(prev); |
188 _committed_regions.remove_after(prev); |
193 return true; |
189 return true; |
194 } else if (crgn->contain_region(uncommitted_rgn.base(), uncommitted_rgn.size())) { |
190 } |
195 // this committed region contains whole uncommitted region |
191 |
196 VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag()); |
192 // del_rgn contains crgn |
197 return remove_uncommitted_region(head, uncommitted_rgn.base(), uncommitted_rgn.size()); |
193 if (del_rgn.contain_region(crgn->base(), crgn->size())) { |
198 } else if (uncommitted_rgn.contain_region(crgn->base(), crgn->size())) { |
|
199 // this committed region has been uncommitted |
|
200 size_t exclude_size = crgn->end() - uncommitted_rgn.base(); |
|
201 uncommitted_rgn.exclude_region(uncommitted_rgn.base(), exclude_size); |
|
202 VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag()); |
194 VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag()); |
203 LinkedListNode<CommittedMemoryRegion>* tmp = head; |
|
204 head = head->next(); |
195 head = head->next(); |
205 _committed_regions.remove_after(prev); |
196 _committed_regions.remove_after(prev); |
206 continue; |
197 continue; // don't update head or prev |
207 } else if (crgn->contain_address(uncommitted_rgn.base())) { |
|
208 size_t toUncommitted = crgn->end() - uncommitted_rgn.base(); |
|
209 crgn->exclude_region(uncommitted_rgn.base(), toUncommitted); |
|
210 uncommitted_rgn.exclude_region(uncommitted_rgn.base(), toUncommitted); |
|
211 VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag()); |
|
212 } else if (uncommitted_rgn.contain_address(crgn->base())) { |
|
213 size_t toUncommitted = uncommitted_rgn.end() - crgn->base(); |
|
214 crgn->exclude_region(crgn->base(), toUncommitted); |
|
215 uncommitted_rgn.exclude_region(uncommitted_rgn.end() - toUncommitted, |
|
216 toUncommitted); |
|
217 VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag()); |
|
218 } |
198 } |
219 } |
199 |
|
200 // Found addr in the current crgn. There are 2 subcases: |
|
201 if (crgn->contain_address(addr)) { |
|
202 |
|
203 // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn) |
|
204 if (crgn->contain_address(end - 1)) { |
|
205 VirtualMemorySummary::record_uncommitted_memory(sz, flag()); |
|
206 return remove_uncommitted_region(head, addr, sz); // done! |
|
207 } else { |
|
208 // (2) Did not find del_rgn's end in crgn. |
|
209 size_t size = crgn->end() - del_rgn.base(); |
|
210 crgn->exclude_region(addr, size); |
|
211 VirtualMemorySummary::record_uncommitted_memory(size, flag()); |
|
212 } |
|
213 |
|
214 } else if (crgn->contain_address(end - 1)) { |
|
215 // Found del_rgn's end, but not its base addr. |
|
216 size_t size = del_rgn.end() - crgn->base(); |
|
217 crgn->exclude_region(crgn->base(), size); |
|
218 VirtualMemorySummary::record_uncommitted_memory(size, flag()); |
|
219 return true; // should be done if the list is sorted properly! |
|
220 } |
|
221 |
220 prev = head; |
222 prev = head; |
221 head = head->next(); |
223 head = head->next(); |
222 } |
224 } |
223 } |
225 } |
224 |
226 |
384 ReservedMemoryRegion rgn(addr, size); |
386 ReservedMemoryRegion rgn(addr, size); |
385 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
387 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
386 |
388 |
387 assert(reserved_rgn != NULL, "No reserved region"); |
389 assert(reserved_rgn != NULL, "No reserved region"); |
388 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
390 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
389 return reserved_rgn->add_committed_region(addr, size, stack); |
391 bool result = reserved_rgn->add_committed_region(addr, size, stack); |
|
392 return result; |
390 } |
393 } |
391 |
394 |
392 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { |
395 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { |
393 assert(addr != NULL, "Invalid address"); |
396 assert(addr != NULL, "Invalid address"); |
394 assert(size > 0, "Invalid size"); |
397 assert(size > 0, "Invalid size"); |
396 |
399 |
397 ReservedMemoryRegion rgn(addr, size); |
400 ReservedMemoryRegion rgn(addr, size); |
398 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
401 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
399 assert(reserved_rgn != NULL, "No reserved region"); |
402 assert(reserved_rgn != NULL, "No reserved region"); |
400 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
403 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
401 return reserved_rgn->remove_uncommitted_region(addr, size); |
404 bool result = reserved_rgn->remove_uncommitted_region(addr, size); |
|
405 return result; |
402 } |
406 } |
403 |
407 |
404 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { |
408 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { |
405 assert(addr != NULL, "Invalid address"); |
409 assert(addr != NULL, "Invalid address"); |
406 assert(size > 0, "Invalid size"); |
410 assert(size > 0, "Invalid size"); |