WebKit Bugzilla
Attachment 340789 Details for
Bug 185803
: [DFG] InById should be converted to MatchStructure
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185803-20180520092622.patch (text/plain), 39.86 KB, created by
Yusuke Suzuki
on 2018-05-19 17:26:24 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-05-19 17:26:24 PDT
Size:
39.86 KB
patch
obsolete
>Subversion Revision: 232001 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 8228176e72b5a333221358c4f3bea8410ceaf0da..e92429573596d0883dc0217ed5c95014b2c00959 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,52 @@ >+2018-05-19 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [DFG] InById should be converted to MatchStructure >+ https://bugs.webkit.org/show_bug.cgi?id=185803 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ MatchStructure is introduced for instanceof optimization. But this node >+ is also useful for InById node. This patch converts InById to MatchStructure >+ node with CheckStructures if possible by using InByIdStatus. >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * bytecode/InByIdStatus.cpp: Added. >+ (JSC::InByIdStatus::appendVariant): >+ (JSC::InByIdStatus::computeFor): >+ (JSC::InByIdStatus::hasExitSite): >+ (JSC::InByIdStatus::computeForStubInfo): >+ (JSC::InByIdStatus::computeForStubInfoWithoutExitSiteFeedback): >+ (JSC::InByIdStatus::filter): >+ (JSC::InByIdStatus::dump const): >+ * bytecode/InByIdStatus.h: Added. >+ (JSC::InByIdStatus::InByIdStatus): >+ (JSC::InByIdStatus::state const): >+ (JSC::InByIdStatus::isSet const): >+ (JSC::InByIdStatus::operator bool const): >+ (JSC::InByIdStatus::isSimple const): >+ (JSC::InByIdStatus::numVariants const): >+ (JSC::InByIdStatus::variants const): >+ (JSC::InByIdStatus::at const): >+ (JSC::InByIdStatus::operator[] const): >+ (JSC::InByIdStatus::takesSlowPath const): >+ * bytecode/InByIdVariant.cpp: Added. >+ (JSC::InByIdVariant::InByIdVariant): >+ (JSC::InByIdVariant::attemptToMerge): >+ (JSC::InByIdVariant::dump const): >+ (JSC::InByIdVariant::dumpInContext const): >+ * bytecode/InByIdVariant.h: Added. >+ (JSC::InByIdVariant::isSet const): >+ (JSC::InByIdVariant::operator bool const): >+ (JSC::InByIdVariant::structureSet const): >+ (JSC::InByIdVariant::structureSet): >+ (JSC::InByIdVariant::conditionSet const): >+ (JSC::InByIdVariant::offset const): >+ (JSC::InByIdVariant::isHit const): >+ * bytecode/PolyProtoAccessChain.h: >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ > 2018-05-18 Filip Pizlo <fpizlo@apple.com> > > DFG should inline InstanceOf ICs >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 2802ef64189360bb704cd358889e0dfcb5476831..4ba86e9ab299941ff519cbd7c9b19ba853765364 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1698,6 +1698,8 @@ > E328DAE91D38D005001A2529 /* BytecodeGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D264281D38C042000BE174 /* BytecodeGraph.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D2642A1D38C042000BE174 /* BytecodeRewriter.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E380A76B1DCD7195000F89E6 /* MacroAssemblerHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ E3305FB320B0F78800CEB82B /* InByIdStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = E3305FAF20B0F78700CEB82B /* InByIdStatus.h */; }; >+ E3305FB520B0F78800CEB82B /* InByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = E3305FB120B0F78800CEB82B /* InByIdVariant.h */; }; > E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */; }; > E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -4554,6 +4556,10 @@ > E326C4961ECBEF5700A9A905 /* ClassInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassInfo.cpp; sourceTree = "<group>"; }; > E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; }; > E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; }; >+ E3305FAF20B0F78700CEB82B /* InByIdStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdStatus.h; sourceTree = "<group>"; }; >+ E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; }; >+ E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; }; >+ E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdStatus.cpp; sourceTree = "<group>"; }; > E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; }; > E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; }; > E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; }; >@@ -5867,9 +5873,9 @@ > 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */, > 1482B6EA0A4300B300517CFC /* JSValueRef.h */, > 86E3C60F167BAB87006D760A /* JSVirtualMachine.h */, >- 795AC61720A2354B0052C76C /* JSVirtualMachinePrivate.h */, > 86E3C610167BAB87006D760A /* JSVirtualMachine.mm */, > 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */, >+ 795AC61720A2354B0052C76C /* JSVirtualMachinePrivate.h */, > A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */, > A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */, > A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */, >@@ -6677,6 +6683,7 @@ > 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */, > FE2B0B681FD0D2970075DA5F /* JSCPoison.cpp */, > FE2B0B701FD8C4630075DA5F /* JSCPoison.h */, >+ FE7497E5209001B00003565B /* JSCPtrTag.h */, > 72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */, > 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */, > 0F2B66BD17B6B5AB00A7AE3F /* JSDataView.cpp */, >@@ -6762,7 +6769,6 @@ > 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */, > 862553CE16136AA5009F17D0 /* JSProxy.cpp */, > 862553CF16136AA5009F17D0 /* JSProxy.h */, >- FE7497E5209001B00003565B /* JSCPtrTag.h */, > 534638721E70D01500F12AC1 /* JSRunLoopTimer.cpp */, > 534638701E70CF3D00F12AC1 /* JSRunLoopTimer.h */, > 14874AE115EBDE4A002E3587 /* JSScope.cpp */, >@@ -7633,6 +7639,10 @@ > 14AD91081DCA92940014F9FE /* GlobalCodeBlock.h */, > 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */, > 0FB399BD20AF6B380017E213 /* ICStatusUtils.h */, >+ E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */, >+ E3305FAF20B0F78700CEB82B /* InByIdStatus.h */, >+ E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */, >+ E3305FB120B0F78800CEB82B /* InByIdVariant.h */, > 7905BB661D12050E0019FE57 /* InlineAccess.cpp */, > 7905BB671D12050E0019FE57 /* InlineAccess.h */, > 148A7BED1B82975A002D9157 /* InlineCallFrame.cpp */, >@@ -8623,7 +8633,6 @@ > 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */, > 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */, > 0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */, >- 795AC61820A2355E0052C76C /* JSVirtualMachinePrivate.h in Headers */, > 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */, > 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */, > 0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */, >@@ -8867,9 +8876,12 @@ > FE1BD0251E72053800134BC9 /* HeapVerifier.h in Headers */, > 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */, > DC2143071CA32E55000A8869 /* ICStats.h in Headers */, >+ 0FB399BE20AF6B3D0017E213 /* ICStatusUtils.h in Headers */, > BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */, > 8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */, > A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */, >+ E3305FB320B0F78800CEB82B /* InByIdStatus.h in Headers */, >+ E3305FB520B0F78800CEB82B /* InByIdVariant.h in Headers */, > C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */, > 0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */, > 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */, >@@ -8913,6 +8925,9 @@ > A55D93AC18514F7900400DED /* InspectorProtocolTypes.h in Headers */, > A50E4B6218809DD50068A46D /* InspectorRuntimeAgent.h in Headers */, > A55165D31BDF0B9E003B75C1 /* InspectorScriptProfilerAgent.h in Headers */, >+ 0F49E9AA20AB4D00001CA0AA /* InstanceOfAccessCase.h in Headers */, >+ 0FB399BF20AF6B3F0017E213 /* InstanceOfStatus.h in Headers */, >+ 0FB399C020AF6B430017E213 /* InstanceOfVariant.h in Headers */, > 969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */, > A7A8AF3B17ADB5F3005AB174 /* Int16Array.h in Headers */, > A7A8AF3C17ADB5F3005AB174 /* Int32Array.h in Headers */, >@@ -8961,6 +8976,7 @@ > FE3A06A61C10B72D00390FDD /* JITBitOrGenerator.h in Headers */, > FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */, > 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */, >+ 0FFB80BC20A794730006AAF6 /* JITCodeInlines.h in Headers */, > FE476FF4207E85D50093CA2D /* JITCodeMap.h in Headers */, > 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */, > 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */, >@@ -9018,6 +9034,7 @@ > A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */, > 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */, > FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */, >+ FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */, > A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */, > 72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */, > 0F2B66EC17B6B5AB00A7AE3F /* JSDataView.h in Headers */, >@@ -9068,7 +9085,6 @@ > A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */, > 7013CA8C1B491A9400CAE613 /* JSJob.h in Headers */, > BC18C4160E16F5CD00B34460 /* JSLexicalEnvironment.h in Headers */, >- 0FB399C020AF6B430017E213 /* InstanceOfVariant.h in Headers */, > BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */, > C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */, > 2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */, >@@ -9094,7 +9110,6 @@ > 7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */, > 7C184E1F17BEE22E007CB63A /* JSPromisePrototype.h in Headers */, > 996B731F1BDA08EF00331B84 /* JSPromisePrototype.lut.h in Headers */, >- FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */, > 2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */, > 862553D216136E1A009F17D0 /* JSProxy.h in Headers */, > A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */, >@@ -9137,6 +9152,7 @@ > BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */, > 86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */, > 86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */, >+ 795AC61820A2355E0052C76C /* JSVirtualMachinePrivate.h in Headers */, > A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */, > A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */, > A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */, >@@ -9193,7 +9209,6 @@ > 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */, > 981ED82328234D91BAECCADE /* MachineContext.h in Headers */, > 14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */, >- 0FB399BF20AF6B3F0017E213 /* InstanceOfStatus.h in Headers */, > 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */, > 86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */, > A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */, >@@ -9228,7 +9243,6 @@ > 7C008CE7187631B600955C24 /* Microtask.h in Headers */, > FE2A87601F02381600EB31B2 /* MinimumReservedZoneSize.h in Headers */, > 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */, >- 0F49E9AA20AB4D00001CA0AA /* InstanceOfAccessCase.h in Headers */, > C4703CD7192844CC0013FBEA /* models.py in Headers */, > E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */, > 9F63434577274FAFB9336C38 /* ModuleNamespaceAccessCase.h in Headers */, >@@ -9273,7 +9287,6 @@ > E34E657520668EAA00FB81AC /* ParseHash.h in Headers */, > 37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */, > BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */, >- 0FFB80BC20A794730006AAF6 /* JITCodeInlines.h in Headers */, > 93052C350FB792190048FDC3 /* ParserArena.h in Headers */, > 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */, > A77F1825164192C700640A47 /* ParserModes.h in Headers */, >@@ -9452,7 +9465,6 @@ > 705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */, > 996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */, > 705B41B01A6E501E00716757 /* SymbolObject.h in Headers */, >- 0FB399BE20AF6B3D0017E213 /* ICStatusUtils.h in Headers */, > 705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */, > 996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */, > BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */, >diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt >index 6ad1a45d7f597f6162da91a4e0d9493a3821a3f2..880691b2df3b2ff7b2bebd7569587dcb426ce7ba 100644 >--- a/Source/JavaScriptCore/Sources.txt >+++ b/Source/JavaScriptCore/Sources.txt >@@ -219,6 +219,8 @@ bytecode/FunctionCodeBlock.cpp > bytecode/GetByIdStatus.cpp > bytecode/GetByIdVariant.cpp > bytecode/GetterSetterAccessCase.cpp >+bytecode/InByIdStatus.cpp >+bytecode/InByIdVariant.cpp > bytecode/InlineAccess.cpp > bytecode/InlineCallFrame.cpp > bytecode/InlineCallFrameSet.cpp >diff --git a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp b/Source/JavaScriptCore/bytecode/InByIdStatus.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..8b310fb99b416bd41ff6d2bef7d63eab8193793d >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/InByIdStatus.cpp >@@ -0,0 +1,237 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "InByIdStatus.h" >+ >+#include "CodeBlock.h" >+#include "ComplexGetStatus.h" >+#include "ICStatusUtils.h" >+#include "JSCInlines.h" >+#include "PolymorphicAccess.h" >+#include "StructureStubInfo.h" >+#include <wtf/ListDump.h> >+ >+namespace JSC { >+ >+bool InByIdStatus::appendVariant(const InByIdVariant& variant) >+{ >+ return appendICStatusVariant(m_variants, variant); >+} >+ >+InByIdStatus InByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, UniquedStringImpl* uid) >+{ >+ ConcurrentJSLocker locker(profiledBlock->m_lock); >+ >+ InByIdStatus result; >+ >+#if ENABLE(DFG_JIT) >+ result = computeForStubInfoWithoutExitSiteFeedback(locker, map.get(CodeOrigin(bytecodeIndex)), uid); >+ >+ if (!result.takesSlowPath() && hasExitSite(profiledBlock, bytecodeIndex)) >+ return InByIdStatus(TakesSlowPath); >+#else >+ UNUSED_PARAM(map); >+#endif >+ >+ return result; >+} >+ >+InByIdStatus InByIdStatus::computeFor( >+ CodeBlock* profiledBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, >+ StubInfoMap& dfgMap, CodeOrigin codeOrigin, UniquedStringImpl* uid) >+{ >+#if ENABLE(DFG_JIT) >+ if (dfgBlock) { >+ CallLinkStatus::ExitSiteData exitSiteData; >+ { >+ ConcurrentJSLocker locker(profiledBlock->m_lock); >+ exitSiteData = CallLinkStatus::computeExitSiteData( >+ profiledBlock, codeOrigin.bytecodeIndex); >+ } >+ >+ InByIdStatus result; >+ { >+ ConcurrentJSLocker locker(dfgBlock->m_lock); >+ result = computeForStubInfoWithoutExitSiteFeedback(locker, dfgMap.get(codeOrigin), uid); >+ } >+ >+ if (result.takesSlowPath()) >+ return result; >+ >+ if (hasExitSite(profiledBlock, codeOrigin.bytecodeIndex)) >+ return InByIdStatus(TakesSlowPath); >+ >+ if (result.isSet()) >+ return result; >+ } >+#else >+ UNUSED_PARAM(dfgBlock); >+ UNUSED_PARAM(dfgMap); >+#endif >+ >+ return computeFor(profiledBlock, baselineMap, codeOrigin.bytecodeIndex, uid); >+} >+ >+#if ENABLE(DFG_JIT) >+bool InByIdStatus::hasExitSite(CodeBlock* profiledBlock, unsigned bytecodeIndex) >+{ >+ UnlinkedCodeBlock* unlinkedCodeBlock = profiledBlock->unlinkedCodeBlock(); >+ ConcurrentJSLocker locker(unlinkedCodeBlock->m_lock); >+ return unlinkedCodeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache)) >+ || unlinkedCodeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache)); >+} >+ >+InByIdStatus InByIdStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin, UniquedStringImpl* uid) >+{ >+ InByIdStatus result = InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(locker, stubInfo, uid); >+ >+ if (!result.takesSlowPath() && InByIdStatus::hasExitSite(profiledBlock, codeOrigin.bytecodeIndex)) >+ return InByIdStatus(TakesSlowPath); >+ return result; >+} >+ >+InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, StructureStubInfo* stubInfo, UniquedStringImpl* uid) >+{ >+ if (!stubInfo || !stubInfo->everConsidered) >+ return InByIdStatus(NoInformation); >+ >+ if (stubInfo->tookSlowPath) >+ return InByIdStatus(TakesSlowPath); >+ >+ // Finally figure out if we can derive an access strategy. >+ InByIdStatus result; >+ result.m_state = Simple; >+ switch (stubInfo->cacheType) { >+ case CacheType::Unset: >+ return InByIdStatus(NoInformation); >+ >+ case CacheType::InByIdSelf: { >+ Structure* structure = stubInfo->u.byIdSelf.baseObjectStructure.get(); >+ if (structure->takesSlowPathInDFGForImpureProperty()) >+ return InByIdStatus(TakesSlowPath); >+ unsigned attributes; >+ InByIdVariant variant; >+ variant.m_offset = structure->getConcurrently(uid, attributes); >+ if (!isValidOffset(variant.m_offset)) >+ return InByIdStatus(TakesSlowPath); >+ if (attributes & PropertyAttribute::CustomAccessor) >+ return InByIdStatus(TakesSlowPath); >+ >+ variant.m_structureSet.add(structure); >+ bool didAppend = result.appendVariant(variant); >+ ASSERT_UNUSED(didAppend, didAppend); >+ return result; >+ } >+ >+ case CacheType::Stub: { >+ PolymorphicAccess* list = stubInfo->u.stub; >+ for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { >+ const AccessCase& access = list->at(listIndex); >+ if (access.viaProxy()) >+ return InByIdStatus(TakesSlowPath); >+ >+ if (access.usesPolyProto()) >+ return InByIdStatus(TakesSlowPath); >+ >+ Structure* structure = access.structure(); >+ if (!structure) { >+ // The null structure cases arise due to array.length. We have no way of creating a >+ // InByIdVariant for those, and we don't really have to since the DFG handles those >+ // cases in FixupPhase using value profiling. That's a bit awkward - we shouldn't >+ // have to use value profiling to discover something that the AccessCase could have >+ // told us. But, it works well enough. So, our only concern here is to not >+ // crash on null structure. >+ return InByIdStatus(TakesSlowPath); >+ } >+ >+ ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), uid); >+ switch (complexGetStatus.kind()) { >+ case ComplexGetStatus::ShouldSkip: >+ continue; >+ >+ case ComplexGetStatus::TakesSlowPath: >+ return InByIdStatus(TakesSlowPath); >+ >+ case ComplexGetStatus::Inlineable: { >+ switch (access.type()) { >+ case AccessCase::InHit: >+ case AccessCase::InMiss: >+ break; >+ default: >+ return InByIdStatus(TakesSlowPath); >+ } >+ >+ InByIdVariant variant( >+ StructureSet(structure), complexGetStatus.offset(), >+ complexGetStatus.conditionSet()); >+ >+ if (!result.appendVariant(variant)) >+ return InByIdStatus(TakesSlowPath); >+ break; >+ } >+ } >+ } >+ >+ return result; >+ } >+ >+ default: >+ return InByIdStatus(TakesSlowPath); >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+ return InByIdStatus(); >+} >+#endif >+ >+void InByIdStatus::filter(const StructureSet& structureSet) >+{ >+ if (m_state != Simple) >+ return; >+ filterICStatusVariants(m_variants, structureSet); >+ if (m_variants.isEmpty()) >+ m_state = NoInformation; >+} >+ >+void InByIdStatus::dump(PrintStream& out) const >+{ >+ out.print("("); >+ switch (m_state) { >+ case NoInformation: >+ out.print("NoInformation"); >+ break; >+ case Simple: >+ out.print("Simple"); >+ break; >+ case TakesSlowPath: >+ out.print("TakesSlowPath"); >+ break; >+ } >+ out.print(", ", listDump(m_variants), ")"); >+} >+ >+} // namespace JSC >+ >diff --git a/Source/JavaScriptCore/bytecode/InByIdStatus.h b/Source/JavaScriptCore/bytecode/InByIdStatus.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6615dfcdf8f4cb1607eb414508d051f5d7ef8018 >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/InByIdStatus.h >@@ -0,0 +1,98 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CallLinkStatus.h" >+#include "CodeOrigin.h" >+#include "ConcurrentJSLock.h" >+#include "InByIdVariant.h" >+ >+namespace JSC { >+ >+class AccessCase; >+class CodeBlock; >+class StructureStubInfo; >+ >+typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap; >+ >+class InByIdStatus { >+public: >+ enum State { >+ // It's uncached so we have no information. >+ NoInformation, >+ // It's cached for a simple access to a known object property with >+ // a possible structure chain and a possible specific value. >+ Simple, >+ // It's known to often take slow path. >+ TakesSlowPath, >+ }; >+ >+ InByIdStatus() = default; >+ >+ InByIdStatus(State state, const InByIdVariant& variant = InByIdVariant()) >+ : m_state(state) >+ { >+ ASSERT((state == Simple) == variant.isSet()); >+ m_variants.append(variant); >+ } >+ >+ static InByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, UniquedStringImpl* uid); >+ static InByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, UniquedStringImpl* uid); >+ >+#if ENABLE(DFG_JIT) >+ static InByIdStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock* baselineBlock, StructureStubInfo*, CodeOrigin, UniquedStringImpl* uid); >+#endif >+ >+ State state() const { return m_state; } >+ >+ bool isSet() const { return m_state != NoInformation; } >+ explicit operator bool() const { return isSet(); } >+ bool isSimple() const { return m_state == Simple; } >+ >+ size_t numVariants() const { return m_variants.size(); } >+ const Vector<InByIdVariant, 1>& variants() const { return m_variants; } >+ const InByIdVariant& at(size_t index) const { return m_variants[index]; } >+ const InByIdVariant& operator[](size_t index) const { return at(index); } >+ >+ bool takesSlowPath() const { return m_state == TakesSlowPath; } >+ >+ // Attempts to reduce the set of variants to fit the given structure set. This may be approximate. >+ void filter(const StructureSet&); >+ >+ void dump(PrintStream&) const; >+ >+private: >+#if ENABLE(DFG_JIT) >+ static bool hasExitSite(CodeBlock*, unsigned bytecodeIndex); >+ static InByIdStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, StructureStubInfo*, UniquedStringImpl* uid); >+#endif >+ bool appendVariant(const InByIdVariant&); >+ >+ State m_state { NoInformation }; >+ Vector<InByIdVariant, 1> m_variants; >+}; >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/InByIdVariant.cpp b/Source/JavaScriptCore/bytecode/InByIdVariant.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..626a5d3332990244ab7b81dcbf5ee59b561500bc >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/InByIdVariant.cpp >@@ -0,0 +1,85 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "InByIdVariant.h" >+ >+#include "JSCInlines.h" >+#include <wtf/ListDump.h> >+ >+namespace JSC { >+ >+InByIdVariant::InByIdVariant(const StructureSet& structureSet, PropertyOffset offset, const ObjectPropertyConditionSet& conditionSet) >+ : m_structureSet(structureSet) >+ , m_conditionSet(conditionSet) >+ , m_offset(offset) >+{ >+ if (!structureSet.size()) { >+ ASSERT(offset == invalidOffset); >+ ASSERT(conditionSet.isEmpty()); >+ } >+} >+ >+bool InByIdVariant::attemptToMerge(const InByIdVariant& other) >+{ >+ if (m_offset != other.m_offset) >+ return false; >+ >+ if (m_conditionSet.isEmpty() != other.m_conditionSet.isEmpty()) >+ return false; >+ >+ ObjectPropertyConditionSet mergedConditionSet; >+ if (!m_conditionSet.isEmpty()) { >+ mergedConditionSet = m_conditionSet.mergedWith(other.m_conditionSet); >+ if (!mergedConditionSet.isValid() || !mergedConditionSet.hasOneSlotBaseCondition()) >+ return false; >+ } >+ m_conditionSet = mergedConditionSet; >+ >+ m_structureSet.merge(other.m_structureSet); >+ >+ return true; >+} >+ >+void InByIdVariant::dump(PrintStream& out) const >+{ >+ dumpInContext(out, 0); >+} >+ >+void InByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const >+{ >+ if (!isSet()) { >+ out.print("<empty>"); >+ return; >+ } >+ >+ out.print( >+ "<", inContext(structureSet(), context), ", ", inContext(m_conditionSet, context)); >+ out.print(", offset = ", offset()); >+ out.print(">"); >+} >+ >+} // namespace JSC >+ >diff --git a/Source/JavaScriptCore/bytecode/InByIdVariant.h b/Source/JavaScriptCore/bytecode/InByIdVariant.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b7898a36878719c28b7fc916b73ac6f9e76f2c45 >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/InByIdVariant.h >@@ -0,0 +1,69 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ObjectPropertyConditionSet.h" >+#include "PropertyOffset.h" >+#include "StructureSet.h" >+ >+namespace JSC { >+namespace DOMJIT { >+class GetterSetter; >+} >+ >+class InByIdStatus; >+struct DumpContext; >+ >+class InByIdVariant { >+public: >+ InByIdVariant(const StructureSet& = StructureSet(), PropertyOffset = invalidOffset, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet()); >+ >+ bool isSet() const { return !!m_structureSet.size(); } >+ explicit operator bool() const { return isSet(); } >+ const StructureSet& structureSet() const { return m_structureSet; } >+ StructureSet& structureSet() { return m_structureSet; } >+ >+ // A non-empty condition set means that this is a prototype in-hit/in-miss. >+ const ObjectPropertyConditionSet& conditionSet() const { return m_conditionSet; } >+ >+ PropertyOffset offset() const { return m_offset; } >+ >+ bool isHit() const { return offset() != invalidOffset; } >+ >+ bool attemptToMerge(const InByIdVariant& other); >+ >+ void dump(PrintStream&) const; >+ void dumpInContext(PrintStream&, DumpContext*) const; >+ >+private: >+ friend class InByIdStatus; >+ >+ StructureSet m_structureSet; >+ ObjectPropertyConditionSet m_conditionSet; >+ PropertyOffset m_offset; >+}; >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >index 52ab76e85574fd6887fb68f6f45c3dc3029db934..b49e4e242e52f081315e48fb1e1bcc297e528ae0 100644 >--- a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >+++ b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >@@ -29,6 +29,7 @@ > > namespace JSC { > >+class JSCell; > class JSGlobalObject; > class JSObject; > class PropertySlot; >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index fa097f32c666ed3f33fdbc4bbe38c15442b4d6e1..0c7738b4680fa68019a086024ddf3294df6be9cd 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -48,6 +48,7 @@ > #include "FunctionCodeBlock.h" > #include "GetByIdStatus.h" > #include "Heap.h" >+#include "InByIdStatus.h" > #include "InstanceOfStatus.h" > #include "JSCInlines.h" > #include "JSFixedArray.h" >@@ -6402,10 +6403,33 @@ void ByteCodeParser::parseBlock(unsigned limit) > case op_in_by_id: { > Node* base = get(VirtualRegister(currentInstruction[2].u.operand)); > unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand]; >- set(VirtualRegister(currentInstruction[1].u.operand), >- addToGraph(InById, OpInfo(identifierNumber), base)); >+ UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber]; >+ >+ InByIdStatus status = InByIdStatus::computeFor( >+ m_inlineStackTop->m_profiledBlock, m_dfgCodeBlock, >+ m_inlineStackTop->m_stubInfos, m_dfgStubInfos, >+ currentCodeOrigin(), uid); >+ >+ if (status.isSimple()) { >+ MatchStructureData* data = m_graph.m_matchStructureData.add(); >+ for (const InByIdVariant& variant : status.variants()) { >+ check(variant.conditionSet()); >+ for (Structure* structure : variant.structureSet()) { >+ MatchStructureVariant matchVariant; >+ matchVariant.structure = m_graph.registerStructure(structure); >+ matchVariant.result = variant.isHit(); >+ >+ data->variants.append(matchVariant); >+ } >+ } >+ >+ Node* match = addToGraph(MatchStructure, OpInfo(data), base); >+ set(VirtualRegister(currentInstruction[1].u.operand), match); >+ NEXT_OPCODE(op_in_by_id); >+ } >+ >+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(InById, OpInfo(identifierNumber), base)); > NEXT_OPCODE(op_in_by_id); >- break; > } > > case op_get_enumerable_length: { >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 72f9954fad476b4d3cd7c2a0def5544fcfe4b577..94e8adbde8ede7e79b8a6ff7c302aa8bacd44921 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,5 +1,22 @@ > 2018-05-19 Yusuke Suzuki <utatane.tea@gmail.com> > >+ [DFG] InById should be converted to MatchStructure >+ https://bugs.webkit.org/show_bug.cgi?id=185803 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/in-by-id-constant.js: Added. >+ (shouldBe): >+ (test1): >+ * stress/in-by-id-match-invalid.js: Added. >+ (shouldBe): >+ (test1): >+ * stress/in-by-id-match.js: Added. >+ (shouldBe): >+ (test1): >+ >+2018-05-19 Yusuke Suzuki <utatane.tea@gmail.com> >+ > [JSC] JSC should have consistent InById IC > https://bugs.webkit.org/show_bug.cgi?id=185682 > >diff --git a/JSTests/stress/in-by-id-constant.js b/JSTests/stress/in-by-id-constant.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9319ea83c76d7884cb10a9887b9f6ce801afad43 >--- /dev/null >+++ b/JSTests/stress/in-by-id-constant.js >@@ -0,0 +1,33 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test1(obj) >+{ >+ return "hello" in obj >+} >+noInline(test1); >+ >+let array = [ >+ [{ >+ hello: 42 >+ }, true], >+ [{ >+ hello: 42, >+ world: 43 >+ }, true], >+ [{ >+ __proto__: { >+ hello: 44 >+ } >+ }, true] >+]; >+for (let i = 0; i < 1e5; ++i) { >+ for (let [obj, result] of array) >+ shouldBe(test1(obj), result); >+} >+ >+// OSRExits. >+for (let i = 0; i < 1e5; ++i) >+ shouldBe(test1({}), false); >diff --git a/JSTests/stress/in-by-id-match-invalid.js b/JSTests/stress/in-by-id-match-invalid.js >new file mode 100644 >index 0000000000000000000000000000000000000000..51755e212ea6f0eb9e0b4eac0b3bdf50f15a9cc2 >--- /dev/null >+++ b/JSTests/stress/in-by-id-match-invalid.js >@@ -0,0 +1,30 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test1(obj) >+{ >+ return "hello" in obj >+} >+noInline(test1); >+ >+let object1 = { >+ hello: 42 >+}; >+let object2 = { >+ cocoa: 44 >+}; >+for (let i = 0; i < 1e5; ++i) { >+ shouldBe(test1(object1), true); >+ shouldBe(test1(object2), false); >+} >+object2.hello = 44; >+for (let i = 0; i < 1e5; ++i) { >+ shouldBe(test1(object1), true); >+ shouldBe(test1(object2), true); >+} >+ >+// OSRExits. >+for (let i = 0; i < 1e5; ++i) >+ shouldBe(test1({}), false); >diff --git a/JSTests/stress/in-by-id-match.js b/JSTests/stress/in-by-id-match.js >new file mode 100644 >index 0000000000000000000000000000000000000000..62ccc31ccfe10abbaf8358a5e090da1014c31c3f >--- /dev/null >+++ b/JSTests/stress/in-by-id-match.js >@@ -0,0 +1,32 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test1(obj) >+{ >+ return "hello" in obj >+} >+noInline(test1); >+ >+let array = [ >+ [{ >+ hello: 42 >+ }, true], >+ [{ >+ world: 43 >+ }, false], >+ [{ >+ __proto__: { >+ hello: 44 >+ } >+ }, true] >+]; >+for (let i = 0; i < 1e5; ++i) { >+ for (let [obj, result] of array) >+ shouldBe(test1(obj), result); >+} >+ >+// OSRExits. >+for (let i = 0; i < 1e5; ++i) >+ shouldBe(test1({}), false);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185803
:
340787
|
340788
|
340789
|
340793
|
341571