将附加信息编码到指针中

问题描述 投票:1回答:1

我的问题是:我需要将一个对象的附加信息编码在一个指向对象的指针中。

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

背景是这样的。

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

我的问题是。

我如何将这些信息编码到64位指针中而不覆盖指针的重要位?

由于x64窗口的地址空间有限,我相信,并不是所有64位的指针都会被使用,所以我相信应该是可以的。但是,我没能找到windows到底使用了指针的哪些位,哪些位没有。说明一下,这个问题是关于64位windows上的usermode。

先谢谢你。

c++ windows pointers 64-bit usermode
1个回答
2
投票

这在很大程度上取决于所使用的架构、操作系统和编译器,但如果你知道这些东西,你可以用它做一些事情。

x86_64定义了一个48位的1 硬件中面向字节的虚拟地址空间,这意味着基本上所有的操作系统和编译器都会使用这个空间。 这意味着

  • 所有有效地址的前17位必须全部相同(全部为0或全部为1)
  • 底部 k 任意位 2k-字节对齐的地址必须全部为0。
  • 此外,几乎所有的操作系统(Windows、Linux和OSX至少)都保留了上位的地址作为内核地址--所有的用户地址必须有上位的17位都是0。

因此,这就给你提供了多种方法,可以将一个有效的指针打包到64位以下,然后在之后用shift和or mask指令重建原始指针。

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

如果你需要更多的位,你可以将指针上移(左)16位,并将这较低的16位用于信息。 要重新构造指针,只需右移16位。

要对指针进行移位和掩码操作,你需要将它们投向 intptr_tint64_t (在任何64位的C或C++实现上,这些都是相同的类型)


1有一些暗示,可能很快就会有硬件将其扩展到56位,所以只有前9位需要是0或1,但在任何操作系统支持这个之前还需要一段时间。

© www.soinside.com 2019 - 2024. All rights reserved.