Support byte code dump when snapshot is executed. (#4327)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-11-16 12:17:41 +01:00
committed by GitHub
parent 81702ff5ea
commit 640a7d33b3
6 changed files with 401 additions and 389 deletions
+378 -5
View File
@@ -17,10 +17,9 @@
#include "ecma-helpers.h"
#include "ecma-big-uint.h"
#include "ecma-bigint.h"
#include "js-parser-internal.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_PARSER)
/** \addtogroup parser Parser
* @{
*
@@ -31,6 +30,8 @@
* @{
*/
#if ENABLED (JERRY_PARSER)
/**
* Free literal.
*/
@@ -52,6 +53,8 @@ util_free_literal (lexer_literal_t *literal_p) /**< literal */
}
} /* util_free_literal */
#endif /* ENABLED (JERRY_PARSER) */
#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
/**
@@ -118,7 +121,7 @@ util_print_bigint (ecma_value_t bigint) /**< bigint to print */
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
/**
* Print literal.
* Print literal
*/
void
util_print_literal (lexer_literal_t *literal_p) /**< literal */
@@ -171,6 +174,378 @@ util_print_literal (lexer_literal_t *literal_p) /**< literal */
JERRY_DEBUG_MSG (")");
} /* util_print_literal */
/**
* Print literal.
*/
static void
util_print_literal_value (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
uint16_t literal_index) /**< literal index */
{
uint16_t argument_end;
uint16_t register_end;
uint16_t ident_end;
uint16_t const_literal_end;
ecma_value_t *literal_start_p;
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) compiled_code_p;
argument_end = args_p->argument_end;
register_end = args_p->register_end;
ident_end = args_p->ident_end;
const_literal_end = args_p->const_literal_end;
literal_start_p = (ecma_value_t *) (args_p + 1);
}
else
{
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) compiled_code_p;
argument_end = args_p->argument_end;
register_end = args_p->register_end;
ident_end = args_p->ident_end;
const_literal_end = args_p->const_literal_end;
literal_start_p = (ecma_value_t *) (args_p + 1);
}
if (literal_index < argument_end)
{
JERRY_DEBUG_MSG (" arg:%d", literal_index);
return;
}
if (literal_index < register_end)
{
JERRY_DEBUG_MSG (" reg:%d", literal_index);
return;
}
if (literal_index > const_literal_end)
{
JERRY_DEBUG_MSG (" lit:%d", literal_index);
return;
}
if (literal_index < ident_end)
{
JERRY_DEBUG_MSG (" ident:%d->", literal_index);
}
else
{
JERRY_DEBUG_MSG (" const:%d->", literal_index);
}
ecma_value_t value = literal_start_p[literal_index - register_end];
if (ecma_is_value_number (value))
{
JERRY_DEBUG_MSG ("number(");
util_print_number (ecma_get_number_from_value (value));
}
#if ENABLED (JERRY_BUILTIN_BIGINT)
else if (ecma_is_value_bigint (value))
{
JERRY_DEBUG_MSG ("bigint(");
util_print_bigint (value);
}
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
else
{
ecma_string_t *literal_p = ecma_get_string_from_value (value);
JERRY_DEBUG_MSG ("string(");
ECMA_STRING_TO_UTF8_STRING (literal_p, chars_p, literal_size);
util_print_chars (chars_p, literal_size);
ECMA_FINALIZE_UTF8_STRING (chars_p, literal_size);
}
JERRY_DEBUG_MSG (")");
} /* util_print_literal_value */
#define PARSER_READ_IDENTIFIER_INDEX(name) \
name = *byte_code_p++; \
if (name >= encoding_limit) \
{ \
name = (uint16_t) (((name << 8) | byte_code_p[0]) - encoding_delta); \
byte_code_p++; \
}
/**
* Print byte code.
*/
void
util_print_cbc (ecma_compiled_code_t *compiled_code_p) /**< compiled code */
{
uint8_t flags;
uint8_t *byte_code_start_p;
uint8_t *byte_code_end_p;
uint8_t *byte_code_p;
uint16_t encoding_limit;
uint16_t encoding_delta;
uint16_t stack_limit;
uint16_t argument_end;
uint16_t register_end;
uint16_t ident_end;
uint16_t const_literal_end;
uint16_t literal_end;
size_t size = ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args = (cbc_uint16_arguments_t *) compiled_code_p;
stack_limit = args->stack_limit;
argument_end = args->argument_end;
register_end = args->register_end;
ident_end = args->ident_end;
const_literal_end = args->const_literal_end;
literal_end = args->literal_end;
}
else
{
cbc_uint8_arguments_t *args = (cbc_uint8_arguments_t *) compiled_code_p;
stack_limit = args->stack_limit;
argument_end = args->argument_end;
register_end = args->register_end;
ident_end = args->ident_end;
const_literal_end = args->const_literal_end;
literal_end = args->literal_end;
}
JERRY_DEBUG_MSG ("\nByte code dump:\n\n Maximum stack depth: %d\n Flags: [",
(int) (stack_limit + register_end));
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
{
JERRY_DEBUG_MSG ("small_lit_enc");
encoding_limit = CBC_SMALL_LITERAL_ENCODING_LIMIT;
encoding_delta = CBC_SMALL_LITERAL_ENCODING_DELTA;
}
else
{
JERRY_DEBUG_MSG ("full_lit_enc");
encoding_limit = CBC_FULL_LITERAL_ENCODING_LIMIT;
encoding_delta = CBC_FULL_LITERAL_ENCODING_DELTA;
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
JERRY_DEBUG_MSG (",uint16_arguments");
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
{
JERRY_DEBUG_MSG (",strict_mode");
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
JERRY_DEBUG_MSG (",mapped_arguments_needed");
size -= argument_end * sizeof (ecma_value_t);
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED)
{
JERRY_DEBUG_MSG (",no_lexical_env");
}
#if ENABLED (JERRY_ESNEXT)
switch (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags))
{
case CBC_FUNCTION_CONSTRUCTOR:
{
JERRY_DEBUG_MSG (",constructor");
break;
}
case CBC_FUNCTION_GENERATOR:
{
JERRY_DEBUG_MSG (",generator");
break;
}
case CBC_FUNCTION_ASYNC:
{
JERRY_DEBUG_MSG (",async");
break;
}
case CBC_FUNCTION_ASYNC_GENERATOR:
{
JERRY_DEBUG_MSG (",async_generator");
break;
}
case CBC_FUNCTION_ACCESSOR:
{
JERRY_DEBUG_MSG (",accessor");
break;
}
case CBC_FUNCTION_ARROW:
{
JERRY_DEBUG_MSG (",arrow");
break;
}
case CBC_FUNCTION_ASYNC_ARROW:
{
JERRY_DEBUG_MSG (",async_arrow");
break;
}
}
#endif /* ENABLED (JERRY_ESNEXT) */
JERRY_DEBUG_MSG ("]\n");
JERRY_DEBUG_MSG (" Argument range end: %d\n", (int) argument_end);
JERRY_DEBUG_MSG (" Register range end: %d\n", (int) register_end);
JERRY_DEBUG_MSG (" Identifier range end: %d\n", (int) ident_end);
JERRY_DEBUG_MSG (" Const literal range end: %d\n", (int) const_literal_end);
JERRY_DEBUG_MSG (" Literal range end: %d\n\n", (int) literal_end);
#if ENABLED (JERRY_ESNEXT)
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
uint32_t extended_info = ecma_compiled_code_resolve_extended_info (compiled_code_p);
JERRY_DEBUG_MSG (" [Extended] Argument length: %d\n\n", (int) CBC_EXTENDED_INFO_GET_LENGTH (extended_info));
size -= sizeof (ecma_value_t);
}
#endif /* ENABLED (JERRY_ESNEXT) */
byte_code_start_p = (uint8_t *) compiled_code_p;
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
byte_code_start_p += sizeof (cbc_uint16_arguments_t);
}
else
{
byte_code_start_p += sizeof (cbc_uint8_arguments_t);
}
byte_code_start_p += (unsigned int) (literal_end - register_end) * sizeof (ecma_value_t);
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
{
size -= sizeof (ecma_value_t);
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
{
size -= sizeof (ecma_value_t);
}
byte_code_end_p = ((uint8_t *) compiled_code_p) + size;
byte_code_p = byte_code_start_p;
while (byte_code_p < byte_code_end_p)
{
cbc_opcode_t opcode = (cbc_opcode_t) *byte_code_p;
cbc_ext_opcode_t ext_opcode = CBC_EXT_NOP;
size_t cbc_offset = (size_t) (byte_code_p - byte_code_start_p);
if (opcode != CBC_EXT_OPCODE)
{
flags = cbc_flags[opcode];
JERRY_DEBUG_MSG (" %3d : %s", (int) cbc_offset, cbc_names[opcode]);
byte_code_p++;
}
else
{
if (byte_code_p + 1 >= byte_code_end_p)
{
break;
}
ext_opcode = (cbc_ext_opcode_t) byte_code_p[1];
if (ext_opcode == CBC_EXT_NOP)
{
break;
}
flags = cbc_ext_flags[ext_opcode];
JERRY_DEBUG_MSG (" %3d : %s", (int) cbc_offset, cbc_ext_names[ext_opcode]);
byte_code_p += 2;
#if ENABLED (JERRY_LINE_INFO)
if (ext_opcode == CBC_EXT_LINE)
{
uint32_t value = 0;
uint8_t byte;
do
{
byte = *byte_code_p++;
value = (value << 7) | (byte & CBC_LOWER_SEVEN_BIT_MASK);
}
while (byte & CBC_HIGHEST_BIT_MASK);
JERRY_DEBUG_MSG (" %d\n", (int) value);
continue;
}
#endif /* ENABLED (JERRY_LINE_INFO) */
}
if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
{
uint16_t literal_index;
PARSER_READ_IDENTIFIER_INDEX (literal_index);
util_print_literal_value (compiled_code_p, literal_index);
}
if (flags & CBC_HAS_LITERAL_ARG2)
{
uint16_t literal_index;
PARSER_READ_IDENTIFIER_INDEX (literal_index);
util_print_literal_value (compiled_code_p, literal_index);
if (!(flags & CBC_HAS_LITERAL_ARG))
{
PARSER_READ_IDENTIFIER_INDEX (literal_index);
util_print_literal_value (compiled_code_p, literal_index);
}
}
if (flags & CBC_HAS_BYTE_ARG)
{
if (opcode == CBC_PUSH_NUMBER_POS_BYTE
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", (int) *byte_code_p + 1);
}
else if (opcode == CBC_PUSH_NUMBER_NEG_BYTE
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", -((int) *byte_code_p + 1));
}
else
{
JERRY_DEBUG_MSG (" byte_arg:%d", *byte_code_p);
}
byte_code_p++;
}
if (flags & CBC_HAS_BRANCH_ARG)
{
size_t branch_offset_length = (opcode != CBC_EXT_OPCODE ? CBC_BRANCH_OFFSET_LENGTH (opcode)
: CBC_BRANCH_OFFSET_LENGTH (ext_opcode));
size_t offset = 0;
do
{
offset = (offset << 8) | *byte_code_p++;
}
while (--branch_offset_length > 0);
JERRY_DEBUG_MSG (" offset:%d(->%d)",
(int) offset,
(int) (cbc_offset + (CBC_BRANCH_IS_FORWARD (flags) ? offset : -offset)));
}
JERRY_DEBUG_MSG ("\n");
}
} /* util_print_cbc */
#undef PARSER_READ_IDENTIFIER_INDEX
#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
/**
@@ -178,5 +553,3 @@ util_print_literal (lexer_literal_t *literal_p) /**< literal */
* @}
* @}
*/
#endif /* ENABLED (JERRY_PARSER) */