[njs] Added generator debug.
Dmitry Volyntsev
xeioex at nginx.com
Wed Jun 29 06:05:40 UTC 2022
details: https://hg.nginx.org/njs/rev/0cdbc3d35a2a
branches:
changeset: 1900:0cdbc3d35a2a
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Jun 28 22:36:37 2022 -0700
description:
Added generator debug.
diffstat:
auto/cc | 4 +
auto/help | 2 +
auto/options | 2 +
src/njs.h | 3 +
src/njs_generator.c | 152 ++++++++++++++++++++++++++++++++++++++++-----------
src/njs_shell.c | 13 ++++
6 files changed, 143 insertions(+), 33 deletions(-)
diffs (512 lines):
diff -r 8fe7d9723477 -r 0cdbc3d35a2a auto/cc
--- a/auto/cc Tue Jun 28 22:36:30 2022 -0700
+++ b/auto/cc Tue Jun 28 22:36:37 2022 -0700
@@ -181,6 +181,10 @@ if [ "$NJS_DEBUG_OPCODE" = "YES" ]; then
njs_define=NJS_DEBUG_OPCODE . auto/define
fi
+if [ "$NJS_DEBUG_GENERATOR" = "YES" ]; then
+ njs_define=NJS_DEBUG_GENERATOR . auto/define
+fi
+
if [ "$NJS_TEST262" = "YES" ]; then
njs_define=NJS_TEST262 . auto/define
fi
diff -r 8fe7d9723477 -r 0cdbc3d35a2a auto/help
--- a/auto/help Tue Jun 28 22:36:30 2022 -0700
+++ b/auto/help Tue Jun 28 22:36:37 2022 -0700
@@ -41,6 +41,8 @@ default: "$NJS_DEBUG"
default: "$NJS_DEBUG_MEMORY"
--debug-opcode=YES enables runtime function tracing, \
default: "$NJS_DEBUG_OPCODE"
+ --debug-generator=YES enables generator debug, \
+default: "$NJS_DEBUG_GENERATOR"
--test262=YES enables test262 extentions, \
default: "$NJS_TEST262"
END
diff -r 8fe7d9723477 -r 0cdbc3d35a2a auto/options
--- a/auto/options Tue Jun 28 22:36:30 2022 -0700
+++ b/auto/options Tue Jun 28 22:36:37 2022 -0700
@@ -9,6 +9,7 @@ NJS_LD_OPT=${NJS_CC_OPT:--O}
NJS_DEBUG=NO
NJS_DEBUG_MEMORY=NO
NJS_DEBUG_OPCODE=NO
+NJS_DEBUG_GENERATOR=NO
NJS_ADDRESS_SANITIZER=NO
NJS_ADDR2LINE=NO
@@ -41,6 +42,7 @@ do
--debug=*) NJS_DEBUG="$value" ;;
--debug-memory=*) NJS_DEBUG_MEMORY="$value" ;;
--debug-opcode=*) NJS_DEBUG_OPCODE="$value" ;;
+ --debug-generator=*) NJS_DEBUG_GENERATOR="$value" ;;
--test262=*) NJS_TEST262="$value" ;;
--no-openssl) NJS_OPENSSL=NO ;;
diff -r 8fe7d9723477 -r 0cdbc3d35a2a src/njs.h
--- a/src/njs.h Tue Jun 28 22:36:30 2022 -0700
+++ b/src/njs.h Tue Jun 28 22:36:37 2022 -0700
@@ -253,6 +253,9 @@ typedef struct {
#ifdef NJS_DEBUG_OPCODE
uint8_t opcode_debug; /* 1 bit */
#endif
+#ifdef NJS_DEBUG_GENERATOR
+ uint8_t generator_debug; /* 1 bit */
+#endif
uint8_t unhandled_rejection;
} njs_vm_opt_t;
diff -r 8fe7d9723477 -r 0cdbc3d35a2a src/njs_generator.c
--- a/src/njs_generator.c Tue Jun 28 22:36:30 2022 -0700
+++ b/src/njs_generator.c Tue Jun 28 22:36:37 2022 -0700
@@ -24,6 +24,12 @@ typedef enum {
} njs_generator_block_type_t;
+typedef enum {
+ NJS_GENERATOR_CONTINUATION = 1,
+ NJS_GENERATOR_EXIT = 2,
+} njs_generator_patch_type_t;
+
+
struct njs_generator_patch_s {
/*
* The jump_offset field points to jump offset field which contains a small
@@ -179,10 +185,10 @@ static njs_int_t njs_generate_start_bloc
const njs_str_t *label);
static njs_generator_block_t *njs_generate_lookup_block(
njs_generator_block_t *block, uint32_t mask, const njs_str_t *label);
-static njs_generator_block_t *njs_generate_find_block(
+static njs_generator_block_t *njs_generate_find_block(njs_vm_t *vm,
njs_generator_block_t *block, uint32_t mask, const njs_str_t *label);
static void njs_generate_patch_block(njs_vm_t *vm, njs_generator_t *generator,
- njs_generator_patch_t *list);
+ njs_generator_block_t *block, unsigned type);
static njs_generator_patch_t *njs_generate_make_continuation_patch(njs_vm_t *vm,
njs_generator_block_t *block, const njs_str_t *label,
njs_jump_off_t offset);
@@ -427,13 +433,16 @@ static njs_int_t njs_generate_index_rele
##__VA_ARGS__)
-#ifdef NJS_GENERATOR_DEBUG
-#define njs_generator_debug(msg, ...) njs_printf(msg "\n", ##__VA_ARGS__)
-#define njs_generator_debug_code(code) \
- njs_disassemble((u_char *) code, NULL, 1, NULL)
+#ifdef NJS_DEBUG_GENERATOR
+#define njs_debug_generator(vm, msg, ...) \
+ if (vm->options.generator_debug) \
+ njs_printf("GENERATOR " msg "\n", ##__VA_ARGS__)
+#define njs_debug_generator_code(code) \
+ if (vm->options.generator_debug) \
+ njs_disassemble((u_char *) code, NULL, 1, NULL)
#else
-#define njs_generator_debug(msg, ...)
-#define njs_generator_debug_code(code)
+#define njs_debug_generator(vm, msg, ...)
+#define njs_debug_generator_code(code)
#endif
@@ -1590,7 +1599,8 @@ njs_generate_while_condition(njs_vm_t *v
ctx = generator->context;
- njs_generate_patch_block(vm, generator, generator->block->continuation);
+ njs_generate_patch_block(vm, generator, generator->block,
+ NJS_GENERATOR_CONTINUATION);
njs_code_set_jump_offset(generator, njs_vmcode_jump_t, ctx->jump_offset);
@@ -1657,7 +1667,8 @@ static njs_int_t
njs_generate_do_while_condition(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
- njs_generate_patch_block(vm, generator, generator->block->continuation);
+ njs_generate_patch_block(vm, generator, generator->block,
+ NJS_GENERATOR_CONTINUATION);
njs_generator_next(generator, njs_generate, node->right);
@@ -1795,7 +1806,8 @@ njs_generate_for_body(njs_vm_t *vm, njs_
return ret;
}
- njs_generate_patch_block(vm, generator, generator->block->continuation);
+ njs_generate_patch_block(vm, generator, generator->block,
+ NJS_GENERATOR_CONTINUATION);
njs_generator_next(generator, njs_generate, update);
@@ -2062,7 +2074,8 @@ njs_generate_for_in_body(njs_vm_t *vm, n
}
}
- njs_generate_patch_block(vm, generator, generator->block->continuation);
+ njs_generate_patch_block(vm, generator, generator->block,
+ NJS_GENERATOR_CONTINUATION);
njs_code_set_jump_offset(generator, njs_vmcode_prop_foreach_t,
ctx->jump_offset);
@@ -2095,6 +2108,24 @@ njs_generate_for_in_body(njs_vm_t *vm, n
}
+#ifdef NJS_DEBUG_GENERATOR
+njs_inline const char*
+njs_block_type(njs_generator_block_type_t type)
+{
+ switch (type) {
+ case NJS_GENERATOR_LOOP:
+ return "LOOP ";
+ case NJS_GENERATOR_SWITCH:
+ return "SWITCH";
+ case NJS_GENERATOR_BLOCK:
+ return "BLOCK ";
+ default:
+ return "TRY ";
+ }
+}
+#endif
+
+
static njs_int_t
njs_generate_start_block(njs_vm_t *vm, njs_generator_t *generator,
njs_generator_block_type_t type, const njs_str_t *label)
@@ -2114,6 +2145,8 @@ njs_generate_start_block(njs_vm_t *vm, n
block->index = 0;
+ njs_debug_generator(vm, "START %s %p", njs_block_type(type), block);
+
return NJS_OK;
}
@@ -2145,8 +2178,8 @@ njs_generate_lookup_block(njs_generator_
static njs_generator_block_t *
-njs_generate_find_block(njs_generator_block_t *block, uint32_t mask,
- const njs_str_t *label)
+njs_generate_find_block(njs_vm_t *vm, njs_generator_block_t *block,
+ uint32_t mask, const njs_str_t *label)
{
njs_generator_block_t *dest_block;
@@ -2172,17 +2205,24 @@ njs_generate_find_block(njs_generator_bl
while (block != NULL) {
if (block->type & NJS_GENERATOR_TRY) {
+ njs_debug_generator(vm, "FIND %s %p",
+ njs_block_type(block->type), block);
return block;
}
if (block == dest_block) {
- return block;
+ break;
}
block = block->next;
}
}
+ njs_debug_generator(vm, "FIND %s %p",
+ dest_block != NULL ? njs_block_type(dest_block->type)
+ : "NONE ",
+ dest_block);
+
return dest_block;
}
@@ -2206,18 +2246,26 @@ njs_generate_make_continuation_patch(njs
patch->label = *label;
+
+ njs_debug_generator(vm, "MAKE CONT %p %L %V", patch, patch->jump_offset,
+ &patch->label);
+
return patch;
}
static void
-njs_generate_patch_block(njs_vm_t *vm, njs_generator_t *generator,
+njs_generate_patch(njs_vm_t *vm, njs_generator_t *generator,
njs_generator_patch_t *list)
{
njs_generator_patch_t *patch, *next;
for (patch = list; patch != NULL; patch = next) {
njs_code_update_offset(generator, patch);
+ njs_debug_generator(vm, "PATCH %p at %L to %L %V", patch,
+ patch->jump_offset,
+ *(njs_code_jump_ptr(generator, patch->jump_offset)),
+ &patch->label);
next = patch->next;
njs_mp_free(vm->mem_pool, patch);
@@ -2225,6 +2273,22 @@ njs_generate_patch_block(njs_vm_t *vm, n
}
+static void
+njs_generate_patch_block(njs_vm_t *vm, njs_generator_t *generator,
+ njs_generator_block_t *block, unsigned type)
+{
+ if (type & NJS_GENERATOR_CONTINUATION) {
+ njs_debug_generator(vm, "PATCH CONT %p", block);
+ njs_generate_patch(vm, generator, block->continuation);
+ }
+
+ if (type & NJS_GENERATOR_EXIT) {
+ njs_debug_generator(vm, "PATCH EXIT %p", block);
+ njs_generate_patch(vm, generator, block->exit);
+ }
+}
+
+
static njs_generator_patch_t *
njs_generate_make_exit_patch(njs_vm_t *vm, njs_generator_block_t *block,
const njs_str_t *label, njs_jump_off_t offset)
@@ -2244,6 +2308,9 @@ njs_generate_make_exit_patch(njs_vm_t *v
patch->label = *label;
+ njs_debug_generator(vm, "MAKE EXIT %p %L %V", patch, patch->jump_offset,
+ &patch->label);
+
return patch;
}
@@ -2256,7 +2323,9 @@ njs_generate_patch_block_exit(njs_vm_t *
block = generator->block;
generator->block = block->next;
- njs_generate_patch_block(vm, generator, block->exit);
+ njs_generate_patch_block(vm, generator, block, NJS_GENERATOR_EXIT);
+
+ njs_debug_generator(vm, "EXIT %s %p", njs_block_type(block->type), block);
njs_mp_free(vm->mem_pool, block);
}
@@ -2307,7 +2376,7 @@ njs_generate_continue_statement(njs_vm_t
label = &node->name;
- block = njs_generate_find_block(generator->block, NJS_GENERATOR_LOOP,
+ block = njs_generate_find_block(vm, generator->block, NJS_GENERATOR_LOOP,
label);
if (njs_slow_path(block == NULL)) {
@@ -2356,7 +2425,8 @@ njs_generate_break_statement(njs_vm_t *v
label = &node->name;
- block = njs_generate_find_block(generator->block, NJS_GENERATOR_ALL, label);
+ block = njs_generate_find_block(vm, generator->block, NJS_GENERATOR_ALL,
+ label);
if (njs_slow_path(block == NULL)) {
goto syntax_error;
}
@@ -3377,7 +3447,7 @@ njs_generate_3addr_operation_end(njs_vm_
code->dst = node->index;
- njs_generator_debug_code(code);
+ njs_debug_generator_code(code);
return njs_generator_stack_pop(vm, generator, generator->context);
}
@@ -3412,7 +3482,7 @@ njs_generate_2addr_operation_end(njs_vm_
code->dst = node->index;
- njs_generator_debug_code(code);
+ njs_debug_generator_code(code);
return njs_generator_stack_pop(vm, generator, NULL);
}
@@ -3461,7 +3531,7 @@ njs_generate_typeof_operation_end(njs_vm
code->dst = node->index;
- njs_generator_debug_code(code);
+ njs_debug_generator_code(code);
return njs_generator_stack_pop(vm, generator, NULL);
}
@@ -3884,6 +3954,8 @@ njs_generate_return_statement_end(njs_vm
immediate = njs_generate_lookup_block(generator->block, NJS_GENERATOR_TRY,
&no_label);
+ njs_debug_generator(vm, "LOOKUP TRY %p", immediate);
+
if (njs_fast_path(immediate == NULL)) {
njs_generate_code(generator, njs_vmcode_return_t, code,
NJS_VMCODE_RETURN, 1, node);
@@ -4267,7 +4339,11 @@ njs_generate_try_left(njs_vm_t *vm, njs_
if (try_block->exit != NULL) {
ctx->try_exit_label = try_block->exit->label;
- njs_generate_patch_block(vm, generator, try_block->exit);
+ njs_debug_generator(vm, "TRY CTX %p EXIT LABEL %V", ctx,
+ &ctx->try_exit_label);
+
+ njs_generate_patch_block(vm, generator, try_block,
+ NJS_GENERATOR_EXIT);
njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_break,
NJS_VMCODE_TRY_BREAK, 1, NULL);
@@ -4282,7 +4358,8 @@ njs_generate_try_left(njs_vm_t *vm, njs_
if (try_block->continuation != NULL) {
ctx->try_cont_label = try_block->continuation->label;
- njs_generate_patch_block(vm, generator, try_block->continuation);
+ njs_generate_patch_block(vm, generator, try_block,
+ NJS_GENERATOR_CONTINUATION);
njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_continue,
NJS_VMCODE_TRY_CONTINUE, 1, NULL);
@@ -4295,6 +4372,10 @@ njs_generate_try_left(njs_vm_t *vm, njs_
}
}
+ njs_debug_generator(vm, "EXIT %s %p",
+ njs_block_type(generator->block->type),
+ generator->block);
+
generator->block = try_block->next;
njs_code_set_jump_offset(generator, njs_vmcode_try_start_t,
@@ -4396,7 +4477,7 @@ njs_generate_try_catch(njs_vm_t *vm, njs
* block != NULL is checked
* by njs_generate_continue_statement()
*/
- block = njs_generate_find_block(generator->block,
+ block = njs_generate_find_block(vm, generator->block,
NJS_GENERATOR_LOOP,
&ctx->try_cont_label);
@@ -4410,7 +4491,7 @@ njs_generate_try_catch(njs_vm_t *vm, njs
}
if (try_block->exit != NULL) {
- block = njs_generate_find_block(generator->block,
+ block = njs_generate_find_block(vm, generator->block,
NJS_GENERATOR_ALL,
&ctx->try_exit_label);
@@ -4462,7 +4543,8 @@ njs_generate_try_finally(njs_vm_t *vm, n
if (catch_block->exit != NULL) {
ctx->catch_exit_label = catch_block->exit->label;
- njs_generate_patch_block(vm, generator, catch_block->exit);
+ njs_generate_patch_block(vm, generator, catch_block,
+ NJS_GENERATOR_EXIT);
njs_generate_code(generator, njs_vmcode_try_trampoline_t,
try_break, NJS_VMCODE_TRY_BREAK, 1, NULL);
@@ -4478,8 +4560,8 @@ njs_generate_try_finally(njs_vm_t *vm, n
if (catch_block->continuation != NULL) {
ctx->catch_cont_label = catch_block->continuation->label;
- njs_generate_patch_block(vm, generator,
- catch_block->continuation);
+ njs_generate_patch_block(vm, generator, catch_block,
+ NJS_GENERATOR_CONTINUATION);
njs_generate_code(generator, njs_vmcode_try_trampoline_t,
try_continue, NJS_VMCODE_TRY_CONTINUE, 1,
@@ -4494,6 +4576,10 @@ njs_generate_try_finally(njs_vm_t *vm, n
}
}
+ njs_debug_generator(vm, "EXIT %s %p",
+ njs_block_type(generator->block->type),
+ generator->block);
+
generator->block = catch_block->next;
njs_code_set_jump_offset(generator, njs_vmcode_catch_t,
@@ -4554,7 +4640,7 @@ njs_generate_try_end(njs_vm_t *vm, njs_g
* block != NULL is checked
* by njs_generate_continue_statement()
*/
- block = njs_generate_find_block(generator->block,
+ block = njs_generate_find_block(vm, generator->block,
NJS_GENERATOR_LOOP, dest_label);
patch = njs_generate_make_continuation_patch(vm, block, dest_label,
@@ -4582,7 +4668,7 @@ njs_generate_try_end(njs_vm_t *vm, njs_g
* block can be NULL for "return" instruction in
* outermost try-catch block.
*/
- block = njs_generate_find_block(generator->block,
+ block = njs_generate_find_block(vm, generator->block,
NJS_GENERATOR_ALL
| NJS_GENERATOR_TRY, dest_label);
if (block != NULL) {
@@ -4911,7 +4997,7 @@ njs_generate_temp_index_get(njs_vm_t *vm
if (cache != NULL && cache->items != 0) {
last = njs_arr_remove_last(cache);
- njs_generator_debug("INDEX REUSE %04Xz", (size_t) *last);
+ njs_debug_generator(vm, "INDEX REUSE %04Xz", (size_t) *last);
return *last;
}
@@ -4977,7 +5063,7 @@ njs_generate_index_release(njs_vm_t *vm,
njs_arr_t *cache;
njs_index_t *last;
- njs_generator_debug("INDEX RELEASE %04Xz", (size_t) index);
+ njs_debug_generator(vm, "INDEX RELEASE %04Xz", (size_t) index);
cache = generator->index_cache;
diff -r 8fe7d9723477 -r 0cdbc3d35a2a src/njs_shell.c
--- a/src/njs_shell.c Tue Jun 28 22:36:30 2022 -0700
+++ b/src/njs_shell.c Tue Jun 28 22:36:37 2022 -0700
@@ -37,6 +37,7 @@ typedef struct {
uint8_t ast;
uint8_t unhandled_rejection;
uint8_t opcode_debug;
+ uint8_t generator_debug;
int exit_code;
char *file;
@@ -273,6 +274,9 @@ main(int argc, char **argv)
vm_options.sandbox = opts.sandbox;
vm_options.unsafe = !opts.safe;
vm_options.module = opts.module;
+#ifdef NJS_DEBUG_GENERATOR
+ vm_options.generator_debug = opts.generator_debug;
+#endif
#ifdef NJS_DEBUG_OPCODE
vm_options.opcode_debug = opts.opcode_debug;
#endif
@@ -338,6 +342,9 @@ njs_options_parse(njs_opts_t *opts, int
" -d print disassembled code.\n"
" -e set failure exit code.\n"
" -f disabled denormals mode.\n"
+#ifdef NJS_DEBUG_GENERATOR
+ " -g enable generator debug.\n"
+#endif
#ifdef NJS_DEBUG_OPCODE
" -o enable opcode debug.\n"
#endif
@@ -417,6 +424,12 @@ njs_options_parse(njs_opts_t *opts, int
opts->denormals = 0;
break;
+#ifdef NJS_DEBUG_GENERATOR
+ case 'g':
+ opts->generator_debug = 1;
+ break;
+#endif
+
#ifdef NJS_DEBUG_OPCODE
case 'o':
opts->opcode_debug = 1;
More information about the nginx-devel
mailing list