0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-22 17:31:53 +00:00

Merge pull request #222 from stesie/issue-217

Send LowMemoryNotification before imposing memory limit
This commit is contained in:
Stefan Siegl 2016-03-27 00:57:39 +01:00
commit 1f54fac62d
2 changed files with 56 additions and 17 deletions

View File

@ -40,27 +40,47 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /*
v8::Locker locker(isolate); v8::Locker locker(isolate);
v8::HeapStatistics hs; v8::HeapStatistics hs;
isolate->GetHeapStatistics(&hs); bool send_notification = false;
bool has_sent_notification = false;
V8JSG(timer_mutex).lock(); do {
if (send_notification) {
for (std::deque< v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin(); #if PHP_V8_API_VERSION >= 3028036
it != V8JSG(timer_stack).end(); it ++) { isolate->LowMemoryNotification();
v8js_timer_ctx *timer_ctx = *it; #else
v8js_ctx *c = timer_ctx->ctx; v8::V8::LowMemoryNotification();
#endif
if(c->isolate != isolate || timer_ctx->killed) { has_sent_notification = true;
continue;
} }
if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) { isolate->GetHeapStatistics(&hs);
timer_ctx->killed = true;
v8::V8::TerminateExecution(c->isolate);
c->memory_limit_hit = true;
}
}
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);
} }
/* }}} */ /* }}} */

View File

@ -204,6 +204,25 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
return; 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) {
#if PHP_V8_API_VERSION >= 3028036
isolate->LowMemoryNotification();
#else
v8::V8::LowMemoryNotification();
#endif
isolate->GetHeapStatistics(&hs);
if (hs.used_heap_size() > memory_limit) {
c->memory_limit_hit = true;
}
}
}
if (c->memory_limit_hit) { if (c->memory_limit_hit) {
// Execution has been terminated due to memory limit // Execution has been terminated due to memory limit
sprintf(exception_string, "Script memory limit of %lu bytes exceeded", memory_limit); sprintf(exception_string, "Script memory limit of %lu bytes exceeded", memory_limit);