|
@@ -40,27 +40,42 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /*
|
|
|
|
|
|
v8::Locker locker(isolate);
|
|
|
v8::HeapStatistics hs;
|
|
|
- isolate->GetHeapStatistics(&hs);
|
|
|
+ bool send_notification, has_sent_notification;
|
|
|
|
|
|
- V8JSG(timer_mutex).lock();
|
|
|
+ do {
|
|
|
+ if (send_notification) {
|
|
|
+ isolate->LowMemoryNotification();
|
|
|
+ has_sent_notification = true;
|
|
|
+ }
|
|
|
|
|
|
- for (std::deque< v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin();
|
|
|
- it != V8JSG(timer_stack).end(); it ++) {
|
|
|
- v8js_timer_ctx *timer_ctx = *it;
|
|
|
- v8js_ctx *c = timer_ctx->ctx;
|
|
|
+ isolate->GetHeapStatistics(&hs);
|
|
|
|
|
|
- if(c->isolate != isolate || timer_ctx->killed) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ V8JSG(timer_mutex).lock();
|
|
|
+
|
|
|
+ for (std::deque< v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin();
|
|
|
+ it != V8JSG(timer_stack).end(); it ++) {
|
|
|
+ v8js_timer_ctx *timer_ctx = *it;
|
|
|
+ v8js_ctx *c = timer_ctx->ctx;
|
|
|
|
|
|
- if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
|
|
|
- timer_ctx->killed = true;
|
|
|
- v8::V8::TerminateExecution(c->isolate);
|
|
|
- c->memory_limit_hit = true;
|
|
|
+ if(c->isolate != isolate || timer_ctx->killed) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
|
|
|
+ if (has_sent_notification) {
|
|
|
+ timer_ctx->killed = true;
|
|
|
+ v8::V8::TerminateExecution(c->isolate);
|
|
|
+ c->memory_limit_hit = true;
|
|
|
+ } else {
|
|
|
+ // force garbage collection, then check again
|
|
|
+ send_notification = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- V8JSG(timer_mutex).unlock();
|
|
|
+ V8JSG(timer_mutex).unlock();
|
|
|
+ } while(send_notification != has_sent_notification);
|
|
|
}
|
|
|
/* }}} */
|
|
|
|