Frontend

V8 엔진에서 number, string은 어떻게 처리될까?

mechaniccoder 2024. 3. 9. 17:23

자바스크립트에서 number, string 타입을 생각 없이 사용하다 최근에 V8 엔진에서 어떻게 처리되고 있는지가 궁금해졌습니다. 이번 포스팅에서는 각각의 타입이 메모리에서 어떻게 할당되고 처리되는지 알아보겠습니다.

Number

number 타입은 내부적으로 SMI(Small Integer), Heap number 2가지 나뉩니다.

1. SMI: 31 bits 범위에 속하는 정수를 의미합니다. 이 범위의 데이터는 Heap이 아닌 Stack 메모리에 저장됩니다.

Smi represents integer Numbers that can be stored in 31 bits.
Smis are immediate which means they are NOT allocated in the heap.

https://github.com/v8/v8/blob/c53c7952e1a4c69df7884250711c755e41d0d8a1/src/objects/smi.h#L23

2. Heap number: SMI가 아닌 정수는 Heap number이며 64 bits의 floating point로 Heap 메모리에 저장됩니다.

The HeapNumber class describes heap allocated numbers that cannot be represented in a Smi (small integer).

https://github.com/v8/v8/blob/c53c7952e1a4c69df7884250711c755e41d0d8a1/src/objects/heap-number.h#L26

String

자바스크립트에선 UTF-16를 사용해 문자열을 인코딩합니다. 일반적인 라틴어 등은 2 bytes로 저장되고 이모지와 같은 문자는 4 bytes로 저장됩니다. apple이라는 문자열은 2 bytes * 4 = 8 bytes의 메모리 사이즈를 가지는 것이죠.

 

Constant pool

constant pool이라는 개념을 알고가면 좋을 것 같습 니다. V8 엔진은 메모리를 효율적으로 사용하기 위해 상수값을 constant pool에서 관리합니다. 아래 코드가 메모리에 어떻게 저장되는지를 그려보면 이해하기 쉬울 것 같습니다.

str1, str2는 constant pool에 동일한 hello를 바라보기 때문에 같은 메모리 주소를 참조하고 있는 것이죠.

const str1 = "Hello";
const str2 = "Hello";
const str3 = "World";
console.log(str1 == str2); // true
console.log(str1 == str3); // false

string constant pool

그럼 아래와 같이 String 생성자로 만든 문자열은 메모리에 어떻게 저장이 될까요? 아래 그림과 같이 생성자에 대한 인스턴스가 Heap 메모리에 저장되고 그 인스턴스에서 constant pool에 문자열을 참조하게 됩니다.

const str1 = "Hello";
const str2 = "Hello";
const str3 = new String("Hello")
console.log(str1 == str2); // true
console.log(str1 == str3); // false
console.log(str2 == str3); // false

string constant pool with String constructor

마치며

V8 엔진에서 Number, String 타입이 어떻게 처리되는지 알아보았습니다. 자바스크립트를 그냥 사용하는 것이 아니라 내부적으로 동작하는 원리를 안다면 더 효율적인 코드를 작성할 수 있을 것이라 기대합니다. 앞으로 V8 엔진과 관련된 내용을 자주 올려 딥 다이브 해보도록 하겠습니다. 

References