v8的Heap中RootObject的初始化

Heap类中有一个Object* root_[],这个数组是在Heap::CreateHeapObjects方法中初始化的,root_数组非常重要,其中包含了各种类的Map对象,和其他非常重要的全局对象。对于root_数组的存取,Heap一以贯之的使用了宏定义的方式
1.root_数组的索引
  enum RootListIndex {
#define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex,
    STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION)
#undef ROOT_INDEX_DECLARATION

#define STRING_INDEX_DECLARATION(name, str) k##name##RootIndex,
    INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
#undef STRING_DECLARATION

    // Utility type maps
#define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
    STRUCT_LIST(DECLARE_STRUCT_MAP)
#undef DECLARE_STRUCT_MAP

    kStringTableRootIndex,
    kStrongRootListLength = kStringTableRootIndex,
    kRootListLength
  };
这里定义了设置获取root_数组所需要的index,它是一个枚举类型
2.root_数组中对象的获取
从上面index的定义,我们可以看到Index被分为三种,分别由STRONG_ROOT_LIST,INTERNALIZED_STRING_LIST和STRUCT_LIST定义的。

我们看如下的宏定义:
#define ROOT_ACCESSOR(type, name, camel_name)                                  \
  type* name() {                                                               \
    return type::cast(roots_[k##camel_name##RootIndex]);                       \
  }                                                                            \
  type* raw_unchecked_##name() {                                               \
    return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]);          \
  }
ROOT_LIST(ROOT_ACCESSOR)

#define STRUCT_MAP_ACCESSOR(NAME, Name, name)                                  \
    Map* name##_map() {                                                        \
      return Map::cast(roots_[k##Name##MapRootIndex]);                         \
    }
STRUCT_LIST(STRUCT_MAP_ACCESSOR)

#define STRING_ACCESSOR(name, str) String* name() {                            \
    return String::cast(roots_[k##name##RootIndex]);                           \
  }
INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
这三个宏定义了getter函数,用于根据类型和名称获取root中相应的对象,分别对应上面的三种不同类型的index。

3.root_数组中对象的设置
#define ROOT_ACCESSOR(type, name, camel_name)                                  \
  inline void set_##name(type* value) {                                        \
    /* The deserializer makes use of the fact that these common roots are */   \
    /* never in new space and never on a page that is being compacted.    */   \
    ASSERT(k##camel_name##RootIndex >= kOldSpaceRoots || !InNewSpace(value));  \
    roots_[k##camel_name##RootIndex] = value;                                  \
  }
  ROOT_LIST(ROOT_ACCESSOR)
这个宏显然定义了setter函数,用于设置root_数组中的一些索引的内容。奇怪的是,这里少了上面的两个宏STRUCT_LIST,INTERNALIZED_STRING_LIST,这说明,由这两个宏定义index的root_数组对象是不可写的,相应的,由ROOT_LIST定义index的root_数组对象是可写的。

4.列表宏
这三个宏的定义如下:
heap.h中定义如下两个宏
#define STRONG_ROOT_LIST(V)                                                    \
  V(Map, byte_array_map, ByteArrayMap)                                         \
  V(Map, free_space_map, FreeSpaceMap)                                         \
  V(Map, one_pointer_filler_map, OnePointerFillerMap)                          \
  V(Map, two_pointer_filler_map, TwoPointerFillerMap)                          \
  /* Cluster the most popular ones in a few cache lines here at the top.    */ \
  V(Smi, store_buffer_top, StoreBufferTop)                                     \
  V(Oddball, undefined_value, UndefinedValue)                                  \
  V(Oddball, the_hole_value, TheHoleValue)                                     \
  V(Oddball, null_value, NullValue)                                            \
  V(Oddball, true_value, TrueValue)                                            \
  V(Oddball, false_value, FalseValue)                                          \
  V(Map, global_property_cell_map, GlobalPropertyCellMap)                      \
  V(Map, shared_function_info_map, SharedFunctionInfoMap)                      \
  V(Map, meta_map, MetaMap)                                                    \
  V(Map, heap_number_map, HeapNumberMap)                                       \
  V(Map, native_context_map, NativeContextMap)                                 \
  V(Map, fixed_array_map, FixedArrayMap)                                       \
  V(M
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Keil ,使用 `malloc` 函数进行内存分配时,需要为其提供一个堆空间,否则会出现内存分配失败等问题。以下是在 Keil 初始化堆空间的步骤: 1. 首先在代码定义堆空间的起始地址和大小,例如: ```c #define HEAP_START 0x20000000 #define HEAP_SIZE 0x1000 ``` 这里定义了堆空间的起始地址为 `0x20000000`,大小为 `0x1000` 字节。 2. 在代码添加 `malloc` 函数的实现。可以使用 Keil 提供的 `rt_misc.c` 文件的 `__user_heap_extend` 函数作为 `malloc` 函数的实现,例如: ```c #include <stddef.h> #include <stdint.h> #define HEAP_START 0x20000000 #define HEAP_SIZE 0x1000 static uint8_t heap[HEAP_SIZE] __attribute__((section(".heap"))); void* __user_heap_extend(size_t incr) { static uint8_t* heap_end = NULL; uint8_t* prev_heap_end; if (heap_end == NULL) { heap_end = heap; } prev_heap_end = heap_end; if (heap_end + incr > heap + HEAP_SIZE) { // 内存不足,返回 NULL return NULL; } heap_end += incr; return prev_heap_end; } void* malloc(size_t size) { return __user_heap_extend(size); } void free(void* ptr) { // 空函数,不需要实现 } ``` 这里使用 `__attribute__((section(".heap")))` 将 `heap` 数组放在 `.heap` 段,以便在链接时将其放置在指定的地址。 3. 在代码调用 `malloc` 函数进行内存分配,例如: ```c int main() { int* p = (int*) malloc(sizeof(int)); if (p == NULL) { // 内存分配失败 return 1; } // 使用分配的内存 *p = 123; // 释放内存 free(p); return 0; } ``` 这样就完成了在 Keil 初始化堆空间的操作,可以使用 `malloc` 函数进行动态内存分配了。需要注意的是,由于 `malloc` 函数实现使用了静态变量,因此需要在 `__user_heap_extend` 函数将其声明为 `static` 变量,以避免链接时出现重复定义的错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值