| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -670,8 +670,9 @@ Environment::Environment(IsolateData* isolate_data, | |||
| 670 | 670 | stream_base_state_(isolate_, | |
| 671 | 671 | StreamBase::kNumStreamBaseStateFields, | |
| 672 | 672 | MAYBE_FIELD_PTR(env_info, stream_base_state)), | |
| 673 | - time_origin_(PERFORMANCE_NOW()), | ||
| 674 | - time_origin_timestamp_(GetCurrentTimeInMicroseconds()), | ||
| 673 | + time_origin_(performance::performance_process_start), | ||
| 674 | + time_origin_timestamp_(performance::performance_process_start_timestamp), | ||
| 675 | + environment_start_(PERFORMANCE_NOW()), | ||
| 675 | 676 | flags_(flags), | |
| 676 | 677 | thread_id_(thread_id.id == static_cast<uint64_t>(-1) | |
| 677 | 678 | ? AllocateEnvironmentThreadId().id | |
@@ -777,7 +778,7 @@ void Environment::InitializeMainContext(Local<Context> context, | |||
| 777 | 778 | set_exiting(false); | |
| 778 | 779 | ||
| 779 | 780 | performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT, | |
| 780 | - time_origin_); | ||
| 781 | + environment_start_); | ||
| 781 | 782 | performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_NODE_START, | |
| 782 | 783 | per_process::node_start_time); | |
| 783 | 784 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -842,9 +842,11 @@ class Environment : public MemoryRetainer { | |||
| 842 | 842 | inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } | |
| 843 | 843 | inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } | |
| 844 | 844 | ||
| 845 | + // https://w3c.github.io/hr-time/#dfn-time-origin | ||
| 845 | 846 | inline uint64_t time_origin() { | |
| 846 | 847 | return time_origin_; | |
| 847 | 848 | } | |
| 849 | + // https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp | ||
| 848 | 850 | inline double time_origin_timestamp() { | |
| 849 | 851 | return time_origin_timestamp_; | |
| 850 | 852 | } | |
@@ -1044,10 +1046,17 @@ class Environment : public MemoryRetainer { | |||
| 1044 | 1046 | ||
| 1045 | 1047 | AliasedInt32Array stream_base_state_; | |
| 1046 | 1048 | ||
| 1047 | - // https://w3c.github.io/hr-time/#dfn-time-origin | ||
| 1048 | - uint64_t time_origin_; | ||
| 1049 | - // https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp | ||
| 1050 | - double time_origin_timestamp_; | ||
| 1049 | + // As PerformanceNodeTiming is exposed in worker_threads, the per_process | ||
| 1050 | + // time origin is exposed in the worker threads. This is an intentional | ||
| 1051 | + // diverge from the HTML spec of web workers. | ||
| 1052 | + // Process start time from the monotonic clock. This should not be used as an | ||
| 1053 | + // absolute time, but only as a time relative to another monotonic clock time. | ||
| 1054 | + const uint64_t time_origin_; | ||
| 1055 | + // Process start timestamp from the wall clock. This is an absolute time | ||
| 1056 | + // exposed as `performance.timeOrigin`. | ||
| 1057 | + const double time_origin_timestamp_; | ||
| 1058 | + // This is the time when the environment is created. | ||
| 1059 | + const uint64_t environment_start_; | ||
| 1051 | 1060 | std::unique_ptr<performance::PerformanceState> performance_state_; | |
| 1052 | 1061 | ||
| 1053 | 1062 | bool has_serialized_options_ = false; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,9 @@ using v8::Value; | |||
| 38 | 38 | // Nanoseconds in a millisecond, as a float. | |
| 39 | 39 | #define NANOS_PER_MILLIS 1e6 | |
| 40 | 40 | ||
| 41 | + const uint64_t performance_process_start = PERFORMANCE_NOW(); | ||
| 42 | + const double performance_process_start_timestamp = | ||
| 43 | + GetCurrentTimeInMicroseconds(); | ||
| 41 | 44 | uint64_t performance_v8_start; | |
| 42 | 45 | ||
| 43 | 46 | PerformanceState::PerformanceState(Isolate* isolate, | |
@@ -271,7 +274,7 @@ void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) { | |||
| 271 | 274 | void GetTimeOrigin(const FunctionCallbackInfo<Value>& args) { | |
| 272 | 275 | Environment* env = Environment::GetCurrent(args); | |
| 273 | 276 | args.GetReturnValue().Set( | |
| 274 | - Number::New(args.GetIsolate(), env->time_origin() / 1e6)); | ||
| 277 | + Number::New(args.GetIsolate(), env->time_origin() / NANOS_PER_MILLIS)); | ||
| 275 | 278 | } | |
| 276 | 279 | ||
| 277 | 280 | void GetTimeOriginTimeStamp(const FunctionCallbackInfo<Value>& args) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,8 @@ namespace performance { | |||
| 20 | 20 | ||
| 21 | 21 | // These occur before the environment is created. Cache them | |
| 22 | 22 | // here and add them to the milestones when the env is init'd. | |
| 23 | + extern const uint64_t performance_process_start; | ||
| 24 | + extern const double performance_process_start_timestamp; | ||
| 23 | 25 | extern uint64_t performance_v8_start; | |
| 24 | 26 | ||
| 25 | 27 | #define NODE_PERFORMANCE_MILESTONES(V) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,10 +9,10 @@ require('worker_threads').parentPort.postMessage(performance.timeOrigin); | |||
| 9 | 9 | `, { eval: true }); | |
| 10 | 10 | ||
| 11 | 11 | w.on('message', common.mustCall((timeOrigin) => { | |
| 12 | - // Worker is created after this main context, it's | ||
| 13 | - // `performance.timeOrigin` must be greater than this | ||
| 14 | - // main context's. | ||
| 15 | - assert.ok(timeOrigin > performance.timeOrigin); | ||
| 12 | + // PerformanceNodeTiming exposes process milestones so the | ||
| 13 | + // `performance.timeOrigin` in the `worker_threads.Worker` must be the start | ||
| 14 | + // time of the process. | ||
| 15 | + assert.strictEqual(timeOrigin, performance.timeOrigin); | ||
| 16 | 16 | })); | |
| 17 | 17 | ||
| 18 | 18 | w.on('exit', common.mustCall((code) => { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const { performance } = require('perf_hooks'); | ||
| 6 | + const { isMainThread } = require('worker_threads'); | ||
| 7 | + | ||
| 8 | + const { nodeTiming } = performance; | ||
| 9 | + assert.strictEqual(nodeTiming.name, 'node'); | ||
| 10 | + assert.strictEqual(nodeTiming.entryType, 'node'); | ||
| 11 | + | ||
| 12 | + assert.strictEqual(nodeTiming.startTime, 0); | ||
| 13 | + const now = performance.now(); | ||
| 14 | + assert.ok(nodeTiming.duration >= now); | ||
| 15 | + | ||
| 16 | + // Check that the nodeTiming milestone values are in the correct order and greater than 0. | ||
| 17 | + const keys = ['nodeStart', 'v8Start', 'environment', 'bootstrapComplete']; | ||
| 18 | + for (let idx = 0; idx < keys.length; idx++) { | ||
| 19 | + if (idx === 0) { | ||
| 20 | + assert.ok(nodeTiming[keys[idx]] >= 0); | ||
| 21 | + continue; | ||
| 22 | + } | ||
| 23 | + assert.ok(nodeTiming[keys[idx]] > nodeTiming[keys[idx - 1]], `expect nodeTiming['${keys[idx]}'] > nodeTiming['${keys[idx - 1]}']`); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + // loop milestones. | ||
| 27 | + assert.strictEqual(nodeTiming.idleTime, 0); | ||
| 28 | + if (isMainThread) { | ||
| 29 | + // Main thread does not start loop until the first tick is finished. | ||
| 30 | + assert.strictEqual(nodeTiming.loopStart, -1); | ||
| 31 | + } else { | ||
| 32 | + // Worker threads run the user script after loop is started. | ||
| 33 | + assert.ok(nodeTiming.loopStart >= nodeTiming.bootstrapComplete); | ||
| 34 | + } | ||
| 35 | + assert.strictEqual(nodeTiming.loopExit, -1); | ||
| 36 | + | ||
| 37 | + setTimeout(common.mustCall(() => { | ||
| 38 | + assert.ok(nodeTiming.idleTime >= 0); | ||
| 39 | + assert.ok(nodeTiming.idleTime + nodeTiming.loopExit <= nodeTiming.duration); | ||
| 40 | + assert.ok(nodeTiming.loopStart >= nodeTiming.bootstrapComplete); | ||
| 41 | + }, 1), 1); | ||
| 42 | + | ||
| 43 | + // Can not be wrapped in common.mustCall(). | ||
| 44 | + process.on('exit', () => { | ||
| 45 | + assert.ok(nodeTiming.loopExit > 0); | ||
| 46 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments