diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-27 19:39:52 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-27 19:39:52 +0000 |
commit | fd2ebe630a17c8bc0af7ec427601bf6daa8d86da (patch) | |
tree | 5765ce3df8717b3735ae5ead6a9f010a44c622db /base | |
parent | d918afeb7f8cf772084a2b0ef6e9f72203997297 (diff) | |
download | chromium_src-fd2ebe630a17c8bc0af7ec427601bf6daa8d86da.zip chromium_src-fd2ebe630a17c8bc0af7ec427601bf6daa8d86da.tar.gz chromium_src-fd2ebe630a17c8bc0af7ec427601bf6daa8d86da.tar.bz2 |
Implement the JSONParser's hidden root optimization without relying on std::string internals.
BUG=126107
TEST=Unit tests on Windows and Android.
Review URL: https://chromiumcodereview.appspot.com/11004002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159095 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/json/json_parser.cc | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc index 00a6a63..02295de 100644 --- a/base/json/json_parser.cc +++ b/base/json/json_parser.cc @@ -28,14 +28,13 @@ const int32 kExtendedASCIIStart = 0x80; // This and the class below are used to own the JSON input string for when // string tokens are stored as StringPiece instead of std::string. This // optimization avoids about 2/3rds of string memory copies. The constructor -// takes the input string and swaps its data into the new instance. The real -// root value is also Swap()ed into the new instance. +// takes ownership of the input string. The real root value is Swap()ed into +// the new instance. class DictionaryHiddenRootValue : public base::DictionaryValue { public: - DictionaryHiddenRootValue(std::string* json, Value* root) { + DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { DCHECK(root->IsType(Value::TYPE_DICTIONARY)); DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); - json->swap(json_); } virtual void Swap(DictionaryValue* other) OVERRIDE { @@ -49,7 +48,7 @@ class DictionaryHiddenRootValue : public base::DictionaryValue { // Then erase the contents of the current dictionary and swap in the // new contents, originally from |other|. Clear(); - json_.clear(); + json_.reset(); DictionaryValue::Swap(copy.get()); } @@ -77,17 +76,16 @@ class DictionaryHiddenRootValue : public base::DictionaryValue { } private: - std::string json_; + scoped_ptr<std::string> json_; DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); }; class ListHiddenRootValue : public base::ListValue { public: - ListHiddenRootValue(std::string* json, Value* root) { + ListHiddenRootValue(std::string* json, Value* root) : json_(json) { DCHECK(root->IsType(Value::TYPE_LIST)); ListValue::Swap(static_cast<ListValue*>(root)); - json->swap(json_); } virtual void Swap(ListValue* other) OVERRIDE { @@ -101,7 +99,7 @@ class ListHiddenRootValue : public base::ListValue { // Then erase the contents of the current list and swap in the new contents, // originally from |other|. Clear(); - json_.clear(); + json_.reset(); ListValue::Swap(copy.get()); } @@ -125,7 +123,7 @@ class ListHiddenRootValue : public base::ListValue { } private: - std::string json_; + scoped_ptr<std::string> json_; DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); }; @@ -206,22 +204,13 @@ JSONParser::~JSONParser() { } Value* JSONParser::Parse(const StringPiece& input) { - // TODO(rsesek): Windows has problems with StringPiece/hidden roots. Fix - // <http://crbug.com/126107> when my Windows box arrives. - // For Android, swapping string doesn't mean swapping internal pointers - // but swapping contents. Since it can't provide the performance gain, - // set the below flag to disable the optimization and make it work. -#if defined(OS_WIN) || defined(OS_ANDROID) - options_ |= JSON_DETACHABLE_CHILDREN; -#endif - - std::string input_copy; + scoped_ptr<std::string> input_copy; // If the children of a JSON root can be detached, then hidden roots cannot // be used, so do not bother copying the input because StringPiece will not // be used anywhere. if (!(options_ & JSON_DETACHABLE_CHILDREN)) { - input_copy = input.as_string(); - start_pos_ = input_copy.data(); + input_copy.reset(new std::string(input.as_string())); + start_pos_ = input_copy->data(); } else { start_pos_ = input.data(); } @@ -262,9 +251,9 @@ Value* JSONParser::Parse(const StringPiece& input) { // hidden root. if (!(options_ & JSON_DETACHABLE_CHILDREN)) { if (root->IsType(Value::TYPE_DICTIONARY)) { - return new DictionaryHiddenRootValue(&input_copy, root.get()); + return new DictionaryHiddenRootValue(input_copy.release(), root.get()); } else if (root->IsType(Value::TYPE_LIST)) { - return new ListHiddenRootValue(&input_copy, root.get()); + return new ListHiddenRootValue(input_copy.release(), root.get()); } else if (root->IsType(Value::TYPE_STRING)) { // A string type could be a JSONStringValue, but because there's no // corresponding HiddenRootValue, the memory will be lost. Deep copy to |