Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: chrome/renderer/extensions/schema_generated_bindings.cc

Issue 9616055: Make a process-wide cache for the v8::Value representation of extension APIs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, go back to old method Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/schema_generated_bindings.h" 5 #include "chrome/renderer/extensions/schema_generated_bindings.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 10
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 public: 74 public:
75 explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher) 75 explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher)
76 : ChromeV8Extension(extension_dispatcher) { 76 : ChromeV8Extension(extension_dispatcher) {
77 RouteStaticFunction("GetExtensionAPIDefinition", 77 RouteStaticFunction("GetExtensionAPIDefinition",
78 &GetExtensionAPIDefinition); 78 &GetExtensionAPIDefinition);
79 RouteStaticFunction("GetNextRequestId", &GetNextRequestId); 79 RouteStaticFunction("GetNextRequestId", &GetNextRequestId);
80 RouteStaticFunction("StartRequest", &StartRequest); 80 RouteStaticFunction("StartRequest", &StartRequest);
81 RouteStaticFunction("SetIconCommon", &SetIconCommon); 81 RouteStaticFunction("SetIconCommon", &SetIconCommon);
82 } 82 }
83 83
84 ~ExtensionImpl() {
85 // TODO(aa): It seems that v8 never deletes us, so this doesn't get called.
86 // Leaving this in here in case v8's implementation ever changes.
87 for (CachedSchemaMap::iterator it = schemas_.begin(); it != schemas_.end();
88 ++it) {
89 if (!it->second.IsEmpty())
90 it->second.Dispose();
91 }
92 }
93
94 private: 84 private:
95 static v8::Handle<v8::Value> GetV8SchemaForAPI(
96 ExtensionImpl* self,
97 v8::Handle<v8::Context> context,
98 const std::string& api_name) {
99 CachedSchemaMap::iterator maybe_api = self->schemas_.find(api_name);
100 if (maybe_api != self->schemas_.end())
101 return maybe_api->second;
102
103 scoped_ptr<V8ValueConverter> v8_value_converter(V8ValueConverter::create());
104 const base::DictionaryValue* schema =
105 ExtensionAPI::GetInstance()->GetSchema(api_name);
106 CHECK(schema) << api_name;
107
108 self->schemas_[api_name] =
109 v8::Persistent<v8::Object>::New(v8::Handle<v8::Object>::Cast(
110 v8_value_converter->ToV8Value(schema, context)));
111 CHECK(!self->schemas_[api_name].IsEmpty());
112
113 return self->schemas_[api_name];
114 }
115
116 static v8::Handle<v8::Value> GetExtensionAPIDefinition( 85 static v8::Handle<v8::Value> GetExtensionAPIDefinition(
117 const v8::Arguments& args) { 86 const v8::Arguments& args) {
118 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); 87 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
119 ExtensionDispatcher* dispatcher = self->extension_dispatcher_; 88 ExtensionDispatcher* dispatcher = self->extension_dispatcher_;
120 89
121 ChromeV8Context* v8_context = dispatcher->v8_context_set().GetCurrent(); 90 ChromeV8Context* v8_context = dispatcher->v8_context_set().GetCurrent();
122 CHECK(v8_context); 91 CHECK(v8_context);
123 92
124 // TODO(kalman): This is being calculated twice, first in 93 // TODO(kalman): This is being calculated twice, first in
125 // ExtensionDispatcher then again here. It might as well be a property of 94 // ExtensionDispatcher then again here. It might as well be a property of
126 // ChromeV8Context, however, this would require making ChromeV8Context take 95 // ChromeV8Context, however, this would require making ChromeV8Context take
127 // an Extension rather than an extension ID. In itself this is fine, 96 // an Extension rather than an extension ID. In itself this is fine,
128 // however it does not play correctly with the "IsTestExtensionId" checks. 97 // however it does not play correctly with the "IsTestExtensionId" checks.
129 // We need to remove that first. 98 // We need to remove that first.
130 scoped_ptr<std::set<std::string> > apis; 99 scoped_ptr<std::set<std::string> > apis;
131 100
132 const std::string& extension_id = v8_context->extension_id(); 101 const std::string& extension_id = v8_context->extension_id();
133 if (dispatcher->IsTestExtensionId(extension_id)) { 102 if (dispatcher->IsTestExtensionId(extension_id)) {
134 apis.reset(new std::set<std::string>()); 103 apis.reset(new std::set<std::string>());
135 // The minimal set of APIs that tests need. 104 // The minimal set of APIs that tests need.
136 apis->insert("extension"); 105 apis->insert("extension");
137 } else { 106 } else {
138 apis = ExtensionAPI::GetInstance()->GetAPIsForContext( 107 apis = ExtensionAPI::GetInstance()->GetAPIsForContext(
139 v8_context->context_type(), 108 v8_context->context_type(),
140 dispatcher->extensions()->GetByID(extension_id), 109 dispatcher->extensions()->GetByID(extension_id),
141 UserScriptSlave::GetDataSourceURLForFrame(v8_context->web_frame())); 110 UserScriptSlave::GetDataSourceURLForFrame(v8_context->web_frame()));
142 } 111 }
143 112
144 v8::Persistent<v8::Context> context(v8::Context::New()); 113 return dispatcher->v8_schema_registry()->GetSchemas(*apis);
145 v8::Context::Scope context_scope(context);
146 v8::Handle<v8::Array> api(v8::Array::New(apis->size()));
147 size_t api_index = 0;
148 for (std::set<std::string>::iterator i = apis->begin(); i != apis->end();
149 ++i) {
150 // TODO(kalman): this caching is actually useless now, because
151 // SchemaGeneratedBindings is per-context not per-process. We should
152 // (e.g.) hang a SchemaRegistry off ExtensionDispatcher (which maintains
153 // a *single* v8::Context rather than multiple ones as here).
154 api->Set(api_index, GetV8SchemaForAPI(self, context, *i));
155 ++api_index;
156 }
157
158 // The persistent extension_api_ will keep the context alive.
159 context.Dispose();
160
161 return api;
162 } 114 }
163 115
164 static v8::Handle<v8::Value> GetNextRequestId(const v8::Arguments& args) { 116 static v8::Handle<v8::Value> GetNextRequestId(const v8::Arguments& args) {
165 static int next_request_id = 0; 117 static int next_request_id = 0;
166 return v8::Integer::New(next_request_id++); 118 return v8::Integer::New(next_request_id++);
167 } 119 }
168 120
169 // Common code for starting an API request to the browser. |value_args| 121 // Common code for starting an API request to the browser. |value_args|
170 // contains the request's arguments. 122 // contains the request's arguments.
171 // Steals value_args contents for efficiency. 123 // Steals value_args contents for efficiency.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 if (details->Has(v8::String::New("tabId"))) { 266 if (details->Has(v8::String::New("tabId"))) {
315 dict->SetInteger("tabId", 267 dict->SetInteger("tabId",
316 details->Get(v8::String::New("tabId"))->Int32Value()); 268 details->Get(v8::String::New("tabId"))->Int32Value());
317 } 269 }
318 270
319 ListValue list_value; 271 ListValue list_value;
320 list_value.Append(dict); 272 list_value.Append(dict);
321 273
322 return StartRequestCommon(args, &list_value); 274 return StartRequestCommon(args, &list_value);
323 } 275 }
324
325 // Cached JS Array representation of each namespace in extension_api.json.
326 // We store this so that we don't have to parse it over and over again for
327 // every context that uses it.
328 typedef std::map<std::string, v8::Persistent<v8::Object> > CachedSchemaMap;
329 CachedSchemaMap schemas_;
330 }; 276 };
331 277
332 } // namespace 278 } // namespace
333 279
334 namespace extensions { 280 namespace extensions {
335 281
336 // static 282 // static
337 ChromeV8Extension* SchemaGeneratedBindings::Get( 283 ChromeV8Extension* SchemaGeneratedBindings::Get(
338 ExtensionDispatcher* extension_dispatcher) { 284 ExtensionDispatcher* extension_dispatcher) {
339 return new ExtensionImpl(extension_dispatcher); 285 return new ExtensionImpl(extension_dispatcher);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 const std::string& extension_id) { 341 const std::string& extension_id) {
396 for (PendingRequestMap::const_iterator it = g_pending_requests.Get().begin(); 342 for (PendingRequestMap::const_iterator it = g_pending_requests.Get().begin();
397 it != g_pending_requests.Get().end(); ++it) { 343 it != g_pending_requests.Get().end(); ++it) {
398 if (it->second->extension_id == extension_id) 344 if (it->second->extension_id == extension_id)
399 return true; 345 return true;
400 } 346 }
401 return false; 347 return false;
402 } 348 }
403 349
404 } // namespace 350 } // namespace
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/extension_dispatcher.h ('k') | chrome/renderer/extensions/v8_schema_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698