mirror of
https://github.com/phpv8/v8js.git
synced 2024-11-09 15:18:41 +00:00
Use isolate->RequestInterrupt to get heap size
This commit is contained in:
parent
0004626015
commit
2252169a98
@ -7,9 +7,9 @@ Test V8::setTimeLimit() : Time limit can be prolonged
|
||||
|
||||
$JS = <<< EOT
|
||||
var text = "abcdefghijklmnopqrstuvwyxz0123456789";
|
||||
/* Spend 20 * >10ms in the loop, i.e. at least 200ms; hence
|
||||
/* Spend 30 * >10ms in the loop, i.e. at least 300ms; hence
|
||||
* it should be killed if prolonging doesn't work. */
|
||||
for (var j = 0; j < 20; ++j) {
|
||||
for (var j = 0; j < 30; ++j) {
|
||||
PHP.prolongTimeLimit();
|
||||
var start = (new Date()).getTime();
|
||||
var encoded = encodeURI(text);
|
||||
@ -22,10 +22,10 @@ for (var j = 0; j < 20; ++j) {
|
||||
EOT;
|
||||
|
||||
$v8 = new V8Js();
|
||||
$v8->setTimeLimit(25);
|
||||
$v8->setTimeLimit(100);
|
||||
|
||||
$v8->prolongTimeLimit = function() use ($v8) {
|
||||
$v8->setTimeLimit(25);
|
||||
$v8->setTimeLimit(100);
|
||||
};
|
||||
|
||||
$v8->executeString($JS);
|
||||
|
76
v8js.cc
76
v8js.cc
@ -1081,40 +1081,74 @@ static void php_v8js_terminate_execution(php_v8js_ctx *c TSRMLS_DC)
|
||||
// This timer will be removed from stack by the parent thread.
|
||||
}
|
||||
|
||||
static void php_v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /* {{{ */
|
||||
#ifdef ZTS
|
||||
TSRMLS_D = (void ***) data;
|
||||
#endif
|
||||
|
||||
if (!V8JSG(timer_stack).size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HeapStatistics hs;
|
||||
isolate->GetHeapStatistics(&hs);
|
||||
|
||||
V8JSG(timer_mutex).lock();
|
||||
|
||||
for (std::deque< php_v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin();
|
||||
it != V8JSG(timer_stack).end(); it ++) {
|
||||
php_v8js_timer_ctx *timer_ctx = *it;
|
||||
php_v8js_ctx *c = timer_ctx->v8js_ctx;
|
||||
|
||||
if(c->isolate != isolate || timer_ctx->killed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
|
||||
timer_ctx->killed = true;
|
||||
php_v8js_terminate_execution(c TSRMLS_CC);
|
||||
c->memory_limit_hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
V8JSG(timer_mutex).unlock();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_v8js_timer_thread(TSRMLS_D)
|
||||
{
|
||||
while (!V8JSG(timer_stop)) {
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
|
||||
v8::HeapStatistics hs;
|
||||
|
||||
V8JSG(timer_mutex).lock();
|
||||
if (V8JSG(timer_stack).size()) {
|
||||
// Get the current timer context
|
||||
php_v8js_timer_ctx *timer_ctx = V8JSG(timer_stack).front();
|
||||
php_v8js_ctx *c = timer_ctx->v8js_ctx;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Get memory usage statistics for the isolate
|
||||
c->isolate->GetHeapStatistics(&hs);
|
||||
|
||||
if (timer_ctx->time_limit > 0 && now > timer_ctx->time_point &&
|
||||
!timer_ctx->killed) {
|
||||
timer_ctx->killed = true;
|
||||
php_v8js_terminate_execution(c TSRMLS_CC);
|
||||
|
||||
V8JSG(timer_mutex).lock();
|
||||
c->time_limit_hit = true;
|
||||
V8JSG(timer_mutex).unlock();
|
||||
if(timer_ctx->killed) {
|
||||
/* execution already terminated, nothing to check anymore,
|
||||
* but wait for caller to pop this timer context. */
|
||||
}
|
||||
|
||||
if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit &&
|
||||
!timer_ctx->killed) {
|
||||
else if(timer_ctx->time_limit > 0 && now > timer_ctx->time_point) {
|
||||
timer_ctx->killed = true;
|
||||
php_v8js_terminate_execution(c TSRMLS_CC);
|
||||
|
||||
V8JSG(timer_mutex).lock();
|
||||
c->memory_limit_hit = true;
|
||||
V8JSG(timer_mutex).unlock();
|
||||
c->time_limit_hit = true;
|
||||
}
|
||||
else if (timer_ctx->memory_limit > 0) {
|
||||
/* If a memory_limit is set, we need to interrupt execution
|
||||
* and check heap size within the callback. We must *not*
|
||||
* directly call GetHeapStatistics here, since we don't have
|
||||
* a v8::Locker on the isolate, but are expected to hold one,
|
||||
* and cannot aquire it as v8 is executing the script ... */
|
||||
void *data = NULL;
|
||||
#ifdef ZTS
|
||||
data = (void *) TSRMLS_C;
|
||||
#endif
|
||||
c->isolate->RequestInterrupt(php_v8js_timer_interrupt_handler, data);
|
||||
}
|
||||
}
|
||||
V8JSG(timer_mutex).unlock();
|
||||
|
||||
// Sleep for 10ms
|
||||
#ifdef _WIN32
|
||||
|
Loading…
Reference in New Issue
Block a user