From 187644b9ab25463f80258d45e8837ee663dc4c86 Mon Sep 17 00:00:00 2001 From: Alireza Khalesi Date: Sat, 20 Sep 2025 23:00:22 +0800 Subject: [PATCH 1/2] Remove redundant call to SetFree for objects bigger than 4GB Fix #119424 --- src/coreclr/gc/gc.cpp | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 03d8ef466b4db3..3b2442e56ee049 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -36272,25 +36272,21 @@ void gc_heap::make_unused_array (uint8_t* x, size_t size, BOOL clearp, BOOL rese reset_memory (x, size); } } - ((CObjectHeader*)x)->SetFree(size); - -#ifdef HOST_64BIT +#ifndef HOST_64BIT + ((CObjectHeader*)x)->SetFree(size); +#else #if BIGENDIAN #error "This won't work on big endian platforms" #endif - size_t size_as_object = (uint32_t)(size - free_object_base_size) + free_object_base_size; - - if (size_as_object < size) - { // // If the size is more than 4GB, we need to create multiple objects because of // the Array::m_NumComponents is uint32_t and the high 32 bits of unused array // size is ignored in regular object size computation. // - uint8_t * tmp = x + size_as_object; - size_t remaining_size = size - size_as_object; + uint8_t * tmp = x; + size_t remaining_size = size; while (remaining_size > UINT32_MAX) { @@ -36305,7 +36301,7 @@ void gc_heap::make_unused_array (uint8_t* x, size_t size, BOOL clearp, BOOL rese } ((CObjectHeader*)tmp)->SetFree(remaining_size); - } + #endif if (clearp) @@ -36315,12 +36311,12 @@ void gc_heap::make_unused_array (uint8_t* x, size_t size, BOOL clearp, BOOL rese // Clear memory set by make_unused_array. void gc_heap::clear_unused_array (uint8_t* x, size_t size) { - // Also clear the sync block - *(((PTR_PTR)x)-1) = 0; - - ((CObjectHeader*)x)->UnsetFree(); - -#ifdef HOST_64BIT +#ifndef HOST_64BIT + UNREFERENCED_PARAMETER(size); + // Also clear the sync block + *(((PTR_PTR)x)-1) = 0; + ((CObjectHeader*)x)->UnsetFree(); +#else #if BIGENDIAN #error "This won't work on big endian platforms" @@ -36328,28 +36324,24 @@ void gc_heap::clear_unused_array (uint8_t* x, size_t size) // The memory could have been cleared in the meantime. We have to mirror the algorithm // from make_unused_array since we cannot depend on the object sizes in memory. - size_t size_as_object = (uint32_t)(size - free_object_base_size) + free_object_base_size; - - if (size_as_object < size) - { - uint8_t * tmp = x + size_as_object; - size_t remaining_size = size - size_as_object; + uint8_t * tmp = x; + size_t remaining_size = size; while (remaining_size > UINT32_MAX) { size_t current_size = UINT32_MAX - get_alignment_constant (FALSE) - Align (min_obj_size, get_alignment_constant (FALSE)); + *(((PTR_PTR)tmp)-1) = 0; ((CObjectHeader*)tmp)->UnsetFree(); remaining_size -= current_size; tmp += current_size; } + *(((PTR_PTR)tmp)-1) = 0; ((CObjectHeader*)tmp)->UnsetFree(); - } -#else - UNREFERENCED_PARAMETER(size); + #endif } From a0c07d27e20a0695a47366bb90c79cb771d9b444 Mon Sep 17 00:00:00 2001 From: Alireza Khalesi Date: Tue, 23 Sep 2025 15:44:39 +0800 Subject: [PATCH 2/2] Fix indentions --- src/coreclr/gc/gc.cpp | 70 +++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 3b2442e56ee049..996e868ee3ca86 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -36273,35 +36273,34 @@ void gc_heap::make_unused_array (uint8_t* x, size_t size, BOOL clearp, BOOL rese } } #ifndef HOST_64BIT - ((CObjectHeader*)x)->SetFree(size); + ((CObjectHeader*)x)->SetFree(size); #else #if BIGENDIAN #error "This won't work on big endian platforms" #endif - // - // If the size is more than 4GB, we need to create multiple objects because of - // the Array::m_NumComponents is uint32_t and the high 32 bits of unused array - // size is ignored in regular object size computation. - // - uint8_t * tmp = x; - size_t remaining_size = size; + // + // If the size is more than 4GB, we need to create multiple objects because of + // the Array::m_NumComponents is uint32_t and the high 32 bits of unused array + // size is ignored in regular object size computation. + // + uint8_t * tmp = x; + size_t remaining_size = size; - while (remaining_size > UINT32_MAX) - { - // Make sure that there will be at least Align(min_obj_size) left - size_t current_size = UINT32_MAX - get_alignment_constant (FALSE) - - Align (min_obj_size, get_alignment_constant (FALSE)); + while (remaining_size > UINT32_MAX) + { + // Make sure that there will be at least Align(min_obj_size) left + size_t current_size = UINT32_MAX - get_alignment_constant (FALSE) + - Align (min_obj_size, get_alignment_constant (FALSE)); - ((CObjectHeader*)tmp)->SetFree(current_size); + ((CObjectHeader*)tmp)->SetFree(current_size); - remaining_size -= current_size; - tmp += current_size; - } + remaining_size -= current_size; + tmp += current_size; + } - ((CObjectHeader*)tmp)->SetFree(remaining_size); - + ((CObjectHeader*)tmp)->SetFree(remaining_size); #endif if (clearp) @@ -36312,10 +36311,10 @@ void gc_heap::make_unused_array (uint8_t* x, size_t size, BOOL clearp, BOOL rese void gc_heap::clear_unused_array (uint8_t* x, size_t size) { #ifndef HOST_64BIT - UNREFERENCED_PARAMETER(size); - // Also clear the sync block - *(((PTR_PTR)x)-1) = 0; - ((CObjectHeader*)x)->UnsetFree(); + UNREFERENCED_PARAMETER(size); + // Also clear the sync block + *(((PTR_PTR)x)-1) = 0; + ((CObjectHeader*)x)->UnsetFree(); #else #if BIGENDIAN @@ -36324,24 +36323,23 @@ void gc_heap::clear_unused_array (uint8_t* x, size_t size) // The memory could have been cleared in the meantime. We have to mirror the algorithm // from make_unused_array since we cannot depend on the object sizes in memory. - uint8_t * tmp = x; - size_t remaining_size = size; - - while (remaining_size > UINT32_MAX) - { - size_t current_size = UINT32_MAX - get_alignment_constant (FALSE) - - Align (min_obj_size, get_alignment_constant (FALSE)); - - *(((PTR_PTR)tmp)-1) = 0; - ((CObjectHeader*)tmp)->UnsetFree(); + uint8_t * tmp = x; + size_t remaining_size = size; - remaining_size -= current_size; - tmp += current_size; - } + while (remaining_size > UINT32_MAX) + { + size_t current_size = UINT32_MAX - get_alignment_constant (FALSE) + - Align (min_obj_size, get_alignment_constant (FALSE)); *(((PTR_PTR)tmp)-1) = 0; ((CObjectHeader*)tmp)->UnsetFree(); + remaining_size -= current_size; + tmp += current_size; + } + + *(((PTR_PTR)tmp)-1) = 0; + ((CObjectHeader*)tmp)->UnsetFree(); #endif }