<div><div dir="auto">Thanks!</div></div><div dir="auto"><br></div><div dir="auto"> Filipe</div><div><br><div class="gmail_quote"><div>On Tue, 19 Jun 2018 at 16:40, Kostya Kortchinsky via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: cryptoad<br>
Date: Tue Jun 19 08:36:30 2018<br>
New Revision: 335054<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=335054&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=335054&view=rev</a><br>
Log:<br>
[scudo] Move noinline functions definitions out of line<br>
<br>
Summary:<br>
Mark `isRssLimitExceeded` as `NOINLINE`, and move it's definition as well as<br>
the one of `performSanityChecks` out of the class definition, as requested.<br>
<br>
Reviewers: filcab, alekseyshl<br>
<br>
Reviewed By: alekseyshl<br>
<br>
Subscribers: delcypher, #sanitizers, llvm-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D48228" rel="noreferrer" target="_blank">https://reviews.llvm.org/D48228</a><br>
<br>
Modified:<br>
compiler-rt/trunk/lib/scudo/scudo_allocator.cpp<br>
<br>
Modified: compiler-rt/trunk/lib/scudo/scudo_allocator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/scudo_allocator.cpp?rev=335054&r1=335053&r2=335054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/scudo_allocator.cpp?rev=335054&r1=335053&r2=335054&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/scudo/scudo_allocator.cpp (original)<br>
+++ compiler-rt/trunk/lib/scudo/scudo_allocator.cpp Tue Jun 19 08:36:30 2018<br>
@@ -243,38 +243,7 @@ struct ScudoAllocator {<br>
explicit ScudoAllocator(LinkerInitialized)<br>
: AllocatorQuarantine(LINKER_INITIALIZED) {}<br>
<br>
- NOINLINE void performSanityChecks() {<br>
- // Verify that the header offset field can hold the maximum offset. In the<br>
- // case of the Secondary allocator, it takes care of alignment and the<br>
- // offset will always be 0. In the case of the Primary, the worst case<br>
- // scenario happens in the last size class, when the backend allocation<br>
- // would already be aligned on the requested alignment, which would happen<br>
- // to be the maximum alignment that would fit in that size class. As a<br>
- // result, the maximum offset will be at most the maximum alignment for the<br>
- // last size class minus the header size, in multiples of MinAlignment.<br>
- UnpackedHeader Header = {};<br>
- const uptr MaxPrimaryAlignment =<br>
- 1 << MostSignificantSetBitIndex(SizeClassMap::kMaxSize - MinAlignment);<br>
- const uptr MaxOffset =<br>
- (MaxPrimaryAlignment - Chunk::getHeaderSize()) >> MinAlignmentLog;<br>
- Header.Offset = MaxOffset;<br>
- if (Header.Offset != MaxOffset)<br>
- dieWithMessage("maximum possible offset doesn't fit in header\n");<br>
- // Verify that we can fit the maximum size or amount of unused bytes in the<br>
- // header. Given that the Secondary fits the allocation to a page, the worst<br>
- // case scenario happens in the Primary. It will depend on the second to<br>
- // last and last class sizes, as well as the dynamic base for the Primary.<br>
- // The following is an over-approximation that works for our needs.<br>
- const uptr MaxSizeOrUnusedBytes = SizeClassMap::kMaxSize - 1;<br>
- Header.SizeOrUnusedBytes = MaxSizeOrUnusedBytes;<br>
- if (Header.SizeOrUnusedBytes != MaxSizeOrUnusedBytes)<br>
- dieWithMessage("maximum possible unused bytes doesn't fit in header\n");<br>
-<br>
- const uptr LargestClassId = SizeClassMap::kLargestClassID;<br>
- Header.ClassId = LargestClassId;<br>
- if (Header.ClassId != LargestClassId)<br>
- dieWithMessage("largest class ID doesn't fit in header\n");<br>
- }<br>
+ NOINLINE void performSanityChecks();<br>
<br>
void init() {<br>
SanitizerToolName = "Scudo";<br>
@@ -323,37 +292,7 @@ struct ScudoAllocator {<br>
return Chunk::isValid(Ptr);<br>
}<br>
<br>
- // Opportunistic RSS limit check. This will update the RSS limit status, if<br>
- // it can, every 100ms, otherwise it will just return the current one.<br>
- bool isRssLimitExceeded() {<br>
- u64 LastCheck = atomic_load_relaxed(&RssLastCheckedAtNS);<br>
- const u64 CurrentCheck = MonotonicNanoTime();<br>
- if (LIKELY(CurrentCheck < LastCheck + (100ULL * 1000000ULL)))<br>
- return atomic_load_relaxed(&RssLimitExceeded);<br>
- if (!atomic_compare_exchange_weak(&RssLastCheckedAtNS, &LastCheck,<br>
- CurrentCheck, memory_order_relaxed))<br>
- return atomic_load_relaxed(&RssLimitExceeded);<br>
- // TODO(kostyak): We currently use sanitizer_common's GetRSS which reads the<br>
- // RSS from /proc/self/statm by default. We might want to<br>
- // call getrusage directly, even if it's less accurate.<br>
- const uptr CurrentRssMb = GetRSS() >> 20;<br>
- if (HardRssLimitMb && UNLIKELY(HardRssLimitMb < CurrentRssMb))<br>
- dieWithMessage("hard RSS limit exhausted (%zdMb vs %zdMb)\n",<br>
- HardRssLimitMb, CurrentRssMb);<br>
- if (SoftRssLimitMb) {<br>
- if (atomic_load_relaxed(&RssLimitExceeded)) {<br>
- if (CurrentRssMb <= SoftRssLimitMb)<br>
- atomic_store_relaxed(&RssLimitExceeded, false);<br>
- } else {<br>
- if (CurrentRssMb > SoftRssLimitMb) {<br>
- atomic_store_relaxed(&RssLimitExceeded, true);<br>
- Printf("Scudo INFO: soft RSS limit exhausted (%zdMb vs %zdMb)\n",<br>
- SoftRssLimitMb, CurrentRssMb);<br>
- }<br>
- }<br>
- }<br>
- return atomic_load_relaxed(&RssLimitExceeded);<br>
- }<br>
+ NOINLINE bool isRssLimitExceeded();<br>
<br>
// Allocates a chunk.<br>
void *allocate(uptr Size, uptr Alignment, AllocType Type,<br>
@@ -622,6 +561,71 @@ struct ScudoAllocator {<br>
}<br>
};<br>
<br>
+NOINLINE void ScudoAllocator::performSanityChecks() {<br>
+ // Verify that the header offset field can hold the maximum offset. In the<br>
+ // case of the Secondary allocator, it takes care of alignment and the<br>
+ // offset will always be 0. In the case of the Primary, the worst case<br>
+ // scenario happens in the last size class, when the backend allocation<br>
+ // would already be aligned on the requested alignment, which would happen<br>
+ // to be the maximum alignment that would fit in that size class. As a<br>
+ // result, the maximum offset will be at most the maximum alignment for the<br>
+ // last size class minus the header size, in multiples of MinAlignment.<br>
+ UnpackedHeader Header = {};<br>
+ const uptr MaxPrimaryAlignment =<br>
+ 1 << MostSignificantSetBitIndex(SizeClassMap::kMaxSize - MinAlignment);<br>
+ const uptr MaxOffset =<br>
+ (MaxPrimaryAlignment - Chunk::getHeaderSize()) >> MinAlignmentLog;<br>
+ Header.Offset = MaxOffset;<br>
+ if (Header.Offset != MaxOffset)<br>
+ dieWithMessage("maximum possible offset doesn't fit in header\n");<br>
+ // Verify that we can fit the maximum size or amount of unused bytes in the<br>
+ // header. Given that the Secondary fits the allocation to a page, the worst<br>
+ // case scenario happens in the Primary. It will depend on the second to<br>
+ // last and last class sizes, as well as the dynamic base for the Primary.<br>
+ // The following is an over-approximation that works for our needs.<br>
+ const uptr MaxSizeOrUnusedBytes = SizeClassMap::kMaxSize - 1;<br>
+ Header.SizeOrUnusedBytes = MaxSizeOrUnusedBytes;<br>
+ if (Header.SizeOrUnusedBytes != MaxSizeOrUnusedBytes)<br>
+ dieWithMessage("maximum possible unused bytes doesn't fit in header\n");<br>
+<br>
+ const uptr LargestClassId = SizeClassMap::kLargestClassID;<br>
+ Header.ClassId = LargestClassId;<br>
+ if (Header.ClassId != LargestClassId)<br>
+ dieWithMessage("largest class ID doesn't fit in header\n");<br>
+}<br>
+<br>
+// Opportunistic RSS limit check. This will update the RSS limit status, if<br>
+// it can, every 100ms, otherwise it will just return the current one.<br>
+NOINLINE bool ScudoAllocator::isRssLimitExceeded() {<br>
+ u64 LastCheck = atomic_load_relaxed(&RssLastCheckedAtNS);<br>
+ const u64 CurrentCheck = MonotonicNanoTime();<br>
+ if (LIKELY(CurrentCheck < LastCheck + (100ULL * 1000000ULL)))<br>
+ return atomic_load_relaxed(&RssLimitExceeded);<br>
+ if (!atomic_compare_exchange_weak(&RssLastCheckedAtNS, &LastCheck,<br>
+ CurrentCheck, memory_order_relaxed))<br>
+ return atomic_load_relaxed(&RssLimitExceeded);<br>
+ // TODO(kostyak): We currently use sanitizer_common's GetRSS which reads the<br>
+ // RSS from /proc/self/statm by default. We might want to<br>
+ // call getrusage directly, even if it's less accurate.<br>
+ const uptr CurrentRssMb = GetRSS() >> 20;<br>
+ if (HardRssLimitMb && UNLIKELY(HardRssLimitMb < CurrentRssMb))<br>
+ dieWithMessage("hard RSS limit exhausted (%zdMb vs %zdMb)\n",<br>
+ HardRssLimitMb, CurrentRssMb);<br>
+ if (SoftRssLimitMb) {<br>
+ if (atomic_load_relaxed(&RssLimitExceeded)) {<br>
+ if (CurrentRssMb <= SoftRssLimitMb)<br>
+ atomic_store_relaxed(&RssLimitExceeded, false);<br>
+ } else {<br>
+ if (CurrentRssMb > SoftRssLimitMb) {<br>
+ atomic_store_relaxed(&RssLimitExceeded, true);<br>
+ Printf("Scudo INFO: soft RSS limit exhausted (%zdMb vs %zdMb)\n",<br>
+ SoftRssLimitMb, CurrentRssMb);<br>
+ }<br>
+ }<br>
+ }<br>
+ return atomic_load_relaxed(&RssLimitExceeded);<br>
+}<br>
+<br>
static ScudoAllocator Instance(LINKER_INITIALIZED);<br>
<br>
static ScudoBackendAllocator &getBackendAllocator() {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"> Filipe</div>