Skip to content

Commit 25069a6

Browse files
joyeecheungtargos
authored andcommitted
timers: use V8 fast API calls
PR-URL: #46579 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent c0b6413 commit 25069a6

File tree

12 files changed

+271
-59
lines changed

12 files changed

+271
-59
lines changed

lib/internal/timers.js

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,11 @@ const {
8181
Symbol,
8282
} = primordials;
8383

84+
const binding = internalBinding('timers');
8485
const {
85-
scheduleTimer,
86-
toggleTimerRef,
87-
getLibuvNow,
8886
immediateInfo,
8987
timeoutInfo,
90-
toggleImmediateRef,
91-
} = internalBinding('timers');
88+
} = binding;
9289

9390
const {
9491
getDefaultTriggerAsyncId,
@@ -306,13 +303,17 @@ class ImmediateList {
306303
const immediateQueue = new ImmediateList();
307304

308305
function incRefCount() {
309-
if (timeoutInfo[0]++ === 0)
310-
toggleTimerRef(true);
306+
if (timeoutInfo[0]++ === 0) {
307+
// We need to use the binding as the receiver for fast API calls.
308+
binding.toggleTimerRef(true);
309+
}
311310
}
312311

313312
function decRefCount() {
314-
if (--timeoutInfo[0] === 0)
315-
toggleTimerRef(false);
313+
if (--timeoutInfo[0] === 0) {
314+
// We need to use the binding as the receiver for fast API calls.
315+
binding.toggleTimerRef(false);
316+
}
316317
}
317318

318319
// Schedule or re-schedule a timer.
@@ -356,7 +357,8 @@ function insertGuarded(item, refed, start) {
356357
item[kRefed] = refed;
357358
}
358359

359-
function insert(item, msecs, start = getLibuvNow()) {
360+
// We need to use the binding as the receiver for fast API calls.
361+
function insert(item, msecs, start = binding.getLibuvNow()) {
360362
// Truncate so that accuracy of sub-millisecond timers is not assumed.
361363
msecs = MathTrunc(msecs);
362364
item._idleStart = start;
@@ -370,7 +372,8 @@ function insert(item, msecs, start = getLibuvNow()) {
370372
timerListQueue.insert(list);
371373

372374
if (nextExpiry > expiry) {
373-
scheduleTimer(msecs);
375+
// We need to use the binding as the receiver for fast API calls.
376+
binding.scheduleTimer(msecs);
374377
nextExpiry = expiry;
375378
}
376379
}
@@ -559,8 +562,10 @@ function getTimerCallbacks(runNextTicks) {
559562
emitBefore(asyncId, timer[trigger_async_id_symbol], timer);
560563

561564
let start;
562-
if (timer._repeat)
563-
start = getLibuvNow();
565+
if (timer._repeat) {
566+
// We need to use the binding as the receiver for fast API calls.
567+
start = binding.getLibuvNow();
568+
}
564569

565570
try {
566571
const args = timer._timerArgs;
@@ -627,17 +632,22 @@ class Immediate {
627632
ref() {
628633
if (this[kRefed] === false) {
629634
this[kRefed] = true;
630-
if (immediateInfo[kRefCount]++ === 0)
631-
toggleImmediateRef(true);
635+
636+
if (immediateInfo[kRefCount]++ === 0) {
637+
// We need to use the binding as the receiver for fast API calls.
638+
binding.toggleImmediateRef(true);
639+
}
632640
}
633641
return this;
634642
}
635643

636644
unref() {
637645
if (this[kRefed] === true) {
638646
this[kRefed] = false;
639-
if (--immediateInfo[kRefCount] === 0)
640-
toggleImmediateRef(false);
647+
if (--immediateInfo[kRefCount] === 0) {
648+
// We need to use the binding as the receiver for fast API calls.
649+
binding.toggleImmediateRef(false);
650+
}
641651
}
642652
return this;
643653
}

lib/timers.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ const {
2727
SymbolToPrimitive
2828
} = primordials;
2929

30+
const binding = internalBinding('timers');
3031
const {
3132
immediateInfo,
32-
toggleImmediateRef
33-
} = internalBinding('timers');
33+
} = binding;
3434
const L = require('internal/linkedlist');
3535
const {
3636
async_id_symbol,
@@ -323,8 +323,10 @@ function clearImmediate(immediate) {
323323
immediateInfo[kCount]--;
324324
immediate._destroyed = true;
325325

326-
if (immediate[kRefed] && --immediateInfo[kRefCount] === 0)
327-
toggleImmediateRef(false);
326+
if (immediate[kRefed] && --immediateInfo[kRefCount] === 0) {
327+
// We need to use the binding as the receiver for fast API calls.
328+
binding.toggleImmediateRef(false);
329+
}
328330
immediate[kRefed] = null;
329331

330332
if (destroyHooksExist() && immediate[async_id_symbol] !== undefined) {

node.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@
668668
'src/string_decoder-inl.h',
669669
'src/string_search.h',
670670
'src/tcp_wrap.h',
671+
'src/timers.h',
671672
'src/tracing/agent.h',
672673
'src/tracing/node_trace_buffer.h',
673674
'src/tracing/node_trace_writer.h',

src/base_object_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ namespace node {
1313
V(fs_binding_data, fs::BindingData) \
1414
V(v8_binding_data, v8_utils::BindingData) \
1515
V(blob_binding_data, BlobBindingData) \
16-
V(process_binding_data, process::BindingData)
16+
V(process_binding_data, process::BindingData) \
17+
V(timers_binding_data, timers::BindingData)
1718

1819
#define UNSERIALIZABLE_BINDING_TYPES(V) \
1920
V(http2_binding_data, http2::BindingData) \

src/env.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,12 +1273,16 @@ void Environment::ToggleImmediateRef(bool ref) {
12731273
}
12741274
}
12751275

1276-
1277-
Local<Value> Environment::GetNow() {
1276+
uint64_t Environment::GetNowUint64() {
12781277
uv_update_time(event_loop());
12791278
uint64_t now = uv_now(event_loop());
12801279
CHECK_GE(now, timer_base());
12811280
now -= timer_base();
1281+
return now;
1282+
}
1283+
1284+
Local<Value> Environment::GetNow() {
1285+
uint64_t now = GetNowUint64();
12821286
if (now <= 0xffffffff)
12831287
return Integer::NewFromUnsigned(isolate(), static_cast<uint32_t>(now));
12841288
else

src/env.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,8 @@ class Environment : public MemoryRetainer {
887887
static inline Environment* ForAsyncHooks(AsyncHooks* hooks);
888888

889889
v8::Local<v8::Value> GetNow();
890+
uint64_t GetNowUint64();
891+
890892
void ScheduleTimer(int64_t duration);
891893
void ToggleTimerRef(bool ref);
892894

src/node_external_reference.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ namespace node {
1313
using CFunctionCallbackWithOneByteString =
1414
uint32_t (*)(v8::Local<v8::Value>, const v8::FastOneByteString&);
1515
using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
16+
using CFunctionCallbackReturnDouble =
17+
double (*)(v8::Local<v8::Object> receiver);
18+
using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> receiver,
19+
int64_t);
20+
using CFunctionCallbackWithBool = void (*)(v8::Local<v8::Object> receiver,
21+
bool);
1622

1723
// This class manages the external references from the V8 heap
1824
// to the C++ addresses in Node.js.
@@ -23,6 +29,9 @@ class ExternalReferenceRegistry {
2329
#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \
2430
V(CFunctionCallback) \
2531
V(CFunctionCallbackWithOneByteString) \
32+
V(CFunctionCallbackReturnDouble) \
33+
V(CFunctionCallbackWithInt64) \
34+
V(CFunctionCallbackWithBool) \
2635
V(const v8::CFunctionInfo*) \
2736
V(v8::FunctionCallback) \
2837
V(v8::AccessorGetterCallback) \

src/node_snapshotable.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "node_util.h"
2121
#include "node_v8.h"
2222
#include "node_v8_platform-inl.h"
23+
#include "timers.h"
2324

2425
#if HAVE_INSPECTOR
2526
#include "inspector/worker_inspector.h" // ParentInspectorHandle

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy