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:
commit
1f54fac62d
@ -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);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
19
v8js_v8.cc
19
v8js_v8.cc
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user