[JSC] Introduce @toObject
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 17:32:08 +0000 (17:32 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 17:32:08 +0000 (17:32 +0000)
commitd5bc6f38e2568aa62b67e6642d3576ed178e1819
treedddc8f38b2a1027af56c4919e2c726d8b82a3fb1
parent6516961f84d96d00bd700042766eb3982082fb49
[JSC] Introduce @toObject
https://bugs.webkit.org/show_bug.cgi?id=178726

Reviewed by Saam Barati.

JSTests:

* stress/array-copywithin.js:
(shouldThrow):
* stress/object-constructor-boolean-edge.js: Added.
(shouldBe):
(test):
* stress/object-constructor-global.js: Added.
(shouldBe):
* stress/object-constructor-null-edge.js: Added.
(shouldBe):
(test):
* stress/object-constructor-number-edge.js: Added.
(shouldBe):
(test):
* stress/object-constructor-object-edge.js: Added.
(shouldBe):
(test):
(i.arg):
* stress/object-constructor-string-edge.js: Added.
(shouldBe):
(test):
* stress/object-constructor-symbol-edge.js: Added.
(shouldBe):
(test):
* stress/object-constructor-undefined-edge.js: Added.
(shouldBe):
(test):
* stress/symbol-array-from.js: Added.
(shouldBe):
* stress/to-object-intrinsic-boolean-edge.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/to-object-intrinsic-null-or-undefined-edge.js: Added.
(shouldThrow):
* stress/to-object-intrinsic-number-edge.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/to-object-intrinsic-object-edge.js: Added.
(shouldBe):
(builtin.createBuiltin):
(i.arg):
* stress/to-object-intrinsic-string-edge.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/to-object-intrinsic-symbol-edge.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/to-object-intrinsic.js: Added.
(shouldBe):
(shouldThrow):
(builtin.createBuiltin):

Source/JavaScriptCore:

This patch introduces @toObject intrinsic. And we introduce op_to_object bytecode and DFG ToObject node.
Previously we emulated @toObject behavior in builtin JS. But it consumes much bytecode size while @toObject
is frequently seen and defined clearly in the spec. Furthermore, the emulated @toObject always calls
ObjectConstructor in LLInt and Baseline.

We add a new intrinsic `@toObject(target, "error message")`. It takes an error message string constant to
offer understandable messages in builtin JS. We can change the frequently seen "emulated ToObject" operation

    if (this === @undefined || this === null)
        @throwTypeError("error message");
    var object = @Object(this);

with

    var object = @toObject(this, "error message");

And we handle op_to_object in DFG as ToObject node. While CallObjectConstructor does not throw an error for null/undefined,
ToObject needs to throw an error for null/undefined. So it is marked as MustGenerate and it clobbers the world.
In fixup phase, we attempt to convert ToObject to CallObjectConstructor with edge filters to relax its side effect.

It also fixes a bug that CallObjectConstructor DFG node uses Node's semantic GlobalObject instead of function's one.

* builtins/ArrayConstructor.js:
(from):
* builtins/ArrayPrototype.js:
(values):
(keys):
(entries):
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(sort):
(globalPrivate.concatSlowPath):
(copyWithin):
* builtins/DatePrototype.js:
(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):
* builtins/GlobalOperations.js:
(globalPrivate.copyDataProperties):
(globalPrivate.copyDataPropertiesNoExclusions):
* builtins/ObjectConstructor.js:
(entries):
* builtins/StringConstructor.js:
(raw):
* builtins/TypedArrayConstructor.js:
(from):
* builtins/TypedArrayPrototype.js:
(map):
(filter):
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::dumpBytecode):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitToObject):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_toObject):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupToObject):
(JSC::DFG::FixupPhase::fixupCallObjectConstructor):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToCallObjectConstructor):
(JSC::DFG::Node::convertToNewStringObject):
(JSC::DFG::Node::convertToNewObject):
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileToObjectOrCallObjectConstructor):
(JSC::DFG::SpeculativeJIT::compileCallObjectConstructor): Deleted.
* 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::compileToObjectOrCallObjectConstructor):
(JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_object):
(JSC::JIT::emitSlow_op_to_object):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_to_object):
(JSC::JIT::emitSlow_op_to_object):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:

Source/WebCore:

Use @isObject instead. It is more efficient.

* Modules/mediastream/NavigatorUserMedia.js:
(getUserMedia):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
65 files changed:
JSTests/ChangeLog
JSTests/stress/array-copywithin.js
JSTests/stress/object-constructor-boolean-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-global.js [new file with mode: 0644]
JSTests/stress/object-constructor-null-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-number-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-object-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-string-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-symbol-edge.js [new file with mode: 0644]
JSTests/stress/object-constructor-undefined-edge.js [new file with mode: 0644]
JSTests/stress/symbol-array-from.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-boolean-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-null-or-undefined-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-number-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-object-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-string-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic-symbol-edge.js [new file with mode: 0644]
JSTests/stress/to-object-intrinsic.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/ArrayConstructor.js
Source/JavaScriptCore/builtins/ArrayPrototype.js
Source/JavaScriptCore/builtins/DatePrototype.js
Source/JavaScriptCore/builtins/GlobalOperations.js
Source/JavaScriptCore/builtins/ObjectConstructor.js
Source/JavaScriptCore/builtins/StringConstructor.js
Source/JavaScriptCore/builtins/TypedArrayConstructor.js
Source/JavaScriptCore/builtins/TypedArrayPrototype.js
Source/JavaScriptCore/bytecode/BytecodeDumper.cpp
Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
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/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/NavigatorUserMedia.js