80 lines
2.1 KiB
C
80 lines
2.1 KiB
C
/********************************************************************
|
|
** Copyright (c) 2018-2020 Guan Wenliang
|
|
** This file is part of the Berry default interpreter.
|
|
** skiars@qq.com, https://github.com/Skiars/berry
|
|
** See Copyright Notice in the LICENSE file or at
|
|
** https://github.com/Skiars/berry/blob/master/LICENSE
|
|
********************************************************************/
|
|
#include "be_mem.h"
|
|
#include "be_exec.h"
|
|
#include "be_vm.h"
|
|
#include "be_gc.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define GC_ALLOC (1 << 2) /* GC in alloc */
|
|
|
|
#ifdef BE_EXPLICIT_MALLOC
|
|
#define malloc BE_EXPLICIT_MALLOC
|
|
#endif
|
|
|
|
#ifdef BE_EXPLICIT_FREE
|
|
#define free BE_EXPLICIT_FREE
|
|
#endif
|
|
|
|
#ifdef BE_EXPLICIT_REALLOC
|
|
#define realloc BE_EXPLICIT_REALLOC
|
|
#endif
|
|
|
|
BERRY_API void* be_os_malloc(size_t size)
|
|
{
|
|
return malloc(size);
|
|
}
|
|
|
|
BERRY_API void be_os_free(void *ptr)
|
|
{
|
|
free(ptr);
|
|
}
|
|
|
|
BERRY_API void* be_os_realloc(void *ptr, size_t size)
|
|
{
|
|
return realloc(ptr, size);
|
|
}
|
|
|
|
static void* _realloc(void *ptr, size_t old_size, size_t new_size)
|
|
{
|
|
if (old_size == new_size) { /* the block unchanged */
|
|
return ptr;
|
|
}
|
|
if (ptr && new_size) { /* realloc block */
|
|
return realloc(ptr, new_size);
|
|
}
|
|
if (new_size) { /* alloc a new block */
|
|
be_assert(ptr == NULL && old_size == 0);
|
|
return malloc(new_size);
|
|
}
|
|
be_assert(new_size == 0);
|
|
|
|
#if BE_USE_DEBUG_GC
|
|
memset(ptr, 0xFF, old_size); /* fill the structure with invalid pointers */
|
|
#endif
|
|
free(ptr);
|
|
return NULL;
|
|
}
|
|
|
|
BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size)
|
|
{
|
|
void *block = _realloc(ptr, old_size, new_size);
|
|
if (!block && new_size) { /* allocation failure */
|
|
vm->gc.status |= GC_ALLOC;
|
|
be_gc_collect(vm); /* try to allocate again after GC */
|
|
vm->gc.status &= ~GC_ALLOC;
|
|
block = _realloc(ptr, old_size, new_size);
|
|
if (!block) { /* lack of heap space */
|
|
be_throw(vm, BE_MALLOC_FAIL);
|
|
}
|
|
}
|
|
vm->gc.usage = vm->gc.usage + new_size - old_size; /* update allocated count */
|
|
return block;
|
|
}
|