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

Tags with more than one variant are always 4 byte aligned #792

Closed
pcwalton opened this issue Aug 1, 2011 · 2 comments
Closed

Tags with more than one variant are always 4 byte aligned #792

pcwalton opened this issue Aug 1, 2011 · 2 comments

Comments

@pcwalton
Copy link
Contributor

pcwalton commented Aug 1, 2011

Because of this code:

fn T_tag(&type_names tn, uint size) -> TypeRef {
    auto s = "tag_" + uint::to_str(size, 10u);
    if (tn.name_has_type(s)) { ret tn.get_type(s); }
    auto t = T_struct(~[T_int(), T_array(T_i8(), size)]);
    tn.associate(s, t);
    ret t;
}

Tags always end up 4 byte aligned when they have more than one variant, even when that's wrong.

@nikomatsakis
Copy link
Contributor

This problem is more urgent as we support more architectures.

In general, I think tags should be laid out as follows (this is fairly close to what the current code does):

  • No data: just like an enum.

  • Only one variant: just like that variant's data

  • Multiple variants with data:

    struct Tag {
        unsigned variant_id;
        union { variant_1, variant_2, variant_3 } data;
    }
    

    where variant_N stands in for the translation of the data types.

The tricky case of course is with generic types. For something like

tag option<T> { none; some(val: T); }

where is the data located? That depends on the type of T and its corresponding alignment restrictions. I am not clear on how the current dynamic shape-walking code (GEP-tuple-like, Shape.h, and friends) handles this kind of dynamic alignment. I could see an argument for using a pessimistic alignment (i.e., maximally align the data in tags always), but that seems to waste a lot of space, since the maximal reasonable alignment is probably 16 bytes (vector data), and you only NEED 4 bytes (for the variant ID).

For reference, the current behavior is:

  • No data: unsigned long variant_id
  • Only one variant: use a char[X] array where X is the size of the variant
  • Multiple variants: struct Tag { unsigned long variant_id; char[X] data; } where X is the size of the largest variant

@nikomatsakis
Copy link
Contributor

Subsumed by #1645

keeperofdakeys pushed a commit to keeperofdakeys/rust that referenced this issue Dec 12, 2017
Add IP_BINDANY for FreeBSD

Adds the IP_BINDANY constant for FreeBSD. Thanks!
coastalwhite pushed a commit to coastalwhite/rust that referenced this issue Aug 5, 2023
celinval pushed a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants