Home  >  Article  >  Web Front-end  >  Node explains the process analysis of executing js

Node explains the process analysis of executing js

不言
不言Original
2018-04-03 14:41:492038browse

The content of this article is to share with you the analysis of the process of node explaining and executing js. Friends who are interested can take a look, and friends in need can also refer to it

Explanation: node is single-threaded. Non-blocking, event-driven (similar to udev events in the kernel, you can refer to the listening-callback mechanism)

Take node-v8.10.0 as the object, mainly src/node_main.cc and src/node.cc document.

  1. Entry
    node-v8.10.0/src/node_main.cc --> 90 int main(int argc, char *argv[])
    Call node::Start( argc, argv);
    node-v8.10.0/src/node.cc --> 4863 int Start(int argc, char** argv)
    a: 4864 atexit([] () { uv_tty_reset_mode( ); });
    # Execute the anonymous function after executing *.js, which is actually executing uv_tty_reset_mode()
    b: 4865 PlatformInit();
    # Execute the inline function PlatformInit(), signal Volume processing function registration
    c: 4866 node::performance::performance_node_start = PERFORMANCE_NOW();
    Encapsulate the uv_hrtime function: src/node_perf_common.h:13:#define PERFORMANCE_NOW() uv_hrtime()
    Export definition :deps/uv/include/uv.h:1457:UV_EXTERN uint64_t uv_hrtime(void);
    Implementation: deps/uv/src/unix/core.c:111:uint64_t uv_hrtime(void)
    uv_hrtime calls uv__hrtime
    Definition: deps/uv/src/unix/internal.h:252:uint64_t uv__hrtime(uv_clocktype_t type);
    Implementation: deps/uv/src/unix/linux-core.c:442:uint64_t uv__hrtime( UV_CLOCKTYPE_T Type) {
    In short: Record the starting time point of the node execution*.js script. Similar, the starting time point of the V8:
    4903 node :: Performance_v8_start = Performance_now;
    # d: 4868 CHECK_GT(argc, 0);
    src/util.h:129:#define CHECK_GT(a, b) CHECK((a) > (b))
    e: 4871 argv = uv_setup_args(argc, argv);
    Definition: deps/uv/include/uv.h:1051:UV_EXTERN char** uv_setup_args(int argc, char** argv);
    Implementation:
    f: 4877 Init(&argc, const_cast(argv), &exec_argc, &exec_argv);
    4542 void Init(int* argc,
    4543 const char** argv,
    4544 int* exec_argc,
    4545 const char*** exec_argv) {
    4617 ProcessArgv(argc, argv, exec_argc, exec_argv);
    4502 ParseArgs(argc, argv, exec _argc, exec_argv, &v8_argc, &v8_argv, is_env);
    4015 Static Void Parseargs (Int* ARGC,
    Analysis parameter
    G: Openssl related configuration
    H: 4895 v8_platform.Initialize
    i: 4902 v8 :: initialize ();
    v8 initialization
    j: 4905 const int exit_code =
    4906 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
    k: Exit
        4908   v8_platform.StopTracingAgent ();
    4910 v8_initialized = false;
    4911 V8::Dispose();
    4919 v8_platform.Dispose();
    4921 delete[] exec_argv;
    4922 exec_argv = nullptr;
    4924 return exit_code;
    2. Analyze part j in 1
    a: 4814 inline int Start(uv_loop_t* event_loop,
    4815 int argc, const char* const* argv,
              4816                  int exec_argc, const char* const* exec_argv) {
          b:  4824   Isolate* const isolate = Isolate::New(params);
              4828   isolate->AddMessageListener(OnMessage);
              4829   isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
              4830   isolate->SetAutorunMicrotasks(false);
              4831   isolate->SetFatalErrorHandler(OnFatalError);
                new Isolate对象,并设置相关参数。
          c:  4843   int exit_code;
              4844   {
              4845     Locker locker(isolate);
              4846     Isolate::Scope isolate_scope(isolate);
              4847     HandleScope handle_scope(isolate);
              4848     IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field());
              4849     exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
              4850   }
                准备开始执行的参数,isolate对象。
          d:  4745 inline int Start(Isolate* isolate, IsolateData* isolate_data,
              4746                  int argc, const char* const* argv,
              4747                  int exec_argc, const char* const* exec_argv) {
          e:  环境准备
                4748   HandleScope handle_scope(isolate);
                4749   Local context = Context::New(isolate);
                4750   Context::Scope context_scope(context);
                4751   Environment env(isolate_data, context);
                4754   env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
                执行代码 src/env.cc:18:void Environment::Start(int argc,
                4771     LoadEnvironment(&env);
                加载env
          f:  在d中的函数里面进行eventloop,没有event的时候,就会退出node

    3.  分析核心部分
            4777   {
            4778     SealHandleScope seal(isolate);
            4779     bool more;
            4780     PERFORMANCE_MARK(&env, LOOP_START);
            4781     do {
            4782       uv_run(env.event_loop(), UV_RUN_DEFAULT);
            4783
            4784       v8_platform.DrainVMTasks();
            4785
            4786       more = uv_loop_alive(env.event_loop());
            4787       if (more)
            4788         continue;
            4789
            4790       EmitBeforeExit(&env);
            4791
            4792       // Emit `beforeExit` if the loop became alive either after emitting
                                                                                                                                                                                                                                                                                                       ‐ ‐‐‐‐‐
    4795 } while (more == true);
    4796 PERFORMANCE_MARK(&env, LOOP_EXIT); // If there is no event processing, exit.
    4797 }
    a: The core function uv_run for processing events
    Declaration: deps/uv/include/uv.h:281:UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
    Implementation: deps /uv/src/unix/core.c:348:int uv_run(uv_loop_t* loop, uv_run_mode mode) {
    b: Determine whether the loop is in the alive state: whether there is a handle, request-signal and the handle is not closed.
    343 int uv_loop_alive(const uv_loop_t* loop) {
    344 return uv__loop_alive(loop);
    345 }
    336 static int uv__loop_alive(const uv_loop_t* loop) {
    337 return uv__has_active_handles(loop ) ||
    338 uv__has_active_reqs(loop) ||
    339 loop->closing_handles != NULL;
    340 }
    c: uv__has_active_handles(loop ):
    deps/uv/src/ uv-common.h:145: #define uv__has_active_handles(loop)                                                                                                                                                                                                                                                                        ):
    129 #define uv__has_active_reqs(loop)                                                                       0)




The above is the detailed content of Node explains the process analysis of executing js. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn