Title: [158875] trunk
Revision
158875
Author
[email protected]
Date
2013-11-07 14:19:58 -0800 (Thu, 07 Nov 2013)

Log Message

Reproducible crash when using Map (affects Web Inspector)
https://bugs.webkit.org/show_bug.cgi?id=123940

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

Trivial fix.  Once again we get bitten by attempting to be clever when
growing while adding entries to indexing maps.

Now we simply do a find(), and then add() _after_ we've ensured there is
sufficient space in the MapData list.

* runtime/MapData.cpp:
(JSC::MapData::add):

LayoutTests:

Add testcases

* js/map-grow-with-holes-expected.txt: Added.
* js/map-grow-with-holes.html: Added.
* js/script-tests/map-grow-with-holes.js: Added.
(get map):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (158874 => 158875)


--- trunk/LayoutTests/ChangeLog	2013-11-07 22:08:21 UTC (rev 158874)
+++ trunk/LayoutTests/ChangeLog	2013-11-07 22:19:58 UTC (rev 158875)
@@ -1,3 +1,17 @@
+2013-11-07  Oliver Hunt  <[email protected]>
+
+        Reproducible crash when using Map (affects Web Inspector)
+        https://bugs.webkit.org/show_bug.cgi?id=123940
+
+        Reviewed by Geoffrey Garen.
+
+        Add testcases
+
+        * js/map-grow-with-holes-expected.txt: Added.
+        * js/map-grow-with-holes.html: Added.
+        * js/script-tests/map-grow-with-holes.js: Added.
+        (get map):
+
 2013-11-07  Michał Pakuła vel Rutka  <[email protected]>
 
         Unreviewed EFL gardening

Added: trunk/LayoutTests/js/map-grow-with-holes-expected.txt (0 => 158875)


--- trunk/LayoutTests/js/map-grow-with-holes-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/map-grow-with-holes-expected.txt	2013-11-07 22:19:58 UTC (rev 158875)
@@ -0,0 +1,9 @@
+Tests to make sure we correctly handle map compaction when growing a Map with holes
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/map-grow-with-holes.html (0 => 158875)


--- trunk/LayoutTests/js/map-grow-with-holes.html	                        (rev 0)
+++ trunk/LayoutTests/js/map-grow-with-holes.html	2013-11-07 22:19:58 UTC (rev 158875)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/script-tests/map-grow-with-holes.js (0 => 158875)


--- trunk/LayoutTests/js/script-tests/map-grow-with-holes.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/map-grow-with-holes.js	2013-11-07 22:19:58 UTC (rev 158875)
@@ -0,0 +1,148 @@
+description("Tests to make sure we correctly handle map compaction when growing a Map with holes");
+
+/*
+ * This test case clobbers the Map with a number of new properties with periodic deletes
+ * creating holes in the backing store.
+ *
+ * When the Map requires more space we trigger an expand and compact, which then
+ * rebuilds the key->index hashmap.  This means that we need to ensure that the
+ * newly added key is not in hashmap during the compaction.
+ *
+ * We duplicate the test as string keyed entries use a distinct hashmap
+ * for key->index.
+ */
+
+var map = new Map();
+var flow = {};
+
+map.clear();
+map.clear();
+map.has(81);
+map.set(81, flow);
+map.has(83);
+map.set(83, flow);
+map.has(85);
+map.set(85, flow);
+map.has(87);
+map.set(87, flow);
+map.has(89);
+map.set(89, flow);
+map.has(91);
+map.set(91, flow);
+map.has(81);
+map.get(81);
+map.delete(81);
+map.has(82);
+map.has(83);
+map.get(83);
+map.delete(83);
+map.has(84);
+map.has(85);
+map.get(85);
+map.delete(85);
+map.has(86);
+map.has(87);
+map.get(87);
+map.delete(87);
+map.has(88);
+map.has(89);
+map.get(89);
+map.delete(89);
+map.has(90);
+map.has(91);
+map.get(91);
+map.delete(91);
+map.has(92);
+map.has(93);
+map.set(93, flow);
+map.has(95);
+map.set(95, flow);
+map.has(97);
+map.set(97, flow);
+map.has(99);
+map.set(99, flow);
+map.has(101);
+map.set(101, flow);
+map.has(103);
+map.set(103, flow);
+map.has(105);
+map.set(105, flow);
+map.has(93);
+map.get(93);
+map.delete(93);
+map.has(94);
+map.has(95);
+map.get(95);
+map.delete(95);
+map.has(96);
+map.has(97);
+map.get(97);
+
+
+map = new Map();
+var flow = {};
+
+map.clear();
+map.clear();
+map.has("81");
+map.set("81", flow);
+map.has("83");
+map.set("83", flow);
+map.has("85");
+map.set("85", flow);
+map.has("87");
+map.set("87", flow);
+map.has("89");
+map.set("89", flow);
+map.has("91");
+map.set("91", flow);
+map.has("81");
+map.get("81");
+map.delete("81");
+map.has("82");
+map.has("83");
+map.get("83");
+map.delete("83");
+map.has("84");
+map.has("85");
+map.get("85");
+map.delete("85");
+map.has("86");
+map.has("87");
+map.get("87");
+map.delete("87");
+map.has("88");
+map.has("89");
+map.get("89");
+map.delete("89");
+map.has("90");
+map.has("91");
+map.get("91");
+map.delete("91");
+map.has("92");
+map.has("93");
+map.set("93", flow);
+map.has("95");
+map.set("95", flow);
+map.has("97");
+map.set("97", flow);
+map.has("99");
+map.set("99", flow);
+map.has("101");
+map.set("101", flow);
+map.has("103");
+map.set("103", flow);
+map.has("105");
+map.set("105", flow);
+map.has("93");
+map.get("93");
+map.delete("93");
+map.has("94");
+map.has("95");
+map.get("95");
+map.delete("95");
+map.has("96");
+map.has("97");
+map.get("97");
+
+

Modified: trunk/Source/_javascript_Core/ChangeLog (158874 => 158875)


--- trunk/Source/_javascript_Core/ChangeLog	2013-11-07 22:08:21 UTC (rev 158874)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-11-07 22:19:58 UTC (rev 158875)
@@ -1,3 +1,19 @@
+2013-11-07  Oliver Hunt  <[email protected]>
+
+        Reproducible crash when using Map (affects Web Inspector)
+        https://bugs.webkit.org/show_bug.cgi?id=123940
+
+        Reviewed by Geoffrey Garen.
+
+        Trivial fix.  Once again we get bitten by attempting to be clever when
+        growing while adding entries to indexing maps.
+
+        Now we simply do a find(), and then add() _after_ we've ensured there is
+        sufficient space in the MapData list.
+
+        * runtime/MapData.cpp:
+        (JSC::MapData::add):
+
 2013-11-07  Mark Lam  <[email protected]>
 
         Cosmetic: rename xxxId to xxxID for ScriptId, SourceId, and BreakpointId.

Modified: trunk/Source/_javascript_Core/runtime/MapData.cpp (158874 => 158875)


--- trunk/Source/_javascript_Core/runtime/MapData.cpp	2013-11-07 22:08:21 UTC (rev 158874)
+++ trunk/Source/_javascript_Core/runtime/MapData.cpp	2013-11-07 22:19:58 UTC (rev 158875)
@@ -80,14 +80,15 @@
 
 template <typename Map, typename Key> MapData::Entry* MapData::add(CallFrame* callFrame, Map& map, Key key, KeyType keyValue)
 {
-    typename Map::AddResult result = map.add(key, m_size);
-    if (!result.isNewEntry)
-        return &m_entries[result.iterator->value];
-    if (!ensureSpaceForAppend(callFrame)) {
-        map.remove(result.iterator);
+    typename Map::iterator location = map.find(key);
+    if (location != map.end())
+        return &m_entries[location->value];
+    
+    if (!ensureSpaceForAppend(callFrame))
         return 0;
-    }
 
+    auto result = map.add(key, m_size);
+    RELEASE_ASSERT(result.isNewEntry);
     Entry* entry = &m_entries[m_size++];
     new (entry) Entry();
     entry->key.set(callFrame->vm(), this, keyValue.value);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to