温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么进行基于js引擎v8源码解析allocation

发布时间:2021-12-09 09:47:37 阅读:124 作者:柒染 栏目:大数据
前端开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

这篇文章将为大家详细讲解有关怎么进行基于js引擎v8源码解析allocation,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

#ifndef V8_ALLOCATION_H_#define V8_ALLOCATION_H_namespace v8 { namespace internal {// A class that controls whether allocation is allowed.  This is for// the C++ heap only!class NativeAllocationChecker { public:  typedef enum { ALLOW, DISALLOW } NativeAllocationAllowed;  explicit inline NativeAllocationChecker(NativeAllocationAllowed allowed)      : allowed_(allowed) {#ifdef DEBUG    if (allowed == DISALLOW) {      allocation_disallowed_++;    }#endif  }  ~NativeAllocationChecker() {#ifdef DEBUG    if (allowed_ == DISALLOW) {      allocation_disallowed_--;    }#endif    ASSERT(allocation_disallowed_ >= 0);  }  static inline bool allocation_allowed() {    return allocation_disallowed_ == 0;  } private:  // This static counter ensures that NativeAllocationCheckers can be nested.  static int allocation_disallowed_;  // This flag applies to this particular instance.  NativeAllocationAllowed allowed_;};// Superclass for classes managed with new & delete.// 管理内存的类,对c函数进行了封装class Malloced { public:  void* operator new(size_t size) { return New(size); }  void  operator delete(void* p) { Delete(p); }  static void FatalProcessOutOfMemory();  static void* New(size_t size);  static void Delete(void* p);};// A macro is used for defining the base class used for embedded instances.// The reason is some compilers allocate a minimum of one word for the// superclass. The macro prevents the use of new & delete in debug mode.// In release mode we are not willing to pay this overhead.#ifdef DEBUG// Superclass for classes with instances allocated inside stack// activations or inside other objects.class Embedded { public:  void* operator new(size_t size);  void  operator delete(void* p);};#define BASE_EMBEDDED : public Embedded#else#define BASE_EMBEDDED#endif// Superclass for classes only using statics.// 类里只有静态成员class AllStatic {#ifdef DEBUG public:  void* operator new(size_t size);  void operator delete(void* p);#endif};// 新建一个T类型的数组template <typename T>static T* NewArray(int size) {  ASSERT(NativeAllocationChecker::allocation_allowed());  T* result = new T[size];  if (result == NULL) Malloced::FatalProcessOutOfMemory();  return result;}template <typename T>static void DeleteArray(T* array) {  delete[] array;}// The normal strdup function uses malloc.  This version of StrDup// uses new and calls the FatalProcessOutOfMemory handler if// allocation fails.// 复制字符串char* StrDup(const char* str);// Allocation policy for allocating in the C free store using malloc// and free. Used as the default policy for lists.class FreeStoreAllocationPolicy { public:  INLINE(static void* New(size_t size)) { return Malloced::New(size); }  INLINE(static void Delete(void* p)) { Malloced::Delete(p); }};// Allocation policy for allocating in preallocated space.// Used as an allocation policy for ScopeInfo when generating// stack traces.// 内存管理 class PreallocatedStorage : public AllStatic { public:  // 管理内存的大小  explicit PreallocatedStorage(size_t size);  size_t size() { return size_; }  static void* New(size_t size);  static void Delete(void* p);  // Preallocate a set number of bytes.  static void Init(size_t size); private:  size_t size_;  // 链表  PreallocatedStorage* previous_;  PreallocatedStorage* next_;  static bool preallocated_;  // 已分配出去的内存链表  static PreallocatedStorage in_use_list_;  // 空闲链表  static PreallocatedStorage free_list_;  // 链表操作函数  void LinkTo(PreallocatedStorage* other);  void Unlink();  DISALLOW_IMPLICIT_CONSTRUCTORS(PreallocatedStorage);};} }  // namespace v8::internal#endif  // V8_ALLOCATION_H_
   
     
 
    
    AI代码助手复制代码

allocation.cc

   
     
 
    #include <stdlib.h>#include "v8.h"namespace v8 { namespace internal {// 对c函数的封装void* Malloced::New(size_t size) {  ASSERT(NativeAllocationChecker::allocation_allowed());  void* result = malloc(size);  if (result == NULL) V8::FatalProcessOutOfMemory("Malloced operator new");  return result;}void Malloced::Delete(void* p) {  free(p);}void Malloced::FatalProcessOutOfMemory() {  V8::FatalProcessOutOfMemory("Out of memory");}#ifdef DEBUGstatic void* invalid = static_cast<void*>(NULL);void* Embedded::operator new(size_t size) {  UNREACHABLE();  return invalid;}void Embedded::operator delete(void* p) {  UNREACHABLE();}void* AllStatic::operator new(size_t size) {  UNREACHABLE();  return invalid;}void AllStatic::operator delete(void* p) {  UNREACHABLE();}#endif// 复制字符串char* StrDup(const char* str) {  int length = strlen(str);  // 申请一个字符数组  char* result = NewArray<char>(length + 1);  // 复制过去  memcpy(result, str, length * kCharSize);  result[length] = '\0';  return result;}int NativeAllocationChecker::allocation_disallowed_ = 0;// 初始化属性PreallocatedStorage PreallocatedStorage::in_use_list_(0);PreallocatedStorage PreallocatedStorage::free_list_(0);bool PreallocatedStorage::preallocated_ = false;// 申请一块内存对其进行管理void PreallocatedStorage::Init(size_t size) {  ASSERT(free_list_.next_ == &free_list_);  ASSERT(free_list_.previous_ == &free_list_);  // 申请size个字节,前n个字节是一个PreallocatedStorage对象  PreallocatedStorage* free_chunk =      reinterpret_cast<PreallocatedStorage*>(new char[size]);  // 初始化链表,双向循环链表  free_list_.next_ = free_list_.previous_ = free_chunk;  free_chunk->next_ = free_chunk->previous_ = &free_list_;  // 大小是申请的大小减去一个PreallocatedStorage对象  free_chunk->size_ = size - sizeof(PreallocatedStorage);  // 已经分配了内存  preallocated_ = true;}// 从预分配的内存里分配一块内存void* PreallocatedStorage::New(size_t size) {  // 没有使用预分配内存,则直接到底层申请一块新的内存,否则从预分配的内存里分配  if (!preallocated_) {    return FreeStoreAllocationPolicy::New(size);  }  ASSERT(free_list_.next_ != &free_list_);  ASSERT(free_list_.previous_ != &free_list_);  /*    ~(kPointerSize - 1)是使高n位取反,n取决于kPointerSize的大小,即1的位置。     size + (kPointerSize - 1)是如果没有按kPointerSize对齐则向上取整。   */  size = (size + kPointerSize - 1) & ~(kPointerSize - 1);  // Search for exact fit.  // 从预分配的内存里找到等于size的块  for (PreallocatedStorage* storage = free_list_.next_;       storage != &free_list_;       storage = storage->next_) {    if (storage->size_ == size) {      // 找到后,把该块从链表中删除,并插入到已分配链表中      storage->Unlink();      storage->LinkTo(&in_use_list_);      // 返回存储数据的首地址,前面存储了一个PreallocatedStorage对象      return reinterpret_cast<void*>(storage + 1);    }  }  // Search for first fit.  // 没有大小等于size的块,则找比size大的块  for (PreallocatedStorage* storage = free_list_.next_;       storage != &free_list_;       storage = storage->next_) {    // 多出来的那一块还需要一个PreallocatedStorage对象进行管理    if (storage->size_ >= size + sizeof(PreallocatedStorage)) {      storage->Unlink();      storage->LinkTo(&in_use_list_);      // 分配一部分出去,storage + 1即可用于存储数据的首地址,加上size得到还剩下的空闲内存首地址      PreallocatedStorage* left_over =          reinterpret_cast<PreallocatedStorage*>(              reinterpret_cast<char*>(storage + 1) + size);      // 剩下的大小等于本来的大小减去size-一个PreallocatedStorage对象      left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);      ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==             storage->size_);      // 更新原来的storage的大小,为请求的size,stroage被切分了      storage->size_ = size;      // 剩下的插入空闲链表      left_over->LinkTo(&free_list_);      // 返回可用于存储数据的首地址      return reinterpret_cast<void*>(storage + 1);    }  }  // Allocation failure.  ASSERT(false);  return NULL;}// We don't attempt to coalesce.// 释放内存,不作合并处理,p是存储数据的首地址void PreallocatedStorage::Delete(void* p) {  if (p == NULL) {    return;  }  // 参考New  if (!preallocated_) {    FreeStoreAllocationPolicy::Delete(p);    return;  }  // 转成PreallocatedStorage指针,减一则指向管理这块内存的PreallocatedStorage对象  PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;  ASSERT(storage->next_->previous_ == storage);  ASSERT(storage->previous_->next_ == storage);  // 脱离原来的链表,插入空闲链表  storage->Unlink();  storage->LinkTo(&free_list_);}// 插入双向循环链表void PreallocatedStorage::LinkTo(PreallocatedStorage* other) {  next_ = other->next_;  other->next_->previous_ = this;  previous_ = other;  other->next_ = this;}void PreallocatedStorage::Unlink() {  next_->previous_ = previous_;  previous_->next_ = next_;}PreallocatedStorage::PreallocatedStorage(size_t size)  : size_(size) {  previous_ = next_ = this;}} }  // namespace v8::internalAI代码助手复制代码

关于怎么进行基于js引擎v8源码解析allocation就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4217331/blog/4379693

js
AI

开发者交流群×