Skip to content

Remove FEATURE_BASICFREEZE#129919

Open
EgorBo wants to merge 1 commit into
mainfrom
EgorBo/remove-feature-basicfreeze
Open

Remove FEATURE_BASICFREEZE#129919
EgorBo wants to merge 1 commit into
mainfrom
EgorBo/remove-feature-basicfreeze

Conversation

@EgorBo

@EgorBo EgorBo commented Jun 27, 2026

Copy link
Copy Markdown
Member

FEATURE_BASICFREEZE has been unconditionally defined in every shipping configuration for years:

  • CoreCLR — src/coreclr/clrdefinitions.cmake
  • NativeAOT — src/coreclr/nativeaot/Runtime/CMakeLists.txt
  • standalone clrgc (built inside the CoreCLR tree)

The only in-repo consumer that compiled the disabled path was the GC sample (src/coreclr/gc/sample), which builds the shared GC sources without CoreCLR's global defines (its add_subdirectory(gc/sample) precedes include(clrdefinitions.cmake)).

This removes the FEATURE_BASICFREEZE symbol entirely, making read-only / frozen segment support unconditional. The enabled code path is unchanged — only the dead #else / #ifndef branches are dropped. Combined conditions are simplified, e.g. #if defined(FEATURE_BASICFREEZE) && !defined(USE_REGIONS)#ifndef USE_REGIONS.

Validation

Built on windows-x64 (Checked) with 0 errors / 0 warnings:

  • coreclr.dll (VM + GC)
  • clrgc.dll / clrgcexp.dll (standalone GC)
  • gcsample.exe — the consumer that previously compiled the removed #else branches; now compiles the frozen-segment code unconditionally
  • NativeAOT Runtime.WorkstationGC / Runtime.ServerGC

FEATURE_BASICFREEZE has been unconditionally defined in every shipping
configuration (CoreCLR via clrdefinitions.cmake, NativeAOT, and the
standalone clrgc) for years. The only in-repo consumer that compiled the
disabled code path was the GC sample (src/coreclr/gc/sample), which builds
the shared GC sources without CoreCLR's global defines.

Remove the symbol entirely, making read-only / frozen segment support
unconditional. The enabled code path is unchanged; only the dead #else /
#ifndef branches are dropped. Combined conditions are simplified, e.g.
`#if defined(FEATURE_BASICFREEZE) && !defined(USE_REGIONS)` becomes
`#ifndef USE_REGIONS`.

Validated by building coreclr.dll, clrgc/clrgcexp, the GC sample, and the
NativeAOT runtime (Workstation/Server GC) on windows-x64.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 27, 2026 01:39
@EgorBo EgorBo requested a review from MichalStrehovsky as a code owner June 27, 2026 01:39
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @anicka-net, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the FEATURE_BASICFREEZE compile-time symbol from CoreCLR and NativeAOT and makes the “frozen/read-only segment” support code paths unconditional, deleting the now-dead #else branches and simplifying related preprocessor conditions.

Changes:

  • Drops FEATURE_BASICFREEZE feature-guarded branches across VM + GC, leaving the already-enabled behavior as the only behavior.
  • Makes frozen-segment QCall entrypoints and registrations unconditional (CoreCLR + NativeAOT).
  • Removes FEATURE_BASICFREEZE from build definition inputs (CoreCLR cmake + NativeAOT cmake + VS Code IntelliSense defines).

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/coreclr/vm/syncblk.cpp Removes dead assertion/return path for frozen-bit validation when basicfreeze was “off”.
src/coreclr/vm/qcallentrypoints.cpp Makes frozen-segment QCall exports unconditional in the QCall table.
src/coreclr/vm/frozenobjectheap.cpp Removes the “GC lacks frozen support” early-return branch; allocation now always uses frozen-segment path.
src/coreclr/vm/comutilnative.h Makes QCall declarations for frozen segment registration unconditional.
src/coreclr/vm/comutilnative.cpp Makes QCall implementations for frozen segment registration unconditional.
src/coreclr/vm/.vscode/c_cpp_properties.json Removes FEATURE_BASICFREEZE from IntelliSense defines list.
src/coreclr/nativeaot/Runtime/GCHelpers.cpp Removes conditional stub return; always registers frozen segments via GC heap.
src/coreclr/nativeaot/Runtime/CMakeLists.txt Stops defining FEATURE_BASICFREEZE for NativeAOT runtime build.
src/coreclr/gc/sweep.cpp Removes feature-guard around read-only segment sweeping helpers.
src/coreclr/gc/relocate_compact.cpp Simplifies readonly-segment check for LOH relocation logic.
src/coreclr/gc/regions_segments.cpp Removes feature-guards around RO segment mapping/insert/remove support.
src/coreclr/gc/plan_phase.cpp Makes sweep_ro_segments() unconditional (as it already was in shipping configs).
src/coreclr/gc/mark_phase.cpp Removes feature-guards around RO segment mark/clear helpers and in-range RO marking (still gated by USE_REGIONS).
src/coreclr/gc/interface.cpp Simplifies feature-conditional initialization / range checks for frozen segments.
src/coreclr/gc/gcpriv.h Makes RO-segment-related members/methods unconditional in the GC heap class declaration.
src/coreclr/gc/gcinternal.h Makes sorted_table, RO-segment range assertions, and lookup prototype unconditional.
src/coreclr/gc/gcinterface.h Updates interface comment block to remove feature-guard wording.
src/coreclr/gc/gcee.cpp Makes Register/Unregister/IsIn/UpdateFrozenSegment implementations unconditional.
src/coreclr/gc/gc.cpp Makes RO segment table storage and lookup support unconditional.
src/coreclr/gc/diagnostics.cpp Makes RO-segment walking helper unconditional.
src/coreclr/gc/collect.cpp Makes seg_table->delete_old_slots() unconditional (as per always-enabled feature).
src/coreclr/gc/background.cpp Makes RO-segment marking/sweeping calls unconditional (still respects USE_REGIONS guards where applicable).
src/coreclr/clrdefinitions.cmake Stops defining FEATURE_BASICFREEZE for CoreCLR builds.

@jkotas jkotas requested a review from a team June 27, 2026 01:45
@github-actions

Copy link
Copy Markdown
Contributor

Copilot Code Review

Holistic Assessment

Motivation: Justified. FEATURE_BASICFREEZE has been unconditionally defined in every shipping configuration (CoreCLR, NativeAOT) for years. Removing always-true preprocessor guards and their dead #else branches is a clear improvement to code readability and maintainability.

Approach: Correct. The PR mechanically removes the symbol definition from build files, drops all #ifdef/#ifndef guards (keeping the enabled path), removes dead #else branches, and simplifies compound conditions. The removal is complete — grep confirms zero remaining references to FEATURE_BASICFREEZE across the repo.

Summary: ✅ LGTM. This is a clean, mechanical dead-code removal with no behavioral changes to any shipping configuration. The enabled code paths are entirely unchanged. The simplification of compound conditions (e.g., #if defined(FEATURE_BASICFREEZE) && !defined(USE_REGIONS)#ifndef USE_REGIONS) is correct. The 23 changed files all follow the same straightforward pattern.


Detailed Findings

Detailed Findings

✅ Complete removal — no remaining references

Verified via repo-wide grep that no references to FEATURE_BASICFREEZE remain in any file (cmake, C++, JSON, headers). The removal is thorough.

✅ Compound condition simplification is correct

All compound conditions were correctly simplified:

  • #if defined(FEATURE_BASICFREEZE) && !defined(USE_REGIONS)#ifndef USE_REGIONS
  • #if defined(STRESS_REGIONS) && defined(FEATURE_BASICFREEZE)#ifdef STRESS_REGIONS
  • #if defined(FEATURE_BASICFREEZE) && defined(USE_REGIONS)#ifdef USE_REGIONS

✅ Dead #else branches correctly removed

The removed #else branches in gcee.cpp, frozenobjectheap.cpp, interface.cpp, GCHelpers.cpp, syncblk.cpp, and gcinternal.h all contained either:

  • Unreachable assertions (assert(!"Should not call...")
  • Hardcoded false returns (return false, return nullptr, return NULL)
  • Weaker assertions without the frozen-segment check

These are the expected dead-code patterns for an always-enabled feature flag.

✅ Functional code preserved unchanged

The enabled code paths (RegisterFrozenSegment, UnregisterFrozenSegment, IsInFrozenSegment, UpdateFrozenSegment, sorted_table, seg_mapping_table, ro_segment_lookup, etc.) are byte-for-byte identical to before — only the surrounding preprocessor guards were stripped.

💡 Minor: a few double blank lines from mechanical removal

In interface.cpp (around NextObj) and gc.cpp (around ro_segment_lookup), the removal of adjacent #ifdef/#endif blocks leaves consecutive blank lines. This is cosmetic only and consistent with the mechanical nature of the change — not worth a follow-up.

Note

This review was created by GitHub Copilot.

Generated by Code Review for issue #129919 · ● 35.8M ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants