Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit 4903093

Browse files
committed
Add Isolate::MemoryPressureNotification() support, closes #57
1 parent 8c67a74 commit 4903093

File tree

5 files changed

+89
-22
lines changed

5 files changed

+89
-22
lines changed

Diff for: src/php_v8_isolate.cc

+42-18
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,21 @@ static PHP_METHOD(Isolate, isMemoryLimitHit) {
296296
RETVAL_BOOL(php_v8_isolate->limits.memory_limit_hit);
297297
}
298298

299+
static PHP_METHOD(Isolate, memoryPressureNotification) {
300+
zend_long level = static_cast<zend_long>(v8::MemoryPressureLevel::kNone);
301+
302+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &level) == FAILURE) {
303+
return;
304+
}
305+
306+
PHP_V8_CHECK_ISOLATE_MEMORY_PRESSURE_LEVEL(level, "Invalid memory pressure level given. See V8\\Isolate MEMORY_PRESSURE_LEVEL_* class constants for available levels.")
307+
308+
PHP_V8_ISOLATE_FETCH_WITH_CHECK(getThis(), php_v8_isolate);
309+
PHP_V8_ENTER_ISOLATE(php_v8_isolate);
310+
311+
isolate->MemoryPressureNotification(static_cast<v8::MemoryPressureLevel>(level));
312+
}
313+
299314
static PHP_METHOD(Isolate, getHeapStatistics) {
300315
if (zend_parse_parameters_none() == FAILURE) {
301316
return;
@@ -511,6 +526,10 @@ ZEND_END_ARG_INFO()
511526
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_isMemoryLimitHit, ZEND_RETURN_VALUE, 0, _IS_BOOL, 0)
512527
ZEND_END_ARG_INFO()
513528

529+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_VOID_INFO_EX(arginfo_memoryPressureNotification, 0)
530+
ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0)
531+
ZEND_END_ARG_INFO()
532+
514533
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_getHeapStatistics, ZEND_RETURN_VALUE, 0, V8\\HeapStatistics, 0)
515534
ZEND_END_ARG_INFO()
516535

@@ -555,24 +574,25 @@ ZEND_END_ARG_INFO()
555574

556575

557576
static const zend_function_entry php_v8_isolate_methods[] = {
558-
PHP_V8_ME(Isolate, __construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
559-
PHP_V8_ME(Isolate, setTimeLimit, ZEND_ACC_PUBLIC)
560-
PHP_V8_ME(Isolate, getTimeLimit, ZEND_ACC_PUBLIC)
561-
PHP_V8_ME(Isolate, isTimeLimitHit, ZEND_ACC_PUBLIC)
562-
PHP_V8_ME(Isolate, setMemoryLimit, ZEND_ACC_PUBLIC)
563-
PHP_V8_ME(Isolate, getMemoryLimit, ZEND_ACC_PUBLIC)
564-
PHP_V8_ME(Isolate, isMemoryLimitHit, ZEND_ACC_PUBLIC)
565-
PHP_V8_ME(Isolate, getHeapStatistics, ZEND_ACC_PUBLIC)
566-
PHP_V8_ME(Isolate, inContext, ZEND_ACC_PUBLIC)
567-
PHP_V8_ME(Isolate, getEnteredContext, ZEND_ACC_PUBLIC)
568-
PHP_V8_ME(Isolate, throwException, ZEND_ACC_PUBLIC)
569-
PHP_V8_ME(Isolate, idleNotificationDeadline, ZEND_ACC_PUBLIC)
570-
PHP_V8_ME(Isolate, lowMemoryNotification, ZEND_ACC_PUBLIC)
571-
PHP_V8_ME(Isolate, terminateExecution, ZEND_ACC_PUBLIC)
572-
PHP_V8_ME(Isolate, isExecutionTerminating, ZEND_ACC_PUBLIC)
573-
PHP_V8_ME(Isolate, cancelTerminateExecution, ZEND_ACC_PUBLIC)
574-
PHP_V8_ME(Isolate, isDead, ZEND_ACC_PUBLIC)
575-
PHP_V8_ME(Isolate, isInUse, ZEND_ACC_PUBLIC)
577+
PHP_V8_ME(Isolate, __construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
578+
PHP_V8_ME(Isolate, setTimeLimit, ZEND_ACC_PUBLIC)
579+
PHP_V8_ME(Isolate, getTimeLimit, ZEND_ACC_PUBLIC)
580+
PHP_V8_ME(Isolate, isTimeLimitHit, ZEND_ACC_PUBLIC)
581+
PHP_V8_ME(Isolate, setMemoryLimit, ZEND_ACC_PUBLIC)
582+
PHP_V8_ME(Isolate, getMemoryLimit, ZEND_ACC_PUBLIC)
583+
PHP_V8_ME(Isolate, isMemoryLimitHit, ZEND_ACC_PUBLIC)
584+
PHP_V8_ME(Isolate, memoryPressureNotification, ZEND_ACC_PUBLIC)
585+
PHP_V8_ME(Isolate, getHeapStatistics, ZEND_ACC_PUBLIC)
586+
PHP_V8_ME(Isolate, inContext, ZEND_ACC_PUBLIC)
587+
PHP_V8_ME(Isolate, getEnteredContext, ZEND_ACC_PUBLIC)
588+
PHP_V8_ME(Isolate, throwException, ZEND_ACC_PUBLIC)
589+
PHP_V8_ME(Isolate, idleNotificationDeadline, ZEND_ACC_PUBLIC)
590+
PHP_V8_ME(Isolate, lowMemoryNotification, ZEND_ACC_PUBLIC)
591+
PHP_V8_ME(Isolate, terminateExecution, ZEND_ACC_PUBLIC)
592+
PHP_V8_ME(Isolate, isExecutionTerminating, ZEND_ACC_PUBLIC)
593+
PHP_V8_ME(Isolate, cancelTerminateExecution, ZEND_ACC_PUBLIC)
594+
PHP_V8_ME(Isolate, isDead, ZEND_ACC_PUBLIC)
595+
PHP_V8_ME(Isolate, isInUse, ZEND_ACC_PUBLIC)
576596
PHP_V8_ME(Isolate, setCaptureStackTraceForUncaughtExceptions, ZEND_ACC_PUBLIC)
577597

578598
PHP_FE_END
@@ -586,6 +606,10 @@ PHP_MINIT_FUNCTION (php_v8_isolate) {
586606
this_ce = zend_register_internal_class(&ce);
587607
this_ce->create_object = php_v8_isolate_ctor;
588608

609+
zend_declare_class_constant_long(this_ce, ZEND_STRL("MEMORY_PRESSURE_LEVEL_NONE"), static_cast<zend_long>(v8::MemoryPressureLevel::kNone));
610+
zend_declare_class_constant_long(this_ce, ZEND_STRL("MEMORY_PRESSURE_LEVEL_MODERATE"), static_cast<zend_long>(v8::MemoryPressureLevel::kModerate));
611+
zend_declare_class_constant_long(this_ce, ZEND_STRL("MEMORY_PRESSURE_LEVEL_CRITICAL"), static_cast<zend_long>(v8::MemoryPressureLevel::kCritical));
612+
589613
memcpy(&php_v8_isolate_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
590614

591615
php_v8_isolate_object_handlers.offset = XtOffsetOf(php_v8_isolate_t, std);

Diff for: src/php_v8_isolate.h

+6
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ inline v8::Local<v8::Private> php_v8_isolate_get_key_local(php_v8_isolate_t *php
115115
return; \
116116
} \
117117

118+
#define PHP_V8_CHECK_ISOLATE_MEMORY_PRESSURE_LEVEL(level, message) \
119+
if (level < static_cast<zend_long>(v8::MemoryPressureLevel::kNone) \
120+
|| level > static_cast<zend_long>(v8::MemoryPressureLevel::kCritical)) { \
121+
PHP_V8_THROW_VALUE_EXCEPTION(message); \
122+
return; \
123+
}
118124

119125

120126
struct _php_v8_isolate_t {

Diff for: stubs/src/Isolate.php

+21-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
class Isolate
2323
{
24+
const MEMORY_PRESSURE_LEVEL_NONE = 0;
25+
const MEMORY_PRESSURE_LEVEL_MODERATE = 1;
26+
const MEMORY_PRESSURE_LEVEL_CRITICAL = 2;
27+
2428
public function __construct(StartupData $snapshot = null)
2529
{
2630
}
@@ -49,6 +53,20 @@ public function isTimeLimitHit(): bool
4953
{
5054
}
5155

56+
/**
57+
* Optional notification that the system is running low on memory.
58+
* V8 uses these notifications to guide heuristics.
59+
* It is allowed to call this function from another thread while
60+
* the isolate is executing long running JavaScript code.
61+
*
62+
* @param int $level
63+
*
64+
* @return void
65+
*/
66+
public function memoryPressureNotification(int $level)
67+
{
68+
}
69+
5270
/**
5371
* Get statistics about the heap memory usage.
5472
*
@@ -82,8 +100,8 @@ public function getEnteredContext(): Context
82100
* operation; the caller must return immediately and only after the exception
83101
* has been handled does it become legal to invoke JavaScript operations.
84102
*
85-
* @param Context $context
86-
* @param Value $value
103+
* @param Context $context
104+
* @param Value $value
87105
* @param Throwable|null $e Exception to associate with a given value.
88106
* Because how underlying object wiring done, wiring PHP to V8 exceptions
89107
* is possible only for V8 exception that are instances of ObjectValue.
@@ -195,7 +213,7 @@ public function isInUse(): bool
195213
* and report it to the message listeners. The option is off by default.
196214
*
197215
* @param bool $capture
198-
* @param int $frame_limit
216+
* @param int $frame_limit
199217
*/
200218
public function setCaptureStackTraceForUncaughtExceptions(bool $capture, int $frame_limit = 10)
201219
{

Diff for: tests/001-verify_extension_entities.phpt

+4
Original file line numberDiff line numberDiff line change
@@ -327,13 +327,17 @@ class V8\StartupData
327327
public static function createFromSource(string $source): V8\StartupData
328328

329329
class V8\Isolate
330+
const MEMORY_PRESSURE_LEVEL_NONE = 0
331+
const MEMORY_PRESSURE_LEVEL_MODERATE = 1
332+
const MEMORY_PRESSURE_LEVEL_CRITICAL = 2
330333
public function __construct(?V8\StartupData $snapshot)
331334
public function setTimeLimit(float $time_limit_in_seconds)
332335
public function getTimeLimit(): float
333336
public function isTimeLimitHit(): bool
334337
public function setMemoryLimit(int $memory_limit_in_bytes)
335338
public function getMemoryLimit(): int
336339
public function isMemoryLimitHit(): bool
340+
public function memoryPressureNotification(int $level)
337341
public function getHeapStatistics(): V8\HeapStatistics
338342
public function inContext(): bool
339343
public function getEnteredContext(): V8\Context

Diff for: tests/Isolate.phpt

+16-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@ $helper->header('Object representation');
1818
$helper->dump($isolate);
1919
$helper->line();
2020

21+
$helper->header('Class constants');
22+
$helper->dump_object_constants($isolate);
23+
$helper->line();
24+
2125
$helper->method_export($isolate, 'getHeapStatistics');
2226

27+
$isolate->lowMemoryNotification();
28+
$isolate->memoryPressureNotification(\V8\Isolate::MEMORY_PRESSURE_LEVEL_NONE);
29+
$isolate->memoryPressureNotification(\V8\Isolate::MEMORY_PRESSURE_LEVEL_MODERATE);
30+
$isolate->memoryPressureNotification(\V8\Isolate::MEMORY_PRESSURE_LEVEL_CRITICAL);
31+
2332
$isolate = null;
2433

2534
// EXPECTF: ---/float\(.+\)/
@@ -31,8 +40,14 @@ Object representation:
3140
object(V8\Isolate)#2 (0) {
3241
}
3342

43+
Class constants:
44+
----------------
45+
V8\Isolate::MEMORY_PRESSURE_LEVEL_NONE = 0
46+
V8\Isolate::MEMORY_PRESSURE_LEVEL_MODERATE = 1
47+
V8\Isolate::MEMORY_PRESSURE_LEVEL_CRITICAL = 2
48+
3449
V8\Isolate->getHeapStatistics():
35-
object(V8\HeapStatistics)#26 (9) {
50+
object(V8\HeapStatistics)#27 (9) {
3651
["total_heap_size":"V8\HeapStatistics":private]=>
3752
float(%f)
3853
["total_heap_size_executable":"V8\HeapStatistics":private]=>

0 commit comments

Comments
 (0)