Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (199072 => 199073)
--- trunk/Source/_javascript_Core/ChangeLog 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-04-05 21:36:25 UTC (rev 199073)
@@ -1,3 +1,125 @@
+2016-04-05 Keith Miller <keith_mil...@apple.com>
+
+ We should support the ability to do a non-effectful getById
+ https://bugs.webkit.org/show_bug.cgi?id=156116
+
+ Reviewed by Benjamin Poulain.
+
+ Currently, there is no way in JS to do a non-effectful getById. A non-effectful getById is
+ useful because it enables us to take different code paths based on values that we would
+ otherwise not be able to have knowledge of. This patch adds this new feature called
+ try_get_by_id that will attempt to do as much of a get_by_id as possible without performing
+ an effectful behavior. Thus, try_get_by_id will return the value if the slot is a value, the
+ GetterSetter object if the slot is a normal accessor (not a CustomGetterSetter) and
+ undefined if the slot is unset. If the slot is proxied or any other cases then the result
+ is null. In theory, if we ever wanted to check for null we could add a sentinal object to
+ the global object that indicates we could not get the result.
+
+ In order to implement this feature we add a new enum GetByIdKind that indicates what to do
+ for accessor properties in PolymorphicAccess. If the GetByIdKind is pure then we treat the
+ get_by_id the same way we would for load and return the value at the appropriate offset.
+ Additionally, in order to make sure the we can properly compare the GetterSetter object
+ with === GetterSetters are now JSObjects. This comes at the cost of eight extra bytes on the
+ GetterSetter object but it vastly simplifies the patch. Additionally, the extra bytes are
+ likely to have little to no impact on memory usage as normal accessors are generally rare.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * builtins/BuiltinExecutables.cpp:
+ (JSC::BuiltinExecutables::createDefaultConstructor):
+ (JSC::BuiltinExecutables::createBuiltinExecutable):
+ (JSC::createBuiltinExecutable):
+ (JSC::BuiltinExecutables::createExecutable):
+ (JSC::createExecutableInternal): Deleted.
+ * builtins/BuiltinExecutables.h:
+ * bytecode/BytecodeIntrinsicRegistry.h:
+ * bytecode/BytecodeList.json:
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset):
+ (JSC::computeDefsForBytecodeOffset):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/PolymorphicAccess.cpp:
+ (JSC::AccessCase::tryGet):
+ (JSC::AccessCase::generate):
+ (WTF::printInternal):
+ * bytecode/PolymorphicAccess.h:
+ (JSC::AccessCase::isGet): Deleted.
+ (JSC::AccessCase::isPut): Deleted.
+ (JSC::AccessCase::isIn): Deleted.
+ * bytecode/StructureStubInfo.cpp:
+ (JSC::StructureStubInfo::reset):
+ * bytecode/StructureStubInfo.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitTryGetById):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BytecodeIntrinsicNode::emit_intrinsic_tryGetById):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::cachedGetById):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::cachedGetById):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::getById):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITInlineCacheGenerator.cpp:
+ (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
+ * jit/JITInlineCacheGenerator.h:
+ * jit/JITInlines.h:
+ (JSC::JIT::callOperation):
+ * jit/JITOperations.cpp:
+ * jit/JITOperations.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitGetByValWithCachedId):
+ (JSC::JIT::emit_op_try_get_by_id):
+ (JSC::JIT::emitSlow_op_try_get_by_id):
+ (JSC::JIT::emit_op_get_by_id):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emitGetByValWithCachedId):
+ (JSC::JIT::emit_op_try_get_by_id):
+ (JSC::JIT::emitSlow_op_try_get_by_id):
+ (JSC::JIT::emit_op_get_by_id):
+ * jit/Repatch.cpp:
+ (JSC::repatchByIdSelfAccess):
+ (JSC::appropriateOptimizingGetByIdFunction):
+ (JSC::appropriateGenericGetByIdFunction):
+ (JSC::tryCacheGetByID):
+ (JSC::repatchGetByID):
+ (JSC::resetGetByID):
+ * jit/Repatch.h:
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionGetGetterSetter):
+ (functionCreateBuiltin):
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * runtime/GetterSetter.cpp:
+ * runtime/GetterSetter.h:
+ * runtime/JSType.h:
+ * runtime/PropertySlot.cpp:
+ (JSC::PropertySlot::getPureResult):
+ * runtime/PropertySlot.h:
+ * runtime/ProxyObject.cpp:
+ (JSC::ProxyObject::getOwnPropertySlotCommon):
+ * tests/stress/try-get-by-id.js: Added.
+ (tryGetByIdText):
+ (getCaller.obj.1.throw.new.Error.let.func):
+ (getCaller.obj.1.throw.new.Error):
+ (throw.new.Error.get let):
+ (throw.new.Error.):
+ (throw.new.Error.let.get createBuiltin):
+ (get let):
+ (let.get createBuiltin):
+ (let.func):
+ (get let.func):
+ (get throw):
+
2016-04-05 Saam barati <sbar...@apple.com>
jsc-layout-tests.yaml/js/script-tests/regress-141098.js failing on Yosemite Debug after r198989
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (199072 => 199073)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-04-05 21:36:25 UTC (rev 199073)
@@ -2508,8 +2508,8 @@
0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntExceptions.cpp; path = llint/LLIntExceptions.cpp; sourceTree = "<group>"; };
0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntExceptions.h; path = llint/LLIntExceptions.h; sourceTree = "<group>"; };
- 0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntSlowPaths.cpp; path = llint/LLIntSlowPaths.cpp; sourceTree = "<group>"; };
- 0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntSlowPaths.h; path = llint/LLIntSlowPaths.h; sourceTree = "<group>"; };
+ 0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = LLIntSlowPaths.cpp; path = llint/LLIntSlowPaths.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = LLIntSlowPaths.h; path = llint/LLIntSlowPaths.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntOffsetsExtractor.cpp; path = llint/LLIntOffsetsExtractor.cpp; sourceTree = "<group>"; };
0F4680C514BBB16900BFE272 /* LLIntCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCommon.h; path = llint/LLIntCommon.h; sourceTree = "<group>"; };
0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOfflineAsmConfig.h; path = llint/LLIntOfflineAsmConfig.h; sourceTree = "<group>"; };
@@ -2643,7 +2643,7 @@
0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; };
0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ComputeDivisionMagic.h; path = b3/B3ComputeDivisionMagic.h; sourceTree = "<group>"; };
- 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = "<group>"; };
+ 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BytecodeUseDef.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureAbstractValue.cpp; path = dfg/DFGStructureAbstractValue.cpp; sourceTree = "<group>"; };
0F898F2F1B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGIntegerRangeOptimizationPhase.cpp; path = dfg/DFGIntegerRangeOptimizationPhase.cpp; sourceTree = "<group>"; };
0F898F301B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGIntegerRangeOptimizationPhase.h; path = dfg/DFGIntegerRangeOptimizationPhase.h; sourceTree = "<group>"; };
@@ -3122,8 +3122,8 @@
1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionHelpers.cpp; sourceTree = "<group>"; };
1429D8DB0ED2205B00B89619 /* CallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallFrame.cpp; sourceTree = "<group>"; };
1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CallFrame.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
- 1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; };
- 1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
+ 1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JIT.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = JIT.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
142D3938103E4560007DCB52 /* NumericStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumericStrings.h; sourceTree = "<group>"; };
142D6F0613539A2800B02E86 /* MarkedBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedBlock.cpp; sourceTree = "<group>"; };
142D6F0713539A2800B02E86 /* MarkedBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedBlock.h; sourceTree = "<group>"; };
@@ -3335,10 +3335,10 @@
6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = "<group>"; };
651122E5140469BA002B101D /* testRegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testRegExp.cpp; sourceTree = "<group>"; };
6511230514046A4C002B101D /* testRegExp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testRegExp; sourceTree = BUILT_PRODUCTS_DIR; };
- 6514F21718B3E1670098FF8B /* Bytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bytecodes.h; sourceTree = "<group>"; };
- 6514F21818B3E1670098FF8B /* InitBytecodes.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; path = InitBytecodes.asm; sourceTree = "<group>"; };
+ 6514F21718B3E1670098FF8B /* Bytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Bytecodes.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 6514F21818B3E1670098FF8B /* InitBytecodes.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; path = InitBytecodes.asm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
6529FB3018B2D63900C61102 /* generate-bytecode-files */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "generate-bytecode-files"; sourceTree = "<group>"; };
- 6529FB3118B2D99900C61102 /* BytecodeList.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BytecodeList.json; sourceTree = "<group>"; };
+ 6529FB3118B2D99900C61102 /* BytecodeList.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = BytecodeList.json; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang._javascript_; };
652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ARM64Disassembler.cpp; path = disassembler/ARM64Disassembler.cpp; sourceTree = "<group>"; };
652A3A221651C69700A80AFE /* A64DOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = A64DOpcode.cpp; path = disassembler/ARM64/A64DOpcode.cpp; sourceTree = "<group>"; };
652A3A231651C69700A80AFE /* A64DOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = A64DOpcode.h; path = disassembler/ARM64/A64DOpcode.h; sourceTree = "<group>"; };
@@ -3427,7 +3427,7 @@
70B791901C0246CE002481E2 /* GeneratorPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratorPrototype.lut.h; sourceTree = "<group>"; };
70DC3E071B2DF2C700054299 /* IteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorPrototype.cpp; sourceTree = "<group>"; };
70DC3E081B2DF2C700054299 /* IteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorPrototype.h; sourceTree = "<group>"; };
- 70DE9A081BE7D670005D89D9 /* LLIntAssembly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntAssembly.h; sourceTree = "<group>"; };
+ 70DE9A081BE7D670005D89D9 /* LLIntAssembly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LLIntAssembly.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringIterator.cpp; sourceTree = "<group>"; };
70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringIterator.h; sourceTree = "<group>"; };
70EC0EC01AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringIteratorPrototype.cpp; sourceTree = "<group>"; };
@@ -3501,7 +3501,7 @@
860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; };
8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeProfiling.cpp; sourceTree = "<group>"; };
8603CEF314C7546400AE59E3 /* CodeProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeProfiling.h; sourceTree = "<group>"; };
- 8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; lineEnding = 0; path = ChangeLog; sourceTree = "<group>"; };
+ 8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; lineEnding = 0; path = ChangeLog; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdentifierInlines.h; sourceTree = "<group>"; };
8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; };
86158AB2155C8B3F00B45C9C /* PropertyName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyName.h; sourceTree = "<group>"; };
@@ -3529,7 +3529,7 @@
86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT64.cpp; path = dfg/DFGSpeculativeJIT64.cpp; sourceTree = "<group>"; };
868916A9155F285400CB2B9A /* PrivateName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateName.h; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
- 86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; };
+ 86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; };
86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; };
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
@@ -3550,7 +3550,7 @@
86CAFEE21035DDE60028A609 /* Executable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Executable.h; sourceTree = "<group>"; };
86CC85A00EE79A4700288682 /* JITInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlines.h; sourceTree = "<group>"; };
86CC85A20EE79B7400288682 /* JITCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCall.cpp; sourceTree = "<group>"; };
- 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess.cpp; sourceTree = "<group>"; };
+ 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JITPropertyAccess.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
86CCEFDD0F413F8900FD7F9E /* JITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCode.h; sourceTree = "<group>"; };
86D22219167EF9440024C804 /* testapi.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = testapi.mm; path = API/tests/testapi.mm; sourceTree = "<group>"; };
86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMAssembler.cpp; sourceTree = "<group>"; };
@@ -3632,11 +3632,11 @@
960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelScope.h; sourceTree = "<group>"; };
9688CB130ED12B4E001D649F /* AssemblerBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBuffer.h; sourceTree = "<group>"; };
9688CB140ED12B4E001D649F /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; };
- 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeGenerator.cpp; sourceTree = "<group>"; };
+ 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = BytecodeGenerator.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeGenerator.h; sourceTree = "<group>"; };
969A07270ED1CE6900F1F681 /* Label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Label.h; sourceTree = "<group>"; };
969A07280ED1CE6900F1F681 /* RegisterID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterID.h; sourceTree = "<group>"; };
- 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlock.cpp; sourceTree = "<group>"; };
+ 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CodeBlock.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
969A07910ED1D3AE00F1F681 /* CodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlock.h; sourceTree = "<group>"; };
969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvalCodeCache.h; sourceTree = "<group>"; };
969A07930ED1D3AE00F1F681 /* Instruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Instruction.h; sourceTree = "<group>"; };
@@ -3980,7 +3980,7 @@
A7BFF3BF179868940002F462 /* DFGFiltrationResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFiltrationResult.h; path = dfg/DFGFiltrationResult.h; sourceTree = "<group>"; };
A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSScriptRef.cpp; sourceTree = "<group>"; };
A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScriptRefPrivate.h; sourceTree = "<group>"; };
- A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
+ A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
A7C1EAEB17987AB600299DB2 /* JSStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStackInlines.h; sourceTree = "<group>"; };
A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = StackVisitor.cpp; sourceTree = "<group>"; };
A7C1EAED17987AB600299DB2 /* StackVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackVisitor.h; sourceTree = "<group>"; };
Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -35,8 +35,6 @@
namespace JSC {
-static UnlinkedFunctionExecutable* createExecutableInternal(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
-
BuiltinExecutables::BuiltinExecutables(VM& vm)
: m_vm(vm)
#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(makeSource(StringImpl::createFromLiteral(s_##name, length)))
@@ -54,9 +52,9 @@
case ConstructorKind::None:
break;
case ConstructorKind::Base:
- return createExecutableInternal(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
+ return createExecutable(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
case ConstructorKind::Derived:
- return createExecutableInternal(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
+ return createExecutable(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
}
ASSERT_NOT_REACHED();
return nullptr;
@@ -64,15 +62,15 @@
UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
{
- return createExecutableInternal(m_vm, code, name, ConstructorKind::None, constructAbility);
+ return createExecutable(m_vm, code, name, ConstructorKind::None, constructAbility);
}
UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
{
- return createExecutableInternal(vm, code, name, ConstructorKind::None, constructAbility);
+ return BuiltinExecutables::createExecutable(vm, code, name, ConstructorKind::None, constructAbility);
}
-UnlinkedFunctionExecutable* createExecutableInternal(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)
+UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)
{
JSTextPosition positionBeforeLastNewline;
ParserError error;
Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h (199072 => 199073)
--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -52,6 +52,7 @@
UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
+ JS_EXPORT_PRIVATE static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
private:
void finalize(Handle<Unknown>, void* context) override;
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -41,6 +41,7 @@
#define JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(macro) \
macro(assert) \
macro(isObject) \
+ macro(tryGetById) \
macro(putByValDirect) \
macro(toString)
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2016-04-05 21:36:25 UTC (rev 199073)
@@ -57,6 +57,7 @@
{ "name" : "op_is_object_or_null", "length" : 3 },
{ "name" : "op_is_function", "length" : 3 },
{ "name" : "op_in", "length" : 4 },
+ { "name" : "op_try_get_by_id", "length" : 4 },
{ "name" : "op_get_by_id", "length" : 9 },
{ "name" : "op_get_array_length", "length" : 9 },
{ "name" : "op_put_by_id", "length" : 9 },
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -141,6 +141,7 @@
case op_resolve_scope:
case op_get_from_scope:
case op_to_primitive:
+ case op_try_get_by_id:
case op_get_by_id:
case op_get_array_length:
case op_typeof:
@@ -363,6 +364,7 @@
case op_tail_call:
case op_call_eval:
case op_construct:
+ case op_try_get_by_id:
case op_get_by_id:
case op_get_array_length:
case op_overrides_has_instance:
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -1095,6 +1095,14 @@
printBinaryOp(out, exec, location, it, "in");
break;
}
+ case op_try_get_by_id: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int id0 = (++it)->u.operand;
+ printLocationAndOp(out, exec, location, it, "try_get_by_id");
+ out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
+ break;
+ }
case op_get_by_id:
case op_get_array_length: {
printGetByIdOp(out, exec, location, it);
Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -159,6 +159,26 @@
{
}
+std::unique_ptr<AccessCase> AccessCase::tryGet(
+ VM& vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure,
+ const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet)
+{
+ std::unique_ptr<AccessCase> result(new AccessCase());
+
+ result->m_type = type;
+ result->m_offset = offset;
+ result->m_structure.set(vm, owner, structure);
+ result->m_conditionSet = conditionSet;
+
+ if (viaProxy || additionalSet) {
+ result->m_rareData = std::make_unique<RareData>();
+ result->m_rareData->viaProxy = viaProxy;
+ result->m_rareData->additionalSet = additionalSet;
+ }
+
+ return result;
+}
+
std::unique_ptr<AccessCase> AccessCase::get(
VM& vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure,
const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet,
@@ -685,6 +705,7 @@
return;
case Load:
+ case GetGetter:
case Getter:
case Setter:
case CustomValueGetter:
@@ -720,7 +741,7 @@
GPRReg loadedValueGPR = InvalidGPRReg;
if (m_type != CustomValueGetter && m_type != CustomAccessorGetter && m_type != CustomValueSetter && m_type != CustomAccessorSetter) {
- if (m_type == Load)
+ if (m_type == Load || m_type == GetGetter)
loadedValueGPR = valueRegs.payloadGPR();
else
loadedValueGPR = scratchGPR;
@@ -739,7 +760,7 @@
jit.load64(
CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)), loadedValueGPR);
#else
- if (m_type == Load) {
+ if (m_type == Load || m_type == GetGetter) {
jit.load32(
CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset),
valueRegs.tagGPR());
@@ -750,7 +771,7 @@
#endif
}
- if (m_type == Load) {
+ if (m_type == Load || m_type == GetGetter) {
state.succeed();
return;
}
@@ -1621,6 +1642,9 @@
case AccessCase::Miss:
out.print("Miss");
return;
+ case AccessCase::GetGetter:
+ out.print("GetGetter");
+ return;
case AccessCase::Getter:
out.print("Getter");
return;
Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -57,6 +57,7 @@
Transition,
Replace,
Miss,
+ GetGetter,
Getter,
Setter,
CustomValueGetter,
@@ -70,78 +71,12 @@
StringLength
};
- static bool isGet(AccessType type)
- {
- switch (type) {
- case Transition:
- case Replace:
- case Setter:
- case CustomValueSetter:
- case CustomAccessorSetter:
- case InHit:
- case InMiss:
- return false;
- case Load:
- case MegamorphicLoad:
- case Miss:
- case Getter:
- case CustomValueGetter:
- case CustomAccessorGetter:
- case IntrinsicGetter:
- case ArrayLength:
- case StringLength:
- return true;
- }
- }
+ static std::unique_ptr<AccessCase> tryGet(
+ VM&, JSCell* owner, AccessType, PropertyOffset, Structure*,
+ const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
+ bool viaProxy = false,
+ WatchpointSet* additionalSet = nullptr);
- static bool isPut(AccessType type)
- {
- switch (type) {
- case Load:
- case MegamorphicLoad:
- case Miss:
- case Getter:
- case CustomValueGetter:
- case CustomAccessorGetter:
- case IntrinsicGetter:
- case InHit:
- case InMiss:
- case ArrayLength:
- case StringLength:
- return false;
- case Transition:
- case Replace:
- case Setter:
- case CustomValueSetter:
- case CustomAccessorSetter:
- return true;
- }
- }
-
- static bool isIn(AccessType type)
- {
- switch (type) {
- case Load:
- case MegamorphicLoad:
- case Miss:
- case Getter:
- case CustomValueGetter:
- case CustomAccessorGetter:
- case IntrinsicGetter:
- case Transition:
- case Replace:
- case Setter:
- case CustomValueSetter:
- case CustomAccessorSetter:
- case ArrayLength:
- case StringLength:
- return false;
- case InHit:
- case InMiss:
- return true;
- }
- }
-
static std::unique_ptr<AccessCase> get(
VM&, JSCell* owner, AccessType, PropertyOffset, Structure*,
const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -148,8 +148,11 @@
}
switch (accessType) {
+ case AccessType::GetPure:
+ resetGetByID(codeBlock, *this, GetByIDKind::Pure);
+ break;
case AccessType::Get:
- resetGetByID(codeBlock, *this);
+ resetGetByID(codeBlock, *this, GetByIDKind::Normal);
break;
case AccessType::Put:
resetPutByID(codeBlock, *this);
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -47,6 +47,7 @@
enum class AccessType : int8_t {
Get,
+ GetPure,
Put,
In
};
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -2359,6 +2359,17 @@
return dst;
}
+RegisterID* BytecodeGenerator::emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
+{
+ ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties are not supported with tryGetById.");
+
+ emitOpcode(op_try_get_by_id);
+ instructions().append(kill(dst));
+ instructions().append(base->index());
+ instructions().append(addConstant(property));
+ return dst;
+}
+
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
{
ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -540,6 +540,7 @@
RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
+ RegisterID* emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -842,6 +842,21 @@
return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
}
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
+{
+ ArgumentListNode* node = m_args->m_listNode;
+ RefPtr<RegisterID> base = generator.emitNode(node);
+ node = node->m_next;
+
+ // Since this is a builtin we expect the creator to use a string literal as the second argument.
+ ASSERT(node->m_expr->isString());
+ const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
+ ASSERT(!node->m_next);
+
+ RegisterID* finalDest = generator.finalDestination(dst);
+ return generator.emitTryGetById(finalDest, base.get(), ident);
+}
+
RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
{
ArgumentListNode* node = m_args->m_listNode;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -194,7 +194,7 @@
JITGetByIdGenerator gen(
m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
JSValueRegs(baseTagGPROrNone, basePayloadGPR),
- JSValueRegs(resultTagGPR, resultPayloadGPR));
+ JSValueRegs(resultTagGPR, resultPayloadGPR), AccessType::Get);
gen.generateFastPath(m_jit);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -164,7 +164,7 @@
}
JITGetByIdGenerator gen(
m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, JSValueRegs(baseGPR),
- JSValueRegs(resultGPR));
+ JSValueRegs(resultGPR), AccessType::Get);
gen.generateFastPath(m_jit);
JITCompiler::JumpList slowCases;
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -7109,7 +7109,7 @@
auto generator = Box<JITGetByIdGenerator>::create(
jit.codeBlock(), node->origin.semantic, callSiteIndex,
params.unavailableRegisters(), JSValueRegs(params[1].gpr()),
- JSValueRegs(params[0].gpr()));
+ JSValueRegs(params[0].gpr()), AccessType::Get);
generator->generateFastPath(jit);
CCallHelpers::Label done = jit.label();
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -228,6 +228,7 @@
DEFINE_OP(op_get_scope)
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
+ DEFINE_OP(op_try_get_by_id)
case op_get_array_length:
DEFINE_OP(op_get_by_id)
DEFINE_OP(op_get_by_val)
@@ -403,6 +404,7 @@
DEFINE_SLOWCASE_OP(op_create_this)
DEFINE_SLOWCASE_OP(op_div)
DEFINE_SLOWCASE_OP(op_eq)
+ DEFINE_SLOWCASE_OP(op_try_get_by_id)
case op_get_array_length:
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_by_val)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JIT.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -502,6 +502,7 @@
void emit_op_get_scope(Instruction*);
void emit_op_eq(Instruction*);
void emit_op_eq_null(Instruction*);
+ void emit_op_try_get_by_id(Instruction*);
void emit_op_get_by_id(Instruction*);
void emit_op_get_arguments_length(Instruction*);
void emit_op_get_by_val(Instruction*);
@@ -612,6 +613,7 @@
void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_callee(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_try_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -736,8 +738,10 @@
MacroAssembler::Call callOperation(V_JITOperation_EC, JSCell*);
MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg);
#if USE(JSVALUE64)
+ MacroAssembler::Call callOperation(J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*);
MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*);
#else
+ MacroAssembler::Call callOperation(J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*);
MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*);
#endif
MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*);
Modified: trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -104,9 +104,9 @@
JITGetByIdGenerator::JITGetByIdGenerator(
CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters,
- JSValueRegs base, JSValueRegs value)
+ JSValueRegs base, JSValueRegs value, AccessType accessType)
: JITByIdGenerator(
- codeBlock, codeOrigin, callSite, AccessType::Get, usedRegisters, base, value)
+ codeBlock, codeOrigin, callSite, accessType, usedRegisters, base, value)
{
RELEASE_ASSERT(base.payloadGPR() != value.tagGPR());
}
Modified: trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -96,7 +96,7 @@
JITGetByIdGenerator(
CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base,
- JSValueRegs value);
+ JSValueRegs value, AccessType);
void generateFastPath(MacroAssembler&);
};
Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITInlines.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -455,6 +455,12 @@
return appendCallWithExceptionCheck(operation);
}
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
+{
+ setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
+ return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
{
setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
@@ -638,6 +644,12 @@
return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
}
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
+{
+ setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
+ return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
{
setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -153,6 +153,36 @@
return missingArgCount;
}
+EncodedJSValue JIT_OPERATION operationTryGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+ Identifier ident = Identifier::fromUid(vm, uid);
+ stubInfo->tookSlowPath = true;
+
+ JSValue baseValue = JSValue::decode(base);
+ PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
+ baseValue.getPropertySlot(exec, ident, slot);
+
+ return JSValue::encode(slot.getPureResult());
+}
+
+EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+ Identifier ident = Identifier::fromUid(vm, uid);
+
+ JSValue baseValue = JSValue::decode(base);
+ PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
+
+ baseValue.getPropertySlot(exec, ident, slot);
+ if (stubInfo->considerCaching() && !slot.isTaintedByProxy() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
+ repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Pure);
+
+ return JSValue::encode(slot.getPureResult());
+}
+
EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
{
VM* vm = &exec->vm();
@@ -188,7 +218,7 @@
bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
if (stubInfo->considerCaching())
- repatchGetByID(exec, baseValue, ident, slot, *stubInfo);
+ repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Normal);
return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
}
Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITOperations.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -287,9 +287,10 @@
#endif
int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL;
int32_t JIT_OPERATION operationConstructArityCheck(ExecState*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationTryGetById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationGetById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -213,7 +213,7 @@
JITGetByIdGenerator gen(
m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
- JSValueRegs(regT0), JSValueRegs(regT0));
+ JSValueRegs(regT0), JSValueRegs(regT0), AccessType::Get);
gen.generateFastPath(*this);
fastDoneCase = jump();
@@ -531,6 +531,43 @@
callOperation(operationDeleteById, dst, regT0, &m_codeBlock->identifier(property));
}
+void JIT::emit_op_try_get_by_id(Instruction* currentInstruction)
+{
+ int resultVReg = currentInstruction[1].u.operand;
+ int baseVReg = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(baseVReg, regT0);
+
+ emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
+
+ JITGetByIdGenerator gen(
+ m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
+ JSValueRegs(regT0), JSValueRegs(regT0), AccessType::GetPure);
+ gen.generateFastPath(*this);
+ addSlowCase(gen.slowPathJump());
+ m_getByIds.append(gen);
+
+ emitPutVirtualRegister(resultVReg);
+}
+
+void JIT::emitSlow_op_try_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ int resultVReg = currentInstruction[1].u.operand;
+ int baseVReg = currentInstruction[2].u.operand;
+ const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+ linkSlowCaseIfNotJSCell(iter, baseVReg);
+ linkSlowCase(iter);
+
+ JITGetByIdGenerator& gen = m_getByIds[m_getByIdIndex++];
+
+ Label coldPathBegin = label();
+
+ Call call = callOperation(operationTryGetByIdOptimize, resultVReg, gen.stubInfo(), regT0, ident->impl());
+
+ gen.reportSlowPathCall(coldPathBegin, call);
+}
+
void JIT::emit_op_get_by_id(Instruction* currentInstruction)
{
int resultVReg = currentInstruction[1].u.operand;
@@ -546,7 +583,7 @@
JITGetByIdGenerator gen(
m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
- JSValueRegs(regT0), JSValueRegs(regT0));
+ JSValueRegs(regT0), JSValueRegs(regT0), AccessType::Get);
gen.generateFastPath(*this);
addSlowCase(gen.slowPathJump());
m_getByIds.append(gen);
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -282,7 +282,7 @@
JITGetByIdGenerator gen(
m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
- JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0));
+ JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::Get);
gen.generateFastPath(*this);
fastDoneCase = jump();
@@ -573,6 +573,43 @@
m_byValInstructionIndex++;
}
+void JIT::emit_op_try_get_by_id(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+
+ emitLoad(base, regT1, regT0);
+ emitJumpSlowCaseIfNotJSCell(base, regT1);
+
+ JITGetByIdGenerator gen(
+ m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
+ JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::GetPure);
+ gen.generateFastPath(*this);
+ addSlowCase(gen.slowPathJump());
+ m_getByIds.append(gen);
+
+ emitStore(dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_try_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ int resultVReg = currentInstruction[1].u.operand;
+ int baseVReg = currentInstruction[2].u.operand;
+ const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+ linkSlowCaseIfNotJSCell(iter, baseVReg);
+ linkSlowCase(iter);
+
+ JITGetByIdGenerator& gen = m_getByIds[m_getByIdIndex++];
+
+ Label coldPathBegin = label();
+
+ Call call = callOperation(operationTryGetByIdOptimize, resultVReg, gen.stubInfo(), regT1, regT0, ident->impl());
+
+ gen.reportSlowPathCall(coldPathBegin, call);
+}
+
+
void JIT::emit_op_get_by_id(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
@@ -587,7 +624,7 @@
JITGetByIdGenerator gen(
m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
- JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0));
+ JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::Get);
gen.generateFastPath(*this);
addSlowCase(gen.slowPathJump());
m_getByIds.append(gen);
Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/Repatch.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -93,7 +93,7 @@
static void repatchByIdSelfAccess(
CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure,
- PropertyOffset offset, const FunctionPtr &slowPathFunction,
+ PropertyOffset offset, const FunctionPtr& slowPathFunction,
bool compact)
{
// Only optimize once!
@@ -213,8 +213,22 @@
return Options::forceICFailure();
}
-static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
+inline J_JITOperation_ESsiJI appropriateOptimizingGetByIdFunction(GetByIDKind kind)
{
+ if (kind == GetByIDKind::Normal)
+ return operationGetByIdOptimize;
+ return operationTryGetByIdOptimize;
+}
+
+inline J_JITOperation_ESsiJI appropriateGenericGetByIdFunction(GetByIDKind kind)
+{
+ if (kind == GetByIDKind::Normal)
+ return operationGetById;
+ return operationTryGetById;
+}
+
+static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind)
+{
if (forceICFailure(exec))
return GiveUpOnCache;
@@ -262,7 +276,7 @@
&& !structure->needImpurePropertyWatchpoint()
&& !loadTargetFromProxy) {
structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
- repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdOptimize, true);
+ repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), appropriateOptimizingGetByIdFunction(kind), true);
stubInfo.initGetByIdSelf(codeBlock, structure, slot.cachedOffset());
return RetryCacheLater;
}
@@ -295,7 +309,19 @@
if (slot.isCacheableGetter())
getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
- if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure))
+ if (kind == GetByIDKind::Pure) {
+ AccessCase::AccessType type;
+ if (slot.isCacheableValue())
+ type = AccessCase::Load;
+ else if (slot.isUnset())
+ type = AccessCase::Miss;
+ else if (slot.isCacheableGetter())
+ type = AccessCase::GetGetter;
+ else
+ RELEASE_ASSERT_NOT_REACHED();
+
+ newCase = AccessCase::tryGet(vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet());
+ } else if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure))
newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
else {
AccessCase::AccessType type;
@@ -330,12 +356,12 @@
return RetryCacheLater;
}
-void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
+void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind)
{
GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap);
- if (tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo) == GiveUpOnCache)
- repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
+ if (tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo, kind) == GiveUpOnCache)
+ repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericGetByIdFunction(kind));
}
static V_JITOperation_ESsiJJI appropriateGenericPutByIdFunction(const PutPropertySlot &slot, PutKind putKind)
@@ -910,9 +936,9 @@
callLinkInfo.remove();
}
-void resetGetByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
+void resetGetByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo, GetByIDKind kind)
{
- repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdOptimize);
+ repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateOptimizingGetByIdFunction(kind));
resetGetByIDCheckAndLoad(stubInfo);
MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
}
Modified: trunk/Source/_javascript_Core/jit/Repatch.h (199072 => 199073)
--- trunk/Source/_javascript_Core/jit/Repatch.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jit/Repatch.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -35,7 +35,12 @@
namespace JSC {
-void repatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
+enum class GetByIDKind {
+ Normal,
+ Pure
+};
+
+void repatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&, GetByIDKind);
void buildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
void buildGetByIDProtoList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
void repatchPutByID(ExecState*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
@@ -46,7 +51,7 @@
void unlinkFor(VM&, CallLinkInfo&);
void linkVirtualFor(ExecState*, CallLinkInfo&);
void linkPolymorphicCall(ExecState*, CallLinkInfo&, CallVariant);
-void resetGetByID(CodeBlock*, StructureStubInfo&);
+void resetGetByID(CodeBlock*, StructureStubInfo&, GetByIDKind);
void resetPutByID(CodeBlock*, StructureStubInfo&);
void resetIn(CodeBlock*, StructureStubInfo&);
Modified: trunk/Source/_javascript_Core/jsc.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/jsc.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/jsc.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -23,6 +23,7 @@
#include "config.h"
#include "ArrayPrototype.h"
+#include "BuiltinExecutables.h"
#include "ButterflyInlines.h"
#include "BytecodeGenerator.h"
#include "CodeBlock.h"
@@ -32,6 +33,7 @@
#include "Disassembler.h"
#include "Exception.h"
#include "ExceptionHelpers.h"
+#include "GetterSetter.h"
#include "HeapProfiler.h"
#include "HeapSnapshotBuilder.h"
#include "HeapStatistics.h"
@@ -551,6 +553,7 @@
static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*);
@@ -571,6 +574,7 @@
static EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState*);
#ifndef NDEBUG
static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
#endif
@@ -740,6 +744,7 @@
addFunction(vm, "forceGCSlowPaths", functionForceGCSlowPaths, 0);
addFunction(vm, "gcHeapSize", functionHeapSize, 0);
addFunction(vm, "addressOf", functionAddressOf, 1);
+ addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
#ifndef NDEBUG
addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
#endif
@@ -788,6 +793,7 @@
addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
+ addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
@@ -1328,6 +1334,30 @@
return returnValue;
}
+static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)
+{
+ JSValue value = exec->argument(0);
+ if (!value.isObject())
+ return JSValue::encode(jsUndefined());
+
+ JSValue property = exec->argument(1);
+ if (!property.isString())
+ return JSValue::encode(jsUndefined());
+
+ Identifier ident = Identifier::fromString(&exec->vm(), property.toString(exec)->value(exec));
+
+ PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
+ value.getPropertySlot(exec, ident, slot);
+
+ JSValue result;
+ if (slot.isCacheableGetter())
+ result = slot.getterSetter();
+ else
+ result = jsNull();
+
+ return JSValue::encode(result);
+}
+
EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*)
{
// We need this function for compatibility with the Mozilla JS tests but for now
@@ -1712,6 +1742,22 @@
return JSValue::encode(jsUndefined());
}
+EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
+{
+ if (exec->argumentCount() < 1 || !exec->argument(0).isString())
+ return JSValue::encode(jsUndefined());
+
+ String functionText = exec->argument(0).toString(exec)->value(exec);
+ if (exec->hadException())
+ return JSValue::encode(JSValue());
+
+ VM& vm = exec->vm();
+ const SourceCode& source = makeSource(functionText);
+ JSFunction* func = JSFunction::createBuiltinFunction(vm, BuiltinExecutables::createExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
+
+ return JSValue::encode(func);
+}
+
EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState* exec)
{
String source = exec->argument(0).toString(exec)->value(exec);
Modified: trunk/Source/_javascript_Core/llint/LLIntData.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/llint/LLIntData.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/llint/LLIntData.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -144,9 +144,9 @@
STATIC_ASSERT(StringType == 6);
STATIC_ASSERT(SymbolType == 7);
- STATIC_ASSERT(ObjectType == 21);
- STATIC_ASSERT(FinalObjectType == 22);
- STATIC_ASSERT(JSFunctionType == 24);
+ STATIC_ASSERT(ObjectType == 20);
+ STATIC_ASSERT(FinalObjectType == 21);
+ STATIC_ASSERT(JSFunctionType == 23);
STATIC_ASSERT(MasqueradesAsUndefined == 1);
STATIC_ASSERT(ImplementsDefaultHasInstance == 2);
STATIC_ASSERT(FirstConstantRegisterIndex == 0x40000000);
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -544,6 +544,19 @@
LLINT_RETURN(result);
}
+LLINT_SLOW_PATH_DECL(slow_path_try_get_by_id)
+{
+ LLINT_BEGIN();
+ CodeBlock* codeBlock = exec->codeBlock();
+ const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
+ JSValue baseValue = LLINT_OP_C(2).jsValue();
+ PropertySlot slot(baseValue, PropertySlot::PropertySlot::InternalMethodType::VMInquiry);
+
+ baseValue.getPropertySlot(exec, ident, slot);
+
+ LLINT_RETURN(slot.getPureResult());
+}
+
LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
{
LLINT_BEGIN();
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h (199072 => 199073)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -69,6 +69,7 @@
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_regexp);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof_custom);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_try_get_by_id);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_arguments_length);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id);
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (199072 => 199073)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2016-04-05 21:36:25 UTC (rev 199073)
@@ -326,9 +326,9 @@
# Type constants.
const StringType = 6
const SymbolType = 7
-const ObjectType = 21
-const FinalObjectType = 22
-const JSFunctionType = 24
+const ObjectType = 20
+const FinalObjectType = 21
+const JSFunctionType = 23
# Type flags constants.
const MasqueradesAsUndefined = 1
@@ -1301,6 +1301,12 @@
dispatch(4)
+_llint_op_try_get_by_id:
+ traceExecution()
+ callSlowPath(_llint_slow_path_try_get_by_id)
+ dispatch(4)
+
+
_llint_op_del_by_id:
traceExecution()
callSlowPath(_llint_slow_path_del_by_id)
Modified: trunk/Source/_javascript_Core/runtime/GetterSetter.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/GetterSetter.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/GetterSetter.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -33,7 +33,7 @@
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(GetterSetter);
-const ClassInfo GetterSetter::s_info = { "GetterSetter", 0, 0, CREATE_METHOD_TABLE(GetterSetter) };
+const ClassInfo GetterSetter::s_info = { "GetterSetter", &Base::s_info, 0, CREATE_METHOD_TABLE(GetterSetter) };
void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
Modified: trunk/Source/_javascript_Core/runtime/GetterSetter.h (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/GetterSetter.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/GetterSetter.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -41,21 +41,21 @@
// that if a property holding a GetterSetter reference is constant-inferred and
// that constant is observed to have a non-null setter (or getter) then we can
// constant fold that setter (or getter).
-class GetterSetter final : public JSCell {
+class GetterSetter final : public JSNonFinalObject {
friend class JIT;
-
+ typedef JSNonFinalObject Base;
private:
GetterSetter(VM& vm, JSGlobalObject* globalObject)
- : JSCell(vm, vm.getterSetterStructure.get())
+ : Base(vm, vm.getterSetterStructure.get())
{
m_getter.set(vm, this, globalObject->nullGetterFunction());
m_setter.set(vm, this, globalObject->nullSetterFunction());
}
public:
- typedef JSCell Base;
- static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+ static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | StructureIsImmortal;
+
static GetterSetter* create(VM& vm, JSGlobalObject* globalObject)
{
GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm, globalObject);
@@ -128,8 +128,13 @@
return OBJECT_OFFSETOF(GetterSetter, m_setter);
}
- DECLARE_INFO;
+ DECLARE_EXPORT_INFO;
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; }
+ static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; }
+ static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; }
+ static bool deleteProperty(JSCell*, ExecState*, PropertyName) { RELEASE_ASSERT_NOT_REACHED(); return false; }
+
private:
WriteBarrier<JSObject> m_getter;
WriteBarrier<JSObject> m_setter;
Modified: trunk/Source/_javascript_Core/runtime/JSType.h (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/JSType.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/JSType.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -35,7 +35,6 @@
StringType,
SymbolType,
- GetterSetterType,
CustomGetterSetterType,
APIValueWrapperType,
@@ -75,6 +74,7 @@
Float64ArrayType,
DataViewType,
+ GetterSetterType,
GlobalObjectType,
LexicalEnvironmentType,
GlobalLexicalEnvironmentType,
Modified: trunk/Source/_javascript_Core/runtime/PropertySlot.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/PropertySlot.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/PropertySlot.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -39,4 +39,21 @@
return JSValue::decode(m_data.custom.getValue(exec, JSValue::encode(thisValue), propertyName));
}
+JSValue PropertySlot::getPureResult() const
+{
+ JSValue result;
+ if (isTaintedByProxy())
+ result = jsNull();
+ else if (isCacheableValue())
+ result = JSValue::decode(m_data.value);
+ else if (isCacheableGetter())
+ result = getterSetter();
+ else if (isUnset())
+ result = jsUndefined();
+ else
+ result = jsNull();
+
+ return result;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/PropertySlot.h (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/PropertySlot.h 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/PropertySlot.h 2016-04-05 21:36:25 UTC (rev 199073)
@@ -94,6 +94,7 @@
JSValue getValue(ExecState*, PropertyName) const;
JSValue getValue(ExecState*, unsigned propertyName) const;
+ JSValue getPureResult() const;
bool isCacheable() const { return m_cacheability == CachingAllowed && m_offset != invalidOffset; }
bool isUnset() const { return m_propertyType == TypeUnset; }
Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (199072 => 199073)
--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2016-04-05 21:27:05 UTC (rev 199072)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2016-04-05 21:36:25 UTC (rev 199073)
@@ -332,8 +332,7 @@
bool ProxyObject::getOwnPropertySlotCommon(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
slot.disableCaching();
- if (slot.internalMethodType() != PropertySlot::InternalMethodType::VMInquiry)
- slot.setIsTaintedByProxy();
+ slot.setIsTaintedByProxy();
switch (slot.internalMethodType()) {
case PropertySlot::InternalMethodType::Get:
slot.setCustom(this, CustomAccessor, performProxyGet);
Added: trunk/Source/_javascript_Core/tests/stress/try-get-by-id.js (0 => 199073)
--- trunk/Source/_javascript_Core/tests/stress/try-get-by-id.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/try-get-by-id.js 2016-04-05 21:36:25 UTC (rev 199073)
@@ -0,0 +1,117 @@
+function tryGetByIdText(propertyName) { return `(function (base) { return @tryGetById(base, '${propertyName}'); })`; }
+
+
+// Test get value off object.
+{
+ let getCaller = createBuiltin(tryGetByIdText("caller"));
+ noInline(getCaller);
+ let obj = {caller: 1};
+
+ for (let i = 0; i < 100000; i++) {
+ if (getCaller(obj) !== 1)
+ throw new Error("wrong on iteration: " + i);
+ }
+}
+
+// Test slot is custom function trap for a value.
+{
+ let getCaller = createBuiltin(tryGetByIdText("caller"));
+ noInline(getCaller);
+ let func = function () {};
+
+ for (let i = 0; i < 100000; i++) {
+ if (getCaller(func) !== null)
+ throw new Error("wrong on iteration: " + i);
+ }
+}
+
+// Test slot is a GetterSetter.
+{
+ let get = createBuiltin(tryGetByIdText("getterSetter"));
+ noInline(get);
+ let obj = {};
+ Object.defineProperty(obj, "getterSetter", { get: function () { throw new Error("should not be called"); } });
+
+ for (let i = 0; i < 100000; i++) {
+ if (get(obj) !== getGetterSetter(obj, "getterSetter"))
+ throw new Error("wrong on iteration: " + i);
+ }
+}
+
+// Test slot is unset.
+{
+ let get = createBuiltin(tryGetByIdText("getterSetter"));
+ noInline(get);
+ let obj = {};
+
+ for (let i = 0; i < 100000; i++) {
+ if (get(obj) !== undefined)
+ throw new Error("wrong on iteration: " + i);
+ }
+}
+
+// Test slot is on a proxy with value.
+{
+ let get = createBuiltin(tryGetByIdText("value"));
+ noInline(get);
+
+ let obj = {value: 1};
+ let p = new Proxy(obj, { get: function() { throw new Error("should not be called"); } });
+
+ for (let i = 0; i < 100000; i++) {
+ if (get(p) !== null)
+ throw new Error("wrong on iteration: " + i);
+ }
+}
+
+// Test mutating inline cache.
+{
+ let get = createBuiltin(tryGetByIdText("caller"));
+ noInline(get);
+
+ let obj = {caller : 1};
+ let func = function() {};
+
+ for (let i = 0; i < 100000; i++) {
+ if (i % 100 === 0) {
+ if (get(func) !== null)
+ throw new Error("wrong on iteration: " + i);
+ } else {
+ if (get(obj) !== 1)
+ throw new Error("wrong on iteration: " + i);
+ }
+ }
+}
+
+// Test new type on each iteration.
+{
+ let get = createBuiltin(tryGetByIdText("caller"));
+ noInline(get);
+
+ let func = function() {};
+
+ for (let i = 0; i < 100000; i++) {
+ if (i % 100 === 0) {
+ if (get(func) !== null)
+ throw new Error("wrong on iteration: " + i);
+ } else {
+ let obj = {caller : 1};
+ if (get(obj) !== 1)
+ throw new Error("wrong on iteration: " + i);
+ }
+ }
+}
+
+// Test with array length. This is null because the value is not cacheable.
+{
+ let get = createBuiltin(tryGetByIdText("length"));
+ noInline(get);
+
+ let arr = [];
+
+ for (let i = 0; i < 100000; i++) {
+ if (get(arr) !== null)
+ throw new Error("wrong on iteration: " + i);
+
+ }
+}