JavaScript Code
var str = "hi";
Memory allocation:
Address | Value | Description |
---|---|---|
...... |
... | |
0x1001 |
call object | Start of a call object's memory |
0x1002 |
0x00af | Reference to invoked function |
0x1003 |
1 | Number of references in this call object |
0x1004 |
str | Name of variable (in practice would not be in a single address) |
0x1005 |
0x1001 |
Memory address of "hi" |
...... |
... | |
0x2001 |
string | type identifier |
0x2002 |
2 | number of bytes |
0x2003 |
h | byte of first character |
0x2004 |
i | byte of second character |
When JS runs: var str = "hi";
by calling some function, it first hoists all variable declarations and creates a spot in memory for the variable. This might leave memory something like:
Address | Value | Description |
---|---|---|
...... |
... | |
0x1001 |
call object | Start of a call object's memory |
0x1002 |
0x00af | Reference to invoked function |
0x1003 |
1 | Number of references in this call object |
0x1004 |
str | Name of variable |
0x1005 |
empty | |
...... |
... |
In practice, the name of the variable, str
, would not be held in a single memory address. Also, the variable names and locations would not be stored in a fixed-memory array (possibly in a hash-table).
Next, the string "hi"
would be created in memory like:
Address | Value | Description |
---|---|---|
...... |
... | |
0x2001 |
string | type identifier |
0x2002 |
2 | number of bytes |
0x2003 |
h | byte of first character |
0x2004 |
i | byte of second character |
Finally, the pointer address of str
would be set to the memory address of "hi"
(0x2001
), leaving memory as indicated at the top of the page.
If we are talking about V8 then part of the activation record that needs to survive after function returns is "detached" from the stack and is allocated a normal heap in a structure called context. Up in my first comment there is a slot for it on the native stack.
After execution just entered
counter
native stack looks like this:this
(global object)counter
)as you can see there is no space reserved for
i
unlike in the previous example. Where does it go? Next thing that happens just after entering this code V8 will create a local context object that looks like this:Lets call it Context_5fff02b (random digits at the end to reflect that each time we enter function
counter
we allocate a new one on the heap):counter
with
contextsnull
with
oreval
null
i
i
undefined
You can see there are quite a few internal fields because contexts are used for multiple purposes. You can look through source code to get a grasp of the details involved.
After local context was created the stack slot where context is stored will be updated:
this
(global object)counter
)This context pointer will be used when working with variable
i
inside functioncounter
and all closures allocated in it will get this context as its outer context.Inside the function code current context is always cached in a register
esi
so storing 0 intoi
looks like this:I decomposed immediate offset into parts to make it clearer where each came from (5th field, 4 bytes per field, -1 to untag tagged pointer) generated code will just say offset
29
.Allocated function will approximately look like this (in fact there are more fields in closures, I skip irrelevant ones)
Hope this helps.