Commit 48a18062 authored by mnaganov's avatar mnaganov Committed by Commit bot

Cache locally function templates returned by gin::CreateFunctionTemplate

V8 caches FunctionTemplates for a lifetime of a web page for its own internal
reasons, thus it is generally a good idea to cache the template returned by
gin::CreateFunctionTemplate function. Otherwise, repeated method invocations
from JS will create substantial memory leaks.

BUG=463487

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

Cr-Commit-Position: refs/heads/master@{#321330}
parent 62bd9e3d
......@@ -188,6 +188,7 @@ MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance)
plugin_message_queue_state_(WAITING_TO_START),
var_converter_(instance->pp_instance(),
V8VarConverter::kDisallowObjectVars),
template_cache_(instance->GetIsolate()),
weak_ptr_factory_(this) {
}
......@@ -217,13 +218,13 @@ v8::Local<v8::Value> MessageChannel::GetNamedProperty(
PepperTryCatchV8 try_catch(instance_, &var_converter_, isolate);
if (identifier == kPostMessage) {
return gin::CreateFunctionTemplate(isolate,
base::Bind(&MessageChannel::PostMessageToNative,
weak_ptr_factory_.GetWeakPtr()))->GetFunction();
return GetFunctionTemplate(isolate, identifier,
&MessageChannel::PostMessageToNative)
->GetFunction();
} else if (identifier == kPostMessageAndAwaitResponse) {
return gin::CreateFunctionTemplate(isolate,
base::Bind(&MessageChannel::PostBlockingMessageToNative,
weak_ptr_factory_.GetWeakPtr()))->GetFunction();
return GetFunctionTemplate(isolate, identifier,
&MessageChannel::PostBlockingMessageToNative)
->GetFunction();
}
std::map<std::string, ScopedPPVar>::const_iterator it =
......@@ -468,4 +469,17 @@ void MessageChannel::UnregisterSyncMessageStatusObserver() {
}
}
v8::Local<v8::FunctionTemplate> MessageChannel::GetFunctionTemplate(
v8::Isolate* isolate,
const std::string& name,
void (MessageChannel::*memberFuncPtr)(gin::Arguments* args)) {
v8::Local<v8::FunctionTemplate> function_template = template_cache_.Get(name);
if (!function_template.IsEmpty())
return function_template;
function_template = gin::CreateFunctionTemplate(
isolate, base::Bind(memberFuncPtr, weak_ptr_factory_.GetWeakPtr()));
template_cache_.Set(name, function_template);
return function_template;
}
} // namespace content
......@@ -18,6 +18,7 @@
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/shared_impl/resource.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
#include "v8/include/v8-util.h"
#include "v8/include/v8.h"
struct PP_Var;
......@@ -142,6 +143,11 @@ class MessageChannel :
void UnregisterSyncMessageStatusObserver();
v8::Local<v8::FunctionTemplate> GetFunctionTemplate(
v8::Isolate* isolate,
const std::string& name,
void (MessageChannel::*memberFuncPtr)(gin::Arguments* args));
PepperPluginInstanceImpl* instance_;
// We pass all non-postMessage calls through to the passthrough_object_.
......@@ -186,6 +192,8 @@ class MessageChannel :
// Observers for sync messages.
base::Closure unregister_observer_callback_;
v8::StdPersistentValueMap<std::string, v8::FunctionTemplate> template_cache_;
// This is used to ensure pending tasks will not fire after this object is
// destroyed.
base::WeakPtrFactory<MessageChannel> weak_ptr_factory_;
......
......@@ -50,9 +50,15 @@ class ScriptableObject : public gin::Wrappable<ScriptableObject>,
v8::Isolate* isolate,
const std::string& identifier) override {
if (identifier == kPostMessageName) {
return gin::CreateFunctionTemplate(isolate,
base::Bind(&MimeHandlerViewContainer::PostMessage,
container_, isolate))->GetFunction();
if (post_message_function_template_.IsEmpty()) {
post_message_function_template_.Reset(
isolate,
gin::CreateFunctionTemplate(
isolate, base::Bind(&MimeHandlerViewContainer::PostMessage,
container_, isolate)));
}
return v8::Local<v8::FunctionTemplate>::New(
isolate, post_message_function_template_)->GetFunction();
}
return v8::Local<v8::Value>();
}
......@@ -71,6 +77,7 @@ class ScriptableObject : public gin::Wrappable<ScriptableObject>,
}
base::WeakPtr<MimeHandlerViewContainer> container_;
v8::Persistent<v8::FunctionTemplate> post_message_function_template_;
};
// static
......
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