Skip to content

Commit 8993f6e

Browse files
committed
Replace user-timing calls with event log
Events are written to an array buffer using a custom instruction format. For now, this is only meant to be used during page start up, before the profiler worker has a chance to start up. Once the worker is ready, call `stopLoggingProfilerEvents` to return the log up to that point, then send the array buffer to the worker. Then switch to the sampling based approach.
1 parent 72f6bca commit 8993f6e

9 files changed

Lines changed: 373 additions & 349 deletions

packages/scheduler/npm/umd/scheduler.development.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@
110110
);
111111
}
112112

113+
function unstable_stopLoggingProfilingEvents() {
114+
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_stopLoggingProfilingEvents.apply(
115+
this,
116+
arguments
117+
);
118+
}
119+
113120
return Object.freeze({
114121
unstable_now: unstable_now,
115122
unstable_scheduleCallback: unstable_scheduleCallback,
@@ -124,6 +131,7 @@
124131
unstable_pauseExecution: unstable_pauseExecution,
125132
unstable_getFirstCallbackNode: unstable_getFirstCallbackNode,
126133
unstable_forceFrameRate: unstable_forceFrameRate,
134+
unstable_stopLoggingProfilingEvents: unstable_stopLoggingProfilingEvents,
127135
get unstable_IdlePriority() {
128136
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
129137
.Scheduler.unstable_IdlePriority;

packages/scheduler/npm/umd/scheduler.production.min.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@
104104
);
105105
}
106106

107+
function unstable_stopLoggingProfilingEvents() {
108+
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_stopLoggingProfilingEvents.apply(
109+
this,
110+
arguments
111+
);
112+
}
113+
107114
return Object.freeze({
108115
unstable_now: unstable_now,
109116
unstable_scheduleCallback: unstable_scheduleCallback,
@@ -118,6 +125,7 @@
118125
unstable_pauseExecution: unstable_pauseExecution,
119126
unstable_getFirstCallbackNode: unstable_getFirstCallbackNode,
120127
unstable_forceFrameRate: unstable_forceFrameRate,
128+
unstable_stopLoggingProfilingEvents: unstable_stopLoggingProfilingEvents,
121129
get unstable_IdlePriority() {
122130
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
123131
.Scheduler.unstable_IdlePriority;

packages/scheduler/npm/umd/scheduler.profiling.min.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@
104104
);
105105
}
106106

107+
function unstable_stopLoggingProfilingEvents() {
108+
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_stopLoggingProfilingEvents.apply(
109+
this,
110+
arguments
111+
);
112+
}
113+
107114
return Object.freeze({
108115
unstable_now: unstable_now,
109116
unstable_scheduleCallback: unstable_scheduleCallback,
@@ -118,6 +125,7 @@
118125
unstable_pauseExecution: unstable_pauseExecution,
119126
unstable_getFirstCallbackNode: unstable_getFirstCallbackNode,
120127
unstable_forceFrameRate: unstable_forceFrameRate,
128+
unstable_stopLoggingProfilingEvents: unstable_stopLoggingProfilingEvents,
121129
get unstable_IdlePriority() {
122130
return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
123131
.Scheduler.unstable_IdlePriority;

packages/scheduler/src/Scheduler.js

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
import {
1212
enableSchedulerDebugging,
13-
enableSharedProfilingBuffer,
1413
enableProfiling,
1514
} from './SchedulerFeatureFlags';
1615
import {
@@ -43,6 +42,7 @@ import {
4342
markSchedulerSuspended,
4443
markSchedulerUnsuspended,
4544
markTaskStart,
45+
stopLoggingProfilerEvents,
4646
} from './SchedulerProfiling';
4747

4848
// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
@@ -78,38 +78,17 @@ var isPerformingWork = false;
7878
var isHostCallbackScheduled = false;
7979
var isHostTimeoutScheduled = false;
8080

81-
function requestHostCallbackWithProfiling(cb) {
81+
function requestHostCallbackWithProfiling(cb, time) {
8282
if (enableProfiling) {
83-
markSchedulerSuspended();
83+
markSchedulerSuspended(time);
8484
requestHostCallbackWithoutProfiling(cb);
8585
}
8686
}
8787

88-
// Expose a shared array buffer that contains profiling information.
89-
export const unstable_sharedProfilingBuffer =
90-
enableProfiling && enableSharedProfilingBuffer ? sharedProfilingBuffer : null;
91-
9288
const requestHostCallback = enableProfiling
9389
? requestHostCallbackWithProfiling
9490
: requestHostCallbackWithoutProfiling;
9591

96-
function flushTask(task, callback, currentTime) {
97-
currentPriorityLevel = task.priorityLevel;
98-
var didUserCallbackTimeout = task.expirationTime <= currentTime;
99-
markTaskRun(task);
100-
var continuationCallback = callback(didUserCallbackTimeout);
101-
if (typeof continuationCallback === 'function') {
102-
markTaskYield(task);
103-
return continuationCallback;
104-
} else {
105-
if (enableProfiling) {
106-
markTaskCompleted(task);
107-
task.isQueued = false;
108-
}
109-
return null;
110-
}
111-
}
112-
11392
function advanceTimers(currentTime) {
11493
// Check for tasks that are no longer delayed and add them to the queue.
11594
let timer = peek(timerQueue);
@@ -141,7 +120,7 @@ function handleTimeout(currentTime) {
141120
if (!isHostCallbackScheduled) {
142121
if (peek(taskQueue) !== null) {
143122
isHostCallbackScheduled = true;
144-
requestHostCallback(flushWork);
123+
requestHostCallback(flushWork, currentTime);
145124
} else {
146125
const firstTimer = peek(timerQueue);
147126
if (firstTimer !== null) {
@@ -153,7 +132,7 @@ function handleTimeout(currentTime) {
153132

154133
function flushWork(hasTimeRemaining, initialTime) {
155134
if (isHostCallbackScheduled) {
156-
markSchedulerUnsuspended();
135+
markSchedulerUnsuspended(initialTime);
157136
}
158137

159138
// We'll need a host callback the next time work is scheduled.
@@ -184,15 +163,24 @@ function flushWork(hasTimeRemaining, initialTime) {
184163
const callback = currentTask.callback;
185164
if (callback !== null) {
186165
currentTask.callback = null;
187-
const continuation = flushTask(currentTask, callback, currentTime);
188-
if (continuation !== null) {
189-
currentTask.callback = continuation;
166+
currentPriorityLevel = currentTask.priorityLevel;
167+
const didUserCallbackTimeout =
168+
currentTask.expirationTime <= currentTime;
169+
markTaskRun(currentTask, currentTime);
170+
const continuationCallback = callback(didUserCallbackTimeout);
171+
currentTime = getCurrentTime();
172+
if (typeof continuationCallback === 'function') {
173+
currentTask.callback = continuationCallback;
174+
markTaskYield(currentTask, currentTime);
190175
} else {
176+
if (enableProfiling) {
177+
markTaskCompleted(currentTask, currentTime);
178+
currentTask.isQueued = false;
179+
}
191180
if (currentTask === peek(taskQueue)) {
192181
pop(taskQueue);
193182
}
194183
}
195-
currentTime = getCurrentTime();
196184
advanceTimers(currentTime);
197185
} else {
198186
pop(taskQueue);
@@ -201,7 +189,7 @@ function flushWork(hasTimeRemaining, initialTime) {
201189
}
202190
// Return whether there's additional work
203191
if (currentTask !== null) {
204-
markSchedulerSuspended();
192+
markSchedulerSuspended(currentTime);
205193
isHostCallbackScheduled = true;
206194
return true;
207195
} else {
@@ -214,7 +202,8 @@ function flushWork(hasTimeRemaining, initialTime) {
214202
} catch (error) {
215203
if (currentTask !== null) {
216204
if (enableProfiling) {
217-
markTaskErrored(currentTask);
205+
const currentTime = getCurrentTime();
206+
markTaskErrored(currentTask, currentTime);
218207
currentTask.isQueued = false;
219208
}
220209
if (currentTask === peek(taskQueue)) {
@@ -312,7 +301,8 @@ function unstable_scheduleCallback(priorityLevel, callback, options) {
312301

313302
var startTime;
314303
var timeout;
315-
var label;
304+
// TODO: Expose the current label when profiling, somehow
305+
// var label;
316306
if (typeof options === 'object' && options !== null) {
317307
var delay = options.delay;
318308
if (typeof delay === 'number' && delay > 0) {
@@ -324,12 +314,12 @@ function unstable_scheduleCallback(priorityLevel, callback, options) {
324314
typeof options.timeout === 'number'
325315
? options.timeout
326316
: timeoutForPriorityLevel(priorityLevel);
327-
if (enableProfiling) {
328-
var _label = options.label;
329-
if (typeof _label === 'string') {
330-
label = _label;
331-
}
332-
}
317+
// if (enableProfiling) {
318+
// var _label = options.label;
319+
// if (typeof _label === 'string') {
320+
// label = _label;
321+
// }
322+
// }
333323
} else {
334324
timeout = timeoutForPriorityLevel(priorityLevel);
335325
startTime = currentTime;
@@ -348,9 +338,9 @@ function unstable_scheduleCallback(priorityLevel, callback, options) {
348338

349339
if (enableProfiling) {
350340
newTask.isQueued = false;
351-
if (typeof options === 'object' && options !== null) {
352-
newTask.label = label;
353-
}
341+
// if (typeof options === 'object' && options !== null) {
342+
// newTask.label = label;
343+
// }
354344
}
355345

356346
if (startTime > currentTime) {
@@ -372,14 +362,14 @@ function unstable_scheduleCallback(priorityLevel, callback, options) {
372362
newTask.sortIndex = expirationTime;
373363
push(taskQueue, newTask);
374364
if (enableProfiling) {
375-
markTaskStart(newTask);
365+
markTaskStart(newTask, currentTime);
376366
newTask.isQueued = true;
377367
}
378368
// Schedule a host callback, if needed. If we're already performing work,
379369
// wait until the next time we yield.
380370
if (!isHostCallbackScheduled && !isPerformingWork) {
381371
isHostCallbackScheduled = true;
382-
requestHostCallback(flushWork);
372+
requestHostCallback(flushWork, currentTime);
383373
}
384374
}
385375

@@ -394,7 +384,12 @@ function unstable_continueExecution() {
394384
isSchedulerPaused = false;
395385
if (!isHostCallbackScheduled && !isPerformingWork) {
396386
isHostCallbackScheduled = true;
397-
requestHostCallback(flushWork);
387+
if (enableProfiling) {
388+
const currentTime = getCurrentTime();
389+
requestHostCallbackWithProfiling(flushWork, currentTime);
390+
} else {
391+
requestHostCallback(flushWork);
392+
}
398393
}
399394
}
400395

@@ -404,14 +399,16 @@ function unstable_getFirstCallbackNode() {
404399

405400
function unstable_cancelCallback(task) {
406401
if (enableProfiling && task.isQueued) {
407-
markTaskCanceled(task);
402+
const currentTime = getCurrentTime();
403+
markTaskCanceled(task, currentTime);
408404
task.isQueued = false;
409405
}
410406
if (task !== null && task === peek(taskQueue)) {
411407
pop(taskQueue);
412408
if (enableProfiling && !isPerformingWork && taskQueue.length === 0) {
413409
// The queue is now empty.
414-
markSchedulerUnsuspended();
410+
const currentTime = getCurrentTime();
411+
markSchedulerUnsuspended(currentTime);
415412
isHostCallbackScheduled = false;
416413
cancelHostCallback();
417414
}
@@ -464,3 +461,13 @@ export {
464461
getCurrentTime as unstable_now,
465462
forceFrameRate as unstable_forceFrameRate,
466463
};
464+
465+
// Stops profiling and returns a log of profiling events
466+
export const unstable_stopLoggingProfilerEvents = enableProfiling
467+
? stopLoggingProfilerEvents
468+
: null;
469+
470+
// Expose a shared array buffer that contains profiling information.
471+
export const unstable_sharedProfilingBuffer = enableProfiling
472+
? sharedProfilingBuffer
473+
: null;

packages/scheduler/src/SchedulerFeatureFlags.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,3 @@ export const requestIdleCallbackBeforeFirstFrame = false;
1212
export const requestTimerEventBeforeFirstFrame = false;
1313
export const enableMessageLoopImplementation = false;
1414
export const enableProfiling = __PROFILE__;
15-
export const enableUserTimingAPI = false;
16-
export const enableSharedProfilingBuffer = false;

0 commit comments

Comments
 (0)