Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 static_assert(WTF::kGenericMaxBucketed == 983040, "generic max bucketed"); | 54 static_assert(WTF::kGenericMaxBucketed == 983040, "generic max bucketed"); |
| 55 | 55 |
| 56 namespace WTF { | 56 namespace WTF { |
| 57 | 57 |
| 58 int PartitionRootBase::gInitializedLock = 0; | 58 int PartitionRootBase::gInitializedLock = 0; |
| 59 bool PartitionRootBase::gInitialized = false; | 59 bool PartitionRootBase::gInitialized = false; |
| 60 PartitionPage PartitionRootBase::gSeedPage; | 60 PartitionPage PartitionRootBase::gSeedPage; |
| 61 PartitionBucket PartitionRootBase::gPagedBucket; | 61 PartitionBucket PartitionRootBase::gPagedBucket; |
| 62 void (*PartitionRootBase::gOomHandlingFunction)() = nullptr; | 62 void (*PartitionRootBase::gOomHandlingFunction)() = nullptr; |
| 63 | 63 |
| 64 void (*partitionAllocHookAlloc)(void* addr, size_t size) = nullptr; | |
| 65 void (*partitionAllocHookFree)(void* addr) = nullptr; | |
| 66 | |
| 64 static uint16_t partitionBucketNumSystemPages(size_t size) | 67 static uint16_t partitionBucketNumSystemPages(size_t size) |
| 65 { | 68 { |
| 66 // This works out reasonably for the current bucket sizes of the generic | 69 // This works out reasonably for the current bucket sizes of the generic |
| 67 // allocator, and the current values of partition page size and constants. | 70 // allocator, and the current values of partition page size and constants. |
| 68 // Specifically, we have enough room to always pack the slots perfectly into | 71 // Specifically, we have enough room to always pack the slots perfectly into |
| 69 // some number of system pages. The only waste is the waste associated with | 72 // some number of system pages. The only waste is the waste associated with |
| 70 // unfaulted pages (i.e. wasted address space). | 73 // unfaulted pages (i.e. wasted address space). |
| 71 // TODO: we end up using a lot of system pages for very small sizes. For | 74 // TODO: we end up using a lot of system pages for very small sizes. For |
| 72 // example, we'll use 12 system pages for slot size 24. The slot size is | 75 // example, we'll use 12 system pages for slot size 24. The slot size is |
| 73 // so small that the waste would be tiny with just 4, or 1, system pages. | 76 // so small that the waste would be tiny with just 4, or 1, system pages. |
| (...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1053 partitionExcessiveAllocationSize(); | 1056 partitionExcessiveAllocationSize(); |
| 1054 | 1057 |
| 1055 ASSERT(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr))); | 1058 ASSERT(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr))); |
| 1056 | 1059 |
| 1057 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr)); | 1060 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr)); |
| 1058 | 1061 |
| 1059 if (UNLIKELY(partitionBucketIsDirectMapped(page->bucket))) { | 1062 if (UNLIKELY(partitionBucketIsDirectMapped(page->bucket))) { |
| 1060 // We may be able to perform the realloc in place by changing the | 1063 // We may be able to perform the realloc in place by changing the |
| 1061 // accessibility of memory pages and, if reducing the size, decommitting | 1064 // accessibility of memory pages and, if reducing the size, decommitting |
| 1062 // them. | 1065 // them. |
| 1063 if (partitionReallocDirectMappedInPlace(root, page, newSize)) | 1066 if (partitionReallocDirectMappedInPlace(root, page, newSize)) { |
| 1067 // Report a realloc as a free followed by alloc when heap profiling | |
| 1068 // is enabled. | |
| 1069 if (UNLIKELY(partitionAllocHookAlloc && partitionAllocHookFree)) { | |
|
Primiano Tucci (use gerrit)
2015/10/12 16:36:46
just check one of them. You always set/reset them
Ruud van Asseldonk
2015/10/13 10:42:18
My reasoning was that an allocation could be happe
Primiano Tucci (use gerrit)
2015/10/14 10:10:12
After discussion offline, I think you want to just
| |
| 1070 partitionAllocHookFree(ptr); | |
| 1071 partitionAllocHookAlloc(ptr, newSize); | |
| 1072 } | |
| 1073 | |
| 1064 return ptr; | 1074 return ptr; |
| 1075 } | |
| 1065 } | 1076 } |
| 1066 | 1077 |
| 1067 size_t actualNewSize = partitionAllocActualSize(root, newSize); | 1078 size_t actualNewSize = partitionAllocActualSize(root, newSize); |
| 1068 size_t actualOldSize = partitionAllocGetSize(ptr); | 1079 size_t actualOldSize = partitionAllocGetSize(ptr); |
| 1069 | 1080 |
| 1070 // TODO: note that tcmalloc will "ignore" a downsizing realloc() unless the | 1081 // TODO: note that tcmalloc will "ignore" a downsizing realloc() unless the |
| 1071 // new size is a significant percentage smaller. We could do the same if we | 1082 // new size is a significant percentage smaller. We could do the same if we |
| 1072 // determine it is a win. | 1083 // determine it is a win. |
| 1073 if (actualNewSize == actualOldSize) { | 1084 if (actualNewSize == actualOldSize) { |
| 1074 // Trying to allocate a block of size newSize would give us a block of | 1085 // Trying to allocate a block of size newSize would give us a block of |
| 1075 // the same size as the one we've already got, so no point in doing | 1086 // the same size as the one we've already got, so no point in doing |
| 1076 // anything here. | 1087 // anything here. |
| 1077 return ptr; | 1088 return ptr; |
| 1078 } | 1089 } |
| 1079 | 1090 |
| 1080 // This realloc cannot be resized in-place. Sadness. | 1091 // This realloc cannot be resized in-place. Sadness. |
| 1081 void* ret = partitionAllocGeneric(root, newSize); | 1092 void* ret = partitionAllocGeneric(root, newSize); |
| 1082 size_t copySize = actualOldSize; | 1093 size_t copySize = actualOldSize; |
| 1083 if (newSize < copySize) | 1094 if (newSize < copySize) |
| 1084 copySize = newSize; | 1095 copySize = newSize; |
| 1085 | 1096 |
| 1086 memcpy(ret, ptr, copySize); | 1097 memcpy(ret, ptr, copySize); |
| 1087 partitionFreeGeneric(root, ptr); | 1098 partitionFreeGeneric(root, ptr); |
| 1099 | |
| 1100 // Report a realloc as a free followed by alloc when heap profiling is | |
| 1101 // enabled. | |
|
Primiano Tucci (use gerrit)
2015/10/12 16:36:46
ditto
| |
| 1102 if (UNLIKELY(partitionAllocHookAlloc && partitionAllocHookFree)) { | |
| 1103 partitionAllocHookFree(ptr); | |
| 1104 partitionAllocHookAlloc(ret, newSize); | |
| 1105 } | |
| 1106 | |
| 1088 return ret; | 1107 return ret; |
| 1089 #endif | 1108 #endif |
| 1090 } | 1109 } |
| 1091 | 1110 |
| 1092 static size_t partitionPurgePage(PartitionPage* page, bool discard) | 1111 static size_t partitionPurgePage(PartitionPage* page, bool discard) |
| 1093 { | 1112 { |
| 1094 const PartitionBucket* bucket = page->bucket; | 1113 const PartitionBucket* bucket = page->bucket; |
| 1095 size_t slotSize = bucket->slotSize; | 1114 size_t slotSize = bucket->slotSize; |
| 1096 if (slotSize < kSystemPageSize || !page->numAllocatedSlots) | 1115 if (slotSize < kSystemPageSize || !page->numAllocatedSlots) |
| 1097 return 0; | 1116 return 0; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1405 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes; | 1424 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes; |
| 1406 if (!isLightDump) | 1425 if (!isLightDump) |
| 1407 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]); | 1426 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]); |
| 1408 } | 1427 } |
| 1409 } | 1428 } |
| 1410 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats); | 1429 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats); |
| 1411 } | 1430 } |
| 1412 | 1431 |
| 1413 } // namespace WTF | 1432 } // namespace WTF |
| 1414 | 1433 |
| OLD | NEW |