已合并
Jerry社区问题维护及测试能力增强-js_heap_system_allocator.patch优化回合主干 #126
yanPeng创建于 2023年10月17日
Jerry社区问题维护及测试能力增强-js_heap_system_allocator.patch优化回合主干 #126
已合并
yanPeng创建于 2023年10月17日
共 2 个文件变更+48-173
@@ -23,6 +23,17 @@
23#include "jrt-bit-fields.h"23#include "jrt-bit-fields.h"
24#include "jrt-libc-includes.h"24#include "jrt-libc-includes.h"
25 25 
26+__weak void *JerryHeapMalloc(uint32_t size)
27+{
28+ return NULL;
29+}
30+__weak bool JerryHeapFree(void *addr)
31+{
32+ return false;
33+}
34+ 
35+__weak void JerryHeapInit() {}
36+ 
26#define JMEM_ALLOCATOR_INTERNAL37#define JMEM_ALLOCATOR_INTERNAL
27#include "jmem-allocator-internal.h"38#include "jmem-allocator-internal.h"
28 39 
@@ -135,6 +146,18 @@ jmem_heap_finalize (void)
135static void * JERRY_ATTR_HOT146static void * JERRY_ATTR_HOT
136jmem_heap_alloc (const size_t size) /**< size of requested block */147jmem_heap_alloc (const size_t size) /**< size of requested block */
137{148{
149+ if (size > 8 && size <= 24) {
150+ void *data_space_p = JerryHeapMalloc (size);
151+ if (data_space_p != NULL)
152+ {
153+ JERRY_CONTEXT (jmem_heap_allocated_size) += size;
154+ while(JERRY_CONTEXT(jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit))
155+ {
156+ JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT;
157+ }
158+ return data_space_p;
159+ }
160+ }
138#if !ENABLED (JERRY_SYSTEM_ALLOCATOR)161#if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
139 /* Align size. */162 /* Align size. */
140 const size_t required_size = ((size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT) * JMEM_ALIGNMENT;163 const size_t required_size = ((size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT) * JMEM_ALIGNMENT;
@@ -470,6 +493,18 @@ jmem_heap_free_block_internal (void *ptr, /**< pointer to beginning of data spac
470 JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_limit) >= JERRY_CONTEXT (jmem_heap_allocated_size));493 JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_limit) >= JERRY_CONTEXT (jmem_heap_allocated_size));
471 JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) > 0);494 JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) > 0);
472 495 
496+ if (JerryHeapFree(ptr)) {
497+ JERRY_CONTEXT (jmem_heap_allocated_size) -= size;
498+ 
499+ while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT(jmem_heap_limit))
500+ {
501+ JERRY_CONTEXT(jmem_heap_limit) -= CONFIG_GC_LIMIT;
502+ }
503+ 
504+ JERRY_ASSERT (JERRY_CONTEXT(jmem_heap_limit) >= JERRY_CONTEXT(jmem_heap_allocated_size));
505+ return;
506+ }
507+ 
473#if !ENABLED (JERRY_SYSTEM_ALLOCATOR)508#if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
474 /* checking that ptr points to the heap */509 /* checking that ptr points to the heap */
475 JERRY_ASSERT (jmem_is_heap_pointer (ptr));510 JERRY_ASSERT (jmem_is_heap_pointer (ptr));
@@ -506,186 +541,22 @@ jmem_heap_realloc_block (void *ptr, /**< memory region to reallocate */
506 const size_t old_size, /**< current size of the region */541 const size_t old_size, /**< current size of the region */
507 const size_t new_size) /**< desired new size */542 const size_t new_size) /**< desired new size */
508{543{
509-#if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
510- JERRY_ASSERT (jmem_is_heap_pointer (ptr));
511- JERRY_ASSERT ((uintptr_t) ptr % JMEM_ALIGNMENT == 0);
512- JERRY_ASSERT (old_size != 0);
513- JERRY_ASSERT (new_size != 0);
514- 
515- jmem_heap_free_t * const block_p = (jmem_heap_free_t *) ptr;
516- const size_t aligned_new_size = (new_size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT;
517- const size_t aligned_old_size = (old_size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT;
518- 
519- if (aligned_old_size == aligned_new_size)
520- {
521- JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size);
522- JMEM_HEAP_STAT_FREE (old_size);
523- JMEM_HEAP_STAT_ALLOC (new_size);
524- return block_p;
525- }
526- 
527- if (aligned_new_size < aligned_old_size)
528- {
529- JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size);
530- JMEM_HEAP_STAT_FREE (old_size);
531- JMEM_HEAP_STAT_ALLOC (new_size);
532- jmem_heap_insert_block ((jmem_heap_free_t *) ((uint8_t *) block_p + aligned_new_size),
533- jmem_heap_find_prev (block_p),
534- aligned_old_size - aligned_new_size);
535- 
536- JERRY_CONTEXT (jmem_heap_allocated_size) -= (aligned_old_size - aligned_new_size);
537- while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT (jmem_heap_limit))
538- {
539- JERRY_CONTEXT (jmem_heap_limit) -= CONFIG_GC_LIMIT;
540- }
541- 
542- return block_p;
543- }
544- 
545- void *ret_block_p = NULL;
546- const size_t required_size = aligned_new_size - aligned_old_size;
547- 
548-#if !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC)
549- if (JERRY_CONTEXT (jmem_heap_allocated_size) + required_size >= JERRY_CONTEXT (jmem_heap_limit))
550-#endif /* !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */
551- {
552- ecma_free_unused_memory (JMEM_PRESSURE_LOW);
553- }
554- 
555- jmem_heap_free_t *prev_p = jmem_heap_find_prev (block_p);
556- JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
557- jmem_heap_free_t * const next_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (prev_p->next_offset);
558- 
559- /* Check if block can be extended at the end */
560- if (((jmem_heap_free_t *) ((uint8_t *) block_p + aligned_old_size)) == next_p)
561- {
562- JMEM_VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
563- 
564- if (required_size <= next_p->size)
565- {
566- /* Block can be extended, update the list. */
567- if (required_size == next_p->size)
568- {
569- prev_p->next_offset = next_p->next_offset;
570- }
571- else
572- {
573- jmem_heap_free_t *const new_next_p = (jmem_heap_free_t *) ((uint8_t *) next_p + required_size);
574- JMEM_VALGRIND_DEFINED_SPACE (new_next_p, sizeof (jmem_heap_free_t));
575- new_next_p->next_offset = next_p->next_offset;
576- new_next_p->size = (uint32_t) (next_p->size - required_size);
577- JMEM_VALGRIND_NOACCESS_SPACE (new_next_p, sizeof (jmem_heap_free_t));
578- prev_p->next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (new_next_p);
579- }
580- 
581- /* next_p will be marked as undefined space. */
582- JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size);
583- ret_block_p = block_p;
584- }
585- else
586- {
587- JMEM_VALGRIND_NOACCESS_SPACE (next_p, sizeof (jmem_heap_free_t));
588- }
589- 
590- JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
591- }
592- /*
593- * Check if block can be extended at the front.
594- * This is less optimal because we need to copy the data, but still better than allocting a new block.
595- */
596- else if (jmem_heap_get_region_end (prev_p) == block_p)
597- {
598- if (required_size <= prev_p->size)
599- {
600- if (required_size == prev_p->size)
601- {
602- JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
603- prev_p = jmem_heap_find_prev (prev_p);
604- JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
605- prev_p->next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (next_p);
606- }
607- else
608- {
609- prev_p->size = (uint32_t) (prev_p->size - required_size);
610- }
611- 
612- JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
613- 
614- ret_block_p = (uint8_t *) block_p - required_size;
615- 
616- /* Mark the the new block as undefined so that we are able to write to it. */
617- JMEM_VALGRIND_UNDEFINED_SPACE (ret_block_p, old_size);
618- /* The blocks are likely to overlap, so mark the old block as defined memory again. */
619- JMEM_VALGRIND_DEFINED_SPACE (block_p, old_size);
620- memmove (ret_block_p, block_p, old_size);
621- 
622- JMEM_VALGRIND_FREELIKE_SPACE (block_p);
623- JMEM_VALGRIND_MALLOCLIKE_SPACE (ret_block_p, new_size);
624- JMEM_VALGRIND_DEFINED_SPACE (ret_block_p, old_size);
625- }
626- else
627- {
628- JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
629- }
630- }
631- 
632- if (ret_block_p != NULL)
633- {
634- /* Managed to extend the block. Update memory usage and the skip pointer. */
635- JERRY_CONTEXT (jmem_heap_list_skip_p) = prev_p;
636- JERRY_CONTEXT (jmem_heap_allocated_size) += required_size;
637- 
638- while (JERRY_CONTEXT (jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit))
639- {
640- JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT;
641- }
642- }
643- else
644- {
645- /* Could not extend block. Allocate new region and copy the data. */
646- /* jmem_heap_alloc_block_internal will adjust the allocated_size, but insert_block will not,
647- so we reduce it here first, so that the limit calculation remains consistent. */
648- JERRY_CONTEXT (jmem_heap_allocated_size) -= aligned_old_size;
649- ret_block_p = jmem_heap_alloc_block_internal (new_size);
650- 
651- /* jmem_heap_alloc_block_internal may trigger garbage collection, which can create new free blocks
652- * in the heap structure, so we need to look up the previous block again. */
653- prev_p = jmem_heap_find_prev (block_p);
654- 
655- memcpy (ret_block_p, block_p, old_size);
656- jmem_heap_insert_block (block_p, prev_p, aligned_old_size);
657- /* jmem_heap_alloc_block_internal will call JMEM_VALGRIND_MALLOCLIKE_SPACE */
658- JMEM_VALGRIND_FREELIKE_SPACE (block_p);
659- }
660- 
661- JMEM_HEAP_STAT_FREE (old_size);
662- JMEM_HEAP_STAT_ALLOC (new_size);
663- return ret_block_p;
664-#else /* ENABLED (JERRY_SYSTEM_ALLOCATOR) */
665 const size_t required_size = new_size - old_size;544 const size_t required_size = new_size - old_size;
666-#if !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC)
667 if (JERRY_CONTEXT (jmem_heap_allocated_size) + required_size >= JERRY_CONTEXT (jmem_heap_limit))545 if (JERRY_CONTEXT (jmem_heap_allocated_size) + required_size >= JERRY_CONTEXT (jmem_heap_limit))
668-#endif /* !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */
669 {546 {
670 ecma_free_unused_memory (JMEM_PRESSURE_LOW);547 ecma_free_unused_memory (JMEM_PRESSURE_LOW);
671 }548 }
672 549 
673- JERRY_CONTEXT (jmem_heap_allocated_size) += required_size;550+ void *newBuffer = jmem_heap_alloc_block(new_size);
674- 551+ size_t copySize = (old_size > new_size) ? new_size : old_size;
675- while (JERRY_CONTEXT (jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit))552+ if (newBuffer) {
676- {553+ memcpy(newBuffer, ptr, copySize);
677- JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT;554+ jmem_heap_free_block(ptr, old_size);
555+ return newBuffer;
556+ }else {
557+ jmem_heap_free_block(ptr, old_size);
558+ return NULL;
678 }559 }
679- 
680- while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT (jmem_heap_limit))
681- {
682- JERRY_CONTEXT (jmem_heap_limit) -= CONFIG_GC_LIMIT;
683- }
684- 
685- JMEM_HEAP_STAT_FREE (old_size);
686- JMEM_HEAP_STAT_ALLOC (new_size);
687- return realloc (ptr, new_size);
688-#endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
689} /* jmem_heap_realloc_block */560} /* jmem_heap_realloc_block */
690 561 
691/**562/**
@@ -16,6 +16,10 @@
16#ifndef JMEM_H16#ifndef JMEM_H
17#define JMEM_H17#define JMEM_H
18 18 
19+#ifndef __weak
20+#define __weak __attribute__((weak))
21+#endif
22+ 
19#include "jrt.h"23#include "jrt.h"
20 24 
21/** \addtogroup mem Memory allocation25/** \addtogroup mem Memory allocation