gpt4 book ai didi

c++ - 如何处理在方法中间在内存中移动的对象?

转载 作者:搜寻专家 更新时间:2023-10-31 01:49:40 25 4
gpt4 key购买 nike

我正在用 C++ 为编程语言编写 VM。该语言是垃圾收集的,所以我有在垃圾收集堆中分配的 C++ 类的实例。我正在使用复制收集器,因此当发生 GC 时,这些对象会在内存中移动。这意味着指向该对象的每个指针都需要更新。 大多数这些指针都很容易处理,除了一个棘手的指针:this。考虑:

class SomeObj : public Managed      // inheriting from this means it's on the GC heap
{
public:
void method()
{
SomeObj* other = new SomeObj(); // could trigger a GC.
printf("%d\n", someField); // this points to wrong memory
}

private:
int someField;
};

如果我正处于 GC 堆上某个对象的实例方法的中间,则 this 指向某个 GC 内存。收集可以发生在此方法的中间。发生这种情况时,对象将移动到新位置。但是,由于我们正处于方法调用的中间,this 仍然指向旧的错误位置。

我可以通过不在托管内存中的类上使用实例方法来解决这个问题,但我确实喜欢这样代码更简单。有什么技术可以解决这个问题吗?

最佳答案

您的 GC 需要扫描堆栈并注册指针并修复它们。如果您的 VM 支持多线程,则需要在扫描线程堆栈时暂停所有线程。 “this”指针将位于堆栈或寄存器中。

由于 C++ 不为堆栈提供类型信息,因此您可能很难处理类似的内容

int i = 1000000;
char * p = new char[10]; // 0xF4240 = 1000000

无论您使用什么方法移动其他指针,都会遇到同样的问题。在某些时候,您的代码必须将句柄转换为指针,并且需要修复这些指针。

像这样修改C++代码

func()->method()

看起来像

struct GCroot call123 = { func() };
call123.obj->method();

多线程问题。如果你有这样的代码

struct GCroot obj123 = { /* .. */ };
obj123.ptr->x = obj123.ptr->x + 1;

它可能会生成这样的伪汇编代码

load r1, obj123.ptr
load r2, (r1)
add r2, 1
store (r1), r2

如果另一个线程在第一个和最后一个 asm 行之间的任何时间执行 GC,那么 r1 如何固定?

关于c++ - 如何处理在方法中间在内存中移动的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16256834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com