OLD | NEW |
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, 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 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 } | 1055 } |
1056 | 1056 |
1057 // Helper for do_malloc(). | 1057 // Helper for do_malloc(). |
1058 inline void* do_malloc_pages(ThreadCache* heap, size_t size) { | 1058 inline void* do_malloc_pages(ThreadCache* heap, size_t size) { |
1059 void* result; | 1059 void* result; |
1060 bool report_large; | 1060 bool report_large; |
1061 | 1061 |
1062 Length num_pages = tcmalloc::pages(size); | 1062 Length num_pages = tcmalloc::pages(size); |
1063 size = num_pages << kPageShift; | 1063 size = num_pages << kPageShift; |
1064 | 1064 |
1065 heap->AddToByteAllocatedTotal(size); // Chromium profiling. | 1065 // Chromium profiling. Measurements in March 2013 suggest this |
| 1066 // imposes a small enough runtime cost that there's no reason to |
| 1067 // try to optimize it. |
| 1068 heap->AddToByteAllocatedTotal(size); |
1066 | 1069 |
1067 if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) { | 1070 if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) { |
1068 result = DoSampledAllocation(size); | 1071 result = DoSampledAllocation(size); |
1069 | 1072 |
1070 SpinLockHolder h(Static::pageheap_lock()); | 1073 SpinLockHolder h(Static::pageheap_lock()); |
1071 report_large = should_report_large(num_pages); | 1074 report_large = should_report_large(num_pages); |
1072 } else { | 1075 } else { |
1073 SpinLockHolder h(Static::pageheap_lock()); | 1076 SpinLockHolder h(Static::pageheap_lock()); |
1074 Span* span = Static::pageheap()->New(num_pages); | 1077 Span* span = Static::pageheap()->New(num_pages); |
1075 result = (span == NULL ? NULL : SpanToMallocResult(span)); | 1078 result = (span == NULL ? NULL : SpanToMallocResult(span)); |
1076 report_large = should_report_large(num_pages); | 1079 report_large = should_report_large(num_pages); |
1077 } | 1080 } |
1078 | 1081 |
1079 if (report_large) { | 1082 if (report_large) { |
1080 ReportLargeAlloc(num_pages, result); | 1083 ReportLargeAlloc(num_pages, result); |
1081 } | 1084 } |
1082 return result; | 1085 return result; |
1083 } | 1086 } |
1084 | 1087 |
1085 inline void* do_malloc(size_t size) { | 1088 inline void* do_malloc(size_t size) { |
1086 AddRoomForMark(&size); | 1089 AddRoomForMark(&size); |
1087 | 1090 |
1088 void* ret = NULL; | 1091 void* ret = NULL; |
1089 | 1092 |
1090 // The following call forces module initialization | 1093 // The following call forces module initialization |
1091 ThreadCache* heap = ThreadCache::GetCache(); | 1094 ThreadCache* heap = ThreadCache::GetCache(); |
1092 // First, check if our security policy allows this size. | 1095 if (size <= kMaxSize && IsAllocSizePermitted(size)) { |
1093 if (IsAllocSizePermitted(size)) { | 1096 size_t cl = Static::sizemap()->SizeClass(size); |
1094 if (size <= kMaxSize) { | 1097 size = Static::sizemap()->class_to_size(cl); |
1095 size_t cl = Static::sizemap()->SizeClass(size); | |
1096 size = Static::sizemap()->class_to_size(cl); | |
1097 | 1098 |
1098 // TODO(jar): If this has any detectable performance impact, it can be | 1099 // Chromium profiling. Measurements in March 2013 suggest this |
1099 // optimized by only tallying sizes if the profiler was activated to | 1100 // imposes a small enough runtime cost that there's no reason to |
1100 // recall these tallies. I don't think this is performance critical, but | 1101 // try to optimize it. |
1101 // we really should measure it. | 1102 heap->AddToByteAllocatedTotal(size); |
1102 heap->AddToByteAllocatedTotal(size); // Chromium profiling. | |
1103 | 1103 |
1104 if ((FLAGS_tcmalloc_sample_parameter > 0) && | 1104 if ((FLAGS_tcmalloc_sample_parameter > 0) && |
1105 heap->SampleAllocation(size)) { | 1105 heap->SampleAllocation(size)) { |
1106 ret = DoSampledAllocation(size); | 1106 ret = DoSampledAllocation(size); |
1107 MarkAllocatedRegion(ret); | 1107 MarkAllocatedRegion(ret); |
1108 } else { | |
1109 // The common case, and also the simplest. This just pops the | |
1110 // size-appropriate freelist, after replenishing it if it's empty. | |
1111 ret = CheckMallocResult(heap->Allocate(size, cl)); | |
1112 } | |
1113 } else { | 1108 } else { |
1114 ret = do_malloc_pages(heap, size); | 1109 // The common case, and also the simplest. This just pops the |
1115 MarkAllocatedRegion(ret); | 1110 // size-appropriate freelist, after replenishing it if it's empty. |
| 1111 ret = CheckMallocResult(heap->Allocate(size, cl)); |
1116 } | 1112 } |
| 1113 } else if (IsAllocSizePermitted(size)) { |
| 1114 ret = do_malloc_pages(heap, size); |
| 1115 MarkAllocatedRegion(ret); |
1117 } | 1116 } |
1118 if (ret == NULL) errno = ENOMEM; | 1117 if (ret == NULL) errno = ENOMEM; |
| 1118 ASSERT(IsAllocSizePermitted(size) || ret == NULL); |
1119 return ret; | 1119 return ret; |
1120 } | 1120 } |
1121 | 1121 |
1122 inline void* do_calloc(size_t n, size_t elem_size) { | 1122 inline void* do_calloc(size_t n, size_t elem_size) { |
1123 // Overflow check | 1123 // Overflow check |
1124 const size_t size = n * elem_size; | 1124 const size_t size = n * elem_size; |
1125 if (elem_size != 0 && size / elem_size != n) return NULL; | 1125 if (elem_size != 0 && size / elem_size != n) return NULL; |
1126 | 1126 |
1127 void* result = do_malloc_or_cpp_alloc(size); | 1127 void* result = do_malloc_or_cpp_alloc(size); |
1128 if (result != NULL) { | 1128 if (result != NULL) { |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1871 *mark = ~allocated_mark; // Distinctively not allocated. | 1871 *mark = ~allocated_mark; // Distinctively not allocated. |
1872 } | 1872 } |
1873 | 1873 |
1874 static void MarkAllocatedRegion(void* ptr) { | 1874 static void MarkAllocatedRegion(void* ptr) { |
1875 if (ptr == NULL) return; | 1875 if (ptr == NULL) return; |
1876 MarkType* mark = GetMarkLocation(ptr); | 1876 MarkType* mark = GetMarkLocation(ptr); |
1877 *mark = GetMarkValue(ptr, mark); | 1877 *mark = GetMarkValue(ptr, mark); |
1878 } | 1878 } |
1879 | 1879 |
1880 #endif // TCMALLOC_VALIDATION | 1880 #endif // TCMALLOC_VALIDATION |
OLD | NEW |