[DFG][FTL] Support MapSet / SetAdd intrinsics
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Nov 2017 10:40:34 +0000 (10:40 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Nov 2017 10:40:34 +0000 (10:40 +0000)
commit67656a7d07d9c8e25e63056eec9af0d9531ef027
treeea38b9e4ceb2be58a9b880d1f20548a5a68fab88
parente9bd43755ecacaa14fa3e09a0be7adff670ddc26
[DFG][FTL] Support MapSet / SetAdd intrinsics
https://bugs.webkit.org/show_bug.cgi?id=179858

Reviewed by Saam Barati.

JSTests:

* microbenchmarks/map-has-and-set.js: Added.
(test):
* stress/map-set-check-failure.js: Added.
(shouldBe):
(shouldThrow):
(target):
* stress/map-set-cse.js: Added.
(shouldBe):
(test):
* stress/set-add-check-failure.js: Added.
(shouldBe):
(shouldThrow):
(set shouldThrow):
* stress/set-add-cse.js: Added.
(shouldBe):

Source/JavaScriptCore:

Map.prototype.set and Set.prototype.add uses MapHash value anyway.
By handling them as MapSet and SetAdd DFG nodes and decoupling
MapSet and SetAdd nodes from MapHash DFG node, we have a chance to
remove duplicate MapHash calculation for the same key.

One story is *set-if-not-exists*.

    if (!map.has(key))
        map.set(key, value);

In the above code, both `has` and `set` require hash value for `key`.
If we can change `set` to the series of DFG nodes:

    1: MapHash(key)
    2: MapSet(MapObjectUse:map, Untyped:key, Untyped:value, Int32Use:@1)

we can remove duplicate @1 produced by `has` operation.

This patch improves SixSpeed map-set.es6 and map-set-object.es6 by 20.5% and 20.4% respectively,

                                 baseline                  patched

    map-set.es6             246.2413+-15.2084    ^    204.3679+-11.2408       ^ definitely 1.2049x faster
    map-set-object.es6      266.5075+-17.2289    ^    221.2792+-12.2948       ^ definitely 1.2044x faster

Microbenchmarks

    map-has-and-set         148.1522+-7.6665     ^    131.4552+-7.8846        ^ definitely 1.1270x faster

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSetAdd):
(JSC::DFG::SpeculativeJIT::compileMapSet):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileSetAdd):
(JSC::FTL::DFG::LowerDFGToB3::compileMapSet):
* jit/JITOperations.h:
* runtime/HashMapImpl.h:
(JSC::HashMapImpl::addNormalized):
(JSC::HashMapImpl::addNormalizedInternal):
* runtime/Intrinsic.cpp:
(JSC::intrinsicName):
* runtime/Intrinsic.h:
* runtime/MapPrototype.cpp:
(JSC::MapPrototype::finishCreation):
* runtime/SetPrototype.cpp:
(JSC::SetPrototype::finishCreation):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225072 268f45cc-cd09-0410-ab3c-d52691b4dbfc
29 files changed:
JSTests/ChangeLog
JSTests/microbenchmarks/map-has-and-set.js [new file with mode: 0644]
JSTests/stress/map-set-check-failure.js [new file with mode: 0644]
JSTests/stress/map-set-cse.js [new file with mode: 0644]
JSTests/stress/set-add-check-failure.js [new file with mode: 0644]
JSTests/stress/set-add-cse.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
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/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/runtime/HashMapImpl.h
Source/JavaScriptCore/runtime/Intrinsic.cpp
Source/JavaScriptCore/runtime/Intrinsic.h
Source/JavaScriptCore/runtime/MapPrototype.cpp
Source/JavaScriptCore/runtime/SetPrototype.cpp