Improve the v8::Object uniqueness check in V8ValueConverterImpl
Previously it used a set with identity hashes of the objects.
Those are not necessarily unique, so now it also stores the handle (with the id hashes as keys), and checks the handle equality for objects with identical hashes.
BUG=177662
Review URL: https://chromiumcodereview.appspot.com/12633013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@189284 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/renderer/v8_value_converter_impl.h b/content/renderer/v8_value_converter_impl.h
index 421c95a..4f58849d 100644
--- a/content/renderer/v8_value_converter_impl.h
+++ b/content/renderer/v8_value_converter_impl.h
@@ -5,8 +5,9 @@
#ifndef CONTENT_RENDERER_V8_VALUE_CONVERTER_IMPL_H_
#define CONTENT_RENDERER_V8_VALUE_CONVERTER_IMPL_H_
-#include <set>
+#include <map>
+#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/common/content_export.h"
#include "content/public/renderer/v8_value_converter.h"
@@ -37,6 +38,9 @@
v8::Handle<v8::Context> context) const OVERRIDE;
private:
+ friend class ScopedAvoidIdentityHashForTesting;
+ typedef std::multimap<int, v8::Handle<v8::Object> > HashToHandleMap;
+
v8::Handle<v8::Value> ToV8ValueImpl(const base::Value* value) const;
v8::Handle<v8::Value> ToV8Array(const base::ListValue* list) const;
v8::Handle<v8::Value> ToV8Object(
@@ -44,9 +48,9 @@
v8::Handle<v8::Value> ToArrayBuffer(const base::BinaryValue* value) const;
base::Value* FromV8ValueImpl(v8::Handle<v8::Value> value,
- std::set<int>* unique_set) const;
+ HashToHandleMap* unique_map) const;
base::Value* FromV8Array(v8::Handle<v8::Array> array,
- std::set<int>* unique_set) const;
+ HashToHandleMap* unique_map) const;
// This will convert objects of type ArrayBuffer or any of the
// ArrayBufferView subclasses. The return value will be NULL if |value| is
@@ -54,7 +58,15 @@
base::BinaryValue* FromV8Buffer(v8::Handle<v8::Value> value) const;
base::Value* FromV8Object(v8::Handle<v8::Object> object,
- std::set<int>* unique_set) const;
+ HashToHandleMap* unique_map) const;
+
+ // If |handle| is not in |map|, then add it to |map| and return true.
+ // Otherwise do nothing and return false. Here "A is unique" means that no
+ // other handle B in the map points to the same object as A. Note that A can
+ // be unique even if there already is another handle with the same identity
+ // hash (key) in the map, because two objects can have the same hash.
+ bool UpdateAndCheckUniqueness(HashToHandleMap* map,
+ v8::Handle<v8::Object> handle) const;
// If true, we will convert Date JavaScript objects to doubles.
bool date_allowed_;
@@ -68,6 +80,10 @@
// If true, undefined and null values are ignored when converting v8 objects
// into Values.
bool strip_null_from_objects_;
+
+ bool avoid_identity_hash_for_testing_;
+
+ DISALLOW_COPY_AND_ASSIGN(V8ValueConverterImpl);
};
} // namespace content