Unreviewed, rolling out r205504.
authorryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2016 21:35:24 +0000 (21:35 +0000)
committerryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2016 21:35:24 +0000 (21:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161645

Broke the iOS device build (Requested by ryanhaddad on
#webkit).

Reverted changeset:

"Make JSMap and JSSet faster"
https://bugs.webkit.org/show_bug.cgi?id=160989
http://trac.webkit.org/changeset/205504

Patch by Commit Queue <commit-queue@webkit.org> on 2016-09-06

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205507 268f45cc-cd09-0410-ab3c-d52691b4dbfc

79 files changed:
JSTests/ChangeLog
JSTests/microbenchmarks/dense-set.js [deleted file]
JSTests/microbenchmarks/large-map-iteration-with-additions.js [deleted file]
JSTests/microbenchmarks/large-map-iteration-with-mutation.js [deleted file]
JSTests/microbenchmarks/large-map-iteration.js [deleted file]
JSTests/microbenchmarks/map-get-get-cse.js [deleted file]
JSTests/microbenchmarks/map-has-get-cse-opportunity.js [deleted file]
JSTests/microbenchmarks/sparse-set.js [deleted file]
JSTests/stress/map-cse-correctness.js [deleted file]
JSTests/stress/map-iteration.js [deleted file]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/SpeculatedType.cpp
Source/JavaScriptCore/bytecode/SpeculatedType.h
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGEdge.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
Source/JavaScriptCore/dfg/DFGHeapLocation.h
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/dfg/DFGUseKind.cpp
Source/JavaScriptCore/dfg/DFGUseKind.h
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/parser/ModuleAnalyzer.cpp
Source/JavaScriptCore/runtime/HashMapImpl.cpp [deleted file]
Source/JavaScriptCore/runtime/HashMapImpl.h [deleted file]
Source/JavaScriptCore/runtime/Intrinsic.h
Source/JavaScriptCore/runtime/JSCJSValue.h
Source/JavaScriptCore/runtime/JSCJSValueInlines.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSMap.cpp
Source/JavaScriptCore/runtime/JSMap.h
Source/JavaScriptCore/runtime/JSMapIterator.cpp
Source/JavaScriptCore/runtime/JSMapIterator.h
Source/JavaScriptCore/runtime/JSModuleLoader.cpp
Source/JavaScriptCore/runtime/JSModuleLoader.h
Source/JavaScriptCore/runtime/JSModuleRecord.cpp
Source/JavaScriptCore/runtime/JSModuleRecord.h
Source/JavaScriptCore/runtime/JSSet.cpp
Source/JavaScriptCore/runtime/JSSet.h
Source/JavaScriptCore/runtime/JSSetIterator.cpp
Source/JavaScriptCore/runtime/JSSetIterator.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/MapBase.cpp [deleted file]
Source/JavaScriptCore/runtime/MapBase.h [deleted file]
Source/JavaScriptCore/runtime/MapConstructor.cpp
Source/JavaScriptCore/runtime/MapIteratorPrototype.cpp
Source/JavaScriptCore/runtime/MapPrototype.cpp
Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
Source/JavaScriptCore/runtime/PropertyDescriptor.h
Source/JavaScriptCore/runtime/SetConstructor.cpp
Source/JavaScriptCore/runtime/SetIteratorPrototype.cpp
Source/JavaScriptCore/runtime/SetPrototype.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringImpl.h
Source/WebCore/ChangeLog
Source/WebCore/ForwardingHeaders/runtime/HashMapImpl.h [deleted file]
Source/WebCore/ForwardingHeaders/runtime/MapBase.h [deleted file]
Source/WebCore/bindings/js/SerializedScriptValue.cpp

index 0e3589e..851e21f 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205504.
+        https://bugs.webkit.org/show_bug.cgi?id=161645
+
+        Broke the iOS device build (Requested by ryanhaddad on
+        #webkit).
+
+        Reverted changeset:
+
+        "Make JSMap and JSSet faster"
+        https://bugs.webkit.org/show_bug.cgi?id=160989
+        http://trac.webkit.org/changeset/205504
+
 2016-09-06  Saam Barati  <sbarati@apple.com>
 
         Make JSMap and JSSet faster
diff --git a/JSTests/microbenchmarks/dense-set.js b/JSTests/microbenchmarks/dense-set.js
deleted file mode 100644 (file)
index d7b0e39..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-(function() {
-    
-    function bench(name, f, arg) {
-        var start = new Date;
-        var result = f(arg);
-        var end = new Date;
-        const verbose = false;
-        if (verbose)
-            print(name + " " + result + " " + (end-start) + "ms");
-    }
-
-    var denseSet = new Set;
-    var excludeSet = [123, 1230, 12300, 123000, 234, 2340, 23400];
-    for (var idx = 0; idx < 5e6; ++idx) {
-        if (excludeSet.includes(idx))
-            continue;
-        denseSet.add(idx);
-    }
-
-    bench("Dense Set Property Existence", function(s) {
-        var count = 0;
-        for (var i = 0; i < 5e6; ++i)
-            if (s.has(i))
-                count++
-        return count;
-    }, denseSet);
-
-})();
diff --git a/JSTests/microbenchmarks/large-map-iteration-with-additions.js b/JSTests/microbenchmarks/large-map-iteration-with-additions.js
deleted file mode 100644 (file)
index fa2d35e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-let counter = 0;
-function bar(map) {
-    for (let [key, value] of map) {
-        if (Math.random() > 0.95) {
-            map.set("" + counter, counter);
-            ++counter;
-        }
-    }
-}
-noInline(bar);
-
-function foo() {
-    let map = new Map;
-    for (let i = 0; i < 1000; i++)
-        map.set(i, i+1);
-
-    let start = Date.now();
-    for (let i = 0; i < 100; i++)
-        bar(map);
-    const verbose = false;
-    if (verbose)
-        print(Date.now() - start);
-
-}
-foo();
diff --git a/JSTests/microbenchmarks/large-map-iteration-with-mutation.js b/JSTests/microbenchmarks/large-map-iteration-with-mutation.js
deleted file mode 100644 (file)
index 5b4e51a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-function bar(map) {
-    for (let [key, value] of map) {
-        if (value - 1 !== key)
-            throw new Error("Bad iteration!");
-        if (Math.random() > 0.95) {
-            map.delete(key);
-        }
-    }
-}
-noInline(bar);
-
-function foo() {
-    let map = new Map;
-    for (let i = 0; i < 80000; i++)
-        map.set(i, i+1);
-
-    let start = Date.now();
-    for (let i = 0; i < 100; i++)
-        bar(map);
-    const verbose = false;
-    if (verbose)
-        print(Date.now() - start);
-
-}
-foo();
diff --git a/JSTests/microbenchmarks/large-map-iteration.js b/JSTests/microbenchmarks/large-map-iteration.js
deleted file mode 100644 (file)
index ad0d431..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-function bar(map) {
-    for (let [key, value] of map) {
-        if (value - 1 !== key)
-            throw new Error("Bad iteration!");
-    }
-}
-noInline(bar);
-
-function foo() {
-    let map = new Map;
-    for (let i = 0; i < 10000; i++)
-        map.set(i, i+1);
-
-    let start = Date.now();
-    for (let i = 0; i < 100; i++)
-        bar(map);
-    const verbose = false;
-    if (verbose)
-        print(Date.now() - start);
-
-}
-foo();
diff --git a/JSTests/microbenchmarks/map-get-get-cse.js b/JSTests/microbenchmarks/map-get-get-cse.js
deleted file mode 100644 (file)
index 32f1f4f..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-function bar(map, p) {
-    return map.get(p) + map.get(p);
-}
-noInline(bar);
-
-function foo() {
-    let map = new Map;
-    let items = [
-        [10, 50],
-        ["450", 78],
-        [{}, {}],
-        [Symbol(), true],
-        [undefined, null],
-        [true, null],
-        [false, true],
-        [45.87, {}]
-    ];
-    for (let [key, value] of items)
-        map.set(key, value);
-    let start = Date.now();
-    for (let i = 0; i < 5000000; i++)
-        bar(map, items[i % items.length][0]);
-    const verbose = false;
-    if (verbose)
-        print(Date.now() - start);
-}
-foo();
diff --git a/JSTests/microbenchmarks/map-has-get-cse-opportunity.js b/JSTests/microbenchmarks/map-has-get-cse-opportunity.js
deleted file mode 100644 (file)
index dadaaf4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-function bar(map, p) {
-    if (map.has(p))
-        return map.get(p);
-}
-noInline(bar);
-
-function foo() {
-    let map = new Map;
-    let items = [
-        [10, 50],
-        ["450", 78],
-        [{}, {}],
-        [Symbol(), true],
-        [undefined, null],
-        [true, null],
-        [false, true],
-        [45.87, {}]
-    ];
-    for (let [key, value] of items)
-        map.set(key, value);
-    let start = Date.now();
-    for (let i = 0; i < 5000000; i++)
-        bar(map, items[i % items.length][0]);
-    const verbose = false;
-    if (verbose)
-        print(Date.now() - start);
-}
-foo();
diff --git a/JSTests/microbenchmarks/sparse-set.js b/JSTests/microbenchmarks/sparse-set.js
deleted file mode 100644 (file)
index 1a7eaac..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-(function() {
-    
-    function bench(name, f, arg) {
-        var start = new Date;
-        var result = f(arg);
-        var end = new Date;
-        const verbose = false;
-        if (verbose)
-            print(name + " " + result + " " + (end-start) + "ms");
-    }
-
-
-    var sparseSet = new Set;
-    for (var x of [123, 1230, 12300, 123000, 234, 2340, 23400]) {
-        sparseSet.add(x);
-    }
-
-    bench("Sparse Set Property Existence", function(s) {
-        var count = 0;
-        for (var i = 0; i < 5e6; ++i)
-            if (s.has(i))
-                count++
-        return count;
-    }, sparseSet);
-})();
diff --git a/JSTests/stress/map-cse-correctness.js b/JSTests/stress/map-cse-correctness.js
deleted file mode 100644 (file)
index 02ceebb..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-function assert(b) {
-    if (!b)
-        throw new Error("Bad result!");
-}
-noInline(assert);
-
-function testHas(map, key, f) {
-    let first = map.has(key);
-    f();
-    let second = map.has(key);
-    return {first, second};
-}
-noInline(testHas);
-
-function testGet(map, key, f) {
-    let first = map.get(key);
-    f();
-    let second = map.get(key);
-    return {first, second};
-}
-noInline(testGet);
-
-function foo() {
-    let map = new Map;
-    for (let i = 0; i < 100000; i++) {
-        let key = i;
-        map.set(key, key);
-        let f = () => map.delete(key);
-        noInline(f);
-        let {first, second} = testHas(map, key, f);
-        assert(first);
-        assert(!second);
-    }
-    for (let i = 0; i < 100000; i++) {
-        let key = i;
-        map.set(key, key);
-        let f = () => {};
-        noInline(f);
-        let {first, second} = testHas(map, key, f);
-        assert(first);
-        assert(second);
-    }
-
-
-    for (let i = 0; i < 100000; i++) {
-        let key = i;
-        let value = {};
-        map.set(key, value);
-        let f = () => map.delete(key);
-        noInline(f);
-        let {first, second} = testGet(map, key, f);
-        assert(first === value);
-        assert(second === undefined);
-    }
-    for (let i = 0; i < 100000; i++) {
-        let key = i;
-        let value = {};
-        map.set(key, value);
-        let f = () => {};
-        noInline(f);
-        let {first, second} = testGet(map, key, f);
-        assert(first === value);
-        assert(second === value);
-    }
-}
-foo();
diff --git a/JSTests/stress/map-iteration.js b/JSTests/stress/map-iteration.js
deleted file mode 100644 (file)
index c5130e3..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-function assert(b) {
-    if (!b)
-        throw new Error("Bad result!");
-}
-noInline(assert);
-
-function test1() {
-    let map = new Map;
-    map.set(20, 30);
-    let iter = map[Symbol.iterator]();
-    let {value, done} = iter.next();
-    assert(value[0] === 20);
-    assert(value[1] === 30);
-    assert(!done);
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test1();
-
-function test2() {
-    let map = new Map;
-    map.set(20, 30);
-    let iter = map[Symbol.iterator]();
-    let {value, done} = iter.next();
-    assert(value[0] === 20);
-    assert(value[1] === 30);
-    assert(!done);
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-
-    map.set(40, 50);
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test2();
-
-function test3() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map[Symbol.iterator]();
-    let {value, done} = iter.next();
-    assert(value[0] === 20);
-    assert(value[1] === 30);
-    assert(!done);
-
-    ({value, done} = iter.next());
-    assert(!done);
-    assert(value[0] === 50);
-    assert(value[1] === 60);
-
-    map.set("foo", "bar");
-    ({value, done} = iter.next());
-    assert(!done);
-    assert(value[0] === "foo");
-    assert(value[1] === "bar");
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test3();
-
-function test4() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map[Symbol.iterator]();
-    let {value, done} = iter.next();
-    assert(value[0] === 20);
-    assert(value[1] === 30);
-    assert(!done);
-
-    map.clear();
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test4();
-
-function test5() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map[Symbol.iterator]();
-    let {value, done} = iter.next();
-    assert(value[0] === 20);
-    assert(value[1] === 30);
-    assert(!done);
-
-    map.clear();
-    map.set(50, 60);
-
-    ({value, done} = iter.next());
-    assert(!done);
-    assert(value[0] === 50);
-    assert(value[1] === 60);
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test5();
-function test6() {
-    let map = new Map;
-    map.set(20, 30);
-    let i = 0;
-    for (let [key, value] of map) {
-        map.delete(key);
-        map.set(key, value);
-        i++;
-        if (i === 1000)
-            break;
-    }
-    assert(i === 1000);
-}
-test6();
-
-function test7() {
-    let map = new Map;
-    map.set(20, 30);
-    let i = 0;
-    for (let [key, value] of map) {
-        map.clear();
-        map.set(key, value);
-        i++;
-        if (i === 1000)
-            break;
-    }
-    assert(i === 1000);
-}
-test7();
-
-function test8() {
-    let map = new Map;
-    map.set(20, 30);
-    for (let i = 0; i < 500; i++)
-        map.set(i, i);
-    let i = 0;
-    for (let [key, value] of map) {
-        assert(key === value);
-        i++;
-        if (key === 250)
-            break;
-    }
-    assert(i === 251);
-}
-test8();
-
-function test9() {
-    assert(1/(-0) === -Infinity);
-
-    let map = new Map;
-    map.set(-0, 50); // We should normalize -0 to +0 in the key.
-    for (let [key, value] of map) {
-        assert(1/key === Infinity);
-    }
-    assert(map.get(0.0) === 50);
-    assert(map.get(0) === 50);
-    assert(map.get(-0) === 50);
-    assert(map.get(+0) === 50);
-}
-for (let i = 0; i < 100; i++)
-    test9();
-
-function test10() {
-    let map = new Map;
-    map.set("negZero", -0); // We should *not* normalize -0 to +0 in the value.
-    for (let [key, value] of map) {
-        assert(1/value === -Infinity);
-    }
-}
-for (let i = 0; i < 100; i++)
-    test10();
-
-function test11() {
-    let map = new Map;
-    map.set(20, 30);
-    let iter = map.keys();
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 20);
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test11();
-
-function test12() {
-    let map = new Map;
-    map.set(20, 30);
-    let iter = map.values();
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 30);
-
-    ({value, done} = iter.next());
-    assert(done);
-    assert(value === undefined);
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test12();
-
-function test13() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.keys();
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 20);
-
-    map.clear();
-    map.set("foo", "bar");
-
-    ({value, done} = iter.next());
-    assert(!done);
-    assert(value === "foo");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test13();
-
-function test14() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.values();
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 30);
-
-    map.clear();
-    map.set("foo", "bar");
-
-    ;({value, done} = iter.next())
-    assert(!done);
-    assert(value === "bar");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test14();
-
-function test15() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.keys();
-
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 20);
-
-    ;({value, done} = iter.next())
-    assert(!done);
-    assert(value === 50);
-
-    map.clear();
-
-    map.set("foo", "bar");
-
-    ({value, done} = iter.next())
-    assert(!done);
-    assert(value === "foo");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test15();
-
-function test16() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.values();
-
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 30);
-
-    ;({value, done} = iter.next())
-    assert(!done);
-    assert(value === 60);
-
-    map.clear();
-
-    map.set("foo", "bar");
-
-    ({value, done} = iter.next())
-    assert(!done);
-    assert(value === "bar");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test16();
-
-function test17() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.keys();
-
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 20);
-
-    ;({value, done} = iter.next())
-    assert(!done);
-    assert(value === 50);
-
-    map.clear();
-
-    map.set("foo", "bar");
-
-    ({value, done} = iter.next())
-    assert(!done);
-    assert(value === "foo");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-
-    map.set("hello", "world");
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test17();
-
-function test18() {
-    let map = new Map;
-    map.set(20, 30);
-    map.set(50, 60);
-    let iter = map.values();
-
-    let {value, done} = iter.next();
-    assert(!done);
-    assert(value === 30);
-
-    ;({value, done} = iter.next())
-    assert(!done);
-    assert(value === 60);
-
-    map.clear();
-
-    map.set("foo", "bar");
-
-    ({value, done} = iter.next())
-    assert(!done);
-    assert(value === "bar");
-
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-
-    map.set("hello", "world");
-    ({value, done} = iter.next())
-    assert(done);
-    assert(value === undefined);
-}
-for (let i = 0; i < 100; i++)
-    test18();
index d2c4f7c..503af3a 100644 (file)
@@ -672,7 +672,6 @@ set(JavaScriptCore_SOURCES
     runtime/GeneratorFunctionPrototype.cpp
     runtime/GeneratorPrototype.cpp
     runtime/GetterSetter.cpp
-    runtime/HashMapImpl.cpp
     runtime/Identifier.cpp
     runtime/IndexingType.cpp
     runtime/InferredType.cpp
@@ -758,7 +757,6 @@ set(JavaScriptCore_SOURCES
     runtime/LazyClassStructure.cpp
     runtime/LiteralParser.cpp
     runtime/Lookup.cpp
-    runtime/MapBase.cpp
     runtime/MapConstructor.cpp
     runtime/MapIteratorPrototype.cpp
     runtime/MapPrototype.cpp
index 117246e..956d198 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205504.
+        https://bugs.webkit.org/show_bug.cgi?id=161645
+
+        Broke the iOS device build (Requested by ryanhaddad on
+        #webkit).
+
+        Reverted changeset:
+
+        "Make JSMap and JSSet faster"
+        https://bugs.webkit.org/show_bug.cgi?id=160989
+        http://trac.webkit.org/changeset/205504
+
 2016-09-06  Saam Barati  <sbarati@apple.com>
 
         Make JSMap and JSSet faster
index 0c5c51d..1c84b78 100644 (file)
                79233C2B1D34715700C5A834 /* JITMathIC.h in Headers */ = {isa = PBXBuildFile; fileRef = 79233C291D34715700C5A834 /* JITMathIC.h */; settings = {ATTRIBUTES = (Private, ); }; };
                792CB3491C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */; };
                792CB34A1C4EED5C00D13AF3 /* PCToCodeOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               795B19971D78BE3500262FA0 /* MapBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 795B19951D78BE3500262FA0 /* MapBase.cpp */; };
-               795B19981D78BE3500262FA0 /* MapBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 795B19961D78BE3500262FA0 /* MapBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
                797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A0907D1D768465008B889B /* HashMapImpl.cpp */; };
-               79A090801D768465008B889B /* HashMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A0907E1D768465008B889B /* HashMapImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79A228351D35D71E00D8E067 /* ArithProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A228331D35D71E00D8E067 /* ArithProfile.cpp */; };
                79A228361D35D71F00D8E067 /* ArithProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A228341D35D71E00D8E067 /* ArithProfile.h */; };
                79AF0BE41D3EFD4C00E95FA5 /* JITMathICInlineResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 79AF0BE31D3EFD4C00E95FA5 /* JITMathICInlineResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79233C291D34715700C5A834 /* JITMathIC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITMathIC.h; sourceTree = "<group>"; };
                792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCToCodeOriginMap.cpp; sourceTree = "<group>"; };
                792CB3481C4EED5C00D13AF3 /* PCToCodeOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCToCodeOriginMap.h; sourceTree = "<group>"; };
-               795B19951D78BE3500262FA0 /* MapBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapBase.cpp; sourceTree = "<group>"; };
-               795B19961D78BE3500262FA0 /* MapBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapBase.h; sourceTree = "<group>"; };
                796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = "<group>"; };
                797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = "<group>"; };
                797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; };
                799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = "<group>"; };
-               79A0907D1D768465008B889B /* HashMapImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashMapImpl.cpp; sourceTree = "<group>"; };
-               79A0907E1D768465008B889B /* HashMapImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMapImpl.h; sourceTree = "<group>"; };
                79A228331D35D71E00D8E067 /* ArithProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArithProfile.cpp; sourceTree = "<group>"; };
                79A228341D35D71E00D8E067 /* ArithProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArithProfile.h; sourceTree = "<group>"; };
                79A899FE1D38612E00D18C73 /* JITMathICForwards.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITMathICForwards.h; sourceTree = "<group>"; };
                                796465681B952FF0003059EE /* GetPutInfo.h */,
                                BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
                                BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
-                               79A0907D1D768465008B889B /* HashMapImpl.cpp */,
-                               79A0907E1D768465008B889B /* HashMapImpl.h */,
                                933A349D038AE80F008635CE /* Identifier.cpp */,
                                933A349A038AE7C6008635CE /* Identifier.h */,
                                8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */,
                                A7E2EA690FB460CF00601F06 /* LiteralParser.h */,
                                F692A8680255597D01FF60F7 /* Lookup.cpp */,
                                F692A8690255597D01FF60F7 /* Lookup.h */,
-                               795B19951D78BE3500262FA0 /* MapBase.cpp */,
-                               795B19961D78BE3500262FA0 /* MapBase.h */,
                                A700873717CBE85300C3E643 /* MapConstructor.cpp */,
                                A700873817CBE85300C3E643 /* MapConstructor.h */,
                                A78507D517CBC6FD0011F6E7 /* MapData.h */,
                                0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
                                1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
                                62EC9BB71B7EB07C00303AD1 /* CallFrameShuffleData.h in Headers */,
-                               795B19981D78BE3500262FA0 /* MapBase.h in Headers */,
                                62D755D71B84FB4A001801FA /* CallFrameShuffler.h in Headers */,
                                0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
                                0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
                                0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
                                A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
                                0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
-                               79A090801D768465008B889B /* HashMapImpl.h in Headers */,
                                0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
                                86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
                                86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */,
                                0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,
                                0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
-                               79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */,
                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
                                0F93274D1C1F66AA00CF6564 /* GPRInfo.cpp in Sources */,
                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
                                52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */,
                                FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */,
                                147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */,
-                               795B19971D78BE3500262FA0 /* MapBase.cpp in Sources */,
                                62D2D38F1ADF103F000206C1 /* FunctionRareData.cpp in Sources */,
                                2AACE63C18CA5A0300ED0191 /* GCActivityCallback.cpp in Sources */,
                                0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
index b2b2fa5..0e602ff 100644 (file)
 #include "SpeculatedType.h"
 
 #include "DirectArguments.h"
-#include "JSCInlines.h"
 #include "JSArray.h"
 #include "JSFunction.h"
-#include "JSMap.h"
-#include "JSSet.h"
+#include "JSCInlines.h"
 #include "ScopedArguments.h"
 #include "StringObject.h"
 #include "ValueProfile.h"
@@ -348,12 +346,6 @@ SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
 
     if (classInfo == RegExpObject::info())
         return SpecRegExpObject;
-
-    if (classInfo == JSMap::info())
-        return SpecMapObject;
-
-    if (classInfo == JSSet::info())
-        return SpecSetObject;
     
     if (classInfo->isSubClassOf(JSFunction::info()))
         return SpecFunction;
index 1636dac..8222ab1 100644 (file)
@@ -39,43 +39,41 @@ class Structure;
 
 typedef uint64_t SpeculatedType;
 static const SpeculatedType SpecNone               = 0; // We don't know anything yet.
-static const SpeculatedType SpecFinalObject        = 1ull << 0; // It's definitely a JSFinalObject.
-static const SpeculatedType SpecArray              = 1ull << 1; // It's definitely a JSArray.
-static const SpeculatedType SpecFunction           = 1ull << 2; // It's definitely a JSFunction.
-static const SpeculatedType SpecInt8Array          = 1ull << 3; // It's definitely an Int8Array or one of its subclasses.
-static const SpeculatedType SpecInt16Array         = 1ull << 4; // It's definitely an Int16Array or one of its subclasses.
-static const SpeculatedType SpecInt32Array         = 1ull << 5; // It's definitely an Int32Array or one of its subclasses.
-static const SpeculatedType SpecUint8Array         = 1ull << 6; // It's definitely an Uint8Array or one of its subclasses.
-static const SpeculatedType SpecUint8ClampedArray  = 1ull << 7; // It's definitely an Uint8ClampedArray or one of its subclasses.
-static const SpeculatedType SpecUint16Array        = 1ull << 8; // It's definitely an Uint16Array or one of its subclasses.
-static const SpeculatedType SpecUint32Array        = 1ull << 9; // It's definitely an Uint32Array or one of its subclasses.
-static const SpeculatedType SpecFloat32Array       = 1ull << 10; // It's definitely an Uint16Array or one of its subclasses.
-static const SpeculatedType SpecFloat64Array       = 1ull << 11; // It's definitely an Uint16Array or one of its subclasses.
+static const SpeculatedType SpecFinalObject        = 1u << 0; // It's definitely a JSFinalObject.
+static const SpeculatedType SpecArray              = 1u << 1; // It's definitely a JSArray.
+static const SpeculatedType SpecFunction           = 1u << 2; // It's definitely a JSFunction.
+static const SpeculatedType SpecInt8Array          = 1u << 3; // It's definitely an Int8Array or one of its subclasses.
+static const SpeculatedType SpecInt16Array         = 1u << 4; // It's definitely an Int16Array or one of its subclasses.
+static const SpeculatedType SpecInt32Array         = 1u << 5; // It's definitely an Int32Array or one of its subclasses.
+static const SpeculatedType SpecUint8Array         = 1u << 6; // It's definitely an Uint8Array or one of its subclasses.
+static const SpeculatedType SpecUint8ClampedArray  = 1u << 7; // It's definitely an Uint8ClampedArray or one of its subclasses.
+static const SpeculatedType SpecUint16Array        = 1u << 8; // It's definitely an Uint16Array or one of its subclasses.
+static const SpeculatedType SpecUint32Array        = 1u << 9; // It's definitely an Uint32Array or one of its subclasses.
+static const SpeculatedType SpecFloat32Array       = 1u << 10; // It's definitely an Uint16Array or one of its subclasses.
+static const SpeculatedType SpecFloat64Array       = 1u << 11; // It's definitely an Uint16Array or one of its subclasses.
 static const SpeculatedType SpecTypedArrayView     = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
-static const SpeculatedType SpecDirectArguments    = 1ull << 12; // It's definitely a DirectArguments object.
-static const SpeculatedType SpecScopedArguments    = 1ull << 13; // It's definitely a ScopedArguments object.
-static const SpeculatedType SpecStringObject       = 1ull << 14; // It's definitely a StringObject.
-static const SpeculatedType SpecRegExpObject       = 1ull << 15; // It's definitely a RegExpObject (and not any subclass of RegExpObject).
-static const SpeculatedType SpecMapObject          = 1ull << 16; // It's definitely Map object (can it be a subclass? FIXME).
-static const SpeculatedType SpecSetObject          = 1ull << 17; // It's definitely s Set object (can it be a subclass? FIXME).
-static const SpeculatedType SpecObjectOther        = 1ull << 18; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
-static const SpeculatedType SpecObject             = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecObjectOther; // Bitmask used for testing for any kind of object prediction.
-static const SpeculatedType SpecStringIdent        = 1ull << 19; // It's definitely a JSString, and it's an identifier.
-static const SpeculatedType SpecStringVar          = 1ull << 20; // It's definitely a JSString, and it's not an identifier.
+static const SpeculatedType SpecDirectArguments    = 1u << 12; // It's definitely a DirectArguments object.
+static const SpeculatedType SpecScopedArguments    = 1u << 13; // It's definitely a ScopedArguments object.
+static const SpeculatedType SpecStringObject       = 1u << 14; // It's definitely a StringObject.
+static const SpeculatedType SpecRegExpObject       = 1u << 15; // It's definitely a RegExpObject (and not any subclass of RegExpObject).
+static const SpeculatedType SpecObjectOther        = 1u << 16; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
+static const SpeculatedType SpecObject             = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecObjectOther; // Bitmask used for testing for any kind of object prediction.
+static const SpeculatedType SpecStringIdent        = 1u << 17; // It's definitely a JSString, and it's an identifier.
+static const SpeculatedType SpecStringVar          = 1u << 18; // It's definitely a JSString, and it's not an identifier.
 static const SpeculatedType SpecString             = SpecStringIdent | SpecStringVar; // It's definitely a JSString.
-static const SpeculatedType SpecSymbol             = 1ull << 21; // It's definitely a Symbol.
-static const SpeculatedType SpecCellOther          = 1ull << 22; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=133078
+static const SpeculatedType SpecSymbol             = 1u << 19; // It's definitely a Symbol.
+static const SpeculatedType SpecCellOther          = 1u << 20; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=133078
 static const SpeculatedType SpecCell               = SpecObject | SpecString | SpecSymbol | SpecCellOther; // It's definitely a JSCell.
-static const SpeculatedType SpecBoolInt32          = 1ull << 23; // It's definitely an Int32 with value 0 or 1.
-static const SpeculatedType SpecNonBoolInt32       = 1ull << 24; // It's definitely an Int32 with value other than 0 or 1.
+static const SpeculatedType SpecBoolInt32          = 1u << 21; // It's definitely an Int32 with value 0 or 1.
+static const SpeculatedType SpecNonBoolInt32       = 1u << 22; // It's definitely an Int32 with value other than 0 or 1.
 static const SpeculatedType SpecInt32Only          = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32.
-static const SpeculatedType SpecInt52Only          = 1ull << 25; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32.
+static const SpeculatedType SpecInt52Only          = 1u << 23; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32.
 static const SpeculatedType SpecAnyInt             = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on.
-static const SpeculatedType SpecAnyIntAsDouble     = 1ull << 26; // It's definitely an Int52 and it's inside a double.
-static const SpeculatedType SpecNonIntAsDouble     = 1ull << 27; // It's definitely not an Int52 but it's a real number and it's a double.
+static const SpeculatedType SpecAnyIntAsDouble     = 1u << 24; // It's definitely an Int52 and it's inside a double.
+static const SpeculatedType SpecNonIntAsDouble     = 1u << 25; // It's definitely not an Int52 but it's a real number and it's a double.
 static const SpeculatedType SpecDoubleReal         = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double.
-static const SpeculatedType SpecDoublePureNaN      = 1ull << 28; // It's definitely a NaN that is sae to tag (i.e. pure).
-static const SpeculatedType SpecDoubleImpureNaN    = 1ull << 29; // It's definitely a NaN that is unsafe to tag (i.e. impure).
+static const SpeculatedType SpecDoublePureNaN      = 1u << 26; // It's definitely a NaN that is sae to tag (i.e. pure).
+static const SpeculatedType SpecDoubleImpureNaN    = 1u << 27; // It's definitely a NaN that is unsafe to tag (i.e. impure).
 static const SpeculatedType SpecDoubleNaN          = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN.
 static const SpeculatedType SpecBytecodeDouble     = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
 static const SpeculatedType SpecFullDouble         = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double.
@@ -83,12 +81,12 @@ static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleR
 static const SpeculatedType SpecFullRealNumber     = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52.
 static const SpeculatedType SpecBytecodeNumber     = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
 static const SpeculatedType SpecFullNumber         = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
-static const SpeculatedType SpecBoolean            = 1ull << 30; // It's definitely a Boolean.
-static const SpeculatedType SpecOther              = 1ull << 31; // It's definitely either Null or Undefined.
+static const SpeculatedType SpecBoolean            = 1u << 28; // It's definitely a Boolean.
+static const SpeculatedType SpecOther              = 1u << 29; // It's definitely either Null or Undefined.
 static const SpeculatedType SpecMisc               = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
 static const SpeculatedType SpecHeapTop            = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN.
 static const SpeculatedType SpecPrimitive          = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc; // It's any non-Object JSValue.
-static const SpeculatedType SpecEmpty              = 1ull << 32; // It's definitely an empty value marker.
+static const SpeculatedType SpecEmpty              = 1u << 30; // It's definitely an empty value marker.
 static const SpeculatedType SpecBytecodeTop        = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local.
 static const SpeculatedType SpecFullTop            = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers.
 
index 5fa5770..8e32440 100644 (file)
@@ -977,22 +977,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         break;
     }
 
-    case MapHash:
-        forNode(node).setType(SpecInt32Only);
-        break;
-
-    case LoadFromJSMapBucket:
-        forNode(node).makeHeapTop();
-        break;
-
-    case GetMapBucket:
-        forNode(node).setType(m_graph, SpecCellOther);
-        break;
-
-    case IsNonEmptyMapBucket:
-        forNode(node).setType(SpecBoolean);
-        break;
-
     case IsEmpty:
     case IsJSArray:
     case IsUndefined:
@@ -2899,7 +2883,7 @@ template<typename AbstractStateType>
 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
 {
     Node* node = m_state.block()->at(indexInBlock);
-
+    
     startExecuting();
     executeEdges(node);
     return executeEffects(indexInBlock, node);
index 4647046..f8060e5 100644 (file)
@@ -2538,37 +2538,7 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin
             set(VirtualRegister(resultOperand), get(operand));
         return true;
     }
-
-    case JSMapGetIntrinsic: {
-        if (argumentCountIncludingThis != 2)
-            return false;
-
-        insertChecks();
-        Node* map = get(virtualRegisterForArgument(0, registerOffset));
-        Node* key = get(virtualRegisterForArgument(1, registerOffset));
-        Node* hash = addToGraph(MapHash, key);
-        Node* bucket = addToGraph(GetMapBucket, Edge(map, MapObjectUse), Edge(key), Edge(hash));
-        Node* result = addToGraph(LoadFromJSMapBucket, OpInfo(), OpInfo(prediction), bucket);
-        set(VirtualRegister(resultOperand), result);
-        return true;
-    }
-
-    case JSSetHasIntrinsic:
-    case JSMapHasIntrinsic: {
-        if (argumentCountIncludingThis != 2)
-            return false;
-
-        insertChecks();
-        Node* mapOrSet = get(virtualRegisterForArgument(0, registerOffset));
-        Node* key = get(virtualRegisterForArgument(1, registerOffset));
-        Node* hash = addToGraph(MapHash, key);
-        UseKind useKind = intrinsic == JSSetHasIntrinsic ? SetObjectUse : MapObjectUse;
-        Node* bucket = addToGraph(GetMapBucket, OpInfo(0), Edge(mapOrSet, useKind), Edge(key), Edge(hash));
-        Node* result = addToGraph(IsNonEmptyMapBucket, bucket);
-        set(VirtualRegister(resultOperand), result);
-        return true;
-    }
-
+        
     default:
         return false;
     }
index 47b8acc..b1a79e0 100644 (file)
@@ -1243,27 +1243,6 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
     case LogShadowChickenTail:
         write(SideState);
         return;
-
-    case MapHash:
-        def(PureValue(node));
-        return;
-    case GetMapBucket: {
-        read(MiscFields);
-        Edge& mapEdge = node->child1();
-        Edge& keyEdge = node->child2();
-        def(HeapLocation(MapBucketLoc, MiscFields, mapEdge, keyEdge), LazyNode(node));
-        return;
-    }
-    case LoadFromJSMapBucket: {
-        read(MiscFields);
-        Edge& bucketEdge = node->child1();
-        def(HeapLocation(JSMapGetLoc, MiscFields, bucketEdge), LazyNode(node));
-        return;
-    }
-    case IsNonEmptyMapBucket:
-        read(MiscFields);
-        def(HeapLocation(MapHasLoc, MiscFields, node->child1()), LazyNode(node));
-        return;
         
     case LastNodeType:
         RELEASE_ASSERT_NOT_REACHED();
index 883b716..671e4d3 100644 (file)
@@ -185,10 +185,6 @@ bool doesGC(Graph& graph, Node* node)
     case ForceOSRExit:
     case CheckWatchdogTimer:
     case StringFromCharCode:
-    case MapHash:
-    case GetMapBucket:
-    case LoadFromJSMapBucket:
-    case IsNonEmptyMapBucket:
     case Unreachable:
     case ExtractOSREntryLocal:
     case CheckTierUpInLoop:
index 4e4ce10..17f0c13 100644 (file)
@@ -189,7 +189,7 @@ private:
     friend class AdjacencyList;
     
 #if USE(JSVALUE64)
-    static constexpr uint32_t shift() { return 8; }
+    static uint32_t shift() { return 7; }
     
     static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
     {
@@ -197,21 +197,8 @@ private:
         uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
         ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
         ASSERT(useKind >= 0 && useKind < LastUseKind);
-        static_assert((static_cast<uintptr_t>(LastUseKind) << 2) < (static_cast<uintptr_t>(1) << shift()), "We rely on this being true to not clobber the node pointer.");
-        uintptr_t result = shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
-        if (!ASSERT_DISABLED) {
-            union U {
-                U() { word = 0; }
-                uintptr_t word;
-                Edge edge;
-            } u;
-            u.word = result;
-            ASSERT(u.edge.useKindUnchecked() == useKind);
-            ASSERT(u.edge.node() == node);
-            ASSERT(u.edge.proofStatusUnchecked() == proofStatus);
-            ASSERT(u.edge.killStatusUnchecked() == killStatus);
-        }
-        return result;
+        ASSERT((static_cast<uintptr_t>(LastUseKind) << 2) <= (static_cast<uintptr_t>(2) << shift()));
+        return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
     }
     
 #else
index 2d94e2c..5c356ab 100644 (file)
@@ -1545,29 +1545,6 @@ private:
             break;
         }
 
-        case GetMapBucket:
-            if (node->child1().useKind() == MapObjectUse)
-                fixEdge<MapObjectUse>(node->child1());
-            else if (node->child1().useKind() == SetObjectUse)
-                fixEdge<SetObjectUse>(node->child1());
-            else
-                RELEASE_ASSERT_NOT_REACHED();
-            fixEdge<UntypedUse>(node->child2());
-            fixEdge<Int32Use>(node->child3());
-            break;
-
-        case LoadFromJSMapBucket:
-            fixEdge<KnownCellUse>(node->child1());
-            break;
-
-        case IsNonEmptyMapBucket:
-            fixEdge<KnownCellUse>(node->child1());
-            break;
-
-        case MapHash:
-            fixEdge<UntypedUse>(node->child1());
-            break;
-
 #if !ASSERT_DISABLED
         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
         case SetArgument:
index 8470637..d441862 100644 (file)
@@ -143,15 +143,6 @@ void printInternal(PrintStream& out, LocationKind kind)
     case RegExpObjectLastIndexLoc:
         out.print("RegExpObjectLastIndexLoc");
         return;
-    case MapBucketLoc:
-        out.print("MapBucketLoc");
-        return;
-    case JSMapGetLoc:
-        out.print("JSMapGetLoc");
-        return;
-    case MapHasLoc:
-        out.print("MapHasLoc");
-        return;
     }
     
     RELEASE_ASSERT_NOT_REACHED();
index e81a554..b0f7a99 100644 (file)
@@ -58,10 +58,7 @@ enum LocationKind {
     StructureLoc,
     TypedArrayByteOffsetLoc,
     StackLoc,
-    StackPayloadLoc,
-    MapBucketLoc,
-    JSMapGetLoc,
-    MapHasLoc
+    StackPayloadLoc
 };
 
 class HeapLocation {
index 27cd325..31a5465 100644 (file)
@@ -1421,7 +1421,6 @@ public:
         case StringReplace:
         case StringReplaceRegExp:
         case ToNumber:
-        case LoadFromJSMapBucket:
             return true;
         default:
             return false;
index 2eccf75..836618a 100644 (file)
@@ -388,12 +388,7 @@ namespace JSC { namespace DFG {
     macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
     macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
     macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
-    macro(ToIndexString, NodeResultJS) \
-    /* Nodes for JSMap and JSSet */ \
-    macro(MapHash, NodeResultInt32) \
-    macro(GetMapBucket, NodeResultJS) \
-    macro(LoadFromJSMapBucket, NodeResultJS) \
-    macro(IsNonEmptyMapBucket, NodeResultBoolean) \
+    macro(ToIndexString, NodeResultJS)
 
 // This enum generates a monotonically increasing id for all Node types,
 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
index 4a6e7d0..20ae52b 100644 (file)
@@ -50,8 +50,6 @@
 #include "JSCInlines.h"
 #include "JSGenericTypedArrayViewConstructorInlines.h"
 #include "JSLexicalEnvironment.h"
-#include "JSMap.h"
-#include "JSSet.h"
 #include "ObjectConstructor.h"
 #include "Repatch.h"
 #include "ScopedArguments.h"
@@ -1817,34 +1815,6 @@ void JIT_OPERATION operationPutDynamicVar(ExecState* exec, JSObject* scope, Enco
     scope->methodTable()->put(scope, exec, ident, JSValue::decode(value), slot);
 }
 
-int32_t JIT_OPERATION operationMapHash(ExecState* exec, EncodedJSValue input)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    return jsMapHash(exec, vm, normalizeMapKey(JSValue::decode(input)));
-}
-
-JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    JSMap::BucketType** bucket = jsCast<JSMap*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
-    if (!bucket)
-        return nullptr;
-    return *bucket;
-}
-
-JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    JSSet::BucketType** bucket = jsCast<JSSet*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
-    if (!bucket)
-        return nullptr;
-    return *bucket;
-}
-
 extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
 {
     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
index 12ba7ac..65ebd9d 100644 (file)
@@ -142,10 +142,6 @@ char* JIT_OPERATION operationEnsureArrayStorage(ExecState*, JSCell*);
 StringImpl* JIT_OPERATION operationResolveRope(ExecState*, JSString*);
 JSString* JIT_OPERATION operationSingleCharacterString(ExecState*, int32_t);
 
-int32_t JIT_OPERATION operationMapHash(ExecState*, EncodedJSValue input);
-JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
-JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
-
 JSCell* JIT_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
 JSCell* JIT_OPERATION operationToStringOnCell(ExecState*, JSCell*);
 JSCell* JIT_OPERATION operationToString(ExecState*, EncodedJSValue);
index 62b6719..1ca81d4 100644 (file)
@@ -708,7 +708,6 @@ private:
         case GetGlobalLexicalVariable:
         case GetClosureVar:
         case GetFromArguments:
-        case LoadFromJSMapBucket:
         case ToNumber: {
             setPrediction(m_currentNode->getHeapPrediction());
             break;
@@ -739,16 +738,6 @@ private:
             break;
         }
 
-        case MapHash:
-            setPrediction(SpecInt32Only);
-            break;
-        case GetMapBucket:
-            setPrediction(SpecCellOther);
-            break;
-        case IsNonEmptyMapBucket:
-            setPrediction(SpecBoolean);
-            break;
-
         case GetRestLength: {
             setPrediction(SpecInt32Only);
             break;
index 68af2fa..74ede5d 100644 (file)
@@ -58,8 +58,6 @@ public:
         case FunctionUse:
         case FinalObjectUse:
         case RegExpObjectUse:
-        case MapObjectUse:
-        case SetObjectUse:
         case ObjectOrOtherUse:
         case StringIdentUse:
         case StringUse:
@@ -357,10 +355,6 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case GetDynamicVar:
     case PutDynamicVar:
     case ResolveScope:
-    case MapHash:
-    case GetMapBucket:
-    case LoadFromJSMapBucket:
-    case IsNonEmptyMapBucket:
         return true;
 
     case BottomValue:
index e16876a..6c1c8ed 100644 (file)
@@ -7407,34 +7407,6 @@ void SpeculativeJIT::speculateRegExpObject(Edge edge)
     speculateRegExpObject(edge, operand.gpr());
 }
 
-void SpeculativeJIT::speculateMapObject(Edge edge, GPRReg cell)
-{
-    speculateCellType(edge, cell, SpecMapObject, JSMapType);
-}
-
-void SpeculativeJIT::speculateMapObject(Edge edge)
-{
-    if (!needsTypeCheck(edge, SpecMapObject))
-        return;
-
-    SpeculateCellOperand operand(this, edge);
-    speculateMapObject(edge, operand.gpr());
-}
-
-void SpeculativeJIT::speculateSetObject(Edge edge, GPRReg cell)
-{
-    speculateCellType(edge, cell, SpecSetObject, JSSetType);
-}
-
-void SpeculativeJIT::speculateSetObject(Edge edge)
-{
-    if (!needsTypeCheck(edge, SpecSetObject))
-        return;
-
-    SpeculateCellOperand operand(this, edge);
-    speculateSetObject(edge, operand.gpr());
-}
-
 void SpeculativeJIT::speculateObjectOrOther(Edge edge)
 {
     if (!needsTypeCheck(edge, SpecObject | SpecOther))
@@ -7722,12 +7694,6 @@ void SpeculativeJIT::speculate(Node*, Edge edge)
     case RegExpObjectUse:
         speculateRegExpObject(edge);
         break;
-    case MapObjectUse:
-        speculateMapObject(edge);
-        break;
-    case SetObjectUse:
-        speculateSetObject(edge);
-        break;
     case ObjectOrOtherUse:
         speculateObjectOrOther(edge);
         break;
index 27a5805..7a849c7 100644 (file)
@@ -1311,12 +1311,6 @@ public:
 
 #if USE(JSVALUE64)
 
-    JITCompiler::Call callOperation(C_JITOperation_ECJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result);
-    }
-
     JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC)
     {
         m_jit.setupArgumentsWithExecState(arg1.gpr(), arg2.gpr(), mathIC);
@@ -1697,12 +1691,6 @@ public:
         return appendCall(operation);
     }
 
-    JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
-    {
-        m_jit.setupArgumentsWithExecState(arg1);
-        return appendCallSetResult(operation, result);
-    }
-
     JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
     {
         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
@@ -1751,18 +1739,6 @@ public:
     }
 #else // USE(JSVALUE32_64)
 
-    JITCompiler::Call callOperation(C_JITOperation_ECJZ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, GPRReg arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3);
-        return appendCallSetResult(operation, result);
-    }
-
-    JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
-    {
-        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR());
-        return appendCallSetResult(operation, result);
-    }
-
     JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC)
     {
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), mathIC);
@@ -2678,10 +2654,6 @@ public:
     void speculateFinalObject(Edge);
     void speculateRegExpObject(Edge, GPRReg cell);
     void speculateRegExpObject(Edge);
-    void speculateMapObject(Edge);
-    void speculateMapObject(Edge, GPRReg cell);
-    void speculateSetObject(Edge);
-    void speculateSetObject(Edge, GPRReg cell);
     void speculateObjectOrOther(Edge);
     void speculateString(Edge edge, GPRReg cell);
     void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
index 3809b75..e37fa13 100644 (file)
@@ -37,7 +37,6 @@
 #include "DFGSlowPathGenerator.h"
 #include "DirectArguments.h"
 #include "GetterSetter.h"
-#include "HashMapImpl.h"
 #include "JSEnvironmentRecord.h"
 #include "JSLexicalEnvironment.h"
 #include "JSPropertyNameEnumerator.h"
@@ -4720,82 +4719,6 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
-    case MapHash: {
-        JSValueOperand input(this, node->child1());
-
-        JSValueRegs inputRegs = input.jsValueRegs();
-
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
-
-        flushRegisters();
-        callOperation(operationMapHash, resultGPR, inputRegs);
-        m_jit.exceptionCheck();
-        int32Result(resultGPR, node);
-        break;
-    }
-
-    case GetMapBucket: {
-        SpeculateCellOperand map(this, node->child1());
-        JSValueOperand key(this, node->child2());
-        SpeculateInt32Operand hash(this, node->child3());
-        GPRFlushedCallResult result(this);
-
-        GPRReg mapGPR = map.gpr();
-        JSValueRegs keyRegs = key.jsValueRegs();
-        GPRReg hashGPR = hash.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        if (node->child1().useKind() == MapObjectUse)
-            speculateMapObject(node->child1(), mapGPR);
-        else if (node->child1().useKind() == SetObjectUse)
-            speculateSetObject(node->child1(), mapGPR);
-        else
-            RELEASE_ASSERT_NOT_REACHED();
-
-        flushRegisters();
-        if (node->child1().useKind() == MapObjectUse)
-            callOperation(operationJSMapFindBucket, resultGPR, mapGPR, keyRegs, hashGPR);
-        else
-            callOperation(operationJSSetFindBucket, resultGPR, mapGPR, keyRegs, hashGPR);
-        m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
-        break;
-    }
-
-    case LoadFromJSMapBucket: {
-        SpeculateCellOperand bucket(this, node->child1());
-        GPRTemporary resultPayload(this);
-        GPRTemporary resultTag(this);
-
-        GPRReg bucketGPR = bucket.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-
-        auto notBucket = m_jit.branchTestPtr(MacroAssembler::Zero, bucketGPR);
-        m_jit.loadValue(MacroAssembler::Address(bucketGPR, HashMapBucket<HashMapBucketDataKeyValue>::offsetOfValue()), JSValueRegs(resultTagGPR, resultPayloadGPR));
-        auto done = m_jit.jump();
-
-        notBucket.link(&m_jit);
-        m_jit.move(TrustedImm32(JSValue::UndefinedTag), resultTagGPR);
-        m_jit.move(TrustedImm32(0), resultPayloadGPR);
-        done.link(&m_jit);
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
-        break;
-    }
-
-    case IsNonEmptyMapBucket: {
-        SpeculateCellOperand bucket(this, node->child1());
-        GPRTemporary result(this);
-
-        GPRReg bucketGPR = bucket.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.comparePtr(MacroAssembler::NotEqual, bucketGPR, TrustedImm32(0), resultGPR);
-        booleanResult(resultGPR, node);
-        break;
-    }
-
     case Flush:
         break;
 
index 800118e..bfb61ef 100644 (file)
@@ -39,9 +39,7 @@
 #include "JSCInlines.h"
 #include "JSEnvironmentRecord.h"
 #include "JSLexicalEnvironment.h"
-#include "JSMap.h"
 #include "JSPropertyNameEnumerator.h"
-#include "JSSet.h"
 #include "ObjectPrototype.h"
 #include "SetupVarargsFrame.h"
 #include "SpillRegistersMode.h"
@@ -4617,168 +4615,6 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
-    case MapHash: {
-        JSValueOperand input(this, node->child1());
-        GPRTemporary temp(this);
-        GPRTemporary result(this);
-
-        GPRReg inputGPR = input.gpr();
-        GPRReg resultGPR = result.gpr();
-        GPRReg tempGPR = temp.gpr();
-
-        MacroAssembler::JumpList straightHash;
-        MacroAssembler::JumpList done;
-        auto isNotCell = m_jit.branchIfNotCell(inputGPR);
-        MacroAssembler::JumpList slowPath;
-        straightHash.append(m_jit.branch8(MacroAssembler::NotEqual, MacroAssembler::Address(inputGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
-        m_jit.loadPtr(MacroAssembler::Address(inputGPR, JSString::offsetOfValue()), resultGPR);
-        slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
-        m_jit.load32(MacroAssembler::Address(resultGPR, StringImpl::flagsOffset()), resultGPR);
-        m_jit.urshift64(MacroAssembler::TrustedImm32(StringImpl::s_flagCount), resultGPR);
-        slowPath.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR));
-        done.append(m_jit.jump());
-
-        isNotCell.link(&m_jit);
-        straightHash.append(m_jit.branchIfNotNumber(inputGPR));
-        straightHash.append(m_jit.branchIfInt32(JSValueRegs(inputGPR)));
-        slowPath.append(m_jit.jump());
-
-        straightHash.link(&m_jit);
-        m_jit.move(inputGPR, resultGPR);
-        m_jit.wangsInt64Hash(resultGPR, tempGPR);
-        done.append(m_jit.jump());
-
-        slowPath.link(&m_jit);
-        silentSpillAllRegisters(resultGPR);
-        callOperation(operationMapHash, resultGPR, inputGPR);
-        silentFillAllRegisters(resultGPR);
-        m_jit.exceptionCheck();
-
-        done.link(&m_jit);
-        int32Result(resultGPR, node);
-        break;
-    }
-    case GetMapBucket: {
-        SpeculateCellOperand map(this, node->child1());
-        JSValueOperand key(this, node->child2());
-        SpeculateInt32Operand hash(this, node->child3());
-        GPRTemporary mask(this);
-        GPRTemporary index(this);
-        GPRTemporary buffer(this);
-        GPRTemporary bucket(this);
-        GPRTemporary result(this);
-
-        GPRReg hashGPR = hash.gpr();
-        GPRReg mapGPR = map.gpr();
-        GPRReg maskGPR = mask.gpr();
-        GPRReg indexGPR = index.gpr();
-        GPRReg bufferGPR = buffer.gpr();
-        GPRReg bucketGPR = bucket.gpr();
-        GPRReg keyGPR = key.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        if (node->child1().useKind() == MapObjectUse)
-            speculateMapObject(node->child1(), mapGPR);
-        else if (node->child1().useKind() == SetObjectUse)
-            speculateSetObject(node->child1(), mapGPR);
-        else
-            RELEASE_ASSERT_NOT_REACHED();
-
-        m_jit.loadPtr(MacroAssembler::Address(mapGPR, node->child1().useKind() == MapObjectUse ? JSMap::offsetOfHashMapImpl() : JSSet::offsetOfHashMapImpl()), bufferGPR);
-        m_jit.load32(MacroAssembler::Address(bufferGPR, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()), maskGPR);
-        m_jit.loadPtr(MacroAssembler::Address(bufferGPR, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfBuffer()), bufferGPR);
-        m_jit.sub32(TrustedImm32(1), maskGPR);
-        m_jit.move(hashGPR, indexGPR);
-
-        MacroAssembler::Label loop = m_jit.label();
-        MacroAssembler::JumpList done;
-        MacroAssembler::JumpList slowPathCases;
-        MacroAssembler::JumpList loopAround;
-
-        m_jit.and32(maskGPR, indexGPR);
-        m_jit.loadPtr(MacroAssembler::BaseIndex(bufferGPR, indexGPR, MacroAssembler::TimesEight), bucketGPR);
-        m_jit.move(bucketGPR, resultGPR);
-        auto notPresentInTable = m_jit.branchPtr(MacroAssembler::Equal, 
-            bucketGPR, TrustedImmPtr(HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::emptyValue()));
-        loopAround.append(m_jit.branchPtr(MacroAssembler::Equal, 
-            bucketGPR, TrustedImmPtr(HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::deletedValue())));
-
-        m_jit.load64(MacroAssembler::Address(bucketGPR, HashMapBucket<HashMapBucketDataKey>::offsetOfKey()), bucketGPR);
-
-        // Perform Object.is()
-        done.append(m_jit.branch64(MacroAssembler::Equal, bucketGPR, keyGPR)); // They're definitely the same value, we found the bucket we were looking for!
-        auto oneIsntCell = m_jit.branchIfNotCell(JSValueRegs(bucketGPR));
-        // first is a cell here.
-        loopAround.append(m_jit.branchIfNotCell(JSValueRegs(keyGPR)));
-        // Both are cells here.
-        loopAround.append(m_jit.branch8(JITCompiler::NotEqual,
-            JITCompiler::Address(bucketGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
-        // The first is a string here.
-        slowPathCases.append(m_jit.branch8(JITCompiler::Equal,
-            JITCompiler::Address(keyGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
-        // The first is a string, but the second is not, we continue to loop around.
-        loopAround.append(m_jit.jump());
-
-        oneIsntCell.link(&m_jit);
-        // We've already done a 64-bit compare at this point, so if one is not a number, they're definitely not equal.
-        loopAround.append(m_jit.branchIfNotNumber(bucketGPR));
-        loopAround.append(m_jit.branchIfNotNumber(keyGPR));
-        // Both are definitely numbers. If we see a double, we go to the slow path.
-        slowPathCases.append(m_jit.branchIfNotInt32(bucketGPR));
-        slowPathCases.append(m_jit.branchIfNotInt32(keyGPR));
-        
-        loopAround.link(&m_jit);
-        m_jit.add32(TrustedImm32(1), indexGPR);
-        m_jit.jump().linkTo(loop, &m_jit);
-
-        slowPathCases.link(&m_jit);
-        silentSpillAllRegisters(indexGPR);
-        if (node->child1().useKind() == MapObjectUse)
-            callOperation(operationJSMapFindBucket, resultGPR, mapGPR, keyGPR, hashGPR);
-        else
-            callOperation(operationJSSetFindBucket, resultGPR, mapGPR, keyGPR, hashGPR);
-        silentFillAllRegisters(indexGPR);
-        m_jit.exceptionCheck();
-        done.append(m_jit.jump());
-
-        notPresentInTable.link(&m_jit);
-        m_jit.move(TrustedImmPtr(nullptr), resultGPR);
-        done.link(&m_jit);
-        cellResult(resultGPR, node);
-        break;
-    }
-
-    case LoadFromJSMapBucket: {
-        SpeculateCellOperand bucket(this, node->child1());
-        GPRTemporary result(this);
-
-        GPRReg bucketGPR = bucket.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        auto notBucket = m_jit.branchTestPtr(MacroAssembler::Zero, bucketGPR);
-        m_jit.load64(MacroAssembler::Address(bucketGPR, HashMapBucket<HashMapBucketDataKeyValue>::offsetOfValue()), resultGPR);
-        auto done = m_jit.jump();
-
-        notBucket.link(&m_jit);
-        m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), resultGPR);
-        done.link(&m_jit);
-        jsValueResult(resultGPR, node);
-        break;
-    }
-
-    case IsNonEmptyMapBucket: {
-        SpeculateCellOperand bucket(this, node->child1());
-        GPRTemporary result(this);
-
-        GPRReg bucketGPR = bucket.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.comparePtr(MacroAssembler::NotEqual, bucketGPR, TrustedImm32(0), resultGPR);
-        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
-        jsValueResult(resultGPR, node, DataFormatJSBoolean);
-        break;
-    }
-
     case IsObject: {
         JSValueOperand value(this, node->child1());
         GPRTemporary result(this, Reuse, value);
index 6956498..e7f9934 100644 (file)
@@ -94,12 +94,6 @@ void printInternal(PrintStream& out, UseKind useKind)
     case RegExpObjectUse:
         out.print("RegExpObject");
         return;
-    case MapObjectUse:
-        out.print("MapObjectUse");
-        return;
-    case SetObjectUse:
-        out.print("SetObjectUse");
-        return;
     case ObjectOrOtherUse:
         out.print("ObjectOrOther");
         return;
index a5c21c1..d2ef933 100644 (file)
@@ -63,8 +63,6 @@ enum UseKind {
     KnownStringUse,
     KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects).
     SymbolUse,
-    MapObjectUse,
-    SetObjectUse,
     StringObjectUse,
     StringOrStringObjectUse,
     NotStringVarUse,
@@ -136,10 +134,6 @@ inline SpeculatedType typeFilterFor(UseKind useKind)
         return SpecHeapTop & ~SpecObject;
     case SymbolUse:
         return SpecSymbol;
-    case MapObjectUse:
-        return SpecMapObject;
-    case SetObjectUse:
-        return SpecSetObject;
     case StringObjectUse:
         return SpecStringObject;
     case StringOrStringObjectUse:
@@ -227,8 +221,6 @@ inline bool isCell(UseKind kind)
     case SymbolUse:
     case StringObjectUse:
     case StringOrStringObjectUse:
-    case MapObjectUse:
-    case SetObjectUse:
         return true;
     default:
         return false;
index 398ce97..d2e16f3 100644 (file)
@@ -32,8 +32,6 @@
 #include "DFGArrayMode.h"
 #include "FTLAbstractHeap.h"
 #include "IndexingType.h"
-#include "JSMap.h"
-#include "JSSet.h"
 
 namespace JSC { namespace FTL {
 
@@ -103,13 +101,7 @@ namespace JSC { namespace FTL {
     macro(Structure_classInfo, Structure::classInfoOffset()) \
     macro(Structure_globalObject, Structure::globalObjectOffset()) \
     macro(Structure_prototype, Structure::prototypeOffset()) \
-    macro(Structure_structureID, Structure::structureIDOffset()) \
-    macro(JSMap_hashMapImpl, JSMap::offsetOfHashMapImpl()) \
-    macro(JSSet_hashMapImpl, JSSet::offsetOfHashMapImpl()) \
-    macro(HashMapImpl_capacity, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()) \
-    macro(HashMapImpl_buffer,  HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfBuffer()) \
-    macro(HashMapBucket_value, HashMapBucket<HashMapBucketDataKeyValue>::offsetOfValue()) \
-    macro(HashMapBucket_key, HashMapBucket<HashMapBucketDataKeyValue>::offsetOfKey()) \
+    macro(Structure_structureID, Structure::structureIDOffset())
 
 #define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
     macro(DirectArguments_storage, DirectArguments::storageOffset(), sizeof(EncodedJSValue)) \
index 8217783..e2c6266 100644 (file)
@@ -181,10 +181,6 @@ inline CapabilityLevel canCompile(Node* node)
     case Unreachable:
     case In:
     case IsJSArray:
-    case MapHash:
-    case GetMapBucket:
-    case LoadFromJSMapBucket:
-    case IsNonEmptyMapBucket:
     case IsEmpty:
     case IsUndefined:
     case IsBoolean:
@@ -429,8 +425,6 @@ CapabilityLevel canCompile(Graph& graph)
                 case StringObjectUse:
                 case StringOrStringObjectUse:
                 case SymbolUse:
-                case MapObjectUse:
-                case SetObjectUse:
                 case FinalObjectUse:
                 case RegExpObjectUse:
                 case NotCellUse:
index 91aaf58..5b2e20c 100644 (file)
@@ -70,7 +70,6 @@
 #include "JSCInlines.h"
 #include "JSGeneratorFunction.h"
 #include "JSLexicalEnvironment.h"
-#include "JSMap.h"
 #include "OperandsInlines.h"
 #include "ScopedArguments.h"
 #include "ScopedArgumentsTable.h"
@@ -899,18 +898,6 @@ private:
         case IsJSArray:
             compileIsJSArray();
             break;
-        case MapHash:
-            compileMapHash();
-            break;
-        case GetMapBucket:
-            compileGetMapBucket();
-            break;
-        case LoadFromJSMapBucket:
-            compileLoadFromJSMapBucket();
-            break;
-        case IsNonEmptyMapBucket:
-            compileIsNonEmptyMapBucket();
-            break;
         case IsObject:
             compileIsObject();
             break;
@@ -6302,229 +6289,6 @@ private:
         setBoolean(m_out.phi(Int32, notCellResult, cellResult));
     }
 
-    void compileMapHash()
-    {
-        LValue value = lowJSValue(m_node->child1());
-
-        LBasicBlock isCellCase = m_out.newBlock();
-        LBasicBlock notCell = m_out.newBlock();
-        LBasicBlock slowCase = m_out.newBlock();
-        LBasicBlock straightHash = m_out.newBlock();
-        LBasicBlock isNumberCase = m_out.newBlock();
-        LBasicBlock isStringCase = m_out.newBlock();
-        LBasicBlock nonEmptyStringCase = m_out.newBlock();
-        LBasicBlock continuation = m_out.newBlock();
-
-        m_out.branch(
-            isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(notCell));
-
-        LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
-        LValue isString = m_out.equal(m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoType), m_out.constInt32(StringType));
-        m_out.branch(
-            isString, unsure(isStringCase), unsure(straightHash));
-
-        m_out.appendTo(isStringCase, nonEmptyStringCase);
-        LValue stringImpl = m_out.loadPtr(value, m_heaps.JSString_value);
-        m_out.branch(
-            m_out.equal(stringImpl, m_out.constIntPtr(0)), rarely(slowCase), usually(nonEmptyStringCase));
-
-        m_out.appendTo(nonEmptyStringCase, notCell);
-        LValue hash = m_out.lShr(m_out.load32(stringImpl, m_heaps.StringImpl_hashAndFlags), m_out.constInt32(StringImpl::s_flagCount));
-        ValueFromBlock nonEmptyStringHashResult = m_out.anchor(hash);
-        m_out.branch(m_out.equal(hash, m_out.constInt32(0)),
-            rarely(slowCase), usually(continuation));
-
-        m_out.appendTo(notCell, isNumberCase);
-        m_out.branch(
-            isNumber(value), unsure(isNumberCase), unsure(straightHash));
-
-        m_out.appendTo(isNumberCase, straightHash);
-        m_out.branch(
-            isInt32(value), unsure(straightHash), unsure(slowCase));
-
-        m_out.appendTo(straightHash, slowCase);
-        // key += ~(key << 32);
-        LValue key = value;
-        LValue temp = key;
-        temp = m_out.shl(temp, m_out.constInt32(32));
-        temp = m_out.bitNot(temp);
-        key = m_out.add(key, temp);
-        // key ^= (key >> 22);
-        temp = key;
-        temp = m_out.lShr(temp, m_out.constInt32(22));
-        key = m_out.bitXor(key, temp);
-        // key += ~(key << 13);
-        temp = key;
-        temp = m_out.shl(temp, m_out.constInt32(13));
-        temp = m_out.bitNot(temp);
-        key = m_out.add(key, temp);
-        // key ^= (key >> 8);
-        temp = key;
-        temp = m_out.lShr(temp, m_out.constInt32(8));
-        key = m_out.bitXor(key, temp);
-        // key += (key << 3);
-        temp = key;
-        temp = m_out.shl(temp, m_out.constInt32(3));
-        key = m_out.add(key, temp);
-        // key ^= (key >> 15);
-        temp = key;
-        temp = m_out.lShr(temp, m_out.constInt32(15));
-        key = m_out.bitXor(key, temp);
-        // key += ~(key << 27);
-        temp = key;
-        temp = m_out.shl(temp, m_out.constInt32(27));
-        temp = m_out.bitNot(temp);
-        key = m_out.add(key, temp);
-        // key ^= (key >> 31);
-        temp = key;
-        temp = m_out.lShr(temp, m_out.constInt32(31));
-        key = m_out.bitXor(key, temp);
-        key = m_out.castToInt32(key);
-
-        ValueFromBlock fastResult = m_out.anchor(key);
-        m_out.jump(continuation);
-
-        m_out.appendTo(slowCase, continuation);
-        ValueFromBlock slowResult = m_out.anchor(
-            vmCall(Int32, m_out.operation(operationMapHash), m_callFrame, value));
-        m_out.jump(continuation);
-
-        m_out.appendTo(continuation, lastNext);
-        setInt32(m_out.phi(Int32, fastResult, slowResult, nonEmptyStringHashResult));
-    }
-
-    void compileGetMapBucket()
-    {
-        LBasicBlock loopStart = m_out.newBlock();
-        LBasicBlock loopAround = m_out.newBlock();
-        LBasicBlock slowPath = m_out.newBlock();
-        LBasicBlock notPresentInTable = m_out.newBlock();
-        LBasicBlock notEmptyValue = m_out.newBlock();
-        LBasicBlock notDeletedValue = m_out.newBlock();
-        LBasicBlock notBitEqual = m_out.newBlock();
-        LBasicBlock bucketKeyNotCell = m_out.newBlock();
-        LBasicBlock bucketKeyIsCell = m_out.newBlock();
-        LBasicBlock bothAreCells = m_out.newBlock();
-        LBasicBlock bucketKeyIsString = m_out.newBlock();
-        LBasicBlock bucketKeyIsNumber = m_out.newBlock();
-        LBasicBlock bothAreNumbers = m_out.newBlock();
-        LBasicBlock bucketKeyIsInt32 = m_out.newBlock();
-        LBasicBlock continuation = m_out.newBlock();
-
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(loopStart);
-
-        LValue map;
-        if (m_node->child1().useKind() == MapObjectUse)
-            map = lowMapObject(m_node->child1());
-        else if (m_node->child1().useKind() == SetObjectUse)
-            map = lowSetObject(m_node->child1());
-        else
-            RELEASE_ASSERT_NOT_REACHED();
-
-        LValue key = lowJSValue(m_node->child2());
-        LValue hash = lowInt32(m_node->child3());
-
-        LValue hashMapImpl = m_out.loadPtr(map, m_node->child1().useKind() == MapObjectUse ? m_heaps.JSMap_hashMapImpl : m_heaps.JSSet_hashMapImpl);
-        LValue buffer = m_out.loadPtr(hashMapImpl, m_heaps.HashMapImpl_buffer);
-        LValue mask = m_out.sub(m_out.load32(hashMapImpl, m_heaps.HashMapImpl_capacity), m_out.int32One);
-
-        ValueFromBlock indexStart = m_out.anchor(hash);
-        m_out.jump(loopStart);
-
-        m_out.appendTo(loopStart, notEmptyValue);
-        LValue unmaskedIndex = m_out.phi(Int32, indexStart);
-        LValue index = m_out.bitAnd(mask, unmaskedIndex);
-        LValue hashMapBucket = m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), buffer, m_out.zeroExt(index, Int64), ScaleEight));
-        ValueFromBlock bucketResult = m_out.anchor(hashMapBucket);
-        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::emptyValue())),
-            unsure(notPresentInTable), unsure(notEmptyValue));
-
-        m_out.appendTo(notEmptyValue, notDeletedValue);
-        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::deletedValue())),
-            unsure(loopAround), unsure(notDeletedValue));
-
-        m_out.appendTo(notDeletedValue, notBitEqual);
-        LValue bucketKey = m_out.load64(hashMapBucket, m_heaps.HashMapBucket_key);
-        // Perform Object.is()
-        m_out.branch(m_out.equal(key, bucketKey),
-            unsure(continuation), unsure(notBitEqual));
-
-        m_out.appendTo(notBitEqual, bucketKeyIsCell);
-        m_out.branch(isCell(bucketKey),
-            unsure(bucketKeyIsCell), unsure(bucketKeyNotCell));
-
-        m_out.appendTo(bucketKeyIsCell, bothAreCells);
-        m_out.branch(isCell(key),
-            unsure(bothAreCells), unsure(loopAround));
-
-        m_out.appendTo(bothAreCells, bucketKeyIsString);
-        m_out.branch(isString(bucketKey),
-            unsure(bucketKeyIsString), unsure(loopAround));
-
-        m_out.appendTo(bucketKeyIsString, bucketKeyNotCell);
-        m_out.branch(isString(key),
-            unsure(slowPath), unsure(loopAround));
-
-        m_out.appendTo(bucketKeyNotCell, bucketKeyIsNumber);
-        m_out.branch(isNotNumber(bucketKey),
-            unsure(loopAround), unsure(bucketKeyIsNumber));
-
-        m_out.appendTo(bucketKeyIsNumber, bothAreNumbers);
-        m_out.branch(isNotNumber(key),
-            unsure(loopAround), unsure(bothAreNumbers));
-
-        m_out.appendTo(bothAreNumbers, bucketKeyIsInt32);
-        m_out.branch(isNotInt32(bucketKey),
-            unsure(slowPath), unsure(bucketKeyIsInt32));
-
-        m_out.appendTo(bucketKeyIsInt32, loopAround);
-        m_out.branch(isNotInt32(key),
-            unsure(slowPath), unsure(loopAround));
-
-        m_out.appendTo(loopAround, slowPath);
-        m_out.addIncomingToPhi(unmaskedIndex, m_out.anchor(m_out.add(index, m_out.int32One)));
-        m_out.jump(loopStart);
-
-        m_out.appendTo(slowPath, notPresentInTable);
-        ValueFromBlock slowPathResult = m_out.anchor(vmCall(pointerType(),
-            m_out.operation(m_node->child1().useKind() == MapObjectUse ? operationJSMapFindBucket : operationJSSetFindBucket), m_callFrame, map, key, hash));
-        m_out.jump(continuation);
-
-        m_out.appendTo(notPresentInTable, continuation);
-        ValueFromBlock notPresentResult = m_out.anchor(m_out.constIntPtr(0));
-        m_out.jump(continuation);
-
-        m_out.appendTo(continuation, lastNext);
-        setMapBucket(m_out.phi(pointerType(), bucketResult, slowPathResult, notPresentResult));
-    }
-
-    void compileLoadFromJSMapBucket()
-    {
-        LValue mapBucket = lowMapBucket(m_node->child1());
-
-        LBasicBlock continuation = m_out.newBlock();
-        LBasicBlock hasBucket = m_out.newBlock();
-
-        ValueFromBlock noBucketResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
-
-        m_out.branch(m_out.equal(mapBucket, m_out.constIntPtr(0)),
-            unsure(continuation), unsure(hasBucket));
-
-        LBasicBlock lastNext = m_out.appendTo(hasBucket, continuation);
-        ValueFromBlock bucketResult = m_out.anchor(m_out.load64(mapBucket, m_heaps.HashMapBucket_value));
-        m_out.jump(continuation);
-
-        m_out.appendTo(continuation, lastNext);
-        setJSValue(m_out.phi(Int64, noBucketResult, bucketResult));
-    }
-
-    void compileIsNonEmptyMapBucket()
-    {
-        LValue bucket = lowMapBucket(m_node->child1());
-        LValue result = m_out.notEqual(bucket, m_out.constIntPtr(0));
-        setBoolean(result);
-    }
-
     void compileIsObjectOrNull()
     {
         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
@@ -10215,20 +9979,6 @@ private:
         speculateRegExpObject(edge, result);
         return result;
     }
-
-    LValue lowMapObject(Edge edge)
-    {
-        LValue result = lowCell(edge);
-        speculateMapObject(edge, result);
-        return result;
-    }
-
-    LValue lowSetObject(Edge edge)
-    {
-        LValue result = lowCell(edge);
-        speculateSetObject(edge, result);
-        return result;
-    }
     
     LValue lowString(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     {
@@ -10352,17 +10102,6 @@ private:
         setStorage(edge.node(), result);
         return result;
     }
-
-    LValue lowMapBucket(Edge edge)
-    {
-        LoweredNodeValue value = m_mapBucketValues.get(edge.node());
-        if (isValid(value))
-            return value.value();
-        
-        LValue result = lowCell(edge);
-        setStorage(edge.node(), result);
-        return result;
-    }
     
     LValue strictInt52ToInt32(Edge edge, LValue value)
     {
@@ -10666,12 +10405,6 @@ private:
         case RegExpObjectUse:
             speculateRegExpObject(edge);
             break;
-        case MapObjectUse:
-            speculateMapObject(edge);
-            break;
-        case SetObjectUse:
-            speculateSetObject(edge);
-            break;
         case StringUse:
             speculateString(edge);
             break;
@@ -11000,28 +10733,6 @@ private:
     {
         speculateRegExpObject(edge, lowCell(edge));
     }
-
-    void speculateMapObject(Edge edge, LValue cell)
-    {
-        FTL_TYPE_CHECK(
-            jsValueValue(cell), edge, SpecMapObject, isNotType(cell, JSMapType));
-    }
-
-    void speculateMapObject(Edge edge)
-    {
-        speculateMapObject(edge, lowCell(edge));
-    }
-
-    void speculateSetObject(Edge edge, LValue cell)
-    {
-        FTL_TYPE_CHECK(
-            jsValueValue(cell), edge, SpecSetObject, isNotType(cell, JSSetType));
-    }
-
-    void speculateSetObject(Edge edge)
-    {
-        speculateSetObject(edge, lowCell(edge));
-    }
     
     void speculateString(Edge edge, LValue cell)
     {
@@ -11790,10 +11501,6 @@ private:
     {
         m_storageValues.set(node, LoweredNodeValue(value, m_highBlock));
     }
-    void setMapBucket(Node* node, LValue value)
-    {
-        m_mapBucketValues.set(node, LoweredNodeValue(value, m_highBlock));
-    }
     void setDouble(Node* node, LValue value)
     {
         m_doubleValues.set(node, LoweredNodeValue(value, m_highBlock));
@@ -11827,10 +11534,6 @@ private:
     {
         setStorage(m_node, value);
     }
-    void setMapBucket(LValue value)
-    {
-        setMapBucket(m_node, value);
-    }
     void setDouble(LValue value)
     {
         setDouble(m_node, value);
@@ -12014,7 +11717,6 @@ private:
     HashMap<Node*, LoweredNodeValue> m_jsValueValues;
     HashMap<Node*, LoweredNodeValue> m_booleanValues;
     HashMap<Node*, LoweredNodeValue> m_storageValues;
-    HashMap<Node*, LoweredNodeValue> m_mapBucketValues;
     HashMap<Node*, LoweredNodeValue> m_doubleValues;
     
     // This is a bit of a hack. It prevents B3 from having to do CSE on loading of arguments.
index 5c29ef5..5200cf5 100644 (file)
@@ -626,52 +626,6 @@ void AssemblyHelpers::emitDumbVirtualCall(CallLinkInfo* info)
         });
 }
 
-#if USE(JSVALUE64)
-void AssemblyHelpers::wangsInt64Hash(GPRReg inputAndResult, GPRReg scratch)
-{
-    GPRReg input = inputAndResult;
-    // key += ~(key << 32);
-    move(input, scratch);
-    lshift64(TrustedImm32(32), scratch);
-    not64(scratch);
-    add64(scratch, input);
-    // key ^= (key >> 22);
-    move(input, scratch);
-    urshift64(TrustedImm32(22), scratch);
-    xor64(scratch, input);
-    // key += ~(key << 13);
-    move(input, scratch);
-    lshift64(TrustedImm32(13), scratch);
-    not64(scratch);
-    add64(scratch, input);
-    // key ^= (key >> 8);
-    move(input, scratch);
-    urshift64(TrustedImm32(8), scratch);
-    xor64(scratch, input);
-    // key += (key << 3);
-    move(input, scratch);
-    lshift64(TrustedImm32(3), scratch);
-    add64(scratch, input);
-    // key ^= (key >> 15);
-    move(input, scratch);
-    urshift64(TrustedImm32(15), scratch);
-    xor64(scratch, input);
-    // key += ~(key << 27);
-    move(input, scratch);
-    lshift64(TrustedImm32(27), scratch);
-    not64(scratch);
-    add64(scratch, input);
-    // key ^= (key >> 31);
-    move(input, scratch);
-    urshift64(TrustedImm32(31), scratch);
-    xor64(scratch, input);
-
-    // return static_cast<unsigned>(result)
-    void* mask = bitwise_cast<void*>(static_cast<uintptr_t>(UINT_MAX));
-    and64(TrustedImmPtr(mask), inputAndResult);
-}
-#endif // USE(JSVALUE64)
-
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 3427fc0..4590a73 100644 (file)
@@ -61,7 +61,7 @@ public:
             ASSERT(m_baselineCodeBlock->jitType() == JITCode::None || JITCode::isBaselineCode(m_baselineCodeBlock->jitType()));
         }
     }
-
+    
     CodeBlock* codeBlock() { return m_codeBlock; }
     VM* vm() { return m_vm; }
     AssemblerType_T& assembler() { return m_assembler; }
@@ -1528,10 +1528,6 @@ public:
         emitAllocateJSObject<ClassType>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
         storePtr(TrustedImmPtr(structure->classInfo()), Address(resultGPR, JSDestructibleObject::classInfoOffset()));
     }
-
-#if USE(JSVALUE64)
-    void wangsInt64Hash(GPRReg inputAndResult, GPRReg scratch);
-#endif
     
 protected:
     VM* m_vm;
index 44ac55d..216adf5 100644 (file)
@@ -205,7 +205,6 @@ typedef JSCell* (JIT_OPERATION *C_JITOperation_EStZ)(ExecState*, Structure*, int
 typedef JSCell* (JIT_OPERATION *C_JITOperation_EStZZ)(ExecState*, Structure*, int32_t, int32_t);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_EZ)(ExecState*, int32_t);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_EJscI)(ExecState*, JSScope*, UniquedStringImpl*);
-typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJZ)(ExecState*, JSCell*, EncodedJSValue, int32_t);
 typedef double (JIT_OPERATION *D_JITOperation_D)(double);
 typedef double (JIT_OPERATION *D_JITOperation_G)(JSGlobalObject*);
 typedef double (JIT_OPERATION *D_JITOperation_DD)(double, double);
index c20aa84..e646936 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC {
 
 ModuleAnalyzer::ModuleAnalyzer(ExecState* exec, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables)
     : m_vm(&exec->vm())
-    , m_moduleRecord(exec->vm(), JSModuleRecord::create(exec, exec->vm(), exec->lexicalGlobalObject()->moduleRecordStructure(), moduleKey, sourceCode, declaredVariables, lexicalVariables))
+    , m_moduleRecord(exec->vm(), JSModuleRecord::create(exec->vm(), exec->lexicalGlobalObject()->moduleRecordStructure(), moduleKey, sourceCode, declaredVariables, lexicalVariables))
 {
 }
 
diff --git a/Source/JavaScriptCore/runtime/HashMapImpl.cpp b/Source/JavaScriptCore/runtime/HashMapImpl.cpp
deleted file mode 100644 (file)
index 5011a8f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "HashMapImpl.h"
-
-#include "CopiedBlockInlines.h"
-#include "CopyVisitorInlines.h"
-
-namespace JSC {
-
-template<>
-const JS_EXPORTDATA ClassInfo HashMapBucket<HashMapBucketDataKey>::s_info =
-    { "HashMapBucket", nullptr, 0, CREATE_METHOD_TABLE(HashMapBucket<HashMapBucketDataKey>) };
-
-template<>
-const JS_EXPORTDATA ClassInfo HashMapBucket<HashMapBucketDataKeyValue>::s_info =
-    { "HashMapBucket", nullptr, 0, CREATE_METHOD_TABLE(HashMapBucket<HashMapBucketDataKeyValue>) };
-
-template <typename Data>
-void HashMapBucket<Data>::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    HashMapBucket* thisObject = jsCast<HashMapBucket*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.append(&thisObject->m_next);
-    visitor.append(&thisObject->m_prev);
-
-    static_assert(sizeof(Data) % sizeof(WriteBarrier<Unknown>) == 0, "We assume that these are filled with WriteBarrier<Unknown> members only.");
-    visitor.appendValues(bitwise_cast<WriteBarrier<Unknown>*>(&thisObject->m_data), sizeof(Data) / sizeof(WriteBarrier<Unknown>));
-}
-
-template<>
-const JS_EXPORTDATA ClassInfo HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::s_info =
-    { "HashMapImpl", nullptr, 0, CREATE_METHOD_TABLE(HashMapImpl<HashMapBucket<HashMapBucketDataKey>>) };
-
-template<>
-const JS_EXPORTDATA ClassInfo HashMapImpl<HashMapBucket<HashMapBucketDataKeyValue>>::s_info =
-    { "HashMapImpl", nullptr, 0, CREATE_METHOD_TABLE(HashMapImpl<HashMapBucket<HashMapBucketDataKeyValue>>) };
-
-template <typename HashMapBucket>
-void HashMapImpl<HashMapBucket>::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    HashMapImpl* thisObject = jsCast<HashMapImpl*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.append(&thisObject->m_head);
-    visitor.append(&thisObject->m_tail);
-
-    visitor.copyLater(thisObject, MapBackingStoreCopyToken, thisObject->m_buffer.get(), thisObject->bufferSizeInBytes());
-}
-
-template <typename HashMapBucket>
-void HashMapImpl<HashMapBucket>::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
-{
-    Base::copyBackingStore(cell, visitor, token);
-
-    HashMapImpl* thisObject = jsCast<HashMapImpl*>(cell);
-    if (token == MapBackingStoreCopyToken && visitor.checkIfShouldCopy(thisObject->m_buffer.get())) {
-        HashMapBufferType* oldBuffer = thisObject->m_buffer.get();
-        size_t bufferSizeInBytes = thisObject->bufferSizeInBytes();
-        HashMapBufferType* newBuffer = static_cast<HashMapBufferType*>(visitor.allocateNewSpace(bufferSizeInBytes));
-        memcpy(newBuffer, oldBuffer, bufferSizeInBytes);
-        thisObject->m_buffer.setWithoutBarrier(newBuffer);
-        visitor.didCopy(oldBuffer, bufferSizeInBytes);
-    }
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/HashMapImpl.h b/Source/JavaScriptCore/runtime/HashMapImpl.h
deleted file mode 100644 (file)
index 1658cf3..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#include "JSCInlines.h"
-#include "JSObject.h"
-
-namespace JSC {
-
-struct HashMapBucketDataKey {
-    WriteBarrier<Unknown> key;
-};
-
-struct HashMapBucketDataKeyValue {
-    WriteBarrier<Unknown> key;
-    WriteBarrier<Unknown> value;
-};
-
-template <typename Data>
-class HashMapBucket : public JSCell {
-    typedef JSCell Base;
-
-    template <typename T = Data>
-    static typename std::enable_if<std::is_same<T, HashMapBucketDataKey>::value, Structure*>::type selectStructure(VM& vm)
-    {
-        return vm.hashMapBucketSetStructure.get();
-    }
-
-    template <typename T = Data>
-    static typename std::enable_if<std::is_same<T, HashMapBucketDataKeyValue>::value, Structure*>::type selectStructure(VM& vm)
-    {
-        return vm.hashMapBucketMapStructure.get();
-    }
-
-public:
-    DECLARE_EXPORT_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
-    }
-
-    static HashMapBucket* create(VM& vm)
-    {
-        HashMapBucket* bucket = new (NotNull, allocateCell<HashMapBucket<Data>>(vm.heap)) HashMapBucket(vm, selectStructure(vm));
-        bucket->finishCreation(vm);
-        ASSERT(!bucket->next());
-        ASSERT(!bucket->prev());
-        return bucket;
-    }
-
-    HashMapBucket(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    { }
-
-    ALWAYS_INLINE void setNext(VM& vm, HashMapBucket* bucket)
-    {
-        m_next.set(vm, this, bucket);
-    }
-    ALWAYS_INLINE void setPrev(VM& vm, HashMapBucket* bucket)
-    {
-        m_prev.set(vm, this, bucket);
-    }
-
-    ALWAYS_INLINE void setKey(VM& vm, JSValue key)
-    {
-        m_data.key.set(vm, this, key);
-    }
-
-    template <typename T = Data>
-    ALWAYS_INLINE typename std::enable_if<std::is_same<T, HashMapBucketDataKeyValue>::value>::type setValue(VM& vm, JSValue value)
-    {
-        m_data.value.set(vm, this, value);
-    }
-    template <typename T = Data>
-    ALWAYS_INLINE typename std::enable_if<std::is_same<T, HashMapBucketDataKey>::value>::type setValue(VM&, JSValue) { }
-
-    ALWAYS_INLINE JSValue key() const { return m_data.key.get(); }
-
-    template <typename T = Data>
-    ALWAYS_INLINE typename std::enable_if<std::is_same<T, HashMapBucketDataKeyValue>::value, JSValue>::type value() const
-    {
-        return m_data.value.get();
-    }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    ALWAYS_INLINE HashMapBucket* next() const { return m_next.get(); }
-    ALWAYS_INLINE HashMapBucket* prev() const { return m_prev.get(); }
-
-    ALWAYS_INLINE bool deleted() const { return m_deleted; }
-    ALWAYS_INLINE void setDeleted(bool deleted) { m_deleted = deleted; }
-
-    static ptrdiff_t offsetOfKey()
-    {
-        return OBJECT_OFFSETOF(HashMapBucket, m_data) + OBJECT_OFFSETOF(Data, key);
-    }
-
-    template <typename T = Data>
-    static typename std::enable_if<std::is_same<T, HashMapBucketDataKeyValue>::value, ptrdiff_t>::type offsetOfValue()
-    {
-        return OBJECT_OFFSETOF(HashMapBucket, m_data) + OBJECT_OFFSETOF(Data, value);
-    }
-
-private:
-    Data m_data;
-    WriteBarrier<HashMapBucket> m_next;
-    WriteBarrier<HashMapBucket> m_prev;
-    bool m_deleted { false };
-};
-
-template <typename BucketType>
-class HashMapBuffer {
-public:
-    HashMapBuffer() = delete;
-
-    static size_t allocationSize(uint32_t capacity)
-    {
-        return capacity * sizeof(BucketType*);
-    }
-
-    ALWAYS_INLINE BucketType** buffer() const
-    {
-        return bitwise_cast<BucketType**>(this);
-    }
-
-    static HashMapBuffer* create(ExecState* exec, VM& vm, JSCell* owner, uint32_t capacity)
-    {
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        size_t allocationSize = HashMapBuffer::allocationSize(capacity);
-        void* data = nullptr;
-        DeferGCForAWhile defer(vm.heap);
-        if (!vm.heap.tryAllocateStorage(owner, allocationSize, &data)) {
-            throwOutOfMemoryError(exec, scope);
-            return nullptr;
-        }
-
-        HashMapBuffer* buffer = static_cast<HashMapBuffer*>(data);
-        memset(buffer, -1, allocationSize);
-        return buffer;
-    }
-};
-
-ALWAYS_INLINE static bool areKeysEqual(ExecState* exec, JSValue a, JSValue b)
-{
-    // We want +0 and -0 to be compared to true here. sameValue() itself doesn't
-    // guarantee that, however, we normalize all keys before comparing and storing
-    // them in the map. The normalization will convert -0.0 and 0.0 to the integer
-    // representation for 0.
-    return sameValue(exec, a, b);
-}
-
-ALWAYS_INLINE JSValue normalizeMapKey(JSValue key)
-{
-    if (!key.isNumber())
-        return key;
-
-    if (key.isInt32())
-        return key;
-
-    double d = key.asDouble();
-    if (std::isnan(d))
-        return key;
-
-    int i = static_cast<int>(d);
-    if (i == d) {
-        // When a key is -0, we convert it to positive zero.
-        // When a key is the double representation for an integer, we convert it to an integer.
-        return jsNumber(i);
-    }
-    // This means key is definitely not negative zero, and it's definitely not a double representation of an integer. 
-    return key;
-}
-
-ALWAYS_INLINE uint32_t jsMapHash(ExecState* exec, VM& vm, JSValue value)
-{
-    ASSERT_WITH_MESSAGE(normalizeMapKey(value) == value, "We expect normalized values flowing into this function.");
-
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (value.isString()) {
-        JSString* string = asString(value);
-        const String& wtfString = string->value(exec);
-        if (UNLIKELY(scope.exception()))
-            return UINT_MAX;
-        return wtfString.impl()->hash();
-    }
-
-    auto wangsInt64Hash = [] (uint64_t key) -> uint32_t {
-        key += ~(key << 32);
-        key ^= (key >> 22);
-        key += ~(key << 13);
-        key ^= (key >> 8);
-        key += (key << 3);
-        key ^= (key >> 15);
-        key += ~(key << 27);
-        key ^= (key >> 31);
-        return static_cast<unsigned>(key);
-    };
-    uint64_t rawValue = JSValue::encode(value);
-    return wangsInt64Hash(rawValue);
-}
-
-template <typename HashMapBucketType>
-class HashMapImpl : public JSCell {
-    typedef JSCell Base;
-    typedef HashMapBuffer<HashMapBucketType> HashMapBufferType;
-
-    template <typename T = HashMapBucketType>
-    static typename std::enable_if<std::is_same<T, HashMapBucket<HashMapBucketDataKey>>::value, Structure*>::type selectStructure(VM& vm)
-    {
-        return vm.hashMapImplSetStructure.get();
-    }
-
-    template <typename T = HashMapBucketType>
-    static typename std::enable_if<std::is_same<T, HashMapBucket<HashMapBucketDataKeyValue>>::value, Structure*>::type selectStructure(VM& vm)
-    {
-        return vm.hashMapImplMapStructure.get();
-    }
-
-public:
-    DECLARE_EXPORT_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
-    }
-
-    static HashMapImpl* create(ExecState* exec, VM& vm)
-    {
-        ASSERT_WITH_MESSAGE(HashMapBucket<HashMapBucketDataKey>::offsetOfKey() == HashMapBucket<HashMapBucketDataKeyValue>::offsetOfKey(), "We assume this to be true in the DFG and FTL JIT.");
-
-        HashMapImpl* impl = new (NotNull, allocateCell<HashMapImpl>(vm.heap)) HashMapImpl(vm, selectStructure(vm));
-        impl->finishCreation(exec, vm);
-        return impl;
-    }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
-
-    HashMapImpl(VM& vm, Structure* structure)
-        : Base(vm, structure)
-        , m_size(0)
-        , m_deleteCount(0)
-        , m_capacity(4)
-    {
-    }
-
-    ALWAYS_INLINE HashMapBucketType** buffer() const
-    {
-        return m_buffer.get()->buffer();
-    }
-
-    void finishCreation(ExecState* exec, VM& vm)
-    {
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        Base::finishCreation(vm);
-
-        makeAndSetNewBuffer(exec, vm);
-        if (UNLIKELY(scope.exception()))
-            return;
-
-        m_head.set(vm, this, HashMapBucketType::create(vm));
-        m_tail.set(vm, this, HashMapBucketType::create(vm));
-
-        m_head->setNext(vm, m_tail.get());
-        m_tail->setPrev(vm, m_head.get());
-        m_head->setDeleted(true);
-        m_tail->setDeleted(true);
-
-    }
-
-    static HashMapBucketType* emptyValue()
-    {
-        return bitwise_cast<HashMapBucketType*>(static_cast<uintptr_t>(-1));
-    }
-
-    static ALWAYS_INLINE bool isEmpty(HashMapBucketType* bucket)
-    {
-        return bucket == emptyValue();
-    }
-
-    static HashMapBucketType* deletedValue()
-    {
-        return bitwise_cast<HashMapBucketType*>(static_cast<uintptr_t>(-3));
-    }
-
-    static ALWAYS_INLINE bool isDeleted(HashMapBucketType* bucket)
-    {
-        return bucket == deletedValue();
-    }
-
-    ALWAYS_INLINE HashMapBucketType** findBucket(ExecState* exec, JSValue key)
-    {
-        VM& vm = exec->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        key = normalizeMapKey(key);
-        uint32_t hash = jsMapHash(exec, vm, key);
-        if (UNLIKELY(scope.exception()))
-            return nullptr;
-        return findBucket(exec, key, hash);
-    }
-
-    ALWAYS_INLINE HashMapBucketType** findBucket(ExecState* exec, JSValue key, uint32_t hash)
-    {
-        ASSERT_WITH_MESSAGE(normalizeMapKey(key) == key, "We expect normalized values flowing into this function.");
-        return findBucketAlreadyHashedAndNormalized(exec, key, hash);
-    }
-
-    ALWAYS_INLINE JSValue get(ExecState* exec, JSValue key)
-    {
-        if (HashMapBucketType** bucket = findBucket(exec, key))
-            return (*bucket)->value();
-        return jsUndefined();
-    }
-
-    ALWAYS_INLINE bool has(ExecState* exec, JSValue key)
-    {
-        return !!findBucket(exec, key);
-    }
-
-    ALWAYS_INLINE void add(ExecState* exec, JSValue key, JSValue value = JSValue())
-    {
-        key = normalizeMapKey(key);
-
-        VM& vm = exec->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        const uint32_t mask = m_capacity - 1;
-        uint32_t index = jsMapHash(exec, vm, key) & mask;
-        if (UNLIKELY(scope.exception()))
-            return;
-        HashMapBucketType** buffer = this->buffer();
-        HashMapBucketType* bucket = buffer[index];
-        while (!isEmpty(bucket)) {
-            if (!isDeleted(bucket) && areKeysEqual(exec, key, bucket->key())) {
-                bucket->setValue(vm, value);
-                return;
-            }
-            index = (index + 1) & mask;
-            bucket = buffer[index];
-        }
-
-        HashMapBucketType* newEntry = m_tail.get();
-        buffer[index] = newEntry;
-        newEntry->setKey(vm, key);
-        newEntry->setValue(vm, value);
-        newEntry->setDeleted(false);
-        HashMapBucketType* newTail = HashMapBucketType::create(vm);
-        m_tail.set(vm, this, newTail);
-        newTail->setPrev(vm, newEntry);
-        newTail->setDeleted(true);
-        newEntry->setNext(vm, newTail);
-        uint32_t newSize = ++m_size;
-        if (2*newSize > m_capacity)
-            rehash(exec);
-    }
-
-    ALWAYS_INLINE bool remove(ExecState* exec, JSValue key)
-    {
-        HashMapBucketType** bucket = findBucket(exec, key);
-        if (!bucket)
-            return false;
-
-        VM& vm = exec->vm();
-        HashMapBucketType* impl = *bucket;
-        impl->next()->setPrev(vm, impl->prev());
-        impl->prev()->setNext(vm, impl->next());
-        impl->setDeleted(true);
-
-        *bucket = deletedValue();
-
-        m_deleteCount++;
-
-        return true;
-    }
-
-    ALWAYS_INLINE uint32_t size() const
-    {
-        RELEASE_ASSERT(m_size >= m_deleteCount);
-        return m_size - m_deleteCount;
-    }
-
-    ALWAYS_INLINE void clear(ExecState* exec)
-    {
-        VM& vm = exec->vm();
-        m_size = 0;
-        m_deleteCount = 0;
-        HashMapBucketType* head = m_head.get();
-        HashMapBucketType* bucket = m_head->next();
-        HashMapBucketType* tail = m_tail.get();
-        while (bucket != tail) {
-            HashMapBucketType* next = bucket->next();
-            // We restart each iterator by pointing it to the head of the list.
-            bucket->setNext(vm, head);
-            bucket = next;
-        }
-        m_head->setNext(vm, m_tail.get());
-        m_tail->setPrev(vm, m_head.get());
-        m_capacity = 4;
-        makeAndSetNewBuffer(exec, vm);
-    }
-
-    ALWAYS_INLINE size_t bufferSizeInBytes() const
-    {
-        return m_capacity * sizeof(HashMapBucketType*);
-    }
-
-    static ptrdiff_t offsetOfBuffer()
-    {
-        return OBJECT_OFFSETOF(HashMapImpl<HashMapBucketType>, m_buffer);
-    }
-
-    static ptrdiff_t offsetOfCapacity()
-    {
-        return OBJECT_OFFSETOF(HashMapImpl<HashMapBucketType>, m_capacity);
-    }
-
-    HashMapBucketType* head() { return m_head.get(); }
-    HashMapBucketType* tail() { return m_tail.get(); }
-
-    size_t approximateSize() const
-    {
-        size_t size = sizeof(HashMapImpl);
-        size += bufferSizeInBytes();
-        size += 2 * sizeof(HashMapBucketType); // Head and tail members.
-        size += (m_deleteCount + m_size) * sizeof(HashMapBucketType); // Number of members on the list.
-        return size;
-    }
-
-private:
-    ALWAYS_INLINE HashMapBucketType** findBucketAlreadyHashedAndNormalized(ExecState* exec, JSValue key, uint32_t hash)
-    {
-        const uint32_t mask = m_capacity - 1;
-        uint32_t index = hash & mask;
-        HashMapBucketType** buffer = this->buffer();
-        HashMapBucketType* bucket = buffer[index];
-
-        while (!isEmpty(bucket)) {
-            if (!isDeleted(bucket) && areKeysEqual(exec, key, bucket->key()))
-                return buffer + index;
-            index = (index + 1) & mask;
-            bucket = buffer[index];
-        }
-        return nullptr;
-    }
-
-    void rehash(ExecState* exec)
-    {
-        VM& vm = exec->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        m_capacity = m_capacity * 2;
-        makeAndSetNewBuffer(exec, vm);
-        if (UNLIKELY(scope.exception()))
-            return;
-
-        HashMapBucketType* iter = m_head->next();
-        HashMapBucketType* end = m_tail.get();
-        const uint32_t mask = m_capacity - 1;
-        RELEASE_ASSERT(!(m_capacity & (m_capacity - 1)));
-        HashMapBucketType** buffer = this->buffer();
-        while (iter != end) {
-            uint32_t index = jsMapHash(exec, vm, iter->key()) & mask;
-            ASSERT_WITH_MESSAGE(!scope.exception(), "All keys should already be hashed before, so this should not throw because it won't resolve ropes.");
-            {
-                HashMapBucketType* bucket = buffer[index];
-                while (!isEmpty(bucket)) {
-                    index = (index + 1) & mask;
-                    bucket = buffer[index];
-                }
-            }
-            buffer[index] = iter;
-            iter = iter->next();
-        }
-    }
-
-    void makeAndSetNewBuffer(ExecState* exec, VM& vm)
-    {
-        ASSERT(!(m_capacity & (m_capacity - 1)));
-
-        HashMapBufferType* buffer = HashMapBufferType::create(exec, vm, this, m_capacity);
-        if (UNLIKELY(!buffer))
-            return;
-
-        m_buffer.set(vm, this, buffer);
-        if (!ASSERT_DISABLED) {
-            for (unsigned i = 0; i < m_capacity; i++)
-                ASSERT(isEmpty(this->buffer()[i]));
-        }
-    }
-
-    WriteBarrier<HashMapBucketType> m_head;
-    WriteBarrier<HashMapBucketType> m_tail;
-    CopyBarrier<HashMapBufferType> m_buffer;
-    uint32_t m_size;
-    uint32_t m_deleteCount;
-    uint32_t m_capacity;
-};
-
-} // namespace JSC
index d988110..4a07939 100644 (file)
@@ -62,9 +62,6 @@ enum JS_EXPORT_PRIVATE Intrinsic {
     IsRegExpObjectIntrinsic,
     IsTypedArrayViewIntrinsic,
     BoundThisNoArgsFunctionCallIntrinsic,
-    JSMapGetIntrinsic,
-    JSMapHasIntrinsic,
-    JSSetHasIntrinsic,
 
     // Getter intrinsics.
     TypedArrayLengthIntrinsic,
index 9f2e7c3..a4f6f68 100644 (file)
@@ -606,9 +606,6 @@ inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) !=
 
 bool isThisValueAltered(const PutPropertySlot&, JSObject* baseObject);
 
-// See section 7.2.9: https://tc39.github.io/ecma262/#sec-samevalue
-bool sameValue(ExecState*, JSValue a, JSValue b);
-
 } // namespace JSC
 
 #endif // JSCJSValue_h
index 62f6c40..779d603 100644 (file)
@@ -1058,22 +1058,6 @@ ALWAYS_INLINE bool isThisValueAltered(const PutPropertySlot& slot, JSObject* bas
     return true;
 }
 
-// See section 7.2.9: https://tc39.github.io/ecma262/#sec-samevalue
-ALWAYS_INLINE bool sameValue(ExecState* exec, JSValue a, JSValue b)
-{
-    if (!a.isNumber())
-        return JSValue::strictEqual(exec, a, b);
-    if (!b.isNumber())
-        return false;
-    double x = a.asNumber();
-    double y = b.asNumber();
-    bool xIsNaN = std::isnan(x);
-    bool yIsNaN = std::isnan(y);
-    if (xIsNaN || yIsNaN)
-        return xIsNaN && yIsNaN;
-    return bitwise_cast<uint64_t>(x) == bitwise_cast<uint64_t>(y);
-}
-
 } // namespace JSC
 
 #endif // JSValueInlines_h
index e122ad6..16fadfc 100644 (file)
@@ -641,7 +641,7 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
     putDirectWithoutTransition(vm, vm.propertyNames->Reflect, reflectObject, DontEnum);
 
     m_moduleLoaderStructure.set(vm, this, JSModuleLoader::createStructure(vm, this, m_moduleLoaderPrototype.get()));
-    m_moduleLoader.set(vm, this, JSModuleLoader::create(globalExec(), vm, this, m_moduleLoaderStructure.get()));
+    m_moduleLoader.set(vm, this, JSModuleLoader::create(vm, this, m_moduleLoaderStructure.get()));
     if (Options::exposeInternalModuleLoader())
         putDirectWithoutTransition(vm, vm.propertyNames->Loader, m_moduleLoader.get(), DontEnum);
 
index deee647..9f534bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "JSMap.h"
 
-#include "JSCInlines.h"
+#include "CopiedBlockInlines.h"
+#include "JSCJSValueInlines.h"
+#include "JSMapIterator.h"
+#include "MapDataInlines.h"
+#include "SlotVisitorInlines.h"
+#include "StructureInlines.h"
 
 namespace JSC {
 
 const ClassInfo JSMap::s_info = { "Map", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMap) };
 
+void JSMap::destroy(JSCell* cell)
+{
+    JSMap* thisObject = jsCast<JSMap*>(cell);
+    thisObject->JSMap::~JSMap();
+}
+
+size_t JSMap::estimatedSize(JSCell* cell)
+{
+    JSMap* thisObject = jsCast<JSMap*>(cell);
+    size_t mapDataSize = thisObject->m_mapData.capacityInBytes();
+    return Base::estimatedSize(cell) + mapDataSize;
+}
+
 String JSMap::toStringName(const JSObject*, ExecState*)
 {
     return ASCIILiteral("Object");
 }
 
+void JSMap::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    Base::visitChildren(cell, visitor);
+    jsCast<JSMap*>(cell)->m_mapData.visitChildren(cell, visitor);
+}
+
+void JSMap::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
+{
+    Base::copyBackingStore(cell, visitor, token);
+    jsCast<JSMap*>(cell)->m_mapData.copyBackingStore(visitor, token);
+}
+
+bool JSMap::has(ExecState* exec, JSValue key)
+{
+    return m_mapData.contains(exec, key);
+}
+
+size_t JSMap::size(ExecState* exec)
+{
+    return m_mapData.size(exec);
+}
+
+JSValue JSMap::get(ExecState* exec, JSValue key)
+{
+    JSValue result = m_mapData.get(exec, key);
+    if (!result)
+        return jsUndefined();
+    return result;
+}
+
+void JSMap::set(ExecState* exec, JSValue key, JSValue value)
+{
+    m_mapData.set(exec, this, key, value);
+}
+
+void JSMap::clear(ExecState*)
+{
+    m_mapData.clear();
+}
+
+bool JSMap::remove(ExecState* exec, JSValue key)
+{
+    return m_mapData.remove(exec, key);
+}
+
 }
index ee149d1..2790f69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSMap_h
 #define JSMap_h
 
+#include "JSDestructibleObject.h"
 #include "JSObject.h"
-#include "MapBase.h"
+#include "MapData.h"
 
 namespace JSC {
 
 class JSMapIterator;
 
-class JSMap : public MapBase<HashMapBucket<HashMapBucketDataKeyValue>> {
-    typedef MapBase<HashMapBucket<HashMapBucketDataKeyValue>> Base;
+class JSMap : public JSDestructibleObject {
 public:
+    typedef JSDestructibleObject Base;
+
     friend class JSMapIterator;
 
+    // Our marking functions expect Entry to maintain this layout, and have all
+    // fields be WriteBarrier<Unknown>
+    class Entry {
+    private:
+        WriteBarrier<Unknown> m_key;
+        WriteBarrier<Unknown> m_value;
+
+    public:
+        const WriteBarrier<Unknown>& key() const
+        {
+            return m_key;
+        }
+
+        const WriteBarrier<Unknown>& value() const
+        {
+            return m_value;
+        }
+
+        void visitChildren(SlotVisitor& visitor)
+        {
+            visitor.append(&m_key);
+            visitor.append(&m_value);
+        }
+
+        void setKey(VM& vm, const JSCell* owner, JSValue key)
+        {
+            m_key.set(vm, owner, key);
+        }
+
+        void setKeyWithoutWriteBarrier(JSValue key)
+        {
+            m_key.setWithoutWriteBarrier(key);
+        }
+
+        void setValue(VM& vm, const JSCell* owner, JSValue value)
+        {
+            m_value.set(vm, owner, value);
+        }
+
+        void clear()
+        {
+            m_key.clear();
+            m_value.clear();
+        }
+    };
+
+    typedef MapDataImpl<Entry, JSMapIterator> MapData;
+
     DECLARE_EXPORT_INFO;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(JSMapType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    static JSMap* create(ExecState* exec, VM& vm, Structure* structure)
+    static JSMap* create(VM& vm, Structure* structure)
     {
         JSMap* instance = new (NotNull, allocateCell<JSMap>(vm.heap)) JSMap(vm, structure);
-        instance->finishCreation(exec, vm);
+        instance->finishCreation(vm);
         return instance;
     }
 
-    ALWAYS_INLINE JSValue get(ExecState* exec, JSValue key)
+    static JSMap* create(ExecState* exec, Structure* structure)
     {
-        return m_map->get(exec, key);
+        return create(exec->vm(), structure);
     }
 
-    ALWAYS_INLINE void set(ExecState* exec, JSValue key, JSValue value)
-    {
-        m_map->add(exec, key, value);
-    }
+    bool has(ExecState*, JSValue);
+    size_t size(ExecState*);
+    JSValue get(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE void set(ExecState*, JSValue key, JSValue value);
+    void clear(ExecState*);
+    bool remove(ExecState*, JSValue);
 
 private:
     JSMap(VM& vm, Structure* structure)
         : Base(vm, structure)
+        , m_mapData(vm, this)
     {
     }
 
+    static void destroy(JSCell*);
+    static size_t estimatedSize(JSCell*);
+    static void visitChildren(JSCell*, SlotVisitor&);
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
     static String toStringName(const JSObject*, ExecState*);
+
+    MapData m_mapData;
 };
 
 }
index 81aadfe..2c388a2 100644 (file)
@@ -38,7 +38,6 @@ void JSMapIterator::finishCreation(VM& vm, JSMap* iteratedObject)
 {
     Base::finishCreation(vm);
     m_map.set(vm, this, iteratedObject);
-    setIterator(vm, m_map->impl()->head());
 }
 
 void JSMapIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -47,7 +46,6 @@ void JSMapIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_map);
-    visitor.append(&thisObject->m_iter);
 }
 
 JSValue JSMapIterator::createPair(CallFrame* callFrame, JSValue key, JSValue value)
@@ -61,9 +59,8 @@ JSValue JSMapIterator::createPair(CallFrame* callFrame, JSValue key, JSValue val
 
 JSMapIterator* JSMapIterator::clone(ExecState* exec)
 {
-    VM& vm = exec->vm();
-    auto clone = JSMapIterator::create(vm, exec->callee()->globalObject()->mapIteratorStructure(), m_map.get(), m_kind);
-    clone->setIterator(vm, m_iter.get());
+    auto clone = JSMapIterator::create(exec->vm(), exec->callee()->globalObject()->mapIteratorStructure(), m_map.get(), m_kind);
+    clone->m_iterator = m_iterator;
     return clone;
 }
 
index bbddc95..7e5403d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved.
+ * Copyright (C) 2013 Apple, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,7 +34,6 @@
 namespace JSC {
 
 class JSMapIterator : public JSNonFinalObject {
-    typedef HashMapBucket<HashMapBucketDataKeyValue> HashMapBucketType;
 public:
     typedef JSNonFinalObject Base;
 
@@ -52,62 +51,52 @@ public:
         return instance;
     }
 
-    ALWAYS_INLINE HashMapBucketType* advanceIter(ExecState* exec)
+    bool next(CallFrame* callFrame, JSValue& value)
     {
-        HashMapBucketType* prev = m_iter.get();
-        if (!prev)
-            return nullptr;
-        HashMapBucketType* bucket = m_iter->next();
-        while (bucket && bucket->deleted()) {
-            prev = bucket;
-            bucket = bucket->next();
-        }
-        if (!bucket) {
-            setIterator(exec->vm(), nullptr);
-            return nullptr;
-        }
-        setIterator(exec->vm(), bucket); // We keep m_iter on the last value since the first thing we do in this function is call next().
-        return bucket;
-    }
-    bool next(ExecState* exec, JSValue& value)
-    {
-        HashMapBucketType* bucket = advanceIter(exec);
-        if (!bucket)
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
             return false;
 
         if (m_kind == IterateValue)
-            value = bucket->value();
+            value = pair.value;
         else if (m_kind == IterateKey)
-            value = bucket->key();
+            value = pair.key;
         else
-            value = createPair(exec, bucket->key(), bucket->value());
+            value = createPair(callFrame, pair.key, pair.value);
         return true;
     }
 
-    bool nextKeyValue(ExecState* exec, JSValue& key, JSValue& value)
+    bool nextKeyValue(JSValue& key, JSValue& value)
     {
-        HashMapBucketType* bucket = advanceIter(exec);
-        if (!bucket)
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
             return false;
 
-        key = bucket->key();
-        value = bucket->value();
+        key = pair.key;
+        value = pair.value;
         return true;
     }
 
+    void finish()
+    {
+        m_iterator.finish();
+    }
+
     IterationKind kind() const { return m_kind; }
     JSValue iteratedValue() const { return m_map.get(); }
     JSMapIterator* clone(ExecState*);
 
+    JSMap::MapData::IteratorData* iteratorData()
+    {
+        return &m_iterator;
+    }
+
 private:
-    JSMapIterator(VM& vm, Structure* structure, JSMap*, IterationKind kind)
+    JSMapIterator(VM& vm, Structure* structure, JSMap* iteratedObject, IterationKind kind)
         : Base(vm, structure)
+        , m_iterator(iteratedObject->m_mapData.createIteratorData(this))
         , m_kind(kind)
-    { }
-
-    void setIterator(VM& vm, HashMapBucketType* bucket)
     {
-        m_iter.setMayBeNull(vm, this, bucket);
     }
 
     JS_EXPORT_PRIVATE void finishCreation(VM&, JSMap*);
@@ -115,7 +104,7 @@ private:
     static void visitChildren(JSCell*, SlotVisitor&);
 
     WriteBarrier<JSMap> m_map;
-    WriteBarrier<HashMapBucketType> m_iter;
+    JSMap::MapData::IteratorData m_iterator;
     IterationKind m_kind;
 };
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSMapIterator);
index bba19b1..1090f8c 100644 (file)
@@ -55,14 +55,11 @@ JSModuleLoader::JSModuleLoader(VM& vm, Structure* structure)
 {
 }
 
-void JSModuleLoader::finishCreation(ExecState* exec, VM& vm, JSGlobalObject* globalObject)
+void JSModuleLoader::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    JSMap* map = JSMap::create(exec, vm, globalObject->mapStructure());
-    RELEASE_ASSERT(!scope.exception());
-    putDirect(vm, Identifier::fromString(&vm, "registry"), map);
+    putDirect(vm, Identifier::fromString(&vm, "registry"), JSMap::create(vm, globalObject->mapStructure()));
 }
 
 // ------------------------------ Functions --------------------------------
index daafc5b..4efcc04 100644 (file)
@@ -47,10 +47,10 @@ public:
         Ready = 6,
     };
 
-    static JSModuleLoader* create(ExecState* exec, VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    static JSModuleLoader* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
         JSModuleLoader* object = new (NotNull, allocateCell<JSModuleLoader>(vm.heap)) JSModuleLoader(vm, structure);
-        object->finishCreation(exec, vm, globalObject);
+        object->finishCreation(vm, globalObject);
         return object;
     }
 
@@ -77,7 +77,7 @@ public:
     JSValue evaluate(ExecState*, JSValue key, JSValue moduleRecord, JSValue initiator);
 
 protected:
-    void finishCreation(ExecState*, VM&, JSGlobalObject*);
+    void finishCreation(VM&, JSGlobalObject*);
 };
 
 } // namespace JSC
index 6394742..eea8435 100644 (file)
@@ -44,17 +44,14 @@ void JSModuleRecord::destroy(JSCell* cell)
     thisObject->JSModuleRecord::~JSModuleRecord();
 }
 
-void JSModuleRecord::finishCreation(ExecState* exec, VM& vm)
+void JSModuleRecord::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("registryEntry")), jsUndefined());
     putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("evaluated")), jsBoolean(false));
 
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    JSMap* map = JSMap::create(exec, vm, globalObject()->mapStructure());
-    RELEASE_ASSERT(!scope.exception());
-    m_dependenciesMap.set(vm, this, map);
+    m_dependenciesMap.set(vm, this, JSMap::create(vm, globalObject()->mapStructure()));
     putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("dependenciesMap")), m_dependenciesMap.get());
 }
 
index 1e54f8c..c424309 100644 (file)
@@ -87,10 +87,10 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    static JSModuleRecord* create(ExecState* exec, VM& vm, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables)
+    static JSModuleRecord* create(VM& vm, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables)
     {
         JSModuleRecord* instance = new (NotNull, allocateCell<JSModuleRecord>(vm.heap)) JSModuleRecord(vm, structure, moduleKey, sourceCode, declaredVariables, lexicalVariables);
-        instance->finishCreation(exec, vm);
+        instance->finishCreation(vm);
         return instance;
     }
 
@@ -152,7 +152,7 @@ private:
     {
     }
 
-    void finishCreation(ExecState*, VM&);
+    void finishCreation(VM&);
 
     JSModuleNamespaceObject* getModuleNamespace(ExecState*);
 
index 76761b2..3dece59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "JSSet.h"
 
-#include "JSCInlines.h"
+#include "CopiedBlockInlines.h"
+#include "JSCJSValueInlines.h"
+#include "JSSetIterator.h"
+#include "MapDataInlines.h"
+#include "SlotVisitorInlines.h"
+#include "StructureInlines.h"
 
 namespace JSC {
 
 const ClassInfo JSSet::s_info = { "Set", &Base::s_info, 0, CREATE_METHOD_TABLE(JSSet) };
 
+void JSSet::destroy(JSCell* cell)
+{
+    JSSet* thisObject = jsCast<JSSet*>(cell);
+    thisObject->JSSet::~JSSet();
+}
+
 String JSSet::toStringName(const JSObject*, ExecState*)
 {
     return ASCIILiteral("Object");
 }
 
+size_t JSSet::estimatedSize(JSCell* cell)
+{
+    JSSet* thisObject = jsCast<JSSet*>(cell);
+    size_t setDataSize = thisObject->m_setData.capacityInBytes();
+    return Base::estimatedSize(cell) + setDataSize;
+}
+
+void JSSet::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    Base::visitChildren(cell, visitor);
+    jsCast<JSSet*>(cell)->m_setData.visitChildren(cell, visitor);
+}
+
+void JSSet::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
+{
+    Base::copyBackingStore(cell, visitor, token);
+    jsCast<JSSet*>(cell)->m_setData.copyBackingStore(visitor, token);
+}
+
+bool JSSet::has(ExecState* exec, JSValue value)
+{
+    return m_setData.contains(exec, value);
+}
+
+size_t JSSet::size(ExecState* exec)
+{
+    return m_setData.size(exec);
+}
+
+void JSSet::add(ExecState* exec, JSValue value)
+{
+    m_setData.set(exec, this, value, value);
+}
+
+void JSSet::clear(ExecState*)
+{
+    m_setData.clear();
+}
+
+bool JSSet::remove(ExecState* exec, JSValue value)
+{
+    return m_setData.remove(exec, value);
+}
+
 }
index b458a44..8805c4e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSSet_h
 #define JSSet_h
 
+#include "JSDestructibleObject.h"
 #include "JSObject.h"
-#include "MapBase.h"
+#include "MapData.h"
 
 namespace JSC {
 
 class JSSetIterator;
 
-class JSSet : public MapBase<HashMapBucket<HashMapBucketDataKey>> {
-    typedef MapBase<HashMapBucket<HashMapBucketDataKey>> Base;
+class JSSet : public JSDestructibleObject {
 public:
+    typedef JSDestructibleObject Base;
 
     friend class JSSetIterator;
 
+    // Our marking functions expect Entry to maintain this layout, and have all
+    // fields be WriteBarrier<Unknown>
+    class Entry {
+    private:
+        WriteBarrier<Unknown> m_key;
+
+    public:
+        const WriteBarrier<Unknown>& key() const
+        {
+            return m_key;
+        }
+
+        const WriteBarrier<Unknown>& value() const
+        {
+            return m_key;
+        }
+
+        void visitChildren(SlotVisitor& visitor)
+        {
+            visitor.append(&m_key);
+        }
+
+        void setKey(VM& vm, const JSCell* owner, JSValue key)
+        {
+            m_key.set(vm, owner, key);
+        }
+
+        void setKeyWithoutWriteBarrier(JSValue key)
+        {
+            m_key.setWithoutWriteBarrier(key);
+        }
+
+        void setValue(VM&, const JSCell*, JSValue)
+        {
+        }
+
+        void clear()
+        {
+            m_key.clear();
+        }
+    };
+
+    typedef MapDataImpl<Entry, JSSetIterator> SetData;
+
     DECLARE_EXPORT_INFO;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(JSSetType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    static JSSet* create(ExecState* exec, VM& vm, Structure* structure)
+    static JSSet* create(VM& vm, Structure* structure)
     {
         JSSet* instance = new (NotNull, allocateCell<JSSet>(vm.heap)) JSSet(vm, structure);
-        instance->finishCreation(exec, vm);
+        instance->finishCreation(vm);
         return instance;
     }
 
-    ALWAYS_INLINE void add(ExecState* exec, JSValue key)
+    static JSSet* create(ExecState* exec, Structure* structure)
     {
-        m_map->add(exec, key);
+        return create(exec->vm(), structure);
     }
 
+    bool has(ExecState*, JSValue);
+    size_t size(ExecState*);
+    JS_EXPORT_PRIVATE void add(ExecState*, JSValue);
+    void clear(ExecState*);
+    bool remove(ExecState*, JSValue);
+
 private:
     JSSet(VM& vm, Structure* structure)
         : Base(vm, structure)
+        , m_setData(vm, this)
     {
     }
 
+    static void destroy(JSCell*);
+    static size_t estimatedSize(JSCell*);
+    static void visitChildren(JSCell*, SlotVisitor&);
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
     static String toStringName(const JSObject*, ExecState*);
+
+    SetData m_setData;
 };
 
 }
index 82871be..2f2deb5 100644 (file)
@@ -38,7 +38,6 @@ void JSSetIterator::finishCreation(VM& vm, JSSet* iteratedObject)
 {
     Base::finishCreation(vm);
     m_set.set(vm, this, iteratedObject);
-    setIterator(vm, m_set->impl()->head());
 }
 
 void JSSetIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -47,7 +46,6 @@ void JSSetIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_set);
-    visitor.append(&thisObject->m_iter);
 }
 
 JSValue JSSetIterator::createPair(CallFrame* callFrame, JSValue key, JSValue value)
@@ -61,9 +59,8 @@ JSValue JSSetIterator::createPair(CallFrame* callFrame, JSValue key, JSValue val
 
 JSSetIterator* JSSetIterator::clone(ExecState* exec)
 {
-    VM& vm = exec->vm();
-    auto clone = JSSetIterator::create(vm, exec->callee()->globalObject()->setIteratorStructure(), m_set.get(), m_kind);
-    clone->setIterator(vm, m_iter.get());
+    auto clone = JSSetIterator::create(exec->vm(), exec->callee()->globalObject()->setIteratorStructure(), m_set.get(), m_kind);
+    clone->m_iterator = m_iterator;
     return clone;
 }
 
index 781afcb..2097fdb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved.
+ * Copyright (C) 2013 Apple, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,6 @@
 namespace JSC {
 
 class JSSetIterator : public JSNonFinalObject {
-    typedef HashMapBucket<HashMapBucketDataKey> HashMapBucketType;
 public:
     typedef JSNonFinalObject Base;
 
@@ -53,51 +52,38 @@ public:
         return instance;
     }
 
-    ALWAYS_INLINE HashMapBucketType* advanceIter(ExecState* exec)
+    bool next(CallFrame* callFrame, JSValue& value)
     {
-        HashMapBucketType* prev = m_iter.get();
-        if (!prev)
-            return nullptr;
-        HashMapBucketType* bucket = m_iter->next();
-        while (bucket && bucket->deleted()) {
-            prev = bucket;
-            bucket = bucket->next();
-        }
-        if (!bucket) {
-            setIterator(exec->vm(), nullptr);
-            return nullptr;
-        }
-        setIterator(exec->vm(), bucket); // We keep m_iter on the last value since the first thing we do in this function is call next().
-        return bucket;
-    }
-
-    bool next(ExecState* exec, JSValue& value)
-    {
-        HashMapBucketType* bucket = advanceIter(exec);
-        if (!bucket)
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
             return false;
-
         if (m_kind == IterateValue || m_kind == IterateKey)
-            value = bucket->key();
+            value = pair.key;
         else
-            value = createPair(exec, bucket->key(), bucket->key());
+            value = createPair(callFrame, pair.key, pair.key);
         return true;
     }
 
+    void finish()
+    {
+        m_iterator.finish();
+    }
+
     IterationKind kind() const { return m_kind; }
     JSValue iteratedValue() const { return m_set.get(); }
     JSSetIterator* clone(ExecState*);
 
-private:
-    JSSetIterator(VM& vm, Structure* structure, JSSet*, IterationKind kind)
-        : Base(vm, structure)
-        , m_kind(kind)
+    JSSet::SetData::IteratorData* iteratorData()
     {
+        return &m_iterator;
     }
 
-    void setIterator(VM& vm, HashMapBucketType* bucket)
+private:
+    JSSetIterator(VM& vm, Structure* structure, JSSet* iteratedObject, IterationKind kind)
+        : Base(vm, structure)
+        , m_iterator(iteratedObject->m_setData.createIteratorData(this))
+        , m_kind(kind)
     {
-        m_iter.setMayBeNull(vm, this, bucket); 
     }
 
     JS_EXPORT_PRIVATE void finishCreation(VM&, JSSet*);
@@ -105,7 +91,7 @@ private:
     static void visitChildren(JSCell*, SlotVisitor&);
 
     WriteBarrier<JSSet> m_set;
-    WriteBarrier<HashMapBucketType> m_iter;
+    JSSet::SetData::IteratorData m_iterator;
     IterationKind m_kind;
 };
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSSetIterator);
index 9e4fe90..54d4ceb 100644 (file)
@@ -82,10 +82,8 @@ enum JSType : uint8_t {
     ModuleEnvironmentType,
     RegExpObjectType,
     ProxyObjectType,
-    JSMapType,
-    JSSetType,
 
-    LastJSCObjectType = JSSetType,
+    LastJSCObjectType = ProxyObjectType,
 };
 
 COMPILE_ASSERT(sizeof(JSType) == sizeof(uint8_t), sizeof_jstype_is_one_byte);
diff --git a/Source/JavaScriptCore/runtime/MapBase.cpp b/Source/JavaScriptCore/runtime/MapBase.cpp
deleted file mode 100644 (file)
index 14d587f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "MapBase.h"
-
-#include "SlotVisitorInlines.h"
-
-namespace JSC {
-
-template <typename HashMapBucketType>
-void MapBase<HashMapBucketType>::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    MapBase* thisObject = static_cast<MapBase*>(cell);
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_map);
-}
-
-template <typename HashMapBucketType>
-size_t MapBase<HashMapBucketType>::estimatedSize(JSCell* cell)
-{
-    return Base::estimatedSize(cell) + static_cast<MapBase*>(cell)->m_map->approximateSize();
-}
-
-template class MapBase<HashMapBucket<HashMapBucketDataKeyValue>>;
-template class MapBase<HashMapBucket<HashMapBucketDataKey>>;
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MapBase.h b/Source/JavaScriptCore/runtime/MapBase.h
deleted file mode 100644 (file)
index 419c04e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#include "HashMapImpl.h"
-#include "JSObject.h"
-
-namespace JSC {
-
-template <typename HashMapBucketType>
-class MapBase : public JSNonFinalObject {
-    typedef HashMapImpl<HashMapBucketType> HashMapImplType;
-    typedef JSNonFinalObject Base;
-public:
-
-    typedef HashMapBucketType BucketType;
-
-    ALWAYS_INLINE size_t size(ExecState*)
-    {
-        return m_map->size();
-    }
-
-    ALWAYS_INLINE bool has(ExecState* exec, JSValue key)
-    {
-        return m_map->has(exec, key);
-    }
-
-    ALWAYS_INLINE void clear(ExecState* exec)
-    {
-        m_map->clear(exec);
-    }
-
-    ALWAYS_INLINE bool remove(ExecState* exec, JSValue key)
-    {
-        return m_map->remove(exec, key);
-    }
-
-    ALWAYS_INLINE HashMapBucketType** findBucket(ExecState* exec, JSValue key, uint32_t hash)
-    {
-        return m_map->findBucket(exec, key, hash);
-    }
-
-    static ptrdiff_t offsetOfHashMapImpl()
-    {
-        return OBJECT_OFFSETOF(MapBase<HashMapBucketType>, m_map);
-    }
-
-    ALWAYS_INLINE HashMapImplType* impl() { return m_map.get(); }
-
-    void finishCreation(ExecState* exec, VM& vm)
-    {
-        Base::finishCreation(vm);
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        HashMapImplType* impl = HashMapImplType::create(exec, vm);
-        if (UNLIKELY(scope.exception()))
-            return;
-        m_map.set(vm, this, impl);
-    }
-
-protected:
-    MapBase(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-
-    static size_t estimatedSize(JSCell*);
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    WriteBarrier<HashMapImplType> m_map;
-};
-
-} // namespace JSC
index 43ae37c..5a2b69a 100644 (file)
@@ -61,11 +61,9 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
 
     JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
     Structure* mapStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->mapStructure());
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    JSMap* map = JSMap::create(exec, vm, mapStructure);
-    if (UNLIKELY(scope.exception()))
+    if (exec->hadException())
         return JSValue::encode(JSValue());
+    JSMap* map = JSMap::create(exec, mapStructure);
     JSValue iterable = exec->argument(0);
     if (iterable.isUndefinedOrNull())
         return JSValue::encode(map);
index e629f3e..1ec4d92 100644 (file)
@@ -58,6 +58,7 @@ EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncNext(CallFrame* callFrame)
     JSValue result;
     if (iterator->next(callFrame, result))
         return JSValue::encode(createIteratorResultObject(callFrame, result, false));
+    iterator->finish();
     return JSValue::encode(createIteratorResultObject(callFrame, jsUndefined(), true));
 }
 
index 0943510..d50f807 100644 (file)
@@ -68,13 +68,14 @@ void MapPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->clear, mapProtoFuncClear, DontEnum, 0);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, mapProtoFuncDelete, DontEnum, 1);
-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->get, mapProtoFuncGet, DontEnum, 1, JSMapGetIntrinsic);
-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, mapProtoFuncHas, DontEnum, 1, JSMapHasIntrinsic);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->get, mapProtoFuncGet, DontEnum, 1);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, mapProtoFuncHas, DontEnum, 1);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->set, mapProtoFuncSet, DontEnum, 2);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().keysPublicName(), mapProtoFuncKeys, DontEnum, 0);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().valuesPublicName(), mapProtoFuncValues, DontEnum, 0);
 
-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getPrivateName(), mapProtoFuncGet, DontEnum, 1, JSMapGetIntrinsic);
+    // Private get / set operations.
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getPrivateName(), mapProtoFuncGet, DontEnum, 1);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().setPrivateName(), mapProtoFuncSet, DontEnum, 2);
 
     JSFunction* entries = JSFunction::create(vm, globalObject, 0, vm.propertyNames->builtinNames().entriesPublicName().string(), mapProtoFuncEntries);
@@ -90,21 +91,16 @@ ALWAYS_INLINE static JSMap* getMap(CallFrame* callFrame, JSValue thisValue)
     VM& vm = callFrame->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (UNLIKELY(!thisValue.isCell())) {
+    if (!thisValue.isObject()) {
         throwVMError(callFrame, scope, createNotAnObjectError(callFrame, thisValue));
         return nullptr;
     }
-
-    if (LIKELY(thisValue.asCell()->type() == JSMapType))
-        return jsCast<JSMap*>(thisValue);
-    throwTypeError(callFrame, scope, ASCIILiteral("Map operation called on non-Map object"));
-    return nullptr;
-}
-
-EncodedJSValue JSC_HOST_CALL privateFuncIsMap(ExecState* exec)
-{
-    JSValue value = exec->uncheckedArgument(0);
-    return JSValue::encode(jsBoolean(value.isCell() && value.asCell()->type() == JSMapType));
+    JSMap* map = jsDynamicCast<JSMap*>(thisValue);
+    if (!map) {
+        throwTypeError(callFrame, scope, ASCIILiteral("Map operation called on non-Map object"));
+        return nullptr;
+    }
+    return map;
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncClear(CallFrame* callFrame)
@@ -191,6 +187,11 @@ EncodedJSValue JSC_HOST_CALL mapProtoFuncKeys(CallFrame* callFrame)
     return JSValue::encode(JSMapIterator::create(vm, callFrame->callee()->globalObject()->mapIteratorStructure(), thisObj, IterateKey));
 }
 
+EncodedJSValue JSC_HOST_CALL privateFuncIsMap(ExecState* exec)
+{
+    return JSValue::encode(jsBoolean(jsDynamicCast<JSMap*>(exec->uncheckedArgument(0))));
+}
+
 EncodedJSValue JSC_HOST_CALL privateFuncMapIterator(ExecState* exec)
 {
     ASSERT(jsDynamicCast<JSMap*>(exec->uncheckedArgument(0)));
@@ -203,12 +204,13 @@ EncodedJSValue JSC_HOST_CALL privateFuncMapIteratorNext(ExecState* exec)
     ASSERT(jsDynamicCast<JSMapIterator*>(exec->thisValue()));
     JSMapIterator* iterator = jsCast<JSMapIterator*>(exec->thisValue());
     JSValue key, value;
-    if (iterator->nextKeyValue(exec, key, value)) {
+    if (iterator->nextKeyValue(key, value)) {
         JSArray* resultArray = jsCast<JSArray*>(exec->uncheckedArgument(0));
         resultArray->putDirectIndex(exec, 0, key);
         resultArray->putDirectIndex(exec, 1, value);
         return JSValue::encode(jsBoolean(false));
     }
+    iterator->finish();
     return JSValue::encode(jsBoolean(true));
 }
 
index 265a0da..2caf58c 100644 (file)
@@ -191,6 +191,22 @@ void PropertyDescriptor::setGetter(JSValue getter)
     m_attributes &= ~ReadOnly;
 }
 
+// See ES5.1 9.12
+bool sameValue(ExecState* exec, JSValue a, JSValue b)
+{
+    if (!a.isNumber())
+        return JSValue::strictEqual(exec, a, b);
+    if (!b.isNumber())
+        return false;
+    double x = a.asNumber();
+    double y = b.asNumber();
+    bool xIsNaN = std::isnan(x);
+    bool yIsNaN = std::isnan(y);
+    if (xIsNaN || yIsNaN)
+        return xIsNaN && yIsNaN;
+    return bitwise_cast<uint64_t>(x) == bitwise_cast<uint64_t>(y);
+}
+
 bool PropertyDescriptor::equalTo(ExecState* exec, const PropertyDescriptor& other) const
 {
     if (other.m_value.isEmpty() != m_value.isEmpty()
index aa61eea..5736d62 100644 (file)
@@ -32,6 +32,9 @@ namespace JSC {
 
 class GetterSetter;
 
+// See ES5.1 9.12
+bool sameValue(ExecState*, JSValue, JSValue);
+
 class PropertyDescriptor {
 public:
     PropertyDescriptor()
index 430986e..e30561c 100644 (file)
@@ -62,11 +62,9 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 
     JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
     Structure* setStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->setStructure());
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    JSSet* set = JSSet::create(exec, vm, setStructure);
-    if (UNLIKELY(scope.exception()))
+    if (exec->hadException())
         return JSValue::encode(JSValue());
+    JSSet* set = JSSet::create(exec, setStructure);
     JSValue iterable = exec->argument(0);
     if (iterable.isUndefinedOrNull())
         return JSValue::encode(set);
index 5128710..5a12c68 100644 (file)
@@ -58,6 +58,7 @@ EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncNext(CallFrame* callFrame)
 
     if (iterator->next(callFrame, result))
         return JSValue::encode(createIteratorResultObject(callFrame, result, false));
+    iterator->finish();
     return JSValue::encode(createIteratorResultObject(callFrame, jsUndefined(), true));
 }
 
index f36b8c5..80046d6 100644 (file)
@@ -68,7 +68,7 @@ void SetPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->add, setProtoFuncAdd, DontEnum, 1);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->clear, setProtoFuncClear, DontEnum, 0);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, setProtoFuncDelete, DontEnum, 1);
-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, setProtoFuncHas, DontEnum, 1, JSSetHasIntrinsic);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, setProtoFuncHas, DontEnum, 1);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().entriesPublicName(), setProtoFuncEntries, DontEnum, 0);
 
     JSFunction* values = JSFunction::create(vm, globalObject, 0, vm.propertyNames->builtinNames().valuesPublicName().string(), setProtoFuncValues);
@@ -85,14 +85,16 @@ ALWAYS_INLINE static JSSet* getSet(CallFrame* callFrame, JSValue thisValue)
     VM& vm = callFrame->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (UNLIKELY(!thisValue.isCell())) {
+    if (!thisValue.isObject()) {
         throwVMError(callFrame, scope, createNotAnObjectError(callFrame, thisValue));
         return nullptr;
     }
-    if (LIKELY(thisValue.asCell()->type() == JSSetType))
-        return jsCast<JSSet*>(thisValue);
-    throwTypeError(callFrame, scope, ASCIILiteral("Set operation called on non-Set object"));
-    return nullptr;
+    JSSet* set = jsDynamicCast<JSSet*>(thisValue);
+    if (!set) {
+        throwTypeError(callFrame, scope, ASCIILiteral("Set operation called on non-Set object"));
+        return nullptr;
+    }
+    return set;
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncAdd(CallFrame* callFrame)
@@ -182,6 +184,7 @@ EncodedJSValue JSC_HOST_CALL privateFuncSetIteratorNext(ExecState* exec)
         resultArray->putDirectIndex(exec, 0, result);
         return JSValue::encode(jsBoolean(false));
     }
+    iterator->finish();
     return JSValue::encode(jsBoolean(true));
 }
 
index f2190e9..1bee77f 100644 (file)
@@ -65,7 +65,6 @@
 #include "JSInternalPromiseDeferred.h"
 #include "JSLexicalEnvironment.h"
 #include "JSLock.h"
-#include "JSMap.h"
 #include "JSPromiseDeferred.h"
 #include "JSPropertyNameEnumerator.h"
 #include "JSTemplateRegistryKey.h"
@@ -254,10 +253,6 @@ VM::VM(VMType vmType, HeapType heapType)
 #if ENABLE(WEBASSEMBLY)
     webAssemblyCodeBlockStructure.set(*this, WebAssemblyCodeBlock::createStructure(*this, 0, jsNull()));
 #endif
-    hashMapBucketSetStructure.set(*this, HashMapBucket<HashMapBucketDataKey>::createStructure(*this, 0, jsNull()));
-    hashMapBucketMapStructure.set(*this, HashMapBucket<HashMapBucketDataKeyValue>::createStructure(*this, 0, jsNull()));
-    hashMapImplSetStructure.set(*this, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::createStructure(*this, 0, jsNull()));
-    hashMapImplMapStructure.set(*this, HashMapImpl<HashMapBucket<HashMapBucketDataKeyValue>>::createStructure(*this, 0, jsNull()));
 
     iterationTerminator.set(*this, JSFinalObject::create(*this, JSFinalObject::createStructure(*this, 0, jsNull(), 1)));
     nativeStdFunctionCellStructure.set(*this, NativeStdFunctionCell::createStructure(*this, 0, jsNull()));
index 2c12969..eabc4eb 100644 (file)
@@ -334,10 +334,6 @@ public:
     Strong<Structure> evalCodeBlockStructure;
     Strong<Structure> functionCodeBlockStructure;
     Strong<Structure> webAssemblyCodeBlockStructure;
-    Strong<Structure> hashMapBucketSetStructure;
-    Strong<Structure> hashMapBucketMapStructure;
-    Strong<Structure> hashMapImplSetStructure;
-    Strong<Structure> hashMapImplMapStructure;
 
     Strong<JSCell> iterationTerminator;
     Strong<JSCell> emptyPropertyNameEnumerator;
index dba695f..e051df0 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205504.
+        https://bugs.webkit.org/show_bug.cgi?id=161645
+
+        Broke the iOS device build (Requested by ryanhaddad on
+        #webkit).
+
+        Reverted changeset:
+
+        "Make JSMap and JSSet faster"
+        https://bugs.webkit.org/show_bug.cgi?id=160989
+        http://trac.webkit.org/changeset/205504
+
 2016-09-06  Saam Barati  <sbarati@apple.com>
 
         Make JSMap and JSSet faster
index e97d8ca..6b80edc 100644 (file)
@@ -148,9 +148,7 @@ private:
     };
 
     // The bottom 6 bits in the hash are flags.
-public:
     static const unsigned s_flagCount = 6;
-private:
     static const unsigned s_flagMask = (1u << s_flagCount) - 1;
     COMPILE_ASSERT(s_flagCount <= StringHasher::flagCount, StringHasher_reserves_enough_bits_for_StringImpl_flags);
     static const unsigned s_flagStringKindCount = 4;
index 9e2282e..39bfe4b 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205504.
+        https://bugs.webkit.org/show_bug.cgi?id=161645
+
+        Broke the iOS device build (Requested by ryanhaddad on
+        #webkit).
+
+        Reverted changeset:
+
+        "Make JSMap and JSSet faster"
+        https://bugs.webkit.org/show_bug.cgi?id=160989
+        http://trac.webkit.org/changeset/205504
+
 2016-09-06  Zalan Bujtas  <zalan@apple.com>
 
         Remove unused overlap checking functions from FrameView.
diff --git a/Source/WebCore/ForwardingHeaders/runtime/HashMapImpl.h b/Source/WebCore/ForwardingHeaders/runtime/HashMapImpl.h
deleted file mode 100644 (file)
index 8233525..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef WebCore_FWD_HashMapImpl_h
-#define WebCore_FWD_HashMapImpl_h
-#include <JavaScriptCore/HashMapImpl.h>
-#endif
diff --git a/Source/WebCore/ForwardingHeaders/runtime/MapBase.h b/Source/WebCore/ForwardingHeaders/runtime/MapBase.h
deleted file mode 100644 (file)
index 94000ec..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef WebCore_FWD_MapBase_h
-#define WebCore_FWD_MapBase_h
-#include <JavaScriptCore/MapBase.h>
-#endif
index 56d9d3f..a3248f4 100644 (file)
@@ -1368,7 +1368,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
             case MapDataStartVisitEntry: {
                 JSMapIterator* iterator = mapIteratorStack.last();
                 JSValue key, value;
-                if (!iterator->nextKeyValue(m_exec, key, value)) {
+                if (!iterator->nextKeyValue(key, value)) {
                     mapIteratorStack.removeLast();
                     JSObject* object = inputObjectStack.last();
                     ASSERT(jsDynamicCast<JSMap*>(object));
@@ -2545,9 +2545,7 @@ DeserializationResult CloneDeserializer::deserialize()
         mapObjectStartState: {
             if (outputObjectStack.size() > maximumFilterRecursion)
                 return std::make_pair(JSValue(), StackOverflowError);
-            JSMap* map = JSMap::create(m_exec, m_exec->vm(), m_globalObject->mapStructure());
-            if (UNLIKELY(m_exec->hadException()))
-                goto error;
+            JSMap* map = JSMap::create(m_exec->vm(), m_globalObject->mapStructure());
             m_gcBuffer.append(map);
             outputObjectStack.append(map);
             mapStack.append(map);
@@ -2576,9 +2574,7 @@ DeserializationResult CloneDeserializer::deserialize()
         setObjectStartState: {
             if (outputObjectStack.size() > maximumFilterRecursion)
                 return std::make_pair(JSValue(), StackOverflowError);
-            JSSet* set = JSSet::create(m_exec, m_exec->vm(), m_globalObject->setStructure());
-            if (UNLIKELY(m_exec->hadException()))
-                goto error;
+            JSSet* set = JSSet::create(m_exec->vm(), m_globalObject->setStructure());
             m_gcBuffer.append(set);
             outputObjectStack.append(set);
             setStack.append(set);