在移植过程中,遇到了指针崩溃的问题,经过多方查找,终于确定和V8_COMPRESS_POINTERS导致的问题。
V8_COMPRESS_POINTERS是v8新加入的功能。可以节省不少内存占用。如果设置v8_enable_pointer_compression = false就会关闭。
如果关闭了该功能,程序可以正常运行。
实际上,该功能只会在64位上开启。因为该功能是将64位指针压缩为32位指针。
基本原理
v8的对象,包括js对象等,很多都是在heap上分配的,这些对象称为heap对象。heap是一段连续的内存。这样,v8对象包含的子对象,他们的指针与v8对象的指针距离都很近,所以如果已知heap对象的地址,那么子对象只需要知道一部分地址即可。
如:一个 heap_object对象,关联一个内部的 map对象,从heap_object取map的地址。
假设 :
heap_object addr = 0x790804030c
子成员map 压缩后地址是 0x08040328
在64位下,将地址分为高32位和低32位,那么map最终地址是取heap_object 的高32位,与map的低32位结合在一起,就可以了:
map最终地址: 0x7908040328 红色部分是heap_object的高32位,蓝色部分是map的压缩地址。
这样才能得到一个完整的地址。
注:v8充分的利用了地址来表示对象的类型。地址总是4字节对齐的,故此,v8将最低3位利用起来,表示不同的数据类型:
在 include/v8-internal.h 中定义的
37 // Tag information for HeapObject.
38 const int kHeapObjectTag = 1;
39 const int kWeakHeapObjectTag = 3;
40 const int kHeapObjectTagSize = 2;
41 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1;
出现问题以及原因分析
当我们对一个 Local result 对象,调用 result->IsUndefined()