Skip to content

Allow the port to allocate/deallocate the heap #946

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ project (Jerry C ASM)
string(TOUPPER "${PLATFORM}" PLATFORM)

# Compiler configuration
if(NOT ("${PLATFORM}" STREQUAL "DARWIN"))
if(NOT (("${PLATFORM}" STREQUAL "DARWIN") OR ("${PLATFORM}" STREQUAL "EXTERNAL")))
if(NOT CMAKE_COMPILER_IS_GNUCC)
message(FATAL_ERROR "gcc compiler is required")
endif()
Expand Down Expand Up @@ -131,6 +131,15 @@ project (Jerry C ASM)
set(INCLUDE_LIBC_INTERFACE ${EXTERNAL_LIBC_INTERFACE})
endif()


# Should we use external jerry-port.c?
if(DEFINED EXTERNAL_PORT_FILE AND NOT EXTERNAL_PORT_FILE STREQUAL "UNDEFINED")
set(SOURCE_PORT_IMPLEMENTATION ${EXTERNAL_PORT_FILE})
set(USE_DEFAULT_PORT FALSE)
else()
set(USE_DEFAULT_PORT TRUE)
endif()

# Are there any interfaces for external libraries, other than libc, that should be registered?
if(DEFINED EXTERNAL_LIBS_INTERFACE AND NOT EXTERNAL_LIBS_INTERFACE STREQUAL "UNDEFINED")
set(INCLUDE_EXTERNAL_LIBS_INTERFACE )
Expand Down
2 changes: 1 addition & 1 deletion build/configs/toolchain_external.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME EXTERNAL)
set(CMAKE_SYSTEM_PROCESSOR "${EXTERNAL_CMAKE_SYSTEM_PROCESSOR}")

CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU)
CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} ${EXTERNAL_CMAKE_C_COMPILER_FAMILY})
13 changes: 12 additions & 1 deletion jerry-core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ project (JerryCore C ASM)
${SOURCE_CORE_PARSER_REGEXP}
${SOURCE_CORE_JRT})

# Jerry port
if(USE_DEFAULT_PORT)
file(GLOB SOURCE_PORT_FILES ${CMAKE_SOURCE_DIR}/targets/default/*.c)
else()
set(SOURCE_PORT_FILES ${SOURCE_PORT_IMPLEMENTATION})
endif()

# All-in-one build
if("${ENABLE_ALL_IN_ONE}" STREQUAL "ON")
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/jerry-all-in.c")
Expand All @@ -157,9 +164,13 @@ project (JerryCore C ASM)
file(APPEND ${ALL_IN_FILE} "#include \"${FILE}\"\n")
endforeach()

foreach(FILE ${SOURCE_PORT_FILES})
file(APPEND ${ALL_IN_FILE} "#include \"${FILE}\"\n")
endforeach()

set(SOURCE_CORE ${ALL_IN_FILE})
else()
set(SOURCE_CORE ${SOURCE_CORE_FILES})
set(SOURCE_CORE ${SOURCE_CORE_FILES} ${SOURCE_PORT_FILES})
endif()

# Per-option configuration
Expand Down
15 changes: 8 additions & 7 deletions jerry-core/ecma/builtin-objects/ecma-builtin-global.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,39 +100,40 @@ ecma_builtin_global_object_print (ecma_value_t this_arg __attr_unused___, /**< t

if (code_point == LIT_CHAR_NULL)
{
printf ("\\u0000");
jerry_port_putchar ('\0');
}
else if (code_point <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
{
printf ("%c", (char) code_point);
jerry_port_putchar ((char) code_point);
}
else
{
JERRY_STATIC_ASSERT (sizeof (code_point) == 2,
size_of_code_point_must_be_equal_to_2_bytes);

uint32_t byte_high = (uint32_t) JRT_EXTRACT_BIT_FIELD (ecma_char_t, code_point,
uint8_t byte_high = (uint8_t) JRT_EXTRACT_BIT_FIELD (ecma_char_t, code_point,
JERRY_BITSINBYTE,
JERRY_BITSINBYTE);
uint32_t byte_low = (uint32_t) JRT_EXTRACT_BIT_FIELD (ecma_char_t, code_point,
uint8_t byte_low = (uint8_t) JRT_EXTRACT_BIT_FIELD (ecma_char_t, code_point,
0,
JERRY_BITSINBYTE);

printf ("\\u%02x%02x", byte_high, byte_low);
jerry_port_putchar (byte_high);
jerry_port_putchar (byte_low);
}
}

if (arg_index < args_number - 1)
{
printf (" ");
jerry_port_putchar (' ');
}

MEM_FINALIZE_LOCAL_ARRAY (utf8_str_p);

ECMA_FINALIZE (str_value);
}

printf ("\n");
jerry_port_putchar ('\n');

if (ecma_is_value_empty (ret_value))
{
Expand Down
18 changes: 18 additions & 0 deletions jerry-core/jerry-port.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ extern "C"
{
#endif /* !__cplusplus */

/**
* Forward definition of heap data structure
*/
struct mem_heap;
typedef struct mem_heap mem_heap_t;

/** \addtogroup jerry_port Jerry engine port
* @{
*/
Expand All @@ -35,6 +41,18 @@ int jerry_port_logmsg (FILE *stream, const char *format, ...);
int jerry_port_errormsg (const char *format, ...);
int jerry_port_putchar (int c);

void jerry_port_abort (void);


/**
* Target port functions for memory management
*/
mem_heap_t *jerry_port_init_heap (void);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add a size argument to this function. At least the implementation can check the size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok!


void jerry_port_finalize_heap (mem_heap_t *mem_heap);

mem_heap_t *jerry_port_get_heap (void);

/**
* @}
*/
Expand Down
12 changes: 0 additions & 12 deletions jerry-core/jerry.c
Original file line number Diff line number Diff line change
Expand Up @@ -2444,15 +2444,3 @@ jerry_api_get_string_size (const jerry_api_string_t *str_p) /**< input string */
return ecma_string_get_size ((ecma_string_t *) str_p);
} /* jerry_api_get_string_size */

/**
* Get length of Jerry string
*
* @return number of characters in the string
*/
jerry_api_length_t
jerry_api_get_string_length (const jerry_api_string_t *str_p) /**< input string */
{
jerry_assert_api_available ();

return ecma_string_get_length ((ecma_string_t *) str_p);
} /* jerry_api_get_string_length */
25 changes: 13 additions & 12 deletions jerry-core/jrt/jrt-fatals.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ void __noreturn
jerry_fatal (jerry_fatal_code_t code) /**< status code */
{
#ifndef JERRY_NDEBUG
printf ("Error: ");
jerry_port_errormsg ("Error: ");

switch (code)
{
case ERR_OUT_OF_MEMORY:
{
printf ("ERR_OUT_OF_MEMORY\n");
jerry_port_errormsg ("ERR_OUT_OF_MEMORY\n");
break;
}
case ERR_SYSCALL:
Expand All @@ -54,12 +54,12 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
}
case ERR_UNIMPLEMENTED_CASE:
{
printf ("ERR_UNIMPLEMENTED_CASE\n");
jerry_port_errormsg ("ERR_UNIMPLEMENTED_CASE\n");
break;
}
case ERR_FAILED_INTERNAL_ASSERTION:
{
printf ("ERR_FAILED_INTERNAL_ASSERTION\n");
jerry_port_errormsg ("ERR_FAILED_INTERNAL_ASSERTION\n");
break;
}
}
Expand All @@ -69,7 +69,7 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
&& code != ERR_OUT_OF_MEMORY
&& jerry_is_abort_on_fail ())
{
abort ();
jerry_port_abort ();
}
else
{
Expand All @@ -92,7 +92,7 @@ jerry_assert_fail (const char *assertion, /**< assertion condition string */
const uint32_t line) /**< line */
{
#if !defined (JERRY_NDEBUG) || !defined (JERRY_DISABLE_HEAVY_DEBUG)
printf ("ICE: Assertion '%s' failed at %s(%s):%lu.\n",
jerry_port_errormsg ("ICE: Assertion '%s' failed at %s(%s):%lu.\n",
assertion, file, function, (unsigned long) line);
#else /* !JERRY_NDEBUG || !JERRY_DISABLE_HEAVY_DEBUG */
(void) assertion;
Expand All @@ -115,7 +115,8 @@ jerry_unreachable (const char *comment, /**< comment to unreachable mark if exis
const uint32_t line) /**< line */
{
#ifndef JERRY_NDEBUG
printf ("ICE: Unreachable control path at %s(%s):%lu was executed", file, function, (unsigned long) line);
jerry_port_errormsg ("ICE: Unreachable control path at %s(%s):%lu was executed",
file, function, (unsigned long) line);
#else /* !JERRY_NDEBUG */
(void) file;
(void) function;
Expand All @@ -124,9 +125,9 @@ jerry_unreachable (const char *comment, /**< comment to unreachable mark if exis

if (comment != NULL)
{
printf ("(%s)", comment);
jerry_port_errormsg ("(%s)", comment);
}
printf (".\n");
jerry_port_errormsg (".\n");

jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
} /* jerry_unreachable */
Expand All @@ -142,7 +143,7 @@ jerry_unimplemented (const char *comment, /**< comment to unimplemented mark if
const uint32_t line) /**< line */
{
#ifndef JERRY_NDEBUG
printf ("SORRY: Unimplemented case at %s(%s):%lu was executed", file, function, (unsigned long) line);
jerry_port_errormsg ("SORRY: Unimplemented case at %s(%s):%lu was executed", file, function, (unsigned long) line);
#else /* !JERRY_NDEBUG */
(void) file;
(void) function;
Expand All @@ -151,9 +152,9 @@ jerry_unimplemented (const char *comment, /**< comment to unimplemented mark if

if (comment != NULL)
{
printf ("(%s)", comment);
jerry_port_errormsg ("(%s)", comment);
}
printf (".\n");
jerry_port_errormsg (".\n");

jerry_fatal (ERR_UNIMPLEMENTED_CASE);
} /* jerry_unimplemented */
81 changes: 81 additions & 0 deletions jerry-core/mem/mem-heap-internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MEM_HEAP_INTERNAL_H
#define MEM_HEAP_INTERNAL_H

#ifndef MEM_HEAP_INTERNAL
# error "The header is for internal routines of memory heap component. Please, don't use the routines directly."
#endif /* !MEM_HEAP_INTERNAL */

#include "mem-allocator.h"
#include "mem-config.h"

/** \addtogroup mem Memory allocation
* @{
*/

/* Calculate heap area size, leaving space for a pointer to the free list */
#define MEM_HEAP_AREA_SIZE (MEM_HEAP_SIZE - MEM_ALIGNMENT)
#define MEM_HEAP_END_OF_LIST ((mem_heap_free_t *const) ~((uint32_t) 0x0))

/**
* Free region node
*/
typedef struct
{
uint32_t next_offset; /* Offset of next region in list */
uint32_t size; /* Size of region */
} mem_heap_free_t;

#ifdef MEM_HEAP_PTR_64
#define MEM_HEAP_GET_OFFSET_FROM_ADDR(h, p) ((uint32_t) ((uint8_t *) (p) - (uint8_t *) (h)->area))
#define MEM_HEAP_GET_ADDR_FROM_OFFSET(h, u) ((mem_heap_free_t *) &(h)->area[u])
#else
/* In this case we simply store the pointer, since it fits anyway. */
#define MEM_HEAP_GET_OFFSET_FROM_ADDR(h, p) ((uint32_t) (p))
#define MEM_HEAP_GET_ADDR_FROM_OFFSET(h, u) ((mem_heap_free_t *)(u))
#endif

/**
* Heap structure
*/
struct mem_heap
{
mem_heap_free_t first;
/* This is used to speed up deallocation. */
mem_heap_free_t *list_skip_p;
/**
* Size of allocated regions
*/
size_t allocated_size;

/**
* Current limit of heap usage, that is upon being reached, causes call of "try give memory back" callbacks
*/
size_t limit;

/**
* Heap area
*/
uint8_t area[MEM_HEAP_AREA_SIZE] __attribute__ ((aligned (MEM_ALIGNMENT)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't that simple. The allocator should ensure the alignment. I would only put this member into a dynamic struct.

};


/**
* @}
*/

#endif /* MEM_HEAP_INTERNAL_H */
Loading