Cal*_*mer 3 optimization ocaml pointers rust union-types
(I\xe2\x80\x99m 指的是装箱作为在运行时区分整数和指针的一种方式。一种技术使用一些编程语言来帮助 GC,如OCaml。不是 RustBox<T>类型。)
我有一个 Rust 枚举,如下所示:
\n\n#[derive(Clone, Copy, Debug, PartialEq)]\nenum Type<\'ts> {\n TVar(usize),\n Constructed(&\'ts ConstructedType<\'ts>),\n}\nRun Code Online (Sandbox Code Playgroud)\n\n据我了解,这个枚举的内存布局将是两个单词。一份用于标签,一份用于有效负载。如果可能的话,我想用一个词来表达记忆。
\n\n像OCaml这样的语言使用一种名为 \xe2\x80\x9cinteger boxing\xe2\x80\x9d 的技术,它利用了指针对齐的事实。这意味着最低位将为 0。如果将整数中的位向左移动一位并将整数的最低位设置为 1,则您\xe2\x80\x99 将使用该位作为标记,但代价是一位整数精度。
\n\nRust 指针保证对齐吗?我如何在 Rust 中为我的类型实现这种技术?
\n我可能没有听懂你所说的一切union,但我认为你需要一个.
#[derive(Clone, Copy, Debug, PartialEq)]\nenum Type<\'ts> {\n TVar(usize),\n Constructed(&\'ts ConstructedType<\'ts>),\n}\n\nunion CompactType<\'ts> {\n num: usize,\n ptr: &\'ts ConstructedType<\'ts>\n}\n\nimpl<\'ts> From<CompactType<\'ts>> for Type<\'ts> {\n fn from(compact: CompactType<\'ts>) -> Type<\'ts> {\n unsafe {\n if compact.num & 1 == 1 {\n Type::TVar(compact.num >> 1)\n } else {\n Type::Constructed(compact.ptr)\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,访问 a 的成员union是不安全的,您必须确保强制执行所有不变量。例如,您必须显式检查是否CompactType使用范围内的值正确创建了 s,并防止在不经过这些检查的情况下构造对象的可能性。
我建议向 中添加构造函数CompactType,该函数返回 aResult或 an Option,以防您尝试使用太大的数字或指向未正确对齐的类型的指针。当该TryFrom功能稳定后,您可以使用它,但与此同时:
enum CompactConvertError {\n NumTooBig(String),\n PtrNotAligned(String),\n}\n\nimpl<\'ts> Type<\'ts> {\n fn to_compact(&self) -> Result<CompactType<\'ts>, CompactConvertError> {\n match self {\n Type::TVar(num) => {\n if num >> (mem::size_of::<usize>() * 8 - 1) == 1 {\n Err(CompactConvertError::NumTooBig(\n String::from("The last bit of the usize cannot be used here"))\n )\n } else {\n Ok(CompactType { num: num << 1 | 1usize })\n } \n },\n Type::Constructed(c) => {\n if mem::align_of_val(*c) % 2 == 1 {\n Err(CompactConvertError::PtrNotAligned(\n String::from("The pointer must be to a type with even alignment"))\n )\n } else {\n Ok(CompactType { ptr: c })\n }\n }\n }\n } \n}\nRun Code Online (Sandbox Code Playgroud)\n\n这应该足够灵活,可以替换ConstructedType为泛型类型参数。唯一的限制是你不应该将它从引用更改为拥有的值,否则你将不得不担心如何正确删除它\xe2\x80\x94,这对于union稳定 Rust 中的类型尚无法完成。
至于对齐,如果ConstructedType大小只有 1 个字节,则需要为其添加对齐,以确保它仅在偶数字节上,否则 Rust 可能会选择将它们打包得更紧密:
#[align(2)]\nstruct ConstructedType<\'ts> { \n // ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n#[align(2)]如果大小大于 2 个字节,绝对不要添加。也许其他人可以提供使该部分更加健壮的建议。
| 归档时间: |
|
| 查看次数: |
965 次 |
| 最近记录: |