Commit 8f8de9cf authored by mnaganov's avatar mnaganov Committed by Commit bot

[Android] Cache function templates in GinJavaBridgeObject to avoid memory leak

V8 caches all function templates internally for the lifetime of a web page in an
unbounded cache. Thus, creating a new function template for each call to a
method of injected object caused JS heap memory to grow linearly.

This is similar to a fix for Pepper Plugin objects (https://codereview.chromium.org/785213002/)

BUG=462664

Review URL: https://codereview.chromium.org/969353004

Cr-Commit-Position: refs/heads/master@{#318890}
parent 098ba6f5
......@@ -66,7 +66,8 @@ GinJavaBridgeObject::GinJavaBridgeObject(
: gin::NamedPropertyInterceptor(isolate, this),
dispatcher_(dispatcher),
object_id_(object_id),
converter_(new GinJavaBridgeValueConverter()) {
converter_(new GinJavaBridgeValueConverter()),
template_cache_(isolate) {
}
GinJavaBridgeObject::~GinJavaBridgeObject() {
......@@ -91,15 +92,10 @@ v8::Local<v8::Value> GinJavaBridgeObject::GetNamedProperty(
}
known_methods_[property] = dispatcher_->HasJavaMethod(object_id_, property);
}
if (known_methods_[property]) {
return gin::CreateFunctionTemplate(
isolate,
base::Bind(&GinJavaBridgeObject::InvokeMethod,
base::Unretained(this),
property))->GetFunction();
} else {
if (known_methods_[property])
return GetFunctionTemplate(isolate, property)->GetFunction();
else
return v8::Local<v8::Value>();
}
}
std::vector<std::string> GinJavaBridgeObject::EnumerateNamedProperties(
......@@ -110,6 +106,19 @@ std::vector<std::string> GinJavaBridgeObject::EnumerateNamedProperties(
return std::vector<std::string> (method_names.begin(), method_names.end());
}
v8::Local<v8::FunctionTemplate> GinJavaBridgeObject::GetFunctionTemplate(
v8::Isolate* isolate,
const std::string& name) {
v8::Local<v8::FunctionTemplate> function_template = template_cache_.Get(name);
if (!function_template.IsEmpty())
return function_template;
function_template = gin::CreateFunctionTemplate(
isolate, base::Bind(&GinJavaBridgeObject::InvokeMethod,
base::Unretained(this), name));
template_cache_.Set(name, function_template);
return function_template;
}
v8::Handle<v8::Value> GinJavaBridgeObject::InvokeMethod(
const std::string& name,
gin::Arguments* args) {
......
......@@ -14,6 +14,7 @@
#include "gin/interceptor.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "v8/include/v8-util.h"
namespace blink {
class WebFrame;
......@@ -55,6 +56,8 @@ class GinJavaBridgeObject : public gin::Wrappable<GinJavaBridgeObject>,
GinJavaBridgeDispatcher::ObjectID object_id);
~GinJavaBridgeObject() override;
v8::Local<v8::FunctionTemplate> GetFunctionTemplate(v8::Isolate* isolate,
const std::string& name);
v8::Handle<v8::Value> InvokeMethod(const std::string& name,
gin::Arguments* args);
......@@ -62,6 +65,7 @@ class GinJavaBridgeObject : public gin::Wrappable<GinJavaBridgeObject>,
GinJavaBridgeDispatcher::ObjectID object_id_;
scoped_ptr<GinJavaBridgeValueConverter> converter_;
std::map<std::string, bool> known_methods_;
v8::StdPersistentValueMap<std::string, v8::FunctionTemplate> template_cache_;
DISALLOW_COPY_AND_ASSIGN(GinJavaBridgeObject);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment