[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