Skip to content

Commit cab46be

Browse files
committed
More gc-friendly property hashmap allocation.
- New allocator is added that returns null on out of memory, property hasmap create uses this allocator for now. - Property hashmaps of objects are removed durring a high severity gc. Follow up patch is in progress. JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu
1 parent 9bce5b0 commit cab46be

File tree

7 files changed

+87
-17
lines changed

7 files changed

+87
-17
lines changed

jerry-core/ecma/base/ecma-gc.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
506506
* Run garbage collection
507507
*/
508508
void
509-
ecma_gc_run (void)
509+
ecma_gc_run (jmem_free_unused_memory_severity_t severity)
510510
{
511511
ecma_gc_new_objects_since_last_gc = 0;
512512

@@ -577,6 +577,27 @@ ecma_gc_run (void)
577577
ecma_gc_sweep (obj_iter_p);
578578
}
579579

580+
if (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH)
581+
{
582+
/* Remove the property hasmap of BLACK objects */
583+
for (ecma_object_t *obj_iter_p = ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK], *obj_next_p;
584+
obj_iter_p != NULL;
585+
obj_iter_p = obj_next_p)
586+
{
587+
obj_next_p = ecma_gc_get_object_next (obj_iter_p);
588+
589+
JERRY_ASSERT (ecma_gc_is_object_visited (obj_iter_p));
590+
591+
ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p);
592+
if (prop_iter_p != NULL
593+
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
594+
{
595+
ecma_property_hashmap_free (obj_iter_p);
596+
}
597+
598+
}
599+
}
600+
580601
/* Unmarking all objects */
581602
ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY] = ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK];
582603
ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK] = NULL;
@@ -603,15 +624,15 @@ ecma_free_unused_memory (jmem_free_unused_memory_severity_t severity) /**< sever
603624
*/
604625
if (ecma_gc_new_objects_since_last_gc * CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC > ecma_gc_objects_number)
605626
{
606-
ecma_gc_run ();
627+
ecma_gc_run (severity);
607628
}
608629
}
609630
else
610631
{
611632
JERRY_ASSERT (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
612633

613634
/* Freeing as much memory as we currently can */
614-
ecma_gc_run ();
635+
ecma_gc_run (severity);
615636
}
616637
} /* ecma_free_unused_memory */
617638

jerry-core/ecma/base/ecma-gc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern void ecma_gc_init (void);
3030
extern void ecma_init_gc_info (ecma_object_t *);
3131
extern void ecma_ref_object (ecma_object_t *);
3232
extern void ecma_deref_object (ecma_object_t *);
33-
extern void ecma_gc_run (void);
33+
extern void ecma_gc_run (jmem_free_unused_memory_severity_t);
3434
extern void ecma_free_unused_memory (jmem_free_unused_memory_severity_t);
3535

3636
/**

jerry-core/ecma/base/ecma-init-finalize.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ ecma_finalize (void)
5454

5555
ecma_finalize_environment ();
5656
ecma_finalize_builtins ();
57-
ecma_gc_run ();
57+
ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
5858
ecma_finalize_lit_storage ();
5959
} /* ecma_finalize */
6060

jerry-core/ecma/base/ecma-property-hashmap.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,12 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
110110

111111
size_t total_size = ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (max_property_count);
112112

113-
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) jmem_heap_alloc_block (total_size);
113+
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) jmem_heap_alloc_block_null_on_error (total_size);
114+
if (hashmap_p == NULL)
115+
{
116+
return;
117+
}
118+
114119
memset (hashmap_p, 0, total_size);
115120

116121
hashmap_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_HASHMAP;

jerry-core/jerry.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ jerry_gc (void)
229229
{
230230
jerry_assert_api_available ();
231231

232-
ecma_gc_run ();
232+
ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
233233
} /* jerry_gc */
234234

235235
/**
@@ -1506,7 +1506,6 @@ jerry_construct_object (const jerry_value_t func_obj_val, /**< function object t
15061506
jerry_size_t args_count) /**< number of the arguments */
15071507
{
15081508
jerry_assert_api_available ();
1509-
15101509
if (jerry_value_is_constructor (func_obj_val))
15111510
{
15121511
ecma_value_t this_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);

jerry-core/jmem/jmem-heap.c

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -364,18 +364,13 @@ void *jmem_heap_alloc_block_internal (const size_t size)
364364
* Allocation of memory block, running 'try to give memory back' callbacks, if there is not enough memory.
365365
*
366366
* Note:
367-
* if after running the callbacks, there is still not enough memory, engine is terminated with ERR_OUT_OF_MEMORY.
367+
* if after running the callbacks, there is still not enough memory, NULL value will be returned
368368
*
369-
* @return pointer to allocated memory block
369+
* @return pointer to allocated memory block or NULL in case of unsuccessful allocation
370370
*/
371-
void * __attribute__((hot))
372-
jmem_heap_alloc_block (const size_t size)
371+
static void *
372+
jmem_heap_gc_and_alloc_block (const size_t size) /**< required memory size */
373373
{
374-
if (unlikely (size == 0))
375-
{
376-
return NULL;
377-
}
378-
379374
VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST;
380375

381376
#ifdef JMEM_GC_BEFORE_EACH_ALLOC
@@ -411,10 +406,59 @@ jmem_heap_alloc_block (const size_t size)
411406
}
412407

413408
JERRY_ASSERT (data_space_p == NULL);
409+
return data_space_p;
410+
} /* jmem_heap_gc_and_alloc_block */
411+
412+
413+
/**
414+
* Allocation of memory block, running 'try to give memory back' callbacks, if there is not enough memory.
415+
*
416+
* Note:
417+
* if after running the callbacks, there is still not enough memory, engine is terminated with ERR_OUT_OF_MEMORY.
418+
*
419+
* @return NULL, if the required memory is 0
420+
* pointer to allocated memory block, otherwise
421+
*/
422+
void * __attribute__((hot))
423+
jmem_heap_alloc_block (const size_t size) /**< required memory size */
424+
{
425+
if (unlikely (size == 0))
426+
{
427+
return NULL;
428+
}
429+
430+
void *data_space_p = jmem_heap_gc_and_alloc_block (size);
431+
432+
if (likely (data_space_p != NULL))
433+
{
434+
return data_space_p;
435+
}
414436

415437
jerry_fatal (ERR_OUT_OF_MEMORY);
416438
} /* jmem_heap_alloc_block */
417439

440+
/**
441+
* Allocation of memory block, running 'try to give memory back' callbacks, if there is not enough memory.
442+
*
443+
* Note:
444+
* if after running the callbacks, there is still not enough memory, NULL will be returned
445+
*
446+
* @return NULL, if the required memory size is 0
447+
* also NULL, if the allocation has failed
448+
* pointer to allocated memory block, otherwise
449+
*/
450+
void * __attribute__((hot))
451+
jmem_heap_alloc_block_null_on_error (const size_t size) /**< required memory size */
452+
{
453+
if (unlikely (size == 0))
454+
{
455+
return NULL;
456+
}
457+
458+
return jmem_heap_gc_and_alloc_block (size);
459+
} /* jmem_heap_alloc_block_null_on_error */
460+
461+
418462
/**
419463
* Allocate block and store block size.
420464
*

jerry-core/jmem/jmem-heap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
extern void jmem_heap_init (void);
3333
extern void jmem_heap_finalize (void);
3434
extern void *jmem_heap_alloc_block (const size_t);
35+
extern void *jmem_heap_alloc_block_null_on_error (const size_t);
3536
extern void jmem_heap_free_block (void *, const size_t);
3637
extern void *jmem_heap_alloc_block_store_size (size_t);
3738
extern void jmem_heap_free_block_size_stored (void *);

0 commit comments

Comments
 (0)