Optimize Promise data structures. (#3768)

This patch reworks several structures:

- Fulfill and reject reactions are combined into one collection. The values in this collection
are compressed: a capability followed by an optional fulfill and reject functions.
- Fulfill and reject reactions are directly stored, no need to allocate an object for them.
- The job queue directly stores its items, this saves a pointer to the value, and the
callback is replaced by an uint8 type.
- Promise status and already resolved is stored in extra_info.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-05-25 18:00:43 +02:00
committed by GitHub
parent 1774cca47c
commit 1105b43c22
8 changed files with 298 additions and 300 deletions
+17 -14
View File
@@ -268,27 +268,28 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended
/* Mark all reactions. */
ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) ext_object_p;
ecma_collection_t *collection_p = promise_object_p->fulfill_reactions;
ecma_collection_t *collection_p = promise_object_p->reactions;
if (collection_p != NULL)
{
ecma_value_t *buffer_p = collection_p->buffer_p;
ecma_value_t *buffer_end_p = buffer_p + collection_p->item_count;
for (uint32_t i = 0; i < collection_p->item_count; i++)
while (buffer_p < buffer_end_p)
{
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
}
}
ecma_value_t value = *buffer_p++;
collection_p = promise_object_p->reject_reactions;
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, value));
if (collection_p != NULL)
{
ecma_value_t *buffer_p = collection_p->buffer_p;
if (JMEM_CP_GET_FIRST_BIT_FROM_POINTER_TAG (value))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (*buffer_p++));
}
for (uint32_t i = 0; i < collection_p->item_count; i++)
{
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
if (JMEM_CP_GET_SECOND_BIT_FROM_POINTER_TAG (value))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (*buffer_p++));
}
}
}
} /* ecma_gc_mark_promise_object */
@@ -1145,8 +1146,10 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
case LIT_MAGIC_STRING_PROMISE_UL:
{
ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value);
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->fulfill_reactions);
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->reject_reactions);
/* Reactions only contains objects. */
ecma_collection_destroy (((ecma_promise_object_t *) object_p)->reactions);
ext_object_size = sizeof (ecma_promise_object_t);
break;
}