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

Packed pointers #2652

Open
daurnimator opened this issue Jun 11, 2019 · 2 comments
Open

Packed pointers #2652

daurnimator opened this issue Jun 11, 2019 · 2 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@daurnimator
Copy link
Collaborator

daurnimator commented Jun 11, 2019

What if aligned pointers could be packed? *packed align(4096) foo only needs usize-12 bits.

Such pointers would mostly be used in a packed struct such as:

packed struct {
    ptr: *packed foo,
    needs_lock: bool,
}

assuming that foo has an alignment requirement of e.g. 8.

This lets zig code nicely implement the common pattern of using lower pointer bits as tag bits without lots of error-prone @ptrToInt and masking. An immediate user would be the red-black tree code.

@daurnimator
Copy link
Collaborator Author

An attribute on the pointer type might not be necessary: similar to how e.g. a u7 might be stored in a 8 bit register, may be passed as a 32 bit parameter and takes up 8 bits in a non-packed struct: *align(4096) foo may be passed in a 64bit register and takes up usize bits in a non-packed struct, but only takes up usize-12 bits in a packed struct.

@shawnl
Copy link
Contributor

shawnl commented Jun 11, 2019

The current packed structs are C ABI compatible. Everywhere else in Zig extern signifies external ABI compatibility, thus I propose we change the existing packed to extern packed. We can then add this feature as packed on structs (not pointers).

packed struct {
    ptr: *foo, // and alignof(foo) >= 2
    needs_lock: bool,
}

then will take up 32 or 64 bits. You can do fancier things which you couldn't do with the c-compatible packed:

packed struct {
  hi: bool,
  ptr: *foo,
  bi: bool,
  ye: u2,
  ptr: big_struct,
  another_bool: bool,
}

and a allocator algorithm would run and assign the small ones to be packed into the pointers. It could eventually even be smart and pick less-used pointers. You can also do this manually using a sub-struct:

struct {
 performance_critical_pointer: *foo,
 packed struct {
   stuffed_ptr: *hi,
   flag: bool,
 }
}

@andrewrk andrewrk added this to the 0.6.0 milestone Jun 11, 2019
@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jun 11, 2019
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Jan 7, 2020
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 27, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 23, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Apr 9, 2023
@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0 Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

3 participants