Enable idle GC in browser.
authorCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 11:41:23 +0000 (19:41 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 11:41:23 +0000 (19:41 +0800)
atom.gyp
browser/atom/atom.coffee
common/api/atom_api_idle_gc.cc [new file with mode: 0644]
common/api/atom_extensions.h

index 11621c5..2a1c6e1 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
@@ -43,6 +43,7 @@
       'browser/native_window_observer.h',
       'common/api/api_messages.cc',
       'common/api/api_messages.h',
+      'common/api/atom_api_idle_gc.cc',
       'common/api/atom_api_v8_util.cc',
       'common/api/atom_bindings.cc',
       'common/api/atom_bindings.h',
index eb20dbe..d6ad0bb 100644 (file)
@@ -1,6 +1,9 @@
 fs = require 'fs'
 path = require 'path'
 
+# Enable idle gc.
+process.atom_binding('idle_gc').start()
+
 # Provide default Content API implementations.
 atom = {}
 
diff --git a/common/api/atom_api_idle_gc.cc b/common/api/atom_api_idle_gc.cc
new file mode 100644 (file)
index 0000000..5756979
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (c) 2013 GitHub, Inc. All rights reserved.
+// Copyright (c) 2012, Ben Noordhuis <info@bnoordhuis.nl>.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "vendor/node/src/node.h"
+
+namespace {
+
+using v8::Arguments;
+using v8::FunctionTemplate;
+using v8::Handle;
+using v8::HandleScope;
+using v8::Object;
+using v8::String;
+using v8::Undefined;
+using v8::V8;
+using v8::Value;
+
+typedef enum { STOP, RUN, PAUSE } gc_state_t;
+
+int64_t interval;
+gc_state_t state;
+gc_state_t prev_state;
+uv_timer_t timer_handle;
+uv_check_t check_handle;
+uv_prepare_t prepare_handle;
+
+void Timer(uv_timer_t*, int) {
+  if (V8::IdleNotification()) state = PAUSE;
+}
+
+void Check(uv_check_t*, int) {
+  prev_state = state;
+}
+
+void Prepare(uv_prepare_t*, int) {
+  if (state == PAUSE && prev_state == PAUSE) state = RUN;
+  if (state == RUN) uv_timer_start(&timer_handle, Timer, interval, 0);
+}
+
+Handle<Value> Stop(const Arguments& args) {
+  state = STOP;
+  uv_timer_stop(&timer_handle);
+  uv_check_stop(&check_handle);
+  uv_prepare_stop(&prepare_handle);
+  return Undefined();
+}
+
+Handle<Value> Start(const Arguments& args) {
+  HandleScope scope;
+  Stop(args);
+
+  interval = args[0]->IsNumber() ? args[0]->IntegerValue() : 0;
+  if (interval <= 0) interval = 5000;  // Default to 5 seconds.
+
+  state = RUN;
+  uv_check_start(&check_handle, Check);
+  uv_prepare_start(&prepare_handle, Prepare);
+
+  return Undefined();
+}
+
+void Init(Handle<Object> obj) {
+  HandleScope scope;
+
+  uv_timer_init(uv_default_loop(), &timer_handle);
+  uv_check_init(uv_default_loop(), &check_handle);
+  uv_prepare_init(uv_default_loop(), &prepare_handle);
+  uv_unref(reinterpret_cast<uv_handle_t*>(&timer_handle));
+  uv_unref(reinterpret_cast<uv_handle_t*>(&check_handle));
+  uv_unref(reinterpret_cast<uv_handle_t*>(&prepare_handle));
+
+  obj->Set(String::New("stop"), FunctionTemplate::New(Stop)->GetFunction());
+  obj->Set(String::New("start"), FunctionTemplate::New(Start)->GetFunction());
+}
+
+NODE_MODULE(atom_common_idle_gc, Init)
+
+}  // namespace
index 879ccae..6e75609 100644 (file)
@@ -18,6 +18,7 @@ NODE_EXT_LIST_ITEM(atom_renderer_ipc)
 
 // Module names start with `atom_common_` can be used by both browser and
 // renderer processes.
+NODE_EXT_LIST_ITEM(atom_common_idle_gc)
 NODE_EXT_LIST_ITEM(atom_common_v8_util)
 
 NODE_EXT_LIST_END