From 4faab8842cab50b18f87b4a8381a476646b8e680 Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sat, 26 Mar 2016 00:37:53 +0100 Subject: [PATCH 1/4] Re-check memory limit, refs #217 --- v8js_v8.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/v8js_v8.cc b/v8js_v8.cc index 8091429..0b4b766 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -204,6 +204,16 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, return; } + if (memory_limit && !c->memory_limit_hit) { + // Re-check memory limit (very short executions might never be hit by timer thread) + v8::HeapStatistics hs; + isolate->GetHeapStatistics(&hs); + + if (hs.used_heap_size() > memory_limit) { + c->memory_limit_hit = true; + } + } + if (c->memory_limit_hit) { // Execution has been terminated due to memory limit sprintf(exception_string, "Script memory limit of %lu bytes exceeded", memory_limit); From b2eb89e49e0ca30cfe561633f361dae652cca55e Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sat, 26 Mar 2016 00:53:52 +0100 Subject: [PATCH 2/4] send LowMemoryNotification before imposing memory limit, fixes #217 --- v8js_timer.cc | 49 ++++++++++++++++++++++++++++++++----------------- v8js_v8.cc | 7 ++++++- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/v8js_timer.cc b/v8js_timer.cc index d556716..36c9f81 100644 --- a/v8js_timer.cc +++ b/v8js_timer.cc @@ -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(); - - 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(c->isolate != isolate || timer_ctx->killed) { - continue; + do { + if (send_notification) { + isolate->LowMemoryNotification(); + has_sent_notification = true; } - 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; - } - } + isolate->GetHeapStatistics(&hs); - V8JSG(timer_mutex).unlock(); + 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(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(); + } while(send_notification != has_sent_notification); } /* }}} */ diff --git a/v8js_v8.cc b/v8js_v8.cc index 0b4b766..1ab13ab 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -210,7 +210,12 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, isolate->GetHeapStatistics(&hs); if (hs.used_heap_size() > memory_limit) { - c->memory_limit_hit = true; + isolate->LowMemoryNotification(); + isolate->GetHeapStatistics(&hs); + + if (hs.used_heap_size() > memory_limit) { + c->memory_limit_hit = true; + } } } From 97ade17ef9aa038192004c6b7986eda1139fd98c Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sat, 26 Mar 2016 12:10:32 +0100 Subject: [PATCH 3/4] fix: initialize variables --- v8js_timer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/v8js_timer.cc b/v8js_timer.cc index 36c9f81..a3ae679 100644 --- a/v8js_timer.cc +++ b/v8js_timer.cc @@ -40,7 +40,8 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /* v8::Locker locker(isolate); v8::HeapStatistics hs; - bool send_notification, has_sent_notification; + bool send_notification = false; + bool has_sent_notification = false; do { if (send_notification) { From 3dca462e9d0279f0dedbb0fb8e20f761f64465e4 Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sat, 26 Mar 2016 14:11:20 +0100 Subject: [PATCH 4/4] Use V8::LowMemoryNotification on V8 < 3.28.36 --- v8js_timer.cc | 4 ++++ v8js_v8.cc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/v8js_timer.cc b/v8js_timer.cc index a3ae679..cb678f1 100644 --- a/v8js_timer.cc +++ b/v8js_timer.cc @@ -45,7 +45,11 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /* do { if (send_notification) { +#if PHP_V8_API_VERSION >= 3028036 isolate->LowMemoryNotification(); +#else + v8::V8::LowMemoryNotification(); +#endif has_sent_notification = true; } diff --git a/v8js_v8.cc b/v8js_v8.cc index 1ab13ab..8d53665 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -210,7 +210,11 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value, isolate->GetHeapStatistics(&hs); if (hs.used_heap_size() > memory_limit) { +#if PHP_V8_API_VERSION >= 3028036 isolate->LowMemoryNotification(); +#else + v8::V8::LowMemoryNotification(); +#endif isolate->GetHeapStatistics(&hs); if (hs.used_heap_size() > memory_limit) {