[JSC] Add a new byte code op_define_property instead of calling defineProperty
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Oct 2016 19:31:24 +0000 (19:31 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Oct 2016 19:31:24 +0000 (19:31 +0000)
commit7e4816639cf2f853e0b0d2130d7a28d2cf73bfa3
treed021e993949bea53da3d82c4cde5d219eccc6c12
parent63191d18af67cb7d2b9e16b0deef5c3a4f66c28b
[JSC] Add a new byte code op_define_property instead of calling defineProperty
https://bugs.webkit.org/show_bug.cgi?id=162108

Reviewed by Saam Barati.

To construct ES6 class, we emitted bytecode that performs the following operations.

    1. construct a new object
    2. put "configurable", "enumerable" etc. fields
    3. call "defineProperty" function

However, this approach has problems. Every time we define a class method, we need to create
a new object to represent property descriptor. This can be removed if we can introduce
a special bytecode or special function.

This patch introduces new bytecodes, op_define_data_property and op_define_accessor_property.
Instead of taking an object, they takes several registers to avoid object allocations.
We're planning to use this bytecode to implement Object.defineProperty in builtin JS next.
This allows us to leverage object allocation sinking. And it also gives us a chance to use
faster ::get and ::hasProperty in JS.

Originally, I attempted to create one bytecode, op_define_property. However, it takes too many
children in DFG and uses so many registers in DFG. This leads tricky program in 32bit platforms.
Furthermore, it does not fit to the number of x64 argument registers. So instead, we introduce
two bytecodes.

And for op_define_accessor_property, we perform CellUse edge filter to getter and setter children.
This edge filter makes us possible to use SpeculateCellOperand and reduce the number of used registers
in comparison with JSValueOperand. To make children Cells even if we do not specify some accessors (for
example, { get: func, set: null } case), we fill registers with special throwTypeErrorFunction.
The attributes bitset keep information like "This property descriptor only has getter slot".

In these two bytecodes, we take attributes (configurable, enumerable, writable, hasGetter etc.) as
register instead of embedding constant int value because we will use these bytecodes to implement
Object.defineProperty next. In Object.defineProperty case, an attributes are not statically defined
at bytecode compiling time.

Run ES6SampleBench/Air 20 times. The result shows ~2% performance improvement.

Baseline:
    firstIteration:     84.05 ms +- 4.37 ms
    averageWorstCase:   40.54 ms +- 2.81 ms
    steadyState:        3317.49 ms +- 48.25 ms
    summary:            223.51 ms +- 5.07 ms

Patched:
    firstIteration:     84.46 ms +- 4.22 ms
    averageWorstCase:   41.48 ms +- 2.33 ms
    steadyState:        3253.48 ms +- 29.31 ms
    summary:            224.40 ms +- 4.72 ms

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/SpecialPointer.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitMoveLinkTimeConstant):
(JSC::BytecodeGenerator::emitCallDefineProperty):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BitwiseNotNode::emitBytecode):
(JSC::ClassExprNode::emitBytecode):
(JSC::ObjectPatternNode::bindValue):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(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):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileDefineDataProperty):
(JSC::DFG::SpeculativeJIT::compileDefineAccessorProperty):
* 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::compileDefineDataProperty):
(JSC::FTL::DFG::LowerDFGToB3::compileDefineAccessorProperty):
(JSC::FTL::DFG::LowerDFGToB3::compilePutByValWithThis): Deleted.
* jit/CCallHelpers.cpp:
(JSC::CCallHelpers::setupFourStubArgsGPR): Deleted.
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupFourStubArgsGPR):
(JSC::CCallHelpers::setupFiveStubArgsGPR):
(JSC::CCallHelpers::setupArgumentsWithExecState):
(JSC::CCallHelpers::setupStubArgsGPR):
(JSC::CCallHelpers::prepareForTailCallSlow): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_define_data_property):
(JSC::JIT::emit_op_define_accessor_property):
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/DefinePropertyAttributes.h: Added.
(JSC::DefinePropertyAttributes::DefinePropertyAttributes):
(JSC::DefinePropertyAttributes::rawRepresentation):
(JSC::DefinePropertyAttributes::hasValue):
(JSC::DefinePropertyAttributes::setValue):
(JSC::DefinePropertyAttributes::hasGet):
(JSC::DefinePropertyAttributes::setGet):
(JSC::DefinePropertyAttributes::hasSet):
(JSC::DefinePropertyAttributes::setSet):
(JSC::DefinePropertyAttributes::writable):
(JSC::DefinePropertyAttributes::configurable):
(JSC::DefinePropertyAttributes::enumerable):
(JSC::DefinePropertyAttributes::setWritable):
(JSC::DefinePropertyAttributes::setConfigurable):
(JSC::DefinePropertyAttributes::setEnumerable):
(JSC::DefinePropertyAttributes::fillWithTriState):
(JSC::DefinePropertyAttributes::extractTriState):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::throwTypeErrorFunction):
(JSC::JSGlobalObject::definePropertyFunction): Deleted.
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructor::addDefineProperty): Deleted.
* runtime/ObjectConstructor.h:
* runtime/PropertyDescriptor.h:
(JSC::toPropertyDescriptor):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
41 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/SpecialPointer.h
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/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/CCallHelpers.cpp
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/DefinePropertyAttributes.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.h
Source/JavaScriptCore/runtime/PropertyDescriptor.h