Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2008, Google Inc. | 1 // Copyright (c) 2008, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 return leftover; | 150 return leftover; |
| 151 } | 151 } |
| 152 | 152 |
| 153 void PageHeap::CommitSpan(Span* span) { | 153 void PageHeap::CommitSpan(Span* span) { |
| 154 TCMalloc_SystemCommit( | 154 TCMalloc_SystemCommit( |
| 155 reinterpret_cast<void*>(span->start << kPageShift), | 155 reinterpret_cast<void*>(span->start << kPageShift), |
| 156 static_cast<size_t>(span->length << kPageShift) | 156 static_cast<size_t>(span->length << kPageShift) |
| 157 ); | 157 ); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void PageHeap::DecommitSpan(Span* span) { | |
| 161 TCMalloc_SystemRelease(reinterpret_cast<void*>(span->start << kPageShift), | |
| 162 static_cast<size_t>(span->length << kPageShift)); | |
| 163 } | |
| 164 | |
| 160 Span* PageHeap::Carve(Span* span, Length n) { | 165 Span* PageHeap::Carve(Span* span, Length n) { |
| 161 ASSERT(n > 0); | 166 ASSERT(n > 0); |
| 162 ASSERT(span->location != Span::IN_USE); | 167 ASSERT(span->location != Span::IN_USE); |
| 163 const int old_location = span->location; | 168 const int old_location = span->location; |
| 164 DLL_Remove(span); | 169 DLL_Remove(span); |
| 165 span->location = Span::IN_USE; | 170 span->location = Span::IN_USE; |
| 166 Event(span, 'A', n); | 171 Event(span, 'A', n); |
| 167 | 172 |
| 168 const int extra = span->length - n; | 173 const int extra = span->length - n; |
| 169 ASSERT(extra >= 0); | 174 ASSERT(extra >= 0); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 194 } | 199 } |
| 195 | 200 |
| 196 void PageHeap::Delete(Span* span) { | 201 void PageHeap::Delete(Span* span) { |
| 197 ASSERT(Check()); | 202 ASSERT(Check()); |
| 198 ASSERT(span->location == Span::IN_USE); | 203 ASSERT(span->location == Span::IN_USE); |
| 199 ASSERT(span->length > 0); | 204 ASSERT(span->length > 0); |
| 200 ASSERT(GetDescriptor(span->start) == span); | 205 ASSERT(GetDescriptor(span->start) == span); |
| 201 ASSERT(GetDescriptor(span->start + span->length - 1) == span); | 206 ASSERT(GetDescriptor(span->start + span->length - 1) == span); |
| 202 span->sizeclass = 0; | 207 span->sizeclass = 0; |
| 203 span->sample = 0; | 208 span->sample = 0; |
| 209 DecommitSpan(span); | |
| 204 | 210 |
| 205 // Coalesce -- we guarantee that "p" != 0, so no bounds checking | 211 // Coalesce -- we guarantee that "p" != 0, so no bounds checking |
| 206 // necessary. We do not bother resetting the stale pagemap | 212 // necessary. We do not bother resetting the stale pagemap |
| 207 // entries for the pieces we are merging together because we only | 213 // entries for the pieces we are merging together because we only |
| 208 // care about the pagemap entries for the boundaries. | 214 // care about the pagemap entries for the boundaries. |
| 209 // | 215 // |
| 210 // Note that the spans we merge into "span" may come out of | 216 // Note that the spans we merge into "span" may come out of |
| 211 // a "returned" list. We move those into "normal" list | 217 // a "normal" or "returned" list. We move those into the |
| 212 // as for 'immediate' operations we favour committing over | 218 // "returned" list in order to favor decommitting over committing. |
| 213 // decommitting (decommitting is performed offline). | |
| 214 const PageID p = span->start; | 219 const PageID p = span->start; |
| 215 const Length n = span->length; | 220 const Length n = span->length; |
| 216 Span* prev = GetDescriptor(p-1); | 221 Span* prev = GetDescriptor(p-1); |
| 217 if (prev != NULL && prev->location != Span::IN_USE) { | 222 if (prev != NULL && prev->location != Span::IN_USE) { |
| 218 // Merge preceding span into this span | 223 // Merge preceding span into this span |
| 219 ASSERT(prev->start + prev->length == p); | 224 ASSERT(prev->start + prev->length == p); |
| 220 const Length len = prev->length; | 225 const Length len = prev->length; |
| 221 if (prev->location == Span::ON_RETURNED_FREELIST) { | 226 if (prev->location == Span::ON_NORMAL_FREELIST) { |
| 222 CommitSpan(prev); | 227 DecommitSpan(prev); |
| 223 } | 228 } |
| 224 DLL_Remove(prev); | 229 DLL_Remove(prev); |
| 225 DeleteSpan(prev); | 230 DeleteSpan(prev); |
| 226 span->start -= len; | 231 span->start -= len; |
| 227 span->length += len; | 232 span->length += len; |
| 228 pagemap_.set(span->start, span); | 233 pagemap_.set(span->start, span); |
| 229 Event(span, 'L', len); | 234 Event(span, 'L', len); |
| 230 } | 235 } |
| 231 Span* next = GetDescriptor(p+n); | 236 Span* next = GetDescriptor(p+n); |
| 232 if (next != NULL && next->location != Span::IN_USE) { | 237 if (next != NULL && next->location != Span::IN_USE) { |
| 233 // Merge next span into this span | 238 // Merge next span into this span |
| 234 ASSERT(next->start == p+n); | 239 ASSERT(next->start == p+n); |
| 235 const Length len = next->length; | 240 const Length len = next->length; |
| 236 if (next->location == Span::ON_RETURNED_FREELIST) { | 241 if (next->location == Span::ON_NORMAL_FREELIST) { |
| 237 CommitSpan(next); | 242 DecommitSpan(next); |
| 238 } | 243 } |
| 239 DLL_Remove(next); | 244 DLL_Remove(next); |
| 240 DeleteSpan(next); | 245 DeleteSpan(next); |
| 241 span->length += len; | 246 span->length += len; |
| 242 pagemap_.set(span->start + span->length - 1, span); | 247 pagemap_.set(span->start + span->length - 1, span); |
| 243 Event(span, 'R', len); | 248 Event(span, 'R', len); |
| 244 } | 249 } |
| 245 | 250 |
| 246 Event(span, 'D', span->length); | 251 Event(span, 'D', span->length); |
|
antonm
2009/10/01 11:59:27
why you don't decommit the span itself? is it by
| |
| 247 span->location = Span::ON_NORMAL_FREELIST; | 252 span->location = Span::ON_RETURNED_FREELIST; |
| 248 if (span->length < kMaxPages) { | 253 if (span->length < kMaxPages) { |
| 249 DLL_Prepend(&free_[span->length].normal, span); | 254 DLL_Prepend(&free_[span->length].normal, span); |
|
Mike Belshe
2009/10/01 02:39:48
I think this is a bug -
DLL_Prepend(&free_[span->
antonm
2009/10/01 11:59:27
That's definitely a bug and I would expect immedia
| |
| 250 } else { | 255 } else { |
| 251 DLL_Prepend(&large_.normal, span); | 256 DLL_Prepend(&large_.normal, span); |
|
Mike Belshe
2009/10/01 02:39:48
ditto
| |
| 252 } | 257 } |
| 253 free_pages_ += n; | 258 free_pages_ += n; |
| 254 | 259 |
| 255 IncrementalScavenge(n); | 260 IncrementalScavenge(n); |
| 256 ASSERT(Check()); | 261 ASSERT(Check()); |
| 257 } | 262 } |
| 258 | 263 |
| 259 void PageHeap::IncrementalScavenge(Length n) { | 264 void PageHeap::IncrementalScavenge(Length n) { |
| 260 // Fast path; not yet time to release memory | 265 // Fast path; not yet time to release memory |
| 261 scavenge_counter_ -= n; | 266 scavenge_counter_ -= n; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 | 502 |
| 498 void PageHeap::ReleaseFreePages() { | 503 void PageHeap::ReleaseFreePages() { |
| 499 for (Length s = 0; s < kMaxPages; s++) { | 504 for (Length s = 0; s < kMaxPages; s++) { |
| 500 ReleaseFreeList(&free_[s].normal, &free_[s].returned); | 505 ReleaseFreeList(&free_[s].normal, &free_[s].returned); |
| 501 } | 506 } |
| 502 ReleaseFreeList(&large_.normal, &large_.returned); | 507 ReleaseFreeList(&large_.normal, &large_.returned); |
| 503 ASSERT(Check()); | 508 ASSERT(Check()); |
| 504 } | 509 } |
| 505 | 510 |
| 506 } // namespace tcmalloc | 511 } // namespace tcmalloc |
| OLD | NEW |