@@ -20,7 +20,6 @@ using v8::Function; |
20 | 20 | using v8::FunctionCallbackInfo; |
21 | 21 | using v8::GCCallbackFlags; |
22 | 22 | using v8::GCType; |
23 | | -using v8::Int32; |
24 | 23 | using v8::Integer; |
25 | 24 | using v8::Isolate; |
26 | 25 | using v8::Local; |
@@ -43,6 +42,7 @@ const double performance_process_start_timestamp = |
43 | 42 | uint64_t performance_v8_start; |
44 | 43 |
|
45 | 44 | PerformanceState::PerformanceState(Isolate* isolate, |
| 45 | + uint64_t time_origin, |
46 | 46 | const PerformanceState::SerializeInfo* info) |
47 | 47 | : root(isolate, |
48 | 48 | sizeof(performance_state_internal), |
@@ -58,24 +58,51 @@ PerformanceState::PerformanceState(Isolate* isolate, |
58 | 58 | root, |
59 | 59 | MAYBE_FIELD_PTR(info, observers)) { |
60 | 60 | if (info == nullptr) { |
61 | | - for (size_t i = 0; i < milestones.Length(); i++) milestones[i] = -1.; |
| 61 | + // For performance states initialized from scratch, reset |
| 62 | + // all the milestones and initialize the time origin. |
| 63 | + // For deserialized performance states, we will do the |
| 64 | + // initialization in the deserialize callback. |
| 65 | + ResetMilestones(); |
| 66 | + Initialize(time_origin); |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +void PerformanceState::ResetMilestones() { |
| 71 | + size_t milestones_length = milestones.Length(); |
| 72 | + for (size_t i = 0; i < milestones_length; ++i) { |
| 73 | + milestones[i] = -1; |
62 | 74 | } |
63 | 75 | } |
64 | 76 |
|
65 | 77 | PerformanceState::SerializeInfo PerformanceState::Serialize( |
66 | 78 | v8::Local<v8::Context> context, v8::SnapshotCreator* creator) { |
| 79 | + // Reset all the milestones to improve determinism in the snapshot. |
| 80 | + // We'll re-initialize them after deserialization. |
| 81 | + ResetMilestones(); |
| 82 | + |
67 | 83 | SerializeInfo info{root.Serialize(context, creator), |
68 | 84 | milestones.Serialize(context, creator), |
69 | 85 | observers.Serialize(context, creator)}; |
70 | 86 | return info; |
71 | 87 | } |
72 | 88 |
|
73 | | -void PerformanceState::Deserialize(v8::Local<v8::Context> context) { |
| 89 | +void PerformanceState::Initialize(uint64_t time_origin) { |
| 90 | + // We are only reusing the milestone array to store the time origin, so do |
| 91 | + // not use the Mark() method. The time origin milestone is not exposed |
| 92 | + // to user land. |
| 93 | + this->milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN] = |
| 94 | + static_cast<double>(time_origin); |
| 95 | +} |
| 96 | + |
| 97 | +void PerformanceState::Deserialize(v8::Local<v8::Context> context, |
| 98 | + uint64_t time_origin) { |
| 99 | + // Resets the pointers. |
74 | 100 | root.Deserialize(context); |
75 | | - // This is just done to set up the pointers, we will actually reset |
76 | | - // all the milestones after deserialization. |
77 | 101 | milestones.Deserialize(context); |
78 | 102 | observers.Deserialize(context); |
| 103 | + |
| 104 | + // Re-initialize the time origin i.e. the process start time. |
| 105 | + Initialize(time_origin); |
79 | 106 | } |
80 | 107 |
|
81 | 108 | std::ostream& operator<<(std::ostream& o, |
@@ -96,18 +123,6 @@ void PerformanceState::Mark(PerformanceMilestone milestone, uint64_t ts) { |
96 | 123 | TRACE_EVENT_SCOPE_THREAD, ts / 1000); |
97 | 124 | } |
98 | 125 |
|
99 | | -// Allows specific Node.js lifecycle milestones to be set from JavaScript |
100 | | -void MarkMilestone(const FunctionCallbackInfo<Value>& args) { |
101 | | - Realm* realm = Realm::GetCurrent(args); |
102 | | - // TODO(legendecas): Remove this check once the sub-realms are supported. |
103 | | - CHECK_EQ(realm->kind(), Realm::Kind::kPrincipal); |
104 | | - Environment* env = realm->env(); |
105 | | - PerformanceMilestone milestone = |
106 | | - static_cast<PerformanceMilestone>(args[0].As<Int32>()->Value()); |
107 | | - if (milestone != NODE_PERFORMANCE_MILESTONE_INVALID) |
108 | | - env->performance_state()->Mark(milestone); |
109 | | -} |
110 | | - |
111 | 126 | void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) { |
112 | 127 | Realm* realm = Realm::GetCurrent(args); |
113 | 128 | // TODO(legendecas): Remove this check once the sub-realms are supported. |
@@ -275,12 +290,6 @@ void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) { |
275 | 290 | args.GetReturnValue().Set(histogram->object()); |
276 | 291 | } |
277 | 292 |
|
278 | | -void GetTimeOrigin(const FunctionCallbackInfo<Value>& args) { |
279 | | - Environment* env = Environment::GetCurrent(args); |
280 | | - args.GetReturnValue().Set( |
281 | | - Number::New(args.GetIsolate(), env->time_origin() / NANOS_PER_MILLIS)); |
282 | | -} |
283 | | - |
284 | 293 | void GetTimeOriginTimeStamp(const FunctionCallbackInfo<Value>& args) { |
285 | 294 | Environment* env = Environment::GetCurrent(args); |
286 | 295 | args.GetReturnValue().Set(Number::New( |
@@ -300,7 +309,6 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, |
300 | 309 |
|
301 | 310 | HistogramBase::Initialize(isolate_data, target); |
302 | 311 |
|
303 | | - SetMethod(isolate, target, "markMilestone", MarkMilestone); |
304 | 312 | SetMethod(isolate, target, "setupObservers", SetupPerformanceObservers); |
305 | 313 | SetMethod(isolate, |
306 | 314 | target, |
@@ -312,7 +320,6 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, |
312 | 320 | RemoveGarbageCollectionTracking); |
313 | 321 | SetMethod(isolate, target, "notify", Notify); |
314 | 322 | SetMethod(isolate, target, "loopIdleTime", LoopIdleTime); |
315 | | - SetMethod(isolate, target, "getTimeOrigin", GetTimeOrigin); |
316 | 323 | SetMethod(isolate, target, "getTimeOriginTimestamp", GetTimeOriginTimeStamp); |
317 | 324 | SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram); |
318 | 325 | SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete); |
@@ -373,13 +380,11 @@ void CreatePerContextProperties(Local<Object> target, |
373 | 380 | } |
374 | 381 |
|
375 | 382 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) { |
376 | | - registry->Register(MarkMilestone); |
377 | 383 | registry->Register(SetupPerformanceObservers); |
378 | 384 | registry->Register(InstallGarbageCollectionTracking); |
379 | 385 | registry->Register(RemoveGarbageCollectionTracking); |
380 | 386 | registry->Register(Notify); |
381 | 387 | registry->Register(LoopIdleTime); |
382 | | - registry->Register(GetTimeOrigin); |
383 | 388 | registry->Register(GetTimeOriginTimeStamp); |
384 | 389 | registry->Register(CreateELDHistogram); |
385 | 390 | registry->Register(MarkBootstrapComplete); |
|