Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RefC] Object Immortalization and Pre-Generation of Constants #3242

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

seagull-kamome
Copy link
Contributor

Description

This PR immortalizes objects whose reference counter has reached its maximum value and makes them excluded from GC. This immortalization is used to make the following improvements.

  • Since there is no longer any need to worry about the refCounter overflowing to 0, change the refCounter from int to uint16_t to reduce the size of the Value_Header and improve memory usage efficiency.
  • Statically generate constants to reduce runtime cost and share data. Constants are naturally immortal.
    Statically generate values that often appear at runtime, such as empty strings and integers less than 100, and share them at runtime to reduce allocation costs. This heuristic may attract many opinions, but it is a good first-try choice.

On the other hand, there is no way to release immortal objects, so they leak. Dynamic immortalization rarely occurs, but it is a problem for programs that run for long periods of time, such as servers. A secondary GC is needed to solve this, but is not implemented in this PR.

Should this change go in the CHANGELOG?

  • If this is a fix, user-facing change, a compiler change, or a new paper
    implementation, I have updated CHANGELOG_NEXT.md (and potentially also
    CONTRIBUTORS.md).

  * Shrink Value_Header to improve utilization of memory.
  * When refCounter reaches its maximum, the object is immortalized to
    avoid overflow. This immotalization is also used to represent
    statically allocated stock objects.
  * Prepare some commonly seen values and share it to improve memory usage.
  * Added debug code to dump memory stats.
* Commonly seen values such as integers less than 100 are predefined and shared.
* Constant String, Int64, Bits64 and Double values are allocated statically as
  indestructible and shared.
Refactor constantName function to return Core String type
and handle unsupported types by throwing InternalError exception.
@mattpolzin mattpolzin added the backend: refc C with reference counting backend label Apr 1, 2024
Ch x => pure "idris2_mkChar(\{escapeChar x})"
Str _ => orStagen
PrT t => pure $ cPrimType t
_ => pure "NULL"
Copy link
Collaborator

Choose a reason for hiding this comment

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

this catch-all feels a bit brittle to me at first look at least

B64 x => pure "((Value*)&idris2_constant_Bits64_\{show x})"
Db x => pure "((Value*)&idris2_constant_Double_\{cCleanString $ show x})"
Str x => pure "((Value*)&idris2_constant_String_\{n})"
_ => throw $ InternalError "[refc] Unsupported type of constant."
Copy link
Collaborator

@mattpolzin mattpolzin Jun 5, 2024

Choose a reason for hiding this comment

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

this compile-time error feels like it could be fairly easily remediated by a new smaller data-type than Constant so that we aren't relying on the invariant that no new type of constant is stored in ConstDef without a new case being added here.

support/refc/memoryManagement.c Outdated Show resolved Hide resolved
Comment on lines +210 to +214
} else if (elem->header.refCounter != 1) {
--elem->header.refCounter;
return;
} else {
IDRIS2_INC_MEMSTAT(n_freed);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I notice that whereas elem->header.refCounter used to be decremented prior to freeing, now it is not; that seems theoretically ok to me, but I wanted to make sure it was intentional because I have not verified that nothing downstream of this code would double check the ref count.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: refc C with reference counting backend
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants