Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
3815aa8
This is an incomplete implementation of a new randomized allocation s…
noahfalk Feb 8, 2024
6a92fcb
Initial update
chrisnas Feb 21, 2024
cdbffc3
Update based on feedback
chrisnas Feb 22, 2024
924afd0
Rename fast_alloc_helper_limit_ptr to alloc_sampling
chrisnas Feb 23, 2024
e0ce093
Remove trailing whitespace in markdown
chrisnas Feb 23, 2024
396c05e
Add sampling threshold computation
chrisnas Feb 23, 2024
91b8b79
Take feedback into account and start to implement AllocationSampled e…
chrisnas Feb 27, 2024
65ff391
Fix typo
chrisnas Feb 27, 2024
b25adc6
Take review into account
chrisnas Feb 29, 2024
d939cdd
Emit the AllocationSampled event
chrisnas Mar 1, 2024
9b0f7da
Fix threshold computation error
chrisnas Mar 14, 2024
8875a4d
Deal with empty allocation context when fixing them
chrisnas Mar 16, 2024
f39a732
Handle the case of objects larger than an allocation context
chrisnas Mar 18, 2024
fbc0b6b
Take review into account
chrisnas Mar 21, 2024
32eb2fa
Take review into account for dynamically sampling
chrisnas Mar 22, 2024
518b4f7
Adding a first test that AllocationSampled is emitted when keyword/ve…
chrisnas Mar 26, 2024
b596f33
Check type name in AllocationSampled test
chrisnas Mar 27, 2024
984ed95
Compare perf impact of allocation sampling
chrisnas Mar 28, 2024
1c46a5d
Fix tests
chrisnas Apr 10, 2024
44e914b
Update tests and doc
chrisnas Apr 16, 2024
9eba36e
Update review
chrisnas Apr 19, 2024
b7614fd
Update based on review
chrisnas Apr 19, 2024
cbc5a12
Add tests and simple framework to measure statistical distribution of…
chrisnas Apr 19, 2024
826d8eb
Add x1/x2/x3 ratio check
chrisnas Apr 22, 2024
a56a5ee
Update array of double implementation for 32 bits
chrisnas Apr 22, 2024
48dbfa1
Updates
chrisnas May 7, 2024
7280c13
Fix markdown
chrisnas May 7, 2024
fd8a1b9
Add AllocationsRunEventSource to compute percentiles more easily
chrisnas May 8, 2024
a4aef1a
Allow percentiles computation
chrisnas May 9, 2024
08ec139
Add ratio based array allocations
chrisnas May 10, 2024
0bbbfa9
take review into account
chrisnas May 13, 2024
cf29e9b
Refactor the code and update upscaling method
chrisnas May 14, 2024
26e8fe0
Add runs for allocations
chrisnas May 14, 2024
52d4071
Handle padding for objects alignment
chrisnas May 16, 2024
db506a3
take GC padding into account
chrisnas May 16, 2024
8522866
Update allocation sampling distribution results
chrisnas May 16, 2024
e1f8ece
Update benchmarks with events
chrisnas May 16, 2024
32f6d31
Beginning of NativeAOT support
chrisnas May 18, 2024
9e31a6e
Fix trailing spaces
chrisnas May 21, 2024
f9f5224
Updates based on PR comments
chrisnas May 21, 2024
97a3bbd
Proposed changes
noahfalk May 21, 2024
734b773
Fix README
noahfalk May 21, 2024
a6120ac
- fix Alloc helper to get the address of the allocated object for All…
chrisnas May 22, 2024
3d0bcd1
Update the design doc
noahfalk May 23, 2024
549e7b0
Merge branch 'main' into chrisnas/alloc_sampling
chrisnas May 23, 2024
147447a
Fix compilation errors for Linux and related to merged changes in Thr…
chrisnas May 24, 2024
2b41997
Fix compilation issue
chrisnas May 24, 2024
4618b37
Restore Thread randomizer initialization
chrisnas May 24, 2024
918fe0c
Remove the randomizer from Thread to have just a singleton
chrisnas May 27, 2024
e82162d
Add a lazily allocated CLRRandom in Thread class
chrisnas May 28, 2024
09eae74
Start a no op implementation of randomized sampling for NativeAOT
chrisnas May 28, 2024
6badfb2
Fix typos in markdown
chrisnas May 29, 2024
d0e46a4
Fix linux compilation errors
chrisnas May 29, 2024
ef5b819
Make alloc context randomizer per thread lazily allocated
chrisnas May 29, 2024
ff77f7a
Fix missing rename in assembly code to use combined_limit instead of …
chrisnas May 29, 2024
77cb736
Fix build errors dues to explicit net8.0 usage in tests
chrisnas May 29, 2024
c40b1a2
Filter out AllocationTick when AllocationSampled is enabled
chrisnas May 30, 2024
a62ea75
Try a fix for build errors related to .csproj that are not really tests
chrisnas May 30, 2024
07ab88b
Avoid touching the IGCToCLREventSink interface because AllocationSampled
chrisnas May 30, 2024
d04b655
Update AllocationTick filtering implementation
chrisnas May 31, 2024
d565045
Fix double[] implementation
chrisnas May 31, 2024
b7bd18f
Fix test due to added field in the event payload
chrisnas May 31, 2024
7cbcb43
Implement emitting the AllocationSampled event in NativeAOT
chrisnas May 31, 2024
86f24c6
First no op implementation for NativeAOT with updated assembly code
chrisnas May 31, 2024
51d9935
Fix typos
chrisnas Jun 3, 2024
a9ef0e5
Fix DEBUG compilation error
chrisnas Jun 3, 2024
dd7e00d
Fix linux/x86 compilation errors
chrisnas Jun 3, 2024
a86a98b
Fix build error
chrisnas Jun 3, 2024
512f011
Try to fix "static" related compilation errors
chrisnas Jun 3, 2024
532f095
Fix test in 32 bit
chrisnas Jun 4, 2024
4fc9b8d
Avoid running AllocationSampled test with Mono + Fix compilation issue
chrisnas Jun 8, 2024
9174212
Start to implement the randomizer with existing 32 bit random
chrisnas Jun 8, 2024
541f59f
Fix compilation error
chrisnas Jun 12, 2024
40f96f3
Allow eventing functions to be called from thread.cpp
chrisnas Jun 14, 2024
29c16b5
Merge branch 'main' into chrisnas/alloc_sampling
chrisnas Jun 17, 2024
20c6d51
Fix assert in AOT
chrisnas Jun 17, 2024
c5ccad8
Fix link issue
chrisnas Jun 24, 2024
39afdf2
Fix NativeAOT build
chrisnas Jun 25, 2024
b2db19e
Merge branch 'main' into chrisnas/alloc_sampling
chrisnas Jun 26, 2024
e4ef681
Fix missing references to gc_alloc_context
chrisnas Jun 26, 2024
abfe6cb
Fix compilation issues
chrisnas Jun 27, 2024
997a293
Update x86 implementation
chrisnas Jun 28, 2024
041e397
Fix
chrisnas Jun 28, 2024
e312bf6
Fixes
chrisnas Jul 1, 2024
ec16fa0
Merge remote-tracking branch 'origin' into chrisnas/alloc_sampling
chrisnas Jul 5, 2024
fd382d3
Fix rebase
chrisnas Jul 5, 2024
a2e30cc
Fix linux gcc build issues
chrisnas Jul 5, 2024
83611b8
Add missing alloc context fixup and randomizer code
chrisnas Jul 9, 2024
c908fe4
Merge remote-tracking branch 'origin' into chrisnas/alloc_sampling
chrisnas Jul 9, 2024
dc02b7c
Fix issue when TLS for alloc context is not initialized
chrisnas Jul 10, 2024
85625cd
Merge remote-tracking branch 'origin' into chrisnas/alloc_sampling
chrisnas Jul 10, 2024
911d5d7
Change randomizer to use sxoshiro128++ for better statistical distrib…
chrisnas Jul 11, 2024
91d58dc
Fix possible crash in GCInterface_GetTotalAllocatedBytesPrecise
chrisnas Jul 11, 2024
11177d9
Fix possible desync between gc_alloc_context and combined_limit
chrisnas Jul 12, 2024
ce40d3d
Merge remote-tracking branch 'origin' into chrisnas/alloc_sampling
chrisnas Jul 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Proposed changes
- Renamed alloc_sampling -> combined_limit
   We were refering to alloc_sampling as the sampling limit but really it is min(sampling_limit, alloc_limit).
   Most of the time alloc_sampling was the AC limit and not a sampling limit. It seemed misleading to
   have 'sampling' in the name when most of the time that isn't what it repreesnts.

- Simplified logic in Alloc()
   Special casing UOH allocations appears unnecessary, performance still looked good without doing that
   Factored all the checks to see if the feature was on inside a IsRandomizedSamplingEnabled() func
   Moved all the fields that are only needed for sampling inside the scope where sampling is enabled
   Adjusted some comments

-Fixed the sampled byte reporting for objects that extend past the AC boundary

- Removed unneeded code changes that were fragments of past code changes no longer being used

- Removed errant whitespace changes in gc code

- consolidated test changes in a folder named "randomizedallocationsampling". We don't need multiple
  folders and I'm trying to consolidate naming this feature as 'randomized' allocation rather than
  'dynamic'

- moved the testing results into a dedicated folder that can be deleted at the end to make it clear what
  stays and what is temporary just for review.
  • Loading branch information
noahfalk committed May 21, 2024
commit 97a3bbd50230ae1f672e79217f3867873323d549
4 changes: 2 additions & 2 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48192,7 +48192,7 @@ HRESULT GCHeap::Initialize()
/*
* Allocation requests less than loh_size_threshold will be allocated on the small object heap.
*
* An object cannot span more than one region and regions in small object heap are of the same size - gc_region_size.
* An object cannot span more than one region and regions in small object heap are of the same size - gc_region_size.
* However, the space available for actual allocations is reduced by the following implementation details -
*
* 1.) heap_segment_mem is set to the new pages + sizeof(aligned_plug_and_gap) in make_heap_segment.
Expand All @@ -48208,7 +48208,7 @@ HRESULT GCHeap::Initialize()
#ifdef FEATURE_STRUCTALIGN
/*
* The above assumed FEATURE_STRUCTALIGN is not turned on for platforms where USE_REGIONS is supported, otherwise it is possible
* that the allocation size is inflated by ComputeMaxStructAlignPad in GCHeap::Alloc and we have to compute an upper bound of that
* that the allocation size is inflated by ComputeMaxStructAlignPad in GCHeap::Alloc and we have to compute an upper bound of that
* function.
*
* Note that ComputeMaxStructAlignPad is defined to be 0 if FEATURE_STRUCTALIGN is turned off.
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -4226,7 +4226,7 @@ class gc_heap

#ifdef DYNAMIC_HEAP_COUNT
// Sample collection -
//
//
// For every GC, we collect the msl wait time + GC pause duration info and use both to calculate the
// throughput cost percentage. We will also be using the wait time and the GC pause duration separately
// for other purposes in the future.
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/vm/amd64/JitHelpers_InlineGetThread.asm
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ LEAF_ENTRY JIT_TrialAllocSFastMP_InlineGetThread, _TEXT
; m_BaseSize is guaranteed to be a multiple of 8.

INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_sampling]
mov r10, [r11 + OFFSET__Thread__m_alloc_context__combined_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]

add rdx, rax
Expand All @@ -65,7 +65,7 @@ NESTED_ENTRY JIT_BoxFastMP_InlineGetThread, _TEXT
mov r8d, [rcx + OFFSET__MethodTable__m_BaseSize]

INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_sampling]
mov r10, [r11 + OFFSET__Thread__m_alloc_context__combined_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]

add r8, rax
Expand Down Expand Up @@ -136,7 +136,7 @@ LEAF_ENTRY AllocateStringFastMP_InlineGetThread, _TEXT
and edx, -8

INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_sampling]
mov r10, [r11 + OFFSET__Thread__m_alloc_context__combined_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]

add rdx, rax
Expand Down Expand Up @@ -189,7 +189,7 @@ LEAF_ENTRY JIT_NewArr1VC_MP_InlineGetThread, _TEXT


INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_sampling]
mov r10, [r11 + OFFSET__Thread__m_alloc_context__combined_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]

add r8, rax
Expand Down Expand Up @@ -238,7 +238,7 @@ LEAF_ENTRY JIT_NewArr1OBJ_MP_InlineGetThread, _TEXT
; to be a multiple of 8.

INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_sampling]
mov r10, [r11 + OFFSET__Thread__m_alloc_context__combined_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]

add r8, rax
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/vm/amd64/JitHelpers_Slow.asm
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ LEAF_ENTRY JIT_TrialAllocSFastSP, _TEXT
jnz JIT_NEW

mov rax, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr] ; alloc_ptr
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_sampling] ; alloc_sampling
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit] ; combined_limit

add r8, rax

Expand Down Expand Up @@ -212,7 +212,7 @@ NESTED_ENTRY JIT_BoxFastUP, _TEXT
jnz JIT_Box

mov rax, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr] ; alloc_ptr
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_sampling] ; alloc_sampling
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit] ; combined_limit

add r8, rax

Expand Down Expand Up @@ -291,7 +291,7 @@ LEAF_ENTRY AllocateStringFastUP, _TEXT
jnz FramedAllocateString

mov rax, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr] ; alloc_ptr
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_sampling] ; alloc_sampling
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit] ; combined_limit

add r8, rax

Expand Down Expand Up @@ -347,7 +347,7 @@ LEAF_ENTRY JIT_NewArr1VC_UP, _TEXT
jnz JIT_NewArr1

mov rax, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr] ; alloc_ptr
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_sampling] ; alloc_sampling
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit] ; combined_limit

add r8, rax
jc AllocFailed
Expand Down Expand Up @@ -400,7 +400,7 @@ LEAF_ENTRY JIT_NewArr1OBJ_UP, _TEXT
jnz JIT_NewArr1

mov rax, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr] ; alloc_ptr
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_sampling] ; alloc_sampling
mov r10, [g_global_ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit] ; combined_limit

add r8, rax

Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/vm/amd64/asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__Thread__m_pFrame
#define OFFSET__Thread__m_alloc_context__alloc_ptr 0x60
ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_ptr == offsetof(Thread, m_alloc_context) + offsetof(ee_alloc_context, gc_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));

#define OFFSET__Thread__m_alloc_context__alloc_sampling 0x58
ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_sampling == offsetof(Thread, m_alloc_context) + offsetof(ee_alloc_context, alloc_sampling));
#define OFFSET__Thread__m_alloc_context__combined_limit 0x58
ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__combined_limit == offsetof(Thread, m_alloc_context) + offsetof(ee_alloc_context, combined_limit));

#define OFFSETOF__ee_alloc_context__alloc_ptr 0x8
ASMCONSTANTS_C_ASSERT(OFFSETOF__ee_alloc_context__alloc_ptr == offsetof(ee_alloc_context, gc_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));

#define OFFSETOF__ee_alloc_context__alloc_sampling 0x0
ASMCONSTANTS_C_ASSERT(OFFSETOF__ee_alloc_context__alloc_sampling == offsetof(ee_alloc_context, alloc_sampling));
#define OFFSETOF__ee_alloc_context__combined_limit 0x0
ASMCONSTANTS_C_ASSERT(OFFSETOF__ee_alloc_context__combined_limit == offsetof(ee_alloc_context, combined_limit));

#define OFFSETOF__ThreadExceptionState__m_pCurrentTracker 0x000
ASMCONSTANTS_C_ASSERT(OFFSETOF__ThreadExceptionState__m_pCurrentTracker
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/frozenobjectheap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Object* FrozenObjectHeapManager::TryAllocateObject(PTR_MethodTable type, size_t

} // end of GCX_PREEMP

PublishFrozenObject(obj, objectSize);
PublishFrozenObject(obj);

return obj;
#endif // !FEATURE_BASICFREEZE
Expand Down
10 changes: 6 additions & 4 deletions src/coreclr/vm/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,26 +446,28 @@ gc_alloc_context * GCToEEInterface::GetAllocContext()

void InvokeGCAllocCallback(ee_alloc_context* pEEAllocContext, enum_alloc_context_func* fn, void* param)
{
// NOTE: Its possible that alloc_ptr = alloc_limit = alloc_sampling = NULL at this point
// NOTE: Its possible that alloc_ptr = alloc_limit = combined_limit = NULL at this point
gc_alloc_context* pAllocContext = &pEEAllocContext->gc_alloc_context;

// The allocation context might be modified by the callback, so we need to save
// the remaining sampling budget and restore it after the callback if needed.
size_t currentSamplingBudget = (size_t)(pEEAllocContext->alloc_sampling - pAllocContext->alloc_ptr);
size_t currentSamplingBudget = (size_t)(pEEAllocContext->combined_limit - pAllocContext->alloc_ptr);
size_t currentSize = (size_t)(pAllocContext->alloc_limit - pAllocContext->alloc_ptr);

fn(pAllocContext, param);

// If the GC changed the size of the allocation context, we need to recompute the sampling limit
// This includes the case where the AC was initially zero-sized/uninitialized.
// Functionally we'd get valid results if we called UpdateCombinedLimit() unconditionally but its
// empirically a little more performant to only call it when the AC size has changed.
if (currentSize != (size_t)(pAllocContext->alloc_limit - pAllocContext->alloc_ptr))
{
pEEAllocContext->ComputeSamplingLimit(GetThread()->GetRandom());
pEEAllocContext->UpdateCombinedLimit(GetThread()->GetRandom());
}
else
{
// Restore the remaining sampling budget as the size is the same.
pEEAllocContext->alloc_sampling = pAllocContext->alloc_ptr + currentSamplingBudget;
pEEAllocContext->combined_limit = pAllocContext->alloc_ptr + currentSamplingBudget;
}
}

Expand Down
81 changes: 48 additions & 33 deletions src/coreclr/vm/gcheaputilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,74 @@ const DWORD SamplingDistributionMean = (100 * 1024);
// This struct adds some state that is only visible to the EE onto the standard gc_alloc_context
typedef struct _ee_alloc_context
{
// This is the address where the next allocation sampling should occur:
// - if sampling is off, this is the same as alloc_limit
// - if sampling is on, this is the next sampled byte in the gc_alloc_context
// - if no such byte exists (i.e. the sampling threshold is outside of the allocation context),
// this is the same as alloc_limit
uint8_t* alloc_sampling;
// Any allocation that would overlap combined_limit needs to be handled by the allocation slow path.
// combined_limit is the minimum of:
// - gc_alloc_context.alloc_limit (the end of the current AC)
// - the sampling_limit
//
// In the simple case that randomized sampling is disabled, combined_limit is always equal to alloc_limit.
//
// There are two different useful interpretations for the sampling_limit. One is to treat the sampling_limit
// as an address and when we allocate an object that overlaps that address we should emit a sampling event.
// The other is that we can treat (sampling_limit - alloc_ptr) as a budget of how many bytes we can allocate
// before emitting a sampling event. If we always allocated objects contiguously in the AC and incremented
// alloc_ptr by the size of the object, these two interpretations would be equivalent. However, when objects
// don't fit in the AC we allocate them in some other address range. The budget interpretation is more
// flexible to handle those cases.
//
// The sampling limit isn't stored in any separate field explicitly, instead it is implied:
// - if combined_limit == alloc_limit there is no sampled byte in the AC. In the budget interpretation
// we can allocate (alloc_limit - alloc_ptr) unsampled bytes. We'll need a new random number after
// that to determine whether future allocated bytes should be sampled.
// This occurs either because the sampling feature is disabled, or because the randomized selection
// of sampled bytes didn't select a byte in this AC.
// - if combined_limit < alloc_limit there is a sample limit in the AC. sample_limit = combined_limit.
uint8_t* combined_limit;
gc_alloc_context gc_alloc_context;

public:
void init()
{
LIMITED_METHOD_CONTRACT;

// we can't compute a sampling limit
// because we don't know the size of the allocation context yet
alloc_sampling = nullptr;
combined_limit = nullptr;
gc_alloc_context.init();
}

inline void ComputeSamplingLimit(CLRRandom* pRandomizer)
static inline bool IsRandomizedSamplingEnabled()
{
// the caller of this function does not have to check if sampling is on/off
// If sampling is off, this is just setting alloc_sampling = alloc_limit
// If sampling is on then we'd do some pseudo-random number generation to decide what is
// the next sampled byte in the gc_alloc_context, if any.
if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context,
TRACE_LEVEL_INFORMATION,
CLR_ALLOCATIONSAMPLING_KEYWORD))
{
// compute the next sampling limit based on a geometric distribution
size_t threshold = ComputeGeometricRandom(pRandomizer);
return ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context,
TRACE_LEVEL_INFORMATION,
CLR_ALLOCATIONSAMPLING_KEYWORD);
}

// Regenerate the randomized sampling limit and update the combined_limit field.
inline void UpdateCombinedLimit(CLRRandom* pRandom)
{
UpdateCombinedLimit(IsRandomizedSamplingEnabled(), pRandom);
}

// if the threshold is larger than the allocation context, no sampling will occur
alloc_sampling = Min(gc_alloc_context.alloc_ptr + threshold, gc_alloc_context.alloc_limit);
// Regenerate the randomized sampling limit and update the combined_limit field.
inline void UpdateCombinedLimit(bool samplingEnabled, CLRRandom* pRandom)
{
if (!samplingEnabled)
{
combined_limit = gc_alloc_context.alloc_limit;
}
else
{
alloc_sampling = gc_alloc_context.alloc_limit;
}
}
// compute the next sampling limit based on a geometric distribution
uint8_t* sampling_limit = gc_alloc_context.alloc_ptr + ComputeGeometricRandom(pRandom);

// it is expected that the caller of these functions has already checked if sampling is on/off
static inline bool IsSampled(CLRRandom* pRandomizer, size_t range)
{
size_t threshold = ComputeGeometricRandom(pRandomizer);
return (threshold < range);
// if the sampling limit is larger than the allocation context, no sampling will occur in this AC
combined_limit = Min(sampling_limit, gc_alloc_context.alloc_limit);
}
}

static inline size_t ComputeGeometricRandom(CLRRandom* pRandomizer)
static inline int ComputeGeometricRandom(CLRRandom* pRandomizer)
{
// compute a random sample from the Geometric distribution
double probability = pRandomizer->NextDouble();
size_t threshold = (size_t)(-log(1 - probability) * SamplingDistributionMean);
int threshold = (int)(-log(1 - probability) * SamplingDistributionMean);
return threshold;
}
} ee_alloc_context;
Expand Down
Loading