js引擎v8源码怎么解析map对象
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,js引擎v8源码怎么解析map对象,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先介绍Map类。下面先看类定义
千家信息网最后更新 2025年12月01日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安全错误
数据库的锁怎样保障安全
获取数据库数据行数据类型
广州社交软件开发公司
奉贤区新时代软件开发参考价格
数据库实验答案
软件开发最难的阶段
kms 服务器
挖财网络技术有限公司纠纷
php在哪里找数据库
服务器存储管理的功能
超能电视正在链接服务器
证书服务器的配置和管理
各国的网络安全法
车站信息网络安全保证措施
网络安全产品运维要求
瑞翊网络技术公司
赌博软件开发要多少
app软件开发版权如何办理
怎样用c 软件开发
网络安全要读研究生吗
干软件开发前几年
表格导入数据库不导入前几行
网络安全工作重要讲话
服务器怎么u盘启动
用网络安全技术有前途吗
白夜极光伺服务器连接失败
数据库期末考试山东科技大学
数据库培训的意义
数据库备份技术的应用
江淮官话语音数据库
账套数据库