溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

js引擎HeadNumber類是怎么實(shí)現(xiàn)的

發(fā)布時(shí)間:2021-12-17 09:34:25 來源:億速云 閱讀:178 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“js引擎HeadNumber類是怎么實(shí)現(xiàn)的”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1 HeadNumber

HeadNumber類的代碼比較少。

   
     
 
    
    

// The HeapNumber class describes heap allocated numbers that cannot be
// represented in a Smi (small integer)
// 存儲(chǔ)了數(shù)字的堆對象
class HeapNumber: public HeapObject {
public:
 // [value]: number value.
 inline double value();
 inline void set_value(double value);

 // Casting.
 static inline HeapNumber* cast(Object* obj);

 // Dispatched behavior.
 Object* HeapNumberToBoolean();

 // Layout description.
 // kSize之前的空間存儲(chǔ)map對象的指針
 static const int kValueOffset = HeapObject::kSize;
 // kValueOffset - kSize之間存儲(chǔ)數(shù)字的值
 static const int kSize = kValueOffset + kDoubleSize;

private:
 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
};

             

我們看看他的實(shí)現(xiàn)。

   
     
 
    
    

// 讀出double類型的值
#define READ_DOUBLE_FIELD(p, offset) \
 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))

// 寫入double類型的值
#define WRITE_DOUBLE_FIELD(p, offset, value) \
 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)

// 讀寫屬性的值
double HeapNumber::value() {
 return READ_DOUBLE_FIELD(this, kValueOffset);
}

// 寫double值到對象
void HeapNumber::set_value(double value) {
 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
}

Object* HeapNumber::HeapNumberToBoolean() {
 // NaN, +0, and -0 should return the false object
 switch (fpclassify(value())) {
   case FP_NAN:  // fall through
   case FP_ZERO: return Heap::false_value();
   default: return Heap::true_value();
 }
}

             

還有一個(gè)函數(shù)就是cast,實(shí)現(xiàn)如下:

   
     
 
    
    

CAST_ACCESSOR(HeapNumber)
#define CAST_ACCESSOR(type)                     \
 type* type::cast(Object* object) {            \
   ASSERT(object->Is##type());                 \
   return reinterpret_cast<type*>(object);     \

CAST_ACCESSOR(HeapNumber);
宏展開后
HeapNumber* HeapNumber::cast(Object* object) {            \
   ASSERT(object->IsHeapNumber());                 \
   return reinterpret_cast<HeapNumber*>(object);     \

             

至此HeapNumber分析完了。接著看下一個(gè)類Array。

2 Array

   
     
 
    
    

// Abstract super class arrays. It provides length behavior.
class Array: public HeapObject {
public:
 // [length]: length of the array.
 inline int length();
 inline void set_length(int value);

 // Convert an object to an array index.
 // Returns true if the conversion succeeded.
 static inline bool IndexFromObject(Object* object, uint32_t* index);

 // Layout descriptor.
 static const int kLengthOffset = HeapObject::kSize;
 static const int kHeaderSize = kLengthOffset + kIntSize;

private:
 DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
};

             

我們發(fā)現(xiàn)數(shù)組的對象內(nèi)存布局中,只有一個(gè)屬性。就是保存length大小的。首先看看讀寫length屬性的實(shí)現(xiàn)。

   
     
 
    
    

#define INT_ACCESSORS(holder, name, offset)                             \
 int holder::name() { return READ_INT_FIELD(this, offset); }           \
 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }

// 定義數(shù)組的length和set_length函數(shù),屬性在對象的偏移的kLengthOffset,緊跟著map指針
INT_ACCESSORS(Array, length, kLengthOffset);

             

再繼續(xù)看IndexFromObject的實(shí)現(xiàn)。

   
     
 
    
    

bool Array::IndexFromObject(Object* object, uint32_t* index) {
 if (object->IsSmi()) {
   int value = Smi::cast(object)->value();
   if (value < 0) return false;
   *index = value;
   return true;
 }
 if (object->IsHeapNumber()) {
   double value = HeapNumber::cast(object)->value();
   uint32_t uint_value = static_cast<uint32_t>(value);
   if (value == static_cast<double>(uint_value)) {
     *index = uint_value;
     return true;
   }
 }
 return false;
}

             

該函數(shù)就是把一個(gè)對象(底層是表示數(shù)字的)轉(zhuǎn)成一個(gè)數(shù)組索引。數(shù)組類也分析完了。我們繼續(xù)。

3 ByteArray

   
     
 
    
    

// ByteArray represents fixed sized byte arrays.  Used by the outside world,
// such as PCRE, and also by the memory allocator and garbage collector to
// fill in free blocks in the heap.
class ByteArray: public Array {
public:
 // Setter and getter.
 inline byte get(int index);
 inline void set(int index, byte value);

 // Treat contents as an int array.
 inline int get_int(int index);
 /*
   ByteArray類沒有定義自己的屬性,他是根據(jù)length算出對象的大小,
   然后在分配內(nèi)存的時(shí)候,多分配一塊存儲(chǔ)數(shù)組元素的內(nèi)存
   const int kObjectAlignmentBits = 2;
   const int kObjectAlignmentMask = (1 << kObjectAlignmentBits) - 1;
   #define OBJECT_SIZE_ALIGN(value)  ((value + kObjectAlignmentMask) & ~kObjectAlignmentMask)
   由此可知,按四個(gè)字節(jié)對齊。OBJECT_SIZE_ALIGN的作用的是不夠4字節(jié)的,會(huì)多分配幾個(gè)字節(jié),使得按四字節(jié)對齊。~kObjectAlignmentMask是低兩位是0,即按四字節(jié)對齊。比如value已經(jīng)4字節(jié)對齊了,則(4 + 0 +3) & ~3 =4,如果value沒有對齊,假設(shè)是5,則(4 + 1 +3) & ~3 = 8;如果value等于6,(4 + 2 + 3) & ~3 = 8;以此類推。
 */
 static int SizeFor(int length) {
   return kHeaderSize + OBJECT_SIZE_ALIGN(length);
 }
 // We use byte arrays for free blocks in the heap.  Given a desired size in
 // bytes that is a multiple of the word size and big enough to hold a byte
 // array, this function returns the number of elements a byte array should
 // have.
 static int LengthFor(int size_in_bytes) {
   ASSERT(IsAligned(size_in_bytes, kPointerSize));
   ASSERT(size_in_bytes >= kHeaderSize);
   return size_in_bytes - kHeaderSize;
 }

 // Returns data start address.
 inline Address GetDataStartAddress();

 // Returns a pointer to the ByteArray object for a given data start address.
 static inline ByteArray* FromDataStartAddress(Address address);

 // Casting.
 static inline ByteArray* cast(Object* obj);

 // Dispatched behavior.
 int ByteArraySize() { return SizeFor(length()); }

private:
 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
};

             

在分析實(shí)現(xiàn)之前我們先看一下ByteArray的對象是怎么被分配的。

   
     
 
    
    

Handle<ByteArray> Factory::NewByteArray(int length) {
 ASSERT(0 <= length);
 CALL_HEAP_FUNCTION(Heap::AllocateByteArray(length), ByteArray);
}

Object* Heap::AllocateByteArray(int length) {
 int size = ByteArray::SizeFor(length);
 AllocationSpace space = size > MaxHeapObjectSize() ? LO_SPACE : NEW_SPACE;

 Object* result = AllocateRaw(size, space);
 if (result->IsFailure()) return result;

 reinterpret_cast<Array*>(result)->set_map(byte_array_map());
 reinterpret_cast<Array*>(result)->set_length(length);
 return result;
}

             

我們看到,首先通過ByteArray::SizeFor算出對象所需的內(nèi)存大小size。然后分配一塊大小為size的內(nèi)存。然后返回這塊內(nèi)存的地址。這時(shí)候我們就可以使用這塊內(nèi)存。我們看看怎么使用的。內(nèi)存布局如下。

js引擎HeadNumber類是怎么實(shí)現(xiàn)的

   
     
 
    
    

byte ByteArray::get(int index) {
 ASSERT(index >= 0 && index < this->length());
 // 根據(jù)索引返回?cái)?shù)組中對應(yīng)元素的值,kHeaderSize是第一個(gè)元素的地址,kCharSize是1,即一個(gè)字節(jié)
 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
}


void ByteArray::set(int index, byte value) {
 ASSERT(index >= 0 && index < this->length());
 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
}

// 把四個(gè)元素(四個(gè)字節(jié))的內(nèi)容作為一個(gè)值。即ByteArray變成IntArray
int ByteArray::get_int(int index) {
 ASSERT(index >= 0 && (index * kIntSize) < this->length());
 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
}


ByteArray* ByteArray::FromDataStartAddress(Address address) {
 ASSERT_TAG_ALIGNED(address);
 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
}

// 返回?cái)?shù)組元素的首地址,地址的低位是用作標(biāo)記,要先減掉。kHeaderSize是第一個(gè)元素在對象內(nèi)存空間的偏移
Address ByteArray::GetDataStartAddress() {
 /*
   typedef uint8_t byte;
   typedef byte* Address;
 */
 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
}              

“js引擎HeadNumber類是怎么實(shí)現(xiàn)的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI