Skip to content

Commit ac3bc2e

Browse files
committed
Simplify GC idle notification
In particular, don't leave the timeout running when the heap is fully compacted.
1 parent 4efe27b commit ac3bc2e

File tree

2 files changed

+28
-26
lines changed

2 files changed

+28
-26
lines changed

benchmark/http_simple.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ var puts = require("sys").puts;
44

55
var old = (process.argv[2] == 'old');
66

7+
puts('pid ' + process.pid);
8+
79
http = require(old ? "http_old" : 'http');
810
if (old) puts('old version');
911

src/node.cc

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,21 @@ static ev_tstamp last_active;
102102
static ev_timer gc_timer;
103103
static ev_check gc_check;
104104
static ev_idle gc_idle;
105-
static bool needs_gc;
106-
#define GC_INTERVAL 2.0
105+
#define GC_INTERVAL 1.0
106+
107+
static void gc_timer_start () {
108+
if (!ev_is_active(&gc_timer)) {
109+
ev_timer_start(EV_DEFAULT_UC_ &gc_timer);
110+
ev_unref(EV_DEFAULT_UC);
111+
}
112+
}
113+
114+
static void gc_timer_stop () {
115+
if (ev_is_active(&gc_timer)) {
116+
ev_ref(EV_DEFAULT_UC);
117+
ev_timer_stop(EV_DEFAULT_UC_ &gc_timer);
118+
}
119+
}
107120

108121

109122
static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
@@ -115,15 +128,10 @@ static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
115128
ev_tstamp idle_time = ev_now(EV_DEFAULT_UC) - last_active;
116129

117130
if (idle_time > GC_INTERVAL) {
118-
if (needs_gc) {
119-
needs_gc = false;
120-
if (!V8::IdleNotification()) {
121-
ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
122-
}
131+
if (!V8::IdleNotification()) {
132+
ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
123133
}
124-
// reset the timer
125-
gc_timer.repeat = GC_INTERVAL;
126-
ev_timer_again(EV_DEFAULT_UC_ watcher);
134+
gc_timer_stop();
127135
}
128136
}
129137

@@ -136,8 +144,8 @@ static void NotifyIdleness(EV_P_ ev_idle *watcher, int revents) {
136144

137145
if (V8::IdleNotification()) {
138146
ev_idle_stop(EV_A_ watcher);
147+
gc_timer_stop();
139148
}
140-
needs_gc = false;
141149
}
142150

143151

@@ -149,23 +157,18 @@ static void Activity(EV_P_ ev_check *watcher, int revents) {
149157

150158
// Don't count GC watchers as activity.
151159

152-
pending -= ev_is_pending(&gc_timer);
153-
pending -= ev_is_pending(&gc_idle);
154-
pending -= ev_is_pending(&next_tick_watcher);
155-
//if (ev_is_pending(&gc_check)) pending--; // This probably never happens?
160+
if (ev_is_pending(&gc_timer)) pending--;
161+
if (ev_is_pending(&gc_idle)) pending--;
162+
if (ev_is_pending(&gc_check)) pending--;
163+
164+
assert(pending >= 0);
156165

157166
//fprintf(stderr, "activity, pending: %d\n", pending);
158167

159168
if (pending) {
160169
last_active = ev_now(EV_DEFAULT_UC);
161170
ev_idle_stop(EV_DEFAULT_UC_ &gc_idle);
162-
163-
if (!needs_gc) {
164-
gc_timer.repeat = GC_INTERVAL;
165-
ev_timer_again(EV_DEFAULT_UC_ &gc_timer);
166-
}
167-
168-
needs_gc = true;
171+
gc_timer_start();
169172
}
170173
}
171174

@@ -1594,10 +1597,7 @@ int main(int argc, char *argv[]) {
15941597

15951598
ev_idle_init(&node::tick_spinner, node::Spin);
15961599

1597-
ev_init(&node::gc_timer, node::CheckIdleness);
1598-
node::gc_timer.repeat = GC_INTERVAL;
1599-
ev_timer_again(EV_DEFAULT_UC_ &node::gc_timer);
1600-
ev_unref(EV_DEFAULT_UC);
1600+
ev_timer_init(&node::gc_timer, node::CheckIdleness, 2*GC_INTERVAL, 2*GC_INTERVAL);
16011601

16021602
ev_check_init(&node::gc_check, node::Activity);
16031603
ev_check_start(EV_DEFAULT_UC_ &node::gc_check);

0 commit comments

Comments
 (0)