前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js引擎v8源码分析之SemiSpace(基于v8 0.1.5)

js引擎v8源码分析之SemiSpace(基于v8 0.1.5)

作者头像
theanarkh
发布2020-02-17 12:48:41
9370
发布2020-02-17 12:48:41
举报
文章被收录于专栏:原创分享原创分享

SemiSpace的管理新生代内存的类,即我们常听到的from区和to区。from区和to区都由一个SemiSpace对象管理。SemiSpace只管理地址,不负责分配和释放管理的内存。下面是Semispace类的定义。

代码语言:javascript
复制
class SemiSpace  BASE_EMBEDDED {
 public:
  SemiSpace(int initial_capacity, int maximum_capacity);
  bool Setup(Address start, int size);
  void TearDown();
  bool HasBeenSetup() { return start_ != NULL; }
  bool Double();
  Address low() { return start_; }
  Address high() { return low() + capacity_; }
  Address age_mark() { return age_mark_; }
  void set_age_mark(Address mark) { age_mark_ = mark; }
  // 判断地址a是否在该对象管理的内存中,&address_mask即让a减去size-1的大小。如果等于start说明在管理范围内
  bool Contains(Address a) {
    return (reinterpret_cast<uint32_t>(a) & address_mask_) == reinterpret_cast<uint32_t>(start_);
  }
  // 类似上面的逻辑,但是堆对象低位是标记,判断时候需要处理一下,加SetUp
  bool Contains(Object* o) {
    return (reinterpret_cast<uint32_t>(o) & object_mask_) == object_expected_;
  }
  // 距离开始地址的p
  int SpaceOffsetForAddress(Address addr) { return addr - low(); }

 private:
  int capacity_;
  int maximum_capacity_;
  Address start_;
  Address age_mark_;
  // 见SetUp函数
  uint32_t address_mask_;
  uint32_t object_mask_;
  uint32_t object_expected_;

 public:
  TRACK_MEMORY("SemiSpace")
};

下面是SemiSpace类的实现。

SemiSpace

新建一个SemiSpace对象的时候默认初始化某些字段。这些字段的真正设置在SetUp函数。

代码语言:javascript
复制
SemiSpace::SemiSpace(int initial_capacity, int maximum_capacity)
    : capacity_(initial_capacity), 
      maximum_capacity_(maximum_capacity),
      start_(NULL), 
      age_mark_(NULL) {
}

Setup

Setup函数是初始化SemiSpace对象属性的函数

代码语言:javascript
复制
// 设置管理的地址范围
bool SemiSpace::Setup(Address start, int size) {
  ASSERT(size == maximum_capacity_);
  // 判断地址的有效性
  if (!MemoryAllocator::CommitBlock(start, capacity_)) return false;
  // 管理地址空间的首地址
  start_ = start;
  // 低于有效范围的掩码,即保证相与后的值小于等于管理的地址范围
  address_mask_ = ~(size - 1);
  // 计算堆对象地址掩码,低位是标记位,判断的时候需要保留,kHeapObjectTag是堆对象的标记
  object_mask_ = address_mask_ | kHeapObjectTag;
  // 见contains函数,对象地址里低位是标记位,判断的时候需要带上
  object_expected_ = reinterpret_cast<uint32_t>(start) | kHeapObjectTag;
  // gc相关
  age_mark_ = start_;
  return true;
}

TearDown

重置SemiSpace管理的地址,但不负责释放内存。

代码语言:javascript
复制
void SemiSpace::TearDown() {
  start_ = NULL;
  capacity_ = 0;
}

Double

“扩容”函数,只不负责内存的分配,只对管理的大小进行扩容。

代码语言:javascript
复制
bool SemiSpace::Double() {
  // 内存在其他地方分配了,这里校验地址是否合法,即是否分配了
  if (!MemoryAllocator::CommitBlock(high(), capacity_)) return false;
  capacity_ *= 2;
  return true;
}

SemiSpace的功能比较简单,有些属性的使用后续用到的时候再分析。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程杂技 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SemiSpace
  • Setup
  • TearDown
  • Double
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档