Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
node: add inTick and lastThrew to infoBox
Browse files Browse the repository at this point in the history
To prevent all unnecessary calls to JS from MakeCallback, the remaining
two immediate return variables inTick and lastThrew have been added to
infoBox. Now MakeCallback should never need to call into JS unless it
absolutely has to.

Also removed Tock. Performance tests showed it was at least as fast or
faster than using a normal object, and this is more readable.
  • Loading branch information
trevnorris committed Jul 31, 2013
1 parent 2cd7adc commit 6a5a7b0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 23 deletions.
17 changes: 16 additions & 1 deletion src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ static Cached<String> immediate_callback_sym;
static struct {
uint32_t length;
uint32_t index;
uint32_t in_tick;
uint32_t last_threw;
} tick_infobox;

#ifdef OPENSSL_NPN_NEGOTIATED
Expand Down Expand Up @@ -969,6 +971,15 @@ MakeDomainCallback(const Handle<Object> object,
}
}

if (tick_infobox.last_threw == 1) {
tick_infobox.last_threw = 0;
return ret;
}

if (tick_infobox.in_tick == 1) {
return ret;
}

if (tick_infobox.length == 0) {
tick_infobox.index = 0;
return ret;
Expand Down Expand Up @@ -1017,6 +1028,10 @@ MakeCallback(const Handle<Object> object,
return Undefined(node_isolate);
}

if (tick_infobox.in_tick == 1) {
return ret;
}

if (tick_infobox.length == 0) {
tick_infobox.index = 0;
return ret;
Expand Down Expand Up @@ -2383,7 +2398,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
Local<Object> info_box = Object::New();
info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
kExternalUnsignedIntArray,
2);
4);
process->Set(String::NewSymbol("_tickInfoBox"), info_box);

// pre-set _events object for faster emit checks
Expand Down
38 changes: 16 additions & 22 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,31 +315,25 @@
};

startup.processNextTick = function() {
var lastThrew = false;
var nextTickQueue = [];
var needSpinner = true;
var inTick = false;

// this infobox thing is used so that the C++ code in src/node.cc
// this infoBox thing is used so that the C++ code in src/node.cc
// can have easy accesss to our nextTick state, and avoid unnecessary
// calls into process._tickCallback.
// order is [length, index]
// order is [length, index, inTick, lastThrew]
// Never write code like this without very good reason!
var infoBox = process._tickInfoBox;
var length = 0;
var index = 1;
var inTick = 2;
var lastThrew = 3;

process.nextTick = nextTick;
// needs to be accessible from cc land
process._nextDomainTick = _nextDomainTick;
process._tickCallback = _tickCallback;
process._tickDomainCallback = _tickDomainCallback;

function Tock(cb, domain) {
this.callback = cb;
this.domain = domain;
}

function tickDone() {
if (infoBox[length] !== 0) {
if (infoBox[length] <= infoBox[index]) {
Expand All @@ -350,7 +344,7 @@
infoBox[length] = nextTickQueue.length;
}
}
inTick = false;
infoBox[inTick] = 0;
infoBox[index] = 0;
}

Expand All @@ -359,12 +353,12 @@
function _tickCallback() {
var callback, nextTickLength, threw;

if (inTick) return;
if (infoBox[inTick] === 1) return;
if (infoBox[length] === 0) {
infoBox[index] = 0;
return;
}
inTick = true;
infoBox[inTick] = 1;

while (infoBox[index] < infoBox[length]) {
callback = nextTickQueue[infoBox[index]++].callback;
Expand All @@ -383,17 +377,17 @@
function _tickDomainCallback() {
var nextTickLength, tock, callback;

if (lastThrew) {
lastThrew = false;
if (infoBox[lastThrew] === 1) {
infoBox[lastThrew] = 0;
return;
}

if (inTick) return;
if (infoBox[inTick] === 1) return;
if (infoBox[length] === 0) {
infoBox[index] = 0;
return;
}
inTick = true;
infoBox[inTick] = 1;

while (infoBox[index] < infoBox[length]) {
tock = nextTickQueue[infoBox[index]++];
Expand All @@ -402,12 +396,12 @@
if (tock.domain._disposed) continue;
tock.domain.enter();
}
lastThrew = true;
infoBox[lastThrew] = 1;
try {
callback();
lastThrew = false;
infoBox[lastThrew] = 0;
} finally {
if (lastThrew) tickDone();
if (infoBox[lastThrew] === 1) tickDone();
}
if (tock.domain)
tock.domain.exit();
Expand All @@ -421,7 +415,7 @@
if (process._exiting)
return;

nextTickQueue.push(new Tock(callback, null));
nextTickQueue.push({ callback: callback, domain: null });
infoBox[length]++;
}

Expand All @@ -430,7 +424,7 @@
if (process._exiting)
return;

nextTickQueue.push(new Tock(callback, process.domain));
nextTickQueue.push({ callback: callback, domain: process.domain });
infoBox[length]++;
}
};
Expand Down

0 comments on commit 6a5a7b0

Please sign in to comment.