Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ if(TARGET coreclr)
$<TARGET_NAME_IF_EXISTS:coreclrpal>
${CLRJIT_STATIC}
${CLRINTERPRETER_STATIC}
vm_gc_wks
$<TARGET_NAME_IF_EXISTS:vm_gc_svr>
cee_wks_core
cee_wks
${FOUNDATION})
endif()

target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} ${CORECLR_STATIC_CLRJIT_STATIC} ${CORECLR_STATIC_CLRINTERPRETER_STATIC} cee_wks_core ${CEE_WKS_STATIC} ${FOUNDATION})
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} ${CORECLR_STATIC_CLRJIT_STATIC} ${CORECLR_STATIC_CLRINTERPRETER_STATIC} vm_gc_wks $<TARGET_NAME_IF_EXISTS:vm_gc_svr> cee_wks_core ${CEE_WKS_STATIC} ${FOUNDATION})
target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED)

if(FEATURE_INPROC_CRASHREPORT AND NOT CLR_CROSS_COMPONENTS_BUILD)
Expand Down
60 changes: 54 additions & 6 deletions src/coreclr/gc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@ set(GC_SOURCES
gcconfig.cpp
gccommon.cpp
gcscan.cpp
gcsvr.cpp
gcwks.cpp
handletable.cpp
handletablecore.cpp
handletablescan.cpp
objecthandle.cpp
softwarewritewatch.cpp
gchandletable.cpp
gceesvr.cpp
gceewks.cpp
gcload.cpp
gcbridge.cpp
handletablecache.cpp)
Expand Down Expand Up @@ -57,6 +53,7 @@ if (CLR_CMAKE_TARGET_WIN32)
env/gcenv.windows.inl
env/volatile.h
gc.h
gcinternal.h
gcconfig.h
gcbridge.h
gcdesc.h
Expand Down Expand Up @@ -105,26 +102,77 @@ list(APPEND GC_SOURCES ${GC_HEADERS})

convert_to_absolute_path(GC_SOURCES ${GC_SOURCES})

set(GC_WKS_SVR_SOURCES
gcee.cpp
gc.cpp
init.cpp
no_gc.cpp
finalization.cpp
dynamic_tuning.cpp
region_free_list.cpp
region_allocator.cpp
memory.cpp
sweep.cpp
collect.cpp
diagnostics.cpp
dynamic_heap_count.cpp
card_table.cpp
relocate_compact.cpp
mark_phase.cpp
background.cpp
interface.cpp
allocation.cpp
plan_phase.cpp
regions_segments.cpp)

if(FEATURE_STANDALONE_GC)
if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64)
set(BUILD_EXP_GC 1)
endif()

# clrgcexp is build with standalone+regions
if (BUILD_EXP_GC)
add_library_clr(clrgcexp SHARED ${GC_SOURCES})
add_library_clr(clrgcexp_gc_wks OBJECT ${GC_WKS_SVR_SOURCES})
add_dependencies(clrgcexp_gc_wks eventing_headers)
target_compile_definitions(clrgcexp_gc_wks PRIVATE USE_REGIONS)
set_property(TARGET clrgcexp_gc_wks PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
set(CLRGGCEXP_OBJECTS
$<TARGET_OBJECTS:clrgcexp_gc_wks>)
if (FEATURE_SVR_GC)
add_library_clr(clrgcexp_gc_svr OBJECT ${GC_WKS_SVR_SOURCES})
add_dependencies(clrgcexp_gc_svr eventing_headers)
target_compile_definitions(clrgcexp_gc_svr PRIVATE SERVER_GC USE_REGIONS)
set_property(TARGET clrgcexp_gc_svr PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
list(APPEND CLRGGCEXP_OBJECTS
$<TARGET_OBJECTS:clrgcexp_gc_svr>)
endif()

add_library_clr(clrgcexp SHARED ${GC_SOURCES} ${CLRGGCEXP_OBJECTS})
add_dependencies(clrgcexp eventing_headers)
target_link_libraries(clrgcexp PRIVATE ${GC_LINK_LIBRARIES})
target_link_libraries(clrgcexp PRIVATE gcexp_dll_wks_descriptor)
if (FEATURE_SVR_GC)
target_link_libraries(clrgcexp PRIVATE gcexp_dll_svr_descriptor)
endif()
target_compile_definitions(clrgcexp PRIVATE -DUSE_REGIONS)
set_property(TARGET clrgcexp PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we set INTERPROCEDURAL_OPTIMIZATION for some targets and not others?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, it should be added to the clrgc too, I've overlooked it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I also wonder why I haven't used add_pgo instead here. I'll double check that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, add_pgo would actually require us to have pgo data for the libcoreclr.so and libcoreclrext.so. We currently generate pgo for libcoreclr.so and libclrjit.so only.
When PGO data is missing, we just fall back to not enabling the LTO at all. The PGO and LTO are tight together, PGO is essentially part of LTO.
There seems to also be an issue with object libraries and PGO. add_pgo only adds the LTO options to the final targets, but on Unix, it needs to be specified at the compilation time too. So any code that we compile as object library and then add to e.g. libcoreclr.so would not have PGO enabled. It seems our PGO optimization is broken as many parts of the coreclr are now object libraries.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should enable LTO by default for everything (there is a cmake global property to do that) and change the add_pgo to only add the option to specify the profile file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enable LTO by default for everything

We cannot enable LTO for the object files and static libraries that we ship. LTO is tied to specific compiler version that is not guaranteed to be on user's machine.

BTW: We do not collect the PGO data for most of libcoreclr.so currently - #128412 is working towards fixing that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we may still be able to compile with -flto and get functional shipping static libs, using fat LTO. The benefit would be that for object files that go both to shipping static libs and to our shared libs, we could take advantage of LTO for the shared libs case. See https://llvm.org/docs/FatLTO.html. Supported in LLVM 17 and newer. But that's for a separate experiment.

install_clr(TARGETS clrgcexp DESTINATIONS . COMPONENT runtime)
endif (BUILD_EXP_GC)

add_library_clr(clrgc_gc_wks OBJECT ${GC_WKS_SVR_SOURCES})
add_dependencies(clrgc_gc_wks eventing_headers)
set(CLRGC_OBJECTS
$<TARGET_OBJECTS:clrgc_gc_wks>)
if(FEATURE_SVR_GC)
add_library_clr(clrgc_gc_svr OBJECT ${GC_WKS_SVR_SOURCES})
add_dependencies(clrgc_gc_svr eventing_headers)
target_compile_definitions(clrgc_gc_svr PRIVATE SERVER_GC)
list(APPEND CLRGC_OBJECTS
$<TARGET_OBJECTS:clrgc_gc_svr>)
endif()

# clrgc is build with standalone+segments
add_library_clr(clrgc SHARED ${GC_SOURCES})
add_library_clr(clrgc SHARED ${GC_SOURCES} ${CLRGC_OBJECTS})
add_dependencies(clrgc eventing_headers)
target_link_libraries(clrgc PRIVATE ${GC_LINK_LIBRARIES})
target_link_libraries(clrgc PRIVATE gc_dll_wks_descriptor)
Expand Down
99 changes: 11 additions & 88 deletions src/coreclr/gc/allocation.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "gcinternal.h"

#ifdef SERVER_GC
namespace SVR
{
#else // SERVER_GC
namespace WKS
{
#endif // SERVER_GC

allocator::allocator (unsigned int num_b, int fbb, alloc_list* b, int gen)
{
Expand Down Expand Up @@ -1321,27 +1330,6 @@ bool gc_heap::new_allocation_allowed (int gen_number)
return TRUE;
}

inline
ptrdiff_t gc_heap::get_desired_allocation (int gen_number)
{
return dd_desired_allocation (dynamic_data_of (gen_number));
}

inline
ptrdiff_t gc_heap::get_new_allocation (int gen_number)
{
return dd_new_allocation (dynamic_data_of (gen_number));
}

//return the amount allocated so far in gen_number
inline
ptrdiff_t gc_heap::get_allocation (int gen_number)
{
dynamic_data* dd = dynamic_data_of (gen_number);

return dd_desired_allocation (dd) - dd_new_allocation (dd);
}

#ifdef SHORT_PLUGS
inline
void set_padding_in_expand (uint8_t* old_loc,
Expand Down Expand Up @@ -3253,29 +3241,6 @@ allocation_state gc_heap::allocate_soh (int gen_number,
return soh_alloc_state;
}

#ifdef BACKGROUND_GC
inline
void gc_heap::bgc_track_uoh_alloc()
{
if (current_c_gc_state == c_gc_state_planning)
{
Interlocked::Increment (&uoh_alloc_thread_count);
dprintf (3, ("h%d: inc lc: %d", heap_number, (int32_t)uoh_alloc_thread_count));
}
}

inline
void gc_heap::bgc_untrack_uoh_alloc()
{
if (current_c_gc_state == c_gc_state_planning)
{
Interlocked::Decrement (&uoh_alloc_thread_count);
dprintf (3, ("h%d: dec lc: %d", heap_number, (int32_t)uoh_alloc_thread_count));
}
}

#endif //BACKGROUND_GC

size_t gc_heap::get_uoh_seg_size (size_t size)
{
size_t default_seg_size =
Expand Down Expand Up @@ -4551,41 +4516,6 @@ BOOL gc_heap::allocate_more_space(alloc_context* acontext, size_t size,
return (status == a_state_can_allocate);
}

inline
CObjectHeader* gc_heap::allocate (size_t jsize, alloc_context* acontext, uint32_t flags)
{
size_t size = Align (jsize);
assert (size >= Align (min_obj_size));
{
retry:
uint8_t* result = acontext->alloc_ptr;
acontext->alloc_ptr+=size;
if (acontext->alloc_ptr <= acontext->alloc_limit)
{
CObjectHeader* obj = (CObjectHeader*)result;
assert (obj != 0);
return obj;
}
else
{
acontext->alloc_ptr -= size;

#ifdef _MSC_VER
#pragma inline_depth(0)
#endif //_MSC_VER

if (! allocate_more_space (acontext, size, flags, 0))
return 0;

#ifdef _MSC_VER
#pragma inline_depth(20)
#endif //_MSC_VER

goto retry;
}
}
}

void gc_heap::leave_allocation_segment (generation* gen)
{
adjust_limit (0, 0, gen);
Expand Down Expand Up @@ -5417,15 +5347,6 @@ generation* gc_heap::ensure_ephemeral_heap_segment (generation* consing_gen)

#endif //!USE_REGIONS

inline
void gc_heap::init_alloc_info (generation* gen, heap_segment* seg)
{
generation_allocation_segment (gen) = seg;
generation_allocation_pointer (gen) = heap_segment_mem (seg);
generation_allocation_limit (gen) = generation_allocation_pointer (gen);
generation_allocation_context_start_region (gen) = generation_allocation_pointer (gen);
}

inline
heap_segment* gc_heap::get_next_alloc_seg (generation* gen)
{
Expand Down Expand Up @@ -5880,3 +5801,5 @@ CObjectHeader* gc_heap::allocate_uoh_object (size_t jsize, uint32_t flags, int g

return obj;
}

} // namespace SVR/WKS
53 changes: 11 additions & 42 deletions src/coreclr/gc/background.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "gcinternal.h"

#ifdef SERVER_GC
namespace SVR
{
#else // SERVER_GC
namespace WKS
{
#endif // SERVER_GC

// static

Expand Down Expand Up @@ -221,47 +230,6 @@ void gc_heap::concurrent_print_time_delta (const char* msg)
}

#ifdef BACKGROUND_GC
inline
BOOL gc_heap::background_marked (uint8_t* o)
{
return mark_array_marked (o);
}

inline
BOOL gc_heap::background_mark1 (uint8_t* o)
{
BOOL to_mark = !mark_array_marked (o);

dprintf (3, ("b*%zx*b(%d)", (size_t)o, (to_mark ? 1 : 0)));
if (to_mark)
{
mark_array_set_marked (o);
dprintf (4, ("n*%zx*n", (size_t)o));
return TRUE;
}
else
return FALSE;
}

// TODO: we could consider filtering out NULL's here instead of going to
// look for it on other heaps
inline
BOOL gc_heap::background_mark (uint8_t* o, uint8_t* low, uint8_t* high)
{
BOOL marked = FALSE;
if ((o >= low) && (o < high))
marked = background_mark1 (o);
#ifdef MULTIPLE_HEAPS
else if (o)
{
gc_heap* hp = heap_of (o);
assert (hp);
if ((o >= hp->background_saved_lowest_address) && (o < hp->background_saved_highest_address))
marked = background_mark1 (o);
}
#endif //MULTIPLE_HEAPS
return marked;
}

#ifdef USE_REGIONS
void gc_heap::set_background_overflow_p (uint8_t* oo)
Expand Down Expand Up @@ -3465,7 +3433,6 @@ void gc_heap::process_background_segment_end (heap_segment* seg,
bgc_verify_mark_array_cleared (seg);
}

inline
BOOL gc_heap::fgc_should_consider_object (uint8_t* o,
heap_segment* seg,
BOOL consider_bgc_mark_p,
Expand Down Expand Up @@ -4611,3 +4578,5 @@ size_t gc_heap::get_mark_array_size (heap_segment* seg)
}

#endif //USE_REGIONS

} // namespace WKS/SVR
Loading
Loading