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

Unified Diff: net/proxy/proxy_resolver_v8.cc

Issue 2817043: Reduce the copying of string data between C++ and javascript in proxy_resolver_v8.cc. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix comment typo 'converts' Created 10 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/proxy/proxy_resolver_v8.h ('k') | net/proxy/proxy_resolver_v8_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/proxy_resolver_v8.cc
===================================================================
--- net/proxy/proxy_resolver_v8.cc (revision 51195)
+++ net/proxy/proxy_resolver_v8.cc (working copy)
@@ -4,6 +4,7 @@
#include "net/proxy/proxy_resolver_v8.h"
+#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -72,6 +73,76 @@
// Pseudo-name for the PAC utility script.
const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js";
+// External string wrapper so V8 can access a string16.
+class V8ExternalString16 : public v8::String::ExternalStringResource {
+ public:
+ explicit V8ExternalString16(const string16& string) : string_(string) {}
+
+ virtual const uint16_t* data() const {
+ return reinterpret_cast<const uint16*>(string_.data());
+ }
+
+ virtual size_t length() const {
+ return string_.size();
+ }
+
+ private:
+ const string16 string_;
+ DISALLOW_COPY_AND_ASSIGN(V8ExternalString16);
+};
+
+// External string wrapper so V8 can access a string literal.
+class V8ExternalASCIILiteral : public v8::String::ExternalAsciiStringResource {
+ public:
+ // |ascii| must be a NULL-terminated C string, and must remain valid
+ // throughout this object's lifetime.
+ V8ExternalASCIILiteral(const char* ascii, size_t length)
+ : ascii_(ascii), length_(length) {
+ DCHECK(IsStringASCII(ascii));
+ }
+
+ virtual const char* data() const {
+ return ascii_;
+ }
+
+ virtual size_t length() const {
+ return length_;
+ }
+
+ private:
+ const char* ascii_;
+ size_t length_;
+ DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral);
+};
+
+// External string wrapper so V8 can access a std::string.
+class V8ExternalASCIIString : public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit V8ExternalASCIIString(const std::string& ascii)
+ : ascii_(ascii) {
+ DCHECK(IsStringASCII(ascii));
+ }
+
+ virtual const char* data() const {
+ return ascii_.data();
+ }
+
+ virtual size_t length() const {
+ return ascii_.size();
+ }
+
+ private:
+ const std::string ascii_;
+ DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIIString);
+};
+
+// When creating a v8::String from a C++ string we have two choices: create
+// a copy, or create a wrapper that shares the same underlying storage.
+// For small strings it is better to just make a copy, whereas for large
+// strings there are savings by sharing the storage. This number identifies
+// the cutoff length for when to start wrapping rather than creating copies.
+const size_t kMaxStringBytesForCopy = 256;
+
// Converts a V8 String to a UTF16 string16.
string16 V8StringToUTF16(v8::Handle<v8::String> s) {
int len = s->Length();
@@ -82,11 +153,32 @@
return result;
}
-// Converts a std::string (UTF8) to a V8 string.
-v8::Local<v8::String> UTF8StdStringToV8String(const std::string& s) {
- return v8::String::New(s.data(), s.size());
+// Converts an ASCII std::string to a V8 string.
+v8::Local<v8::String> ASCIIStringToV8String(const std::string& s) {
+ DCHECK(IsStringASCII(s));
+ if (s.size() <= kMaxStringBytesForCopy)
+ return v8::String::New(s.data(), s.size());
+ return v8::String::NewExternal(new V8ExternalASCIIString(s));
}
+// Converts a UTF16 string16 to a V8 string.
+v8::Local<v8::String> UTF16StringToV8String(const string16& s) {
+ if (s.size() * 2 <= kMaxStringBytesForCopy) {
+ return v8::String::New(
+ reinterpret_cast<const uint16_t*>(s.data()), s.size());
+ }
+ return v8::String::NewExternal(new V8ExternalString16(s));
+}
+
+// Converts an ASCII string literal to a V8 string.
+v8::Local<v8::String> ASCIILiteralToV8String(const char* ascii) {
+ DCHECK(IsStringASCII(ascii));
+ size_t length = strlen(ascii);
+ if (length <= kMaxStringBytesForCopy)
+ return v8::String::New(ascii, length);
+ return v8::String::NewExternal(new V8ExternalASCIILiteral(ascii, length));
+}
+
// Stringizes a V8 object by calling its toString() method. Returns true
// on success. This may fail if the toString() throws an exception.
bool V8ObjectToUTF16String(v8::Handle<v8::Value> object,
@@ -169,8 +261,8 @@
}
v8::Handle<v8::Value> argv[] = {
- UTF8StdStringToV8String(query_url.spec()),
- UTF8StdStringToV8String(query_url.host()),
+ ASCIIStringToV8String(query_url.spec()),
+ ASCIIStringToV8String(query_url.host()),
};
v8::TryCatch try_catch;
@@ -206,7 +298,7 @@
return OK;
}
- int InitV8(const std::string& pac_data_utf8) {
+ int InitV8(const string16& pac_script) {
v8::Locker locked;
v8::HandleScope scope;
@@ -216,28 +308,28 @@
// Attach the javascript bindings.
v8::Local<v8::FunctionTemplate> alert_template =
v8::FunctionTemplate::New(&AlertCallback, v8_this_);
- global_template->Set(v8::String::New("alert"), alert_template);
+ global_template->Set(ASCIILiteralToV8String("alert"), alert_template);
v8::Local<v8::FunctionTemplate> my_ip_address_template =
v8::FunctionTemplate::New(&MyIpAddressCallback, v8_this_);
- global_template->Set(v8::String::New("myIpAddress"),
+ global_template->Set(ASCIILiteralToV8String("myIpAddress"),
my_ip_address_template);
v8::Local<v8::FunctionTemplate> dns_resolve_template =
v8::FunctionTemplate::New(&DnsResolveCallback, v8_this_);
- global_template->Set(v8::String::New("dnsResolve"),
+ global_template->Set(ASCIILiteralToV8String("dnsResolve"),
dns_resolve_template);
// Microsoft's PAC extensions (incomplete):
v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
v8::FunctionTemplate::New(&DnsResolveExCallback, v8_this_);
- global_template->Set(v8::String::New("dnsResolveEx"),
+ global_template->Set(ASCIILiteralToV8String("dnsResolveEx"),
dns_resolve_ex_template);
v8::Local<v8::FunctionTemplate> my_ip_address_ex_template =
v8::FunctionTemplate::New(&MyIpAddressExCallback, v8_this_);
- global_template->Set(v8::String::New("myIpAddressEx"),
+ global_template->Set(ASCIILiteralToV8String("myIpAddressEx"),
my_ip_address_ex_template);
v8_context_ = v8::Context::New(NULL, global_template);
@@ -247,16 +339,18 @@
// Add the PAC utility functions to the environment.
// (This script should never fail, as it is a string literal!)
// Note that the two string literals are concatenated.
- int rv = RunScript(PROXY_RESOLVER_SCRIPT
- PROXY_RESOLVER_SCRIPT_EX,
- kPacUtilityResourceName);
+ int rv = RunScript(
+ ASCIILiteralToV8String(
+ PROXY_RESOLVER_SCRIPT
+ PROXY_RESOLVER_SCRIPT_EX),
+ kPacUtilityResourceName);
if (rv != OK) {
NOTREACHED();
return rv;
}
// Add the user's PAC code to the environment.
- rv = RunScript(pac_data_utf8, kPacResourceName);
+ rv = RunScript(UTF16StringToV8String(pac_script), kPacResourceName);
if (rv != OK)
return rv;
@@ -285,7 +379,8 @@
private:
bool GetFindProxyForURL(v8::Local<v8::Value>* function) {
- *function = v8_context_->Global()->Get(v8::String::New("FindProxyForURL"));
+ *function = v8_context_->Global()->Get(
+ ASCIILiteralToV8String("FindProxyForURL"));
return (*function)->IsFunction();
}
@@ -301,15 +396,15 @@
js_bindings_->OnError(line_number, error_message);
}
- // Compiles and runs |script_utf8| in the current V8 context.
+ // Compiles and runs |script| in the current V8 context.
// Returns OK on success, otherwise an error code.
- int RunScript(const std::string& script_utf8, const char* script_name) {
+ int RunScript(v8::Handle<v8::String> script, const char* script_name) {
v8::TryCatch try_catch;
// Compile the script.
- v8::Local<v8::String> text = UTF8StdStringToV8String(script_utf8);
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New(script_name));
- v8::Local<v8::Script> code = v8::Script::Compile(text, &origin);
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(ASCIILiteralToV8String(script_name));
+ v8::Local<v8::Script> code = v8::Script::Compile(script, &origin);
// Execute.
if (!code.IsEmpty())
@@ -370,8 +465,8 @@
}
if (!success)
- result = "127.0.0.1";
- return UTF8StdStringToV8String(result);
+ return ASCIILiteralToV8String("127.0.0.1");
+ return ASCIIStringToV8String(result);
}
// V8 callback for when "myIpAddressEx()" is invoked by the PAC script.
@@ -403,7 +498,7 @@
if (!success)
ip_address_list = std::string();
- return UTF8StdStringToV8String(ip_address_list);
+ return ASCIIStringToV8String(ip_address_list);
}
// V8 callback for when "dnsResolve()" is invoked by the PAC script.
@@ -435,7 +530,7 @@
NULL);
}
- return success ? UTF8StdStringToV8String(ip_address) : v8::Null();
+ return success ? ASCIIStringToV8String(ip_address) : v8::Null();
}
// V8 callback for when "dnsResolveEx()" is invoked by the PAC script.
@@ -471,7 +566,7 @@
if (!success)
ip_address_list = std::string();
- return UTF8StdStringToV8String(ip_address_list);
+ return ASCIIStringToV8String(ip_address_list);
}
static void LogEventToCurrentRequest(Context* context,
@@ -540,15 +635,15 @@
}
int ProxyResolverV8::SetPacScript(const GURL& /*url*/,
- const std::string& bytes_utf8,
+ const string16& pac_script,
CompletionCallback* /*callback*/) {
context_.reset();
- if (bytes_utf8.empty())
+ if (pac_script.empty())
return ERR_PAC_SCRIPT_FAILED;
// Try parsing the PAC script.
scoped_ptr<Context> context(new Context(js_bindings_.get()));
- int rv = context->InitV8(bytes_utf8);
+ int rv = context->InitV8(pac_script);
if (rv == OK)
context_.reset(context.release());
return rv;
« no previous file with comments | « net/proxy/proxy_resolver_v8.h ('k') | net/proxy/proxy_resolver_v8_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698