在指针中编码附加信息

Encode additional information in pointer

我的问题:

我需要在指向对象的指针中编码有关对象的附加信息。 我认为我可以做的是使用指针的一部分来这样做。也就是说,使用几个位编码 bool 标志。据我所知,windows 内核中某些类型的句柄也是如此。

背景:

我正在编写一个小型内存管理系统,可以对未使用的对象进行垃圾回收。为了减少对象引用的内存消耗并加快复制速度,我想使用带有附加编码数据的指针,例如对象的状态(存活或准备好被收集),锁定位和类似的东西,可以用一个位来表示。

我的问题:

如何在不实际覆盖指针的重要位的情况下将此类信息编码为 64 位指针?

由于x64 windows 有地址限制space,我相信,并不是指针的所有64 位都被使用,所以我相信这应该是可能的。但是,我无法找到 windows 哪些位实际用于指针,哪些位没有。澄清一下,这个问题是关于 64 位 windows.

上的用户模式的

提前致谢。

这在很大程度上取决于体系结构、OS 和使用的编译器,但如果您知道这些,就可以用它做一些事情。

x86_64在硬件中定义了一个48位1面向字节的虚拟地址space,这意味着基本上所有OSes编译器将使用它。这意味着:

  • 所有有效地址的前17位必须全部相同(全0或全1)
  • 任何2k字节对齐地址的底部k位必须全部0秒
  • 此外,几乎所有的OSes(Windows、Linux和至少OSX)都将高位设置为内核的地址保留addresses -- 所有用户地址必须高17位全0

因此,这为您提供了多种将有效指针打包成小于 64 位的方法,然后使用移位 and/or 掩码指令重建原始指针。

如果你只需要 3 位并且总是使用 8 字节对齐的指针,你可以使用底部的 3 位来编码额外的信息,并在使用指针之前将它们屏蔽掉。

如果需要更多位,可以将指针向上(向左)移动 16 位,并使用低 16 位作为信息。要重建指针,只需右移 16.

要对指针进行移位和屏蔽操作,您需要将它们转换为 intptr_tint64_t(它们在 C 或 C++ 的任何 64 位实现上都是相同的类型)


1有一些暗示可能很快就会有硬件将其扩展到 56 位,因此只有前 9 位需要是 0 或 1 , 但在任何 OS 支持这个

之前还需要一段时间