HeapObject是Object的子类。是所有基于堆分配的对象的基类。
class HeapObject: public Object {
public:
// 每个堆对象都有一个map对象,记录对象的类型,大小等信息
inline Map* map();
inline void set_map(Map* value);
// 对象的地址+对象标记
static inline HeapObject* FromAddress(Address address);
// 对象的真正地址
inline Address address();
void Iterate(ObjectVisitor* v);
void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
void IterateStructBody(int object_size, ObjectVisitor* v);
inline void CopyBody(JSObject* from);
inline int Size();
inline int SizeFromMap(Map* map);
static inline Object* GetHeapObjectField(HeapObject* obj, int index);
static inline HeapObject* cast(Object* obj);
// 内存布局信息,v8不定义对象的属性,而是通过offset来定义每个属性的位置
static const int kMapOffset = Object::kSize;
static const int kSize = kMapOffset + kPointerSize;
protected:
// 遍历
inline void IteratePointers(ObjectVisitor* v, int start, int end);
inline void IteratePointer(ObjectVisitor* v, int offset);
int SlowSizeFromMap(Map* map);
private:
// 禁止直接创建对象
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
};
下面是定义
1 读取对象的属性
Object* HeapObject::GetHeapObjectField(HeapObject* obj, int index) {
return READ_FIELD(obj, HeapObject::kSize + kPointerSize * index);
}
2 存取map对象
// 堆对象的开始地址是一个Map对象
Map* HeapObject::map() {
return reinterpret_cast<Map*> READ_FIELD(this, kMapOffset);
}
// 设置堆对象的map对象
void HeapObject::set_map(Map* value) {
WRITE_FIELD(this, kMapOffset, value);
}
3 获取堆对象地址
// 封装过的地址,kHeapObjectTag表示是一个堆对象
HeapObject* HeapObject::FromAddress(Address address) {
ASSERT_TAG_ALIGNED(address);
return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
}
// 对象的真正地址
Address HeapObject::address() {
return reinterpret_cast<Address>(this) - kHeapObjectTag;
}
4 遍历对象空间
// FIELD_ADDR算出开始的虚拟地址
void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
}
void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
}
5 复制对象的内容,不包括map对象
void HeapObject::CopyBody(JSObject* from) {
ASSERT(map() == from->map());
ASSERT(Size() == from->Size());
int object_size = Size();
// 从map对象指针后面开始复制
for (int offset = kSize; offset < object_size; offset += kPointerSize) {
Object* value = READ_FIELD(from, offset);
WRITE_FIELD(this, offset, value);
// 写屏障,用于gc
WRITE_BARRIER(this, offset);
}
}
6 计算对象大小,子类定义或者可以从map对象直接得到。
// 计算对象的大小
int HeapObject::Size() {
return SizeFromMap(map());
}
int HeapObject::SizeFromMap(Map* map) {
InstanceType instance_type = map->instance_type();
// Only inline the two most frequent cases.
if (instance_type == JS_OBJECT_TYPE) return map->instance_size();
if (instance_type == FIXED_ARRAY_TYPE) {
// 数组对象大小,包括元数据和存储数据的部分
return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
}
// Otherwise do the general size computation.
return SlowSizeFromMap(map);
}
int HeapObject::SlowSizeFromMap(Map* map) {
InstanceType instance_type = map->instance_type();
if (instance_type < FIRST_NONSTRING_TYPE && (reinterpret_cast<String*>(this)->map_representation_tag(map) == kSeqStringTag)) {
if (reinterpret_cast<String*>(this)->is_ascii_map(map)) {
return reinterpret_cast<AsciiString*>(this)->AsciiStringSize(map);
} else {
return reinterpret_cast<TwoByteString*>(this)->TwoByteStringSize(map);
}
}
switch (instance_type) {
case FIXED_ARRAY_TYPE:
return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
case BYTE_ARRAY_TYPE:
return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
case CODE_TYPE:
return reinterpret_cast<Code*>(this)->CodeSize();
case MAP_TYPE:
return Map::kSize;
default:
return map->instance_size();
}
}
7 遍历对象,在各个子类和迭代器中定义。后续额外分析。
堆对象的内存布局。