mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Documentation update
Sections after Lcache are updated. Sections Property Hashmap, Literal Store and Snapshot are added. JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu
This commit is contained in:
parent
044345a76e
commit
06a332a760
@ -132,6 +132,10 @@ byte[1] = (literal_index & 0xff)
|
||||
|
||||
Since most functions require less than 255 literal, small encoding provides a single byte literal index for all literals. Small encoding consumes less space than full encoding, but it has a limited range.
|
||||
|
||||
## Literal Store
|
||||
|
||||
JerryScript do not have a global string table for literals, but stores them into the Literal Store. During the parsing phase, when a new literal appears with the same identifier that already has occurred before, the string won't be stored once again, but the identifier in the Literal Store will be used. If a new literal is not in the Literal Store yet, it will be inserted.
|
||||
|
||||
## Byte-code Categories
|
||||
|
||||
Byte-codes can be placed into four main categories.
|
||||
@ -201,11 +205,15 @@ Branch byte-codes are used to perform conditional and unconditional jumps in the
|
||||
|
||||
</div>
|
||||
|
||||
## Snapshot
|
||||
|
||||
The compiled byte-code can be saved into a snapshot, which also can be loaded back for execution. Directly executing the snapshot saves the costs of parsing the source in terms of memory consumption and performance. The snapshot can also be executed from ROM, in which case the overhead of loading it into the memory can also be saved.
|
||||
|
||||
|
||||
# Virtual Machine
|
||||
|
||||
Virtual machine is an interpreter which executes byte-code instructions one by one. The function that starts the interpretation is `vm_run` in `./jerry-core/vm/vm.c`. `vm_loop` is the main loop of the virtual machine, which has the peculiarity that it is *non-recursive*. This means that in case of function calls it does not calls itself recursively but returns, which has the benefit that it does not burdens the stack as a recursive implementation.
|
||||
|
||||
|
||||
# ECMA
|
||||
|
||||
ECMA component of the engine is responsible for the following notions:
|
||||
@ -234,7 +242,7 @@ simple value is a pre-defined constant which can be:
|
||||
* false
|
||||
* empty (uninitialized value)
|
||||
|
||||
### Compressed pointers
|
||||
### Compressed Pointers
|
||||
|
||||
Compressed pointers were introduced to save heap space.
|
||||
{: class="thumbnail center-block img-responsive" }
|
||||
@ -259,11 +267,11 @@ Several references to single allocated number are not supported. Each reference
|
||||
|
||||
Strings in JerryScript are not just character sequences, but can hold numbers and so-called magic ids too. For common character sequences there is a table in the read only memory that contains magic id and character sequence pairs. If a string is already in this table, the magic id of its string is stored, not the character sequence itself. Using numbers speeds up the property access. These techniques save memory.
|
||||
|
||||
### Object / Lexical environment
|
||||
### Object / Lexical Environment
|
||||
|
||||
An object can be a conventional data object or a lexical environment object. Unlike other data types, object can have references (called properties) to other data types. Because of circular references, reference counting is not always enough to determine dead objects. Hence a chain list is formed from all existing objects, which can be used to find unreferenced objects during garbage collection. The `gc-next` pointer of each object shows the next allocated object in the chain list.
|
||||
|
||||
Lexical environments ([link](http://www.ecma-international.org/ecma-262/5.1/#sec-10.2)) are implemented as objects in JerryScript, since lexical environments contains key-value pairs (called bindings) like objects. This simplifies the implementation and reduces code size.
|
||||
Lexical environments (link) are implemented as objects in JerryScript, since lexical environments contains key-value pairs (called bindings) like objects. This simplifies the implementation and reduces code size.
|
||||
|
||||
{: class="thumbnail center-block img-responsive" }
|
||||
|
||||
@ -274,19 +282,25 @@ The objects are represented as following structure:
|
||||
* GC's visited flag
|
||||
* type (function object, lexical environment, etc.)
|
||||
|
||||
### Properties of objects
|
||||
### Properties of Objects
|
||||
{: class="thumbnail center-block img-responsive" }
|
||||
|
||||
Objects have a linked lists that contains their properties. This list actually contains property pairs, in order to save memory described in the followings:
|
||||
Objects have a linked list that contains their properties. This list actually contains property pairs, in order to save memory described in the followings:
|
||||
A property is 7 bit long and its type field is 2 bit long which consumes 9 bit which does not fit into 1 byte but consumes 2 bytes. Hence, placing together two properties (14 bit) with the 2 bit long type field fits into 2 bytes.
|
||||
|
||||
If the number of property pairs reach a limit (currently this limit defined to 16), the first element of the property pair list is a hashmap (called property hashmap), which is used to find a property instead of finding it by linear search.
|
||||
#### Property Hashmap
|
||||
|
||||
### Collections
|
||||
If the number of property pairs reach a limit (currently this limit is defined to 16), a hash map (called [property hashmap](#Property Hashmap)) is inserted at the first position of the property pair list, in order to find a property using it, instead of finding it by iterating linearly over the property pairs.
|
||||
|
||||
Collections are array-like data structures, which are optimized to save memory. Actually, a collection is a linked list whose elements are not single elements, but arrays which can contain multiple elements.
|
||||
Property hashmap contains 2<sup>n</sup> elements, where 2<sup>n</sup> is larger than the number of properties of the object. Each element can have tree types of value:
|
||||
|
||||
### Internal properties
|
||||
* null, indicating an empty element
|
||||
* deleted, indicating a deleted property, or
|
||||
* reference to the existing property
|
||||
|
||||
This hashmap is a must-return type cache, meaning that every property that the object have, can be found using it.
|
||||
|
||||
#### Internal Properties
|
||||
|
||||
Internal properties are special properties that carry meta-information that cannot be accessed by the JavaScript code, but important for the engine itself. Some examples of internal properties are listed below:
|
||||
|
||||
@ -304,61 +318,18 @@ LCache is a hashmap for finding a property specified by an object and by a prope
|
||||
|
||||
When a property access occurs, a hash value is extracted form the demanded property name and than this hash is used to index the LCache. After that, in the indexed row the specified object and property name will be searched.
|
||||
|
||||
It is important to note, that if the specified property is not found in the LCache, it does not mean that it does not exist. If the property is not found, it will be searched in the property-list of the object, and if it is found there, the property will be placed into the LCache.
|
||||
It is important to note, that if the specified property is not found in the LCache, it does not mean that it does not exist (i.e. LCache is a may-return cache). If the property is not found, it will be searched in the property-list of the object, and if it is found there, the property will be placed into the LCache.
|
||||
|
||||
### Completion value
|
||||
### Collections
|
||||
|
||||
Many algorithms/routines described in ECMA return a value of "completion" type, that is triplet of the following form:
|
||||
Collections are array-like data structures, which are optimized to save memory. Actually, a collection is a linked list whose elements are not single elements, but arrays which can contain multiple elements.
|
||||
|
||||
{: class="thumbnail center-block img-responsive" }
|
||||
### Exception Handling
|
||||
|
||||
Jerry introduces two additional completion types:
|
||||
* exit - produced by `exitval` opcode, indicates request to finish execution
|
||||
* meta - produced by meta instruction, used to catch meta opcodes in interpreter loop without explicit comparison on every iteration (for example: meta 'end_with')
|
||||
In order to implement a sense of exception handling, the return values of JerryScript functions are able to indicate their faulty or "exceptional" operation. The return values are actually ECMA values (see section [Data representation](#data representation)) in which the error bit is set if an erroneous operation is occurred.
|
||||
|
||||
### Value management and ownership
|
||||
### Value Management and Ownership
|
||||
|
||||
Every value stored by engine is associated with virtual "ownership" (that is responsible for manage the value and free it when is is not needed, or pass ownership of the value to somewhere)
|
||||
Every ECMA value stored by the engine is associated with a virtual "ownership", that defines how to manage the value: when to free it when it is not needed anymore and how to pass the value to an other function.
|
||||
|
||||
<div class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| Value type| "Alloc" op | "Free" op|
|
||||
| Number| ecma_alloc_number| ecma_dealloc_number|
|
||||
| String| ecma_copy_or_ref_ecma_string| ecma_deref_ecma_string|
|
||||
| Object|ecma_ref_object (for on_stack references) on_heap references are managed by GC|ecma_deref_object (for on_stack references) on_heap references are managed by GC|
|
||||
| Property|(ownership is strongly connected with corresponding object)|(ownership is strongly connected with corresponding object)|
|
||||
| Simple value|no memory management|no memory management|
|
||||
| ecma_value (including values contained in completion value)|ecma_copy_value| ecma_free_value|
|
||||
|
||||
</div>
|
||||
|
||||
Initially, value is allocated by its owner (i.e with ownership).
|
||||
Value, passed in argument is passed without ownership.
|
||||
Value, returned from function is returned with ownership.
|
||||
Rules for completion value are the same as rules for values, contained in them.
|
||||
|
||||
## Opcode handler structure
|
||||
|
||||
Most opcode handlers consists of the following steps:
|
||||
1. Decode instruction (i.e. extract `idx`-s)
|
||||
2. Read input values from variables/registers
|
||||
3. Perform necessary type conversions
|
||||
4. Perform calls to runtime
|
||||
5. Save execution result to output variable
|
||||
6. Increment opcode position counter
|
||||
7. Return completion value.
|
||||
|
||||
Steps 2-5 can produce exceptions.
|
||||
In this case execution is continued after corresponding FINALIZE mark, and completion value is set to throw exception.
|
||||
|
||||
## Exception handling
|
||||
|
||||
Operations that could produce exceptions should be performed in one of the following ways:
|
||||
* wrapped into ECMA_TRY_CATCH block:
|
||||
* `ECMA_TRY_CATCH (value_returned_from_op, op (... ),`
|
||||
* `ret_value_of_the_whole_routine_handler)``
|
||||
* `...`
|
||||
* `ECMA_FINALIZE(value_returned_from_op);`
|
||||
* `return ret_value;`
|
||||
* `ret_value = op(...);`
|
||||
* manual handling (for special cases like interpretation of opfunc_try_block).
|
||||
Initially, value is allocated by its owner (i.e. with ownership). The owner has the responsibility for freeing the allocated value. When the value is passed to a function as an argument, the ownership of it will not pass, the called function have to make an own copy of the value. However, as long as a function returns a value, the ownership will pass, thus the caller will be responsible for freeing it.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user