js引擎v8源码怎么解析map对象
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,js引擎v8源码怎么解析map对象,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先介绍Map类。下面先看类定义
千家信息网最后更新 2026年11月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安全错误
数据库的锁怎样保障安全
咖啡
上海喔噻互联网科技有限公司
互联网科技工作委员会
互联网科技的发展
平安科技 互联网
合肥互联网科技公司
朗涯互联网科技
富国互联网科技创新基金
深圳前海聚择互联网科技有限公司
互联网科技中介
彤创互联网科技有限公司
崇明区互联网教育科技诚信经营
开一家科技互联网公司需要多少钱
互联网金融科技展
互联网在线教育科技创业
本届互联网大会上的黑科技
扫呗互联网科技有限公司
玉溪新华互联网科技怎么选
互联网对科技影响
数字科技和互联网金融哪个好
伟宏互联网科技
金融科技还是互联网
网络科技有限互联网
北京互联网科技有限公司
互联网科技的未来发展
互联网高科技企业
互联网行业科技股
云南省自由互联网科技有限公司
万物互联网智能科技
互联网领先科技活动