summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-27 19:39:52 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-27 19:39:52 +0000
commitfd2ebe630a17c8bc0af7ec427601bf6daa8d86da (patch)
tree5765ce3df8717b3735ae5ead6a9f010a44c622db /base
parentd918afeb7f8cf772084a2b0ef6e9f72203997297 (diff)
downloadchromium_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.cc37
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