js引擎v8源码怎么解析map对象
发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,js引擎v8源码怎么解析map对象,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先介绍Map类。下面先看类定义
千家信息网最后更新 2025年02月04日js引擎v8源码怎么解析map对象
js引擎v8源码怎么解析map对象,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
首先介绍Map类。下面先看类定义
// All heap objects have a Map that describes their structure.
// A Map contains information about:
// - Size information about the object
// - How to iterate over an object (for garbage collection)
class Map: public HeapObject {
public:
// instance size.
inline int instance_size();
inline void set_instance_size(int value);
// instance type.
inline InstanceType instance_type();
inline void set_instance_type(InstanceType value);
// tells how many unused property fields are available in the instance.
// (only used for JSObject in fast mode).
inline int unused_property_fields();
inline void set_unused_property_fields(int value);
// bit field.
inline byte bit_field();
inline void set_bit_field(byte value);
// Tells whether this object has a special lookup behavior.
void set_special_lookup() {
set_bit_field(bit_field() | (1 << kHasSpecialLookup));
}
bool has_special_lookup() {
return ((1 << kHasSpecialLookup) & bit_field()) != 0;
}
// Tells whether the object in the prototype property will be used
// for instances created from this function. If the prototype
// property is set to a value that is not a JSObject, the prototype
// property will not be used to create instances of the function.
// See ECMA-262, 13.2.2.
inline void set_non_instance_prototype(bool value);
inline bool has_non_instance_prototype();
// Tells whether the instance with this map should be ignored by the
// __proto__ accessor.
inline void set_is_hidden_prototype() {
set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
}
inline bool is_hidden_prototype() {
return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
}
// Tells whether the instance has a named interceptor.
inline void set_has_named_interceptor() {
set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
}
inline bool has_named_interceptor() {
return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
}
// Tells whether the instance has a named interceptor.
inline void set_has_indexed_interceptor() {
set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
}
inline bool has_indexed_interceptor() {
return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
}
// Tells whether the instance is undetectable.
// An undetectable object is a special class of JSObject: 'typeof' operator
// returns undefined, ToBoolean returns false. Otherwise it behaves like
// a normal JS object. It is useful for implementing undetectable
// document.all in Firefox & Safari.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
inline void set_is_undetectable() {
set_bit_field(bit_field() | (1 << kIsUndetectable));
}
inline bool is_undetectable() {
return ((1 << kIsUndetectable) & bit_field()) != 0;
}
// Tells whether the instance has a call-as-function handler.
inline void set_has_instance_call_handler() {
set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));
}
inline bool has_instance_call_handler() {
return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;
}
// Tells whether the instance needs security checks when accessing its
// properties.
inline void set_needs_access_check() {
set_bit_field(bit_field() | (1 << kNeedsAccessCheck));
}
inline bool needs_access_check() {
return ((1 << kNeedsAccessCheck) & bit_field()) != 0;
}
// [prototype]: implicit prototype object.
/*
#define DECL_ACCESSORS(name, type) \
inline type* name(); \
inline void set_##name(type* value)
宏展开后变成,定义了读写某个属性的函数
Object * prototype();
void * set_prototype(Object * value);
属性的定义如下(宏展开后也是读写某个属性):
#define ACCESSORS(holder, name, type, offset) \
type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
void holder::set_##name(type* value) { \
WRITE_FIELD(this, offset, value); \
WRITE_BARRIER(this, offset); \
}
// 定义各个类的读写某属性的函数,第三第四个参数是类型和偏移
ACCESSORS(Map, instance_descriptors, DescriptorArray,
kInstanceDescriptorsOffset)
ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
ACCESSORS(Map, constructor, Object, kConstructorOffset
*/
DECL_ACCESSORS(prototype, Object)
// [constructor]: points back to the function responsible for this map.
DECL_ACCESSORS(constructor, Object)
// [instance descriptors]: describes the object.
DECL_ACCESSORS(instance_descriptors, DescriptorArray)
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, FixedArray)
// Returns a copy of the map.
Object* Copy();
// Returns the property index for name (only valid for FAST MODE).
int PropertyIndexFor(String* name);
// Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex();
// Returns the number of properties described in instance_descriptors.
int NumberOfDescribedProperties();
// Casting.
static inline Map* cast(Object* obj);
// Locate an accessor in the instance descriptor.
AccessorDescriptor* FindAccessor(String* name);
// Make sure the instance descriptor has no map transitions
Object* EnsureNoMapTransitions();
// Code cache operations.
// Clears the code cache.
inline void ClearCodeCache();
// Update code cache.
Object* UpdateCodeCache(String* name, Code* code);
// Returns the found code or undefined if absent.
Object* FindInCodeCache(String* name, Code::Flags flags);
// Tells whether code is in the code cache.
bool IncludedInCodeCache(Code* code);
// Dispatched behavior.
void MapIterateBody(ObjectVisitor* v);
#ifdef DEBUG
void MapPrint();
void MapVerify();
#endif
// Layout description.
static const int kInstanceAttributesOffset = HeapObject::kSize;
static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
static const int kInstanceDescriptorsOffset =
kConstructorOffset + kPointerSize;
static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize;
static const int kSize = kCodeCacheOffset + kIntSize;
// Byte offsets within kInstanceAttributesOffset attributes.
static const int kInstanceSizeOffset = kInstanceAttributesOffset + 0;
static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 2;
static const int kBitFieldOffset = kInstanceAttributesOffset + 3;
// kBitFieldOffset对应的一个字节,下面分别是该一个字节各比特位的标记
static const int kHasSpecialLookup = 0;
static const int kHasNonInstancePrototype = 1;
static const int kIsHiddenPrototype = 2;
static const int kHasNamedInterceptor = 3;
static const int kHasIndexedInterceptor = 4;
static const int kIsUndetectable = 5;
static const int kHasInstanceCallHandler = 6;
static const int kNeedsAccessCheck = 7;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
};
下面的map的属性内存布局。
我们逐个函数分析他的实现。首先看objects-inl.h中的实现。
// 获取对象某个属性的地址,p是对象的首地址,offset是偏移,kHeapObjectTag是对象的标记,算地址的时候需要减掉
#define FIELD_ADDR(p, offset) \
(reinterpret_cast(p) + offset - kHeapObjectTag)
// 读写一个字节的内容
#define READ_BYTE_FIELD(p, offset) \
(*reinterpret_cast(FIELD_ADDR(p, offset)))
#define WRITE_BYTE_FIELD(p, offset, value) \
(*reinterpret_cast(FIELD_ADDR(p, offset)) = value)
void Map::set_instance_size(int value) {
ASSERT(0 <= value && value < 256);
WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast(value));
}
InstanceType Map::instance_type() {
return static_cast(READ_BYTE_FIELD(this, kInstanceTypeOffset));
}
void Map::set_instance_type(InstanceType value) {
ASSERT(0 <= value && value < 256);
WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
}
int Map::unused_property_fields() {
return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
}
void Map::set_unused_property_fields(int value) {
WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
}
// 读写一个字节的内容,每个比特都记录着一个标记
byte Map::bit_field() {
return READ_BYTE_FIELD(this, kBitFieldOffset);
}
void Map::set_bit_field(byte value) {
WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
}
void Map::set_non_instance_prototype(bool value) {
if (value) {
// 设置该位
set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
} else {
// 清除该位
set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
}
}
// 是否设置了某位
bool Map::has_non_instance_prototype() {
return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
}
void Map::ClearCodeCache() {
// No write barrier is needed since empty_fixed_array is not in new space.
// Please note this function is used during marking:
// - MarkCompactCollector::MarkUnmarkedObject
ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());
}
从上面的代码中我们知道,只是对某些属性或标记进行读写。
关于js引擎v8源码怎么解析map对象问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。
属性
对象
字节
标记
内容
函数
地址
问题
引擎
源码
更多
面的
偏移
分析
帮助
解答
易行
简单易行
代码
内存
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
湖南科奥软件开发有限公司
卓奇网络安全教育
观看未成年人网络安全后的感想
河南量化积分管理软件开发系统
贵州通用服务器
预言软件开发公司
10亿人游戏服务器
软件开发应使用什么编程语言
软件开发过程 软件描述
中禾美俞互联网科技有限公司
数据库主要掌握哪些内容
cod8专用服务器
网络安全法保护信息
网络安全宣传大使杨凤岭
通州区特定软件开发特点
怎样设置管家婆数据库地址
网络安全协会会员大会新闻稿
谷歌参与ipv4根服务器部署
mysql 大型数据库
工业网络技术发展的看法
MySQL数据库中Map
重庆智能还款软件开发
网络安全公安警察网站
关于数据库的特点
博山销售软件开发公司
数据库数据转json数据
网络安全 信息安全6
博图触摸屏的数据库
服务器负载新
中电30所网络安全研究院