diff --git a/README.md b/README.md index c4a54b6..e409173 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,14 @@ class V8Js public function setMemoryLimit($limit) {} + /** + * Set the average object size (in bytes) for this V8Js object. + * V8's "amount of external memory" is adjusted by this value for every exported object. V8 triggers a garbage collection once this totals to 192 MB. + * @param int $average_object_size + */ + public function setAverageObjectSize($average_object_size) + {} + /** * Returns uncaught pending exception or null if there is no pending exception. * @return V8JsScriptException|null diff --git a/tests/set_average_object_size_basic.phpt b/tests/set_average_object_size_basic.phpt new file mode 100644 index 0000000..8247ef1 --- /dev/null +++ b/tests/set_average_object_size_basic.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test V8::setAverageObjectSize() : Average object size can be set on V8Js object +--SKIPIF-- + +--FILE-- +setAverageObjectSize(32768); + +// there's no API to query the currently announced external memory allocation, +// hence not much we can do here... + +?> +===EOF=== +--EXPECT-- +===EOF=== diff --git a/v8js_class.cc b/v8js_class.cc index f10725f..65c4993 100644 --- a/v8js_class.cc +++ b/v8js_class.cc @@ -158,7 +158,7 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */ it != c->weak_objects.end(); ++it) { zval *value = it->first; zval_ptr_dtor(&value); - c->isolate->AdjustAmountOfExternalAllocatedMemory(-1024); + c->isolate->AdjustAmountOfExternalAllocatedMemory(-c->average_object_size); it->second.Reset(); } c->weak_objects.~map(); @@ -254,6 +254,8 @@ static zend_object_value v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */ new(&c->v8js_v8objects) std::list(); new(&c->script_objects) std::vector(); + c->average_object_size = 1024; + retval.handle = zend_objects_store_put(c, NULL, (zend_objects_free_object_storage_t) v8js_free_storage, NULL TSRMLS_CC); retval.handlers = &v8js_object_handlers; @@ -899,6 +901,22 @@ static PHP_METHOD(V8Js, setMemoryLimit) } /* }}} */ +/* {{{ proto void V8Js::setAverageObjectSize(average_object_size) + */ +static PHP_METHOD(V8Js, setAverageObjectSize) +{ + v8js_ctx *c; + long average_object_size = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &average_object_size) == FAILURE) { + return; + } + + c = (v8js_ctx *) zend_object_store_get_object(getThis() TSRMLS_CC); + c->average_object_size = average_object_size; +} +/* }}} */ + static void v8js_persistent_zval_ctor(zval **p) /* {{{ */ { zval *orig_ptr = *p; @@ -1178,6 +1196,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setmoduleloader, 0, 0, 1) ZEND_ARG_INFO(0, callable) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setaverageobjectsize, 0, 0, 1) + ZEND_ARG_INFO(0, average_object_size) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_registerextension, 0, 0, 2) ZEND_ARG_INFO(0, extension_name) ZEND_ARG_INFO(0, script) @@ -1217,6 +1239,7 @@ const zend_function_entry v8js_methods[] = { /* {{{ */ PHP_ME(V8Js, setModuleLoader, arginfo_v8js_setmoduleloader, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC) PHP_ME(V8Js, setMemoryLimit, arginfo_v8js_setmemorylimit, ZEND_ACC_PUBLIC) + PHP_ME(V8Js, setAverageObjectSize, arginfo_v8js_setaverageobjectsize, ZEND_ACC_PUBLIC) PHP_ME(V8Js, registerExtension, arginfo_v8js_registerextension, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(V8Js, getExtensions, arginfo_v8js_getextensions, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) diff --git a/v8js_class.h b/v8js_class.h index 0e91243..f4edeb5 100644 --- a/v8js_class.h +++ b/v8js_class.h @@ -47,6 +47,7 @@ struct v8js_ctx { bool time_limit_hit; long memory_limit; bool memory_limit_hit; + long average_object_size; v8js_tmpl_t global_template; v8js_tmpl_t array_tmpl; diff --git a/v8js_object_export.cc b/v8js_object_export.cc index 949888f..9562178 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -259,7 +259,7 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo& i // Just tell v8 that we're allocating some external memory // (for the moment we just always tell 1k instead of trying to find out actual values) - isolate->AdjustAmountOfExternalAllocatedMemory(1024); + isolate->AdjustAmountOfExternalAllocatedMemory(ctx->average_object_size); } /* }}} */ @@ -275,7 +275,7 @@ static void v8js_weak_object_callback(const v8::WeakCallbackDataweak_objects.at(value).Reset(); ctx->weak_objects.erase(value); - isolate->AdjustAmountOfExternalAllocatedMemory(-1024); + isolate->AdjustAmountOfExternalAllocatedMemory(-ctx->average_object_size); } static void v8js_weak_closure_callback(const v8::WeakCallbackData &data) {