WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 57.09 KB, created by
Filip Pizlo
on 2014-06-12 16:33:42 PDT
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2014-06-12 16:33:42 PDT
Size:
57.09 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 169920) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,80 @@ >+2014-06-12 Filip Pizlo <fpizlo@apple.com> >+ >+ [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants >+ https://bugs.webkit.org/show_bug.cgi?id=133821 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This allows us to efficiently cache accesses that differ only in the prototypes on the path >+ from the base to the prototype that has the field. >+ >+ It also simplifies a bunch of code - IntendedStructureChain is now just an intermediate >+ data structure. >+ >+ * CMakeLists.txt: >+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * bytecode/ConstantStructureCheck.cpp: Added. >+ (JSC::ConstantStructureCheck::dumpInContext): >+ (JSC::ConstantStructureCheck::dump): >+ (JSC::structureFor): >+ (JSC::areCompatible): >+ (JSC::mergeInto): >+ * bytecode/ConstantStructureCheck.h: Added. >+ (JSC::ConstantStructureCheck::ConstantStructureCheck): >+ (JSC::ConstantStructureCheck::operator!): >+ (JSC::ConstantStructureCheck::constant): >+ (JSC::ConstantStructureCheck::structure): >+ * bytecode/GetByIdStatus.cpp: >+ (JSC::GetByIdStatus::computeForStubInfo): >+ * bytecode/GetByIdVariant.cpp: >+ (JSC::GetByIdVariant::GetByIdVariant): >+ (JSC::GetByIdVariant::operator=): >+ (JSC::GetByIdVariant::attemptToMerge): >+ (JSC::GetByIdVariant::dumpInContext): >+ * bytecode/GetByIdVariant.h: >+ (JSC::GetByIdVariant::constantChecks): >+ (JSC::GetByIdVariant::alternateBase): >+ (JSC::GetByIdVariant::GetByIdVariant): Deleted. >+ (JSC::GetByIdVariant::chain): Deleted. >+ * bytecode/PutByIdVariant.cpp: >+ (JSC::PutByIdVariant::dumpInContext): >+ * bytecode/PutByIdVariant.h: >+ (JSC::PutByIdVariant::transition): >+ (JSC::PutByIdVariant::constantChecks): >+ (JSC::PutByIdVariant::structureChain): Deleted. >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::emitChecks): >+ (JSC::DFG::ByteCodeParser::handleGetById): >+ (JSC::DFG::ByteCodeParser::handlePutById): >+ (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck): Deleted. >+ (JSC::DFG::ByteCodeParser::structureChainIsStillValid): Deleted. >+ (JSC::DFG::ByteCodeParser::emitPrototypeChecks): Deleted. >+ * dfg/DFGConstantFoldingPhase.cpp: >+ (JSC::DFG::ConstantFoldingPhase::foldConstants): >+ (JSC::DFG::ConstantFoldingPhase::emitGetByOffset): >+ (JSC::DFG::ConstantFoldingPhase::emitPutByOffset): >+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck): >+ * dfg/DFGDesiredStructureChains.cpp: Removed. >+ * dfg/DFGDesiredStructureChains.h: Removed. >+ * dfg/DFGGraph.h: >+ (JSC::DFG::Graph::watchpoints): >+ (JSC::DFG::Graph::chains): Deleted. >+ * dfg/DFGPlan.cpp: >+ (JSC::DFG::Plan::isStillValid): >+ (JSC::DFG::Plan::checkLivenessAndVisitChildren): >+ (JSC::DFG::Plan::cancel): >+ * dfg/DFGPlan.h: >+ * ftl/FTLLowerDFGToLLVM.cpp: >+ (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset): >+ * runtime/IntendedStructureChain.cpp: >+ (JSC::IntendedStructureChain::gatherChecks): >+ * runtime/IntendedStructureChain.h: >+ (JSC::IntendedStructureChain::at): >+ (JSC::IntendedStructureChain::operator[]): >+ > 2014-06-11 Filip Pizlo <fpizlo@apple.com> > > [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 169901) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -67,6 +67,7 @@ set(JavaScriptCore_SOURCES > bytecode/CodeBlockJettisoningWatchpoint.cpp > bytecode/CodeOrigin.cpp > bytecode/CodeType.cpp >+ bytecode/ConstantStructureCheck.cpp > bytecode/DFGExitProfile.cpp > bytecode/DeferredCompilationCallback.cpp > bytecode/ExecutionCounter.cpp >@@ -131,7 +132,6 @@ set(JavaScriptCore_SOURCES > dfg/DFGCriticalEdgeBreakingPhase.cpp > dfg/DFGDCEPhase.cpp > dfg/DFGDesiredIdentifiers.cpp >- dfg/DFGDesiredStructureChains.cpp > dfg/DFGDesiredTransitions.cpp > dfg/DFGDesiredWatchpoints.cpp > dfg/DFGDesiredWeakReferences.cpp >Index: Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (revision 169901) >+++ Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (working copy) >@@ -321,6 +321,7 @@ > <ClCompile Include="..\bytecode\CodeBlockJettisoningWatchpoint.cpp" /> > <ClCompile Include="..\bytecode\CodeOrigin.cpp" /> > <ClCompile Include="..\bytecode\CodeType.cpp" /> >+ <ClCompile Include="..\bytecode\ConstantStructureCheck.cpp" /> > <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" /> > <ClCompile Include="..\bytecode\DFGExitProfile.cpp" /> > <ClCompile Include="..\bytecode\ExecutionCounter.cpp" /> >@@ -382,7 +383,6 @@ > <ClCompile Include="..\dfg\DFGCSEPhase.cpp" /> > <ClCompile Include="..\dfg\DFGDCEPhase.cpp" /> > <ClCompile Include="..\dfg\DFGDesiredIdentifiers.cpp" /> >- <ClCompile Include="..\dfg\DFGDesiredStructureChains.cpp" /> > <ClCompile Include="..\dfg\DFGDesiredTransitions.cpp" /> > <ClCompile Include="..\dfg\DFGDesiredWatchpoints.cpp" /> > <ClCompile Include="..\dfg\DFGDesiredWeakReferences.cpp" /> >@@ -856,6 +856,7 @@ > <ClInclude Include="..\bytecode\CodeOrigin.h" /> > <ClInclude Include="..\bytecode\CodeType.h" /> > <ClInclude Include="..\bytecode\Comment.h" /> >+ <ClInclude Include="..\bytecode\ConstantStructureCheck.h" /> > <ClInclude Include="..\bytecode\DataFormat.h" /> > <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" /> > <ClInclude Include="..\bytecode\DFGExitProfile.h" /> >@@ -943,7 +944,6 @@ > <ClInclude Include="..\dfg\DFGCSEPhase.h" /> > <ClInclude Include="..\dfg\DFGDCEPhase.h" /> > <ClInclude Include="..\dfg\DFGDesiredIdentifiers.h" /> >- <ClInclude Include="..\dfg\DFGDesiredStructureChains.h" /> > <ClInclude Include="..\dfg\DFGDesiredTransitions.h" /> > <ClInclude Include="..\dfg\DFGDesiredWatchpoints.h" /> > <ClInclude Include="..\dfg\DFGDesiredWeakReferences.h" /> >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 169901) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -251,6 +251,8 @@ > 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */; }; > 0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; }; >+ 0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1723,8 +1725,6 @@ > A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; }; > A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */; }; > A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */; }; >- A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; settings = {ATTRIBUTES = (Private, ); }; }; > A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; > A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; }; >@@ -2415,6 +2415,8 @@ > 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFGSimplificationPhase.h; path = dfg/DFGCFGSimplificationPhase.h; sourceTree = "<group>"; }; > 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValidate.cpp; path = dfg/DFGValidate.cpp; sourceTree = "<group>"; }; > 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValidate.h; path = dfg/DFGValidate.h; sourceTree = "<group>"; }; >+ 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = "<group>"; }; >+ 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = "<group>"; }; > 0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; }; > 0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; }; > 0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; }; >@@ -3366,8 +3368,6 @@ > A7386553118697B400540279 /* ThunkGenerators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerators.h; sourceTree = "<group>"; }; > A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyJSValue.cpp; path = dfg/DFGLazyJSValue.cpp; sourceTree = "<group>"; }; > A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; }; >- A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredStructureChains.cpp; path = dfg/DFGDesiredStructureChains.cpp; sourceTree = "<group>"; }; >- A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredStructureChains.h; path = dfg/DFGDesiredStructureChains.h; sourceTree = "<group>"; }; > A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSaneStringGetByValSlowPathGenerator.h; path = dfg/DFGSaneStringGetByValSlowPathGenerator.h; sourceTree = "<group>"; }; > A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefPrivate.h; sourceTree = "<group>"; }; > A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; }; >@@ -5038,8 +5038,6 @@ > 0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */, > 0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */, > 0F8F2B98172F04FD007DBDA5 /* DFGDesiredIdentifiers.h */, >- A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */, >- A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */, > C2C0F7CB17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp */, > C2C0F7CC17BBFC5B00464FE4 /* DFGDesiredTransitions.h */, > 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */, >@@ -5352,6 +5350,8 @@ > 0FBD7E671447998F00481315 /* CodeOrigin.h */, > 0F8F943F1667632D00D61971 /* CodeType.cpp */, > 0F0B83A514BCF50400885B4F /* CodeType.h */, >+ 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */, >+ 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */, > 0F426A4A1460CD6B00131F8F /* DataFormat.h */, > 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */, > 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */, >@@ -6032,7 +6032,6 @@ > 0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */, > 0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */, > 0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */, >- A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */, > C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */, > 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */, > C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */, >@@ -6483,6 +6482,7 @@ > BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */, > 90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */, > 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */, >+ 0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */, > 7C008CE7187631B600955C24 /* Microtask.h in Headers */, > 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */, > 86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */, >@@ -7618,7 +7618,6 @@ > 0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */, > 0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */, > 0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */, >- A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */, > C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */, > 0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */, > C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */, >@@ -7856,6 +7855,7 @@ > A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */, > A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */, > 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */, >+ 0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */, > C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */, > A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */, > A74DEF95182D991400522C22 /* JSMapIterator.cpp in Sources */, >Index: Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp (working copy) >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2014 Apple Inc. All rights reserved. >+ * >+ * 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 "ConstantStructureCheck.h" >+ >+namespace JSC { >+ >+void ConstantStructureCheck::dumpInContext(PrintStream& out, DumpContext* context) const >+{ >+ out.print( >+ "(Check if ", inContext(JSValue(m_constant), context), " has structure ", >+ pointerDumpInContext(m_structure, context), ")"); >+} >+ >+void ConstantStructureCheck::dump(PrintStream& out) const >+{ >+ dumpInContext(out, nullptr); >+} >+ >+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant) >+{ >+ for (unsigned i = vector.size(); i--;) { >+ if (vector[i].constant() == constant) >+ return vector[i].structure(); >+ } >+ return nullptr; >+} >+ >+bool areCompatible(const ConstantStructureCheckVector& a, const ConstantStructureCheckVector& b) >+{ >+ for (unsigned i = a.size(); i--;) { >+ Structure* otherStructure = structureFor(b, a[i].constant()); >+ if (!otherStructure) >+ continue; >+ if (a[i].structure() != otherStructure) >+ return false; >+ } >+ return true; >+} >+ >+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target) >+{ >+ for (unsigned i = source.size(); i--;) { >+ if (structureFor(target, source[i].constant())) >+ continue; >+ target.append(source[i]); >+ } >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/ConstantStructureCheck.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ConstantStructureCheck.h (revision 0) >+++ Source/JavaScriptCore/bytecode/ConstantStructureCheck.h (working copy) >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2014 Apple Inc. All rights reserved. >+ * >+ * 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. >+ */ >+ >+#ifndef ConstantStructureCheck_h >+#define ConstantStructureCheck_h >+ >+#include "DumpContext.h" >+#include "JSCell.h" >+#include "Structure.h" >+#include <wtf/PrintStream.h> >+#include <wtf/Vector.h> >+ >+namespace JSC { >+ >+class ConstantStructureCheck { >+public: >+ ConstantStructureCheck() >+ : m_constant(nullptr) >+ , m_structure(nullptr) >+ { >+ } >+ >+ ConstantStructureCheck(JSCell* constant, Structure* structure) >+ : m_constant(constant) >+ , m_structure(structure) >+ { >+ ASSERT(!!m_constant == !!m_structure); >+ } >+ >+ bool operator!() const { return !m_constant; } >+ >+ JSCell* constant() const { return m_constant; } >+ Structure* structure() const { return m_structure; } >+ >+ void dumpInContext(PrintStream&, DumpContext*) const; >+ void dump(PrintStream&) const; >+ >+private: >+ JSCell* m_constant; >+ Structure* m_structure; >+}; >+ >+typedef Vector<ConstantStructureCheck, 2> ConstantStructureCheckVector; >+ >+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant); >+bool areCompatible(const ConstantStructureCheckVector&, const ConstantStructureCheckVector&); >+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target); >+ >+} // namespace JSC >+ >+#endif // ConstantStructureCheck_h >+ >Index: Source/JavaScriptCore/bytecode/GetByIdStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (revision 169902) >+++ Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (working copy) >@@ -253,7 +253,7 @@ GetByIdStatus GetByIdStatus::computeForS > } > > GetByIdVariant variant( >- StructureSet(structure), myOffset, specificValue, chain, >+ StructureSet(structure), myOffset, specificValue, chain.get(), > std::move(callLinkStatus)); > > if (!result.appendVariant(variant)) >Index: Source/JavaScriptCore/bytecode/GetByIdVariant.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdVariant.cpp (revision 169902) >+++ Source/JavaScriptCore/bytecode/GetByIdVariant.cpp (working copy) >@@ -28,9 +28,31 @@ > > #include "CallLinkStatus.h" > #include "JSCInlines.h" >+#include <wtf/ListDump.h> > > namespace JSC { > >+GetByIdVariant::GetByIdVariant( >+ const StructureSet& structureSet, PropertyOffset offset, JSValue specificValue, >+ const IntendedStructureChain* chain, std::unique_ptr<CallLinkStatus> callLinkStatus) >+ : m_structureSet(structureSet) >+ , m_alternateBase(nullptr) >+ , m_specificValue(specificValue) >+ , m_offset(offset) >+ , m_callLinkStatus(std::move(callLinkStatus)) >+{ >+ if (!structureSet.size()) { >+ ASSERT(offset == invalidOffset); >+ ASSERT(!specificValue); >+ ASSERT(!chain); >+ } >+ >+ if (chain && chain->size()) { >+ m_alternateBase = chain->terminalPrototype(); >+ chain->gatherChecks(m_constantChecks); >+ } >+} >+ > GetByIdVariant::~GetByIdVariant() { } > > GetByIdVariant::GetByIdVariant(const GetByIdVariant& other) >@@ -41,7 +63,8 @@ GetByIdVariant::GetByIdVariant(const Get > GetByIdVariant& GetByIdVariant::operator=(const GetByIdVariant& other) > { > m_structureSet = other.m_structureSet; >- m_chain = other.m_chain; >+ m_constantChecks = other.m_constantChecks; >+ m_alternateBase = other.m_alternateBase; > m_specificValue = other.m_specificValue; > m_offset = other.m_offset; > if (other.m_callLinkStatus) >@@ -53,18 +76,19 @@ GetByIdVariant& GetByIdVariant::operator > > bool GetByIdVariant::attemptToMerge(const GetByIdVariant& other) > { >- if (!!m_chain != !!other.m_chain) >- return false; >- if (m_chain && *m_chain != *other.m_chain) >+ if (m_alternateBase != other.m_alternateBase) > return false; > if (m_offset != other.m_offset) > return false; > if (m_callLinkStatus || other.m_callLinkStatus) > return false; >+ if (!areCompatible(m_constantChecks, other.m_constantChecks)) >+ return false; > > if (m_specificValue != other.m_specificValue) > m_specificValue = JSValue(); > >+ mergeInto(other.m_constantChecks, m_constantChecks); > m_structureSet.merge(other.m_structureSet); > > return true; >@@ -84,10 +108,12 @@ void GetByIdVariant::dumpInContext(Print > > out.print( > "<", inContext(structureSet(), context), ", ", >- pointerDumpInContext(chain(), context), ", ", >- inContext(specificValue(), context), ", ", offset()); >+ "[", listDumpInContext(m_constantChecks, context), "], ", >+ "alternateBase = ", inContext(JSValue(m_alternateBase), context), ", ", >+ "specificValue = ", inContext(specificValue(), context), ", ", >+ "offset = ", offset()); > if (m_callLinkStatus) >- out.print("call: ", *m_callLinkStatus); >+ out.print("call = ", *m_callLinkStatus); > out.print(">"); > } > >Index: Source/JavaScriptCore/bytecode/GetByIdVariant.h >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdVariant.h (revision 169902) >+++ Source/JavaScriptCore/bytecode/GetByIdVariant.h (working copy) >@@ -27,6 +27,7 @@ > #define GetByIdVariant_h > > #include "CallLinkStatus.h" >+#include "ConstantStructureCheck.h" > #include "IntendedStructureChain.h" > #include "JSCJSValue.h" > #include "PropertyOffset.h" >@@ -43,20 +44,8 @@ public: > GetByIdVariant( > const StructureSet& structureSet = StructureSet(), > PropertyOffset offset = invalidOffset, JSValue specificValue = JSValue(), >- PassRefPtr<IntendedStructureChain> chain = nullptr, >- std::unique_ptr<CallLinkStatus> callLinkStatus = nullptr) >- : m_structureSet(structureSet) >- , m_chain(chain) >- , m_specificValue(specificValue) >- , m_offset(offset) >- , m_callLinkStatus(std::move(callLinkStatus)) >- { >- if (!structureSet.size()) { >- ASSERT(offset == invalidOffset); >- ASSERT(!specificValue); >- ASSERT(!chain); >- } >- } >+ const IntendedStructureChain* chain = nullptr, >+ std::unique_ptr<CallLinkStatus> callLinkStatus = nullptr); > > ~GetByIdVariant(); > >@@ -66,7 +55,8 @@ public: > bool isSet() const { return !!m_structureSet.size(); } > bool operator!() const { return !isSet(); } > const StructureSet& structureSet() const { return m_structureSet; } >- IntendedStructureChain* chain() const { return const_cast<IntendedStructureChain*>(m_chain.get()); } >+ const ConstantStructureCheckVector& constantChecks() const { return m_constantChecks; } >+ JSObject* alternateBase() const { return m_alternateBase; } > JSValue specificValue() const { return m_specificValue; } > PropertyOffset offset() const { return m_offset; } > CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); } >@@ -80,7 +70,8 @@ private: > friend class GetByIdStatus; > > StructureSet m_structureSet; >- RefPtr<IntendedStructureChain> m_chain; >+ ConstantStructureCheckVector m_constantChecks; >+ JSObject* m_alternateBase; > JSValue m_specificValue; > PropertyOffset m_offset; > std::unique_ptr<CallLinkStatus> m_callLinkStatus; >Index: Source/JavaScriptCore/bytecode/PutByIdVariant.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/PutByIdVariant.cpp (revision 169901) >+++ Source/JavaScriptCore/bytecode/PutByIdVariant.cpp (working copy) >@@ -26,6 +26,8 @@ > #include "config.h" > #include "PutByIdVariant.h" > >+#include <wtf/ListDump.h> >+ > namespace JSC { > > void PutByIdVariant::dump(PrintStream& out) const >@@ -48,8 +50,8 @@ void PutByIdVariant::dumpInContext(Print > case Transition: > out.print( > "<Transition: ", pointerDumpInContext(oldStructure(), context), " -> ", >- pointerDumpInContext(newStructure(), context), ", ", >- pointerDumpInContext(structureChain(), context), ", ", offset(), ">"); >+ pointerDumpInContext(newStructure(), context), ", [", >+ listDumpInContext(constantChecks(), context), "], ", offset(), ">"); > return; > } > >Index: Source/JavaScriptCore/bytecode/PutByIdVariant.h >=================================================================== >--- Source/JavaScriptCore/bytecode/PutByIdVariant.h (revision 169901) >+++ Source/JavaScriptCore/bytecode/PutByIdVariant.h (working copy) >@@ -64,7 +64,8 @@ public: > result.m_kind = Transition; > result.m_oldStructure = oldStructure; > result.m_newStructure = newStructure; >- result.m_structureChain = structureChain; >+ if (structureChain) >+ structureChain->gatherChecks(result.m_constantChecks); > result.m_offset = offset; > return result; > } >@@ -92,10 +93,10 @@ public: > return m_newStructure; > } > >- IntendedStructureChain* structureChain() const >+ const ConstantStructureCheckVector& constantChecks() const > { > ASSERT(kind() == Transition); >- return m_structureChain.get(); >+ return m_constantChecks; > } > > PropertyOffset offset() const >@@ -111,7 +112,7 @@ private: > Kind m_kind; > Structure* m_oldStructure; > Structure* m_newStructure; >- RefPtr<IntendedStructureChain> m_structureChain; >+ ConstantStructureCheckVector m_constantChecks; > PropertyOffset m_offset; > }; > >Index: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (working copy) >@@ -1471,7 +1471,8 @@ bool AbstractInterpreter<AbstractStateTy > // Assert things that we can't handle and that the computeFor() method > // above won't be able to return. > ASSERT(status[0].structureSet().size() == 1); >- ASSERT(!status[0].chain()); >+ ASSERT(status[0].constantChecks().isEmpty()); >+ ASSERT(!status[0].alternateBase()); > > if (status[0].specificValue()) { > if (status[0].specificValue().isCell()) { >@@ -1679,7 +1680,7 @@ bool AbstractInterpreter<AbstractStateTy > if (!variant.structureSet().contains(structure)) > continue; > >- if (variant.chain()) >+ if (variant.alternateBase()) > break; > > filter(value, structure); >Index: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (revision 169902) >+++ Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (working copy) >@@ -192,7 +192,7 @@ private: > void handlePutById( > Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&, > bool isDirect); >- Node* emitPrototypeChecks(IntendedStructureChain*); >+ void emitChecks(const ConstantStructureCheckVector&); > > Node* getScope(bool skipTop, unsigned skipCount); > >@@ -665,11 +665,6 @@ private: > return objectNode; > } > >- Node* cellConstantWithStructureCheck(JSCell* object) >- { >- return cellConstantWithStructureCheck(object, m_graph.freeze(object)->structure()); >- } >- > SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex) > { > ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock); >@@ -798,22 +793,6 @@ private: > return node; > } > >- bool structureChainIsStillValid(bool direct, Structure* previousStructure, StructureChain* chain) >- { >- if (direct) >- return true; >- >- if (!previousStructure->storedPrototype().isNull() && previousStructure->storedPrototype().asCell()->structure() != chain->head()->get()) >- return false; >- >- for (WriteBarrier<Structure>* it = chain->head(); *it; ++it) { >- if (!(*it)->storedPrototype().isNull() && (*it)->storedPrototype().asCell()->structure() != it[1].get()) >- return false; >- } >- >- return true; >- } >- > void buildOperandMapsIfNecessary(); > > VM* m_vm; >@@ -1705,20 +1684,10 @@ Node* ByteCodeParser::handlePutByOffset( > return result; > } > >-Node* ByteCodeParser::emitPrototypeChecks(IntendedStructureChain* chain) >+void ByteCodeParser::emitChecks(const ConstantStructureCheckVector& vector) > { >- m_graph.chains().addLazily(chain); >- JSValue prototype = chain->prototype(); >- if (prototype.isNull()) >- return nullptr; >- Node* base = nullptr; >- for (unsigned i = 0; i < chain->size(); ++i) { >- JSObject* currentObject = asObject(prototype); >- Structure* currentStructure = chain->at(i); >- base = cellConstantWithStructureCheck(currentObject, currentStructure); >- prototype = currentStructure->prototypeForLookup(m_inlineStackTop->m_codeBlock); >- } >- return base; >+ for (unsigned i = 0; i < vector.size(); ++i) >+ cellConstantWithStructureCheck(vector[i].constant(), vector[i].structure()); > } > > void ByteCodeParser::handleGetById( >@@ -1747,10 +1716,8 @@ void ByteCodeParser::handleGetById( > // 1) Emit prototype structure checks for all chains. This could sort of maybe not be > // optimal, if there is some rarely executed case in the chain that requires a lot > // of checks and those checks are not watchpointable. >- for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) { >- if (getByIdStatus[variantIndex].chain()) >- emitPrototypeChecks(getByIdStatus[variantIndex].chain()); >- } >+ for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) >+ emitChecks(getByIdStatus[variantIndex].constantChecks()); > > // 2) Emit a MultiGetByOffset > MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add(); >@@ -1771,8 +1738,10 @@ void ByteCodeParser::handleGetById( > > addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base); > >- if (variant.chain()) >- base = emitPrototypeChecks(variant.chain()); >+ emitChecks(variant.constantChecks()); >+ >+ if (variant.alternateBase()) >+ base = weakJSConstant(variant.alternateBase()); > > // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to > // ensure that the base of the original get_by_id is kept alive until we're done with >@@ -1869,9 +1838,7 @@ void ByteCodeParser::handlePutById( > for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) { > if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition) > continue; >- if (!putByIdStatus[variantIndex].structureChain()) >- continue; >- emitPrototypeChecks(putByIdStatus[variantIndex].structureChain()); >+ emitChecks(putByIdStatus[variantIndex].constantChecks()); > } > } > >@@ -1898,16 +1865,8 @@ void ByteCodeParser::handlePutById( > return; > } > >- if (variant.structureChain() && !variant.structureChain()->isStillValid()) { >- emitPutById(base, identifierNumber, value, putByIdStatus, isDirect); >- return; >- } >- >- m_graph.chains().addLazily(variant.structureChain()); >- > addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base); >- if (!isDirect) >- emitPrototypeChecks(variant.structureChain()); >+ emitChecks(variant.constantChecks()); > > ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated()); > >Index: Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (working copy) >@@ -150,7 +150,7 @@ private: > if (!variant.structureSet().contains(structure)) > continue; > >- if (variant.chain()) >+ if (variant.alternateBase()) > break; > > emitGetByOffset(indexInBlock, node, structure, variant, data.identifierNumber); >@@ -197,7 +197,8 @@ private: > GetByIdStatus status = GetByIdStatus::computeFor( > vm(), structure, m_graph.identifiers()[identifierNumber]); > >- if (!status.isSimple() || status.numVariants() != 1) { >+ if (!status.isSimple() || status.numVariants() != 1 || >+ !status[0].constantChecks().isEmpty() || status[0].alternateBase()) { > // FIXME: We could handle prototype cases. > // https://bugs.webkit.org/show_bug.cgi?id=110386 > break; >@@ -319,7 +320,7 @@ private: > > bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell; > >- ASSERT(!variant.chain()); >+ ASSERT(!variant.alternateBase()); > ASSERT_UNUSED(structure, variant.structureSet().contains(structure)); > > // Now before we do anything else, push the CFA forward over the GetById >@@ -382,23 +383,11 @@ private: > if (variant.kind() == PutByIdVariant::Transition) { > transition = m_graph.m_transitions.add(structure, variant.newStructure()); > >- if (node->op() == PutById) { >- if (!structure->storedPrototype().isNull()) { >- addStructureTransitionCheck( >- origin, indexInBlock, >- structure->storedPrototype().asCell()); >- } >- >- m_graph.chains().addLazily(variant.structureChain()); >- >- for (unsigned i = 0; i < variant.structureChain()->size(); ++i) { >- JSValue prototype = variant.structureChain()->at(i)->storedPrototype(); >- if (prototype.isNull()) >- continue; >- ASSERT(prototype.isCell()); >- addStructureTransitionCheck( >- origin, indexInBlock, prototype.asCell()); >- } >+ for (unsigned i = 0; i < variant.constantChecks().size(); ++i) { >+ addStructureTransitionCheck( >+ origin, indexInBlock, >+ variant.constantChecks()[i].constant(), >+ variant.constantChecks()[i].structure()); > } > } > >@@ -450,7 +439,7 @@ private: > m_graph.m_storageAccessData.append(storageAccessData); > } > >- void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell) >+ void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure) > { > if (m_graph.watchpoints().consider(cell->structure())) > return; >@@ -461,7 +450,7 @@ private: > > m_insertionSet.insertNode( > indexInBlock, SpecNone, CheckStructure, origin, >- OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse)); >+ OpInfo(m_graph.addStructureSet(structure)), Edge(weakConstant, CellUse)); > } > > InPlaceAbstractState m_state; >Index: Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp (working copy) >@@ -1,56 +0,0 @@ >-/* >- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. >- * >- * 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 "DFGDesiredStructureChains.h" >- >-#if ENABLE(DFG_JIT) >- >-#include "JSCInlines.h" >- >-namespace JSC { namespace DFG { >- >-DesiredStructureChains::DesiredStructureChains() { } >-DesiredStructureChains::~DesiredStructureChains() { } >- >-bool DesiredStructureChains::areStillValid() const >-{ >- for (unsigned i = 0; i < m_vector.size(); ++i) { >- if (!m_vector[i]->isStillValid()) >- return false; >- } >- return true; >-} >- >-void DesiredStructureChains::visitChildren(SlotVisitor& visitor) >-{ >- for (unsigned i = m_vector.size(); i--;) >- m_vector[i]->visitChildren(visitor); >-} >- >-} } // namespace JSC::DFG >- >-#endif // ENABLE(DFG_JIT) >- >Index: Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h (working copy) >@@ -1,59 +0,0 @@ >-/* >- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. >- * >- * 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. >- */ >- >-#ifndef DFGDesiredStructureChains_h >-#define DFGDesiredStructureChains_h >- >-#if ENABLE(DFG_JIT) >- >-#include "IntendedStructureChain.h" >-#include <wtf/Vector.h> >- >-namespace JSC { namespace DFG { >- >-class DesiredStructureChains { >-public: >- DesiredStructureChains(); >- ~DesiredStructureChains(); >- >- void addLazily(PassRefPtr<IntendedStructureChain> chain) >- { >- m_vector.append(chain); >- } >- >- bool areStillValid() const; >- >- void visitChildren(SlotVisitor&); >- >-private: >- Vector<RefPtr<IntendedStructureChain>> m_vector; >-}; >- >-} } // namespace JSC::DFG >- >-#endif // ENABLE(DFG_JIT) >- >-#endif // DFGDesiredStructureChains_h >- >Index: Source/JavaScriptCore/dfg/DFGGraph.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.h (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGGraph.h (working copy) >@@ -671,7 +671,6 @@ public: > > DesiredIdentifiers& identifiers() { return m_plan.identifiers; } > DesiredWatchpoints& watchpoints() { return m_plan.watchpoints; } >- DesiredStructureChains& chains() { return m_plan.chains; } > > FullBytecodeLiveness& livenessFor(CodeBlock*); > FullBytecodeLiveness& livenessFor(InlineCallFrame*); >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -400,8 +400,6 @@ bool Plan::isStillValid() > return false; > if (!watchpoints.areStillValid()) > return false; >- if (!chains.areStillValid()) >- return false; > return true; > } > >@@ -471,7 +469,6 @@ void Plan::checkLivenessAndVisitChildren > codeBlocks.mark(codeBlock.get()); > codeBlocks.mark(profiledDFGCodeBlock.get()); > >- chains.visitChildren(visitor); > weakReferences.visitChildren(visitor); > writeBarriers.visitChildren(visitor); > transitions.visitChildren(visitor); >@@ -500,7 +497,6 @@ void Plan::cancel() > inlineCallFrames = nullptr; > watchpoints = DesiredWatchpoints(); > identifiers = DesiredIdentifiers(); >- chains = DesiredStructureChains(); > weakReferences = DesiredWeakReferences(); > writeBarriers = DesiredWriteBarriers(); > transitions = DesiredTransitions(); >Index: Source/JavaScriptCore/dfg/DFGPlan.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.h (revision 169901) >+++ Source/JavaScriptCore/dfg/DFGPlan.h (working copy) >@@ -30,7 +30,6 @@ > #include "DFGCompilationKey.h" > #include "DFGCompilationMode.h" > #include "DFGDesiredIdentifiers.h" >-#include "DFGDesiredStructureChains.h" > #include "DFGDesiredTransitions.h" > #include "DFGDesiredWatchpoints.h" > #include "DFGDesiredWeakReferences.h" >@@ -92,7 +91,6 @@ struct Plan : public ThreadSafeRefCounte > RefPtr<InlineCallFrameSet> inlineCallFrames; > DesiredWatchpoints watchpoints; > DesiredIdentifiers identifiers; >- DesiredStructureChains chains; > DesiredWeakReferences weakReferences; > DesiredWriteBarriers writeBarriers; > DesiredTransitions transitions; >Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (revision 169901) >+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (working copy) >@@ -3240,8 +3240,8 @@ private: > result = m_out.constInt64(JSValue::encode(variant.specificValue())); > else { > LValue propertyBase; >- if (variant.chain()) >- propertyBase = weakPointer(variant.chain()->terminalPrototype()); >+ if (variant.alternateBase()) >+ propertyBase = weakPointer(variant.alternateBase()); > else > propertyBase = base; > if (!isInlineOffset(variant.offset())) >Index: Source/JavaScriptCore/runtime/IntendedStructureChain.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/IntendedStructureChain.cpp (revision 169902) >+++ Source/JavaScriptCore/runtime/IntendedStructureChain.cpp (working copy) >@@ -145,6 +145,17 @@ bool IntendedStructureChain::operator==( > && m_vector == other.m_vector; > } > >+void IntendedStructureChain::gatherChecks(ConstantStructureCheckVector& vector) const >+{ >+ JSValue currentPrototype = m_prototype; >+ for (unsigned i = 0; i < size(); ++i) { >+ JSObject* currentObject = asObject(currentPrototype); >+ Structure* currentStructure = at(i); >+ vector.append(ConstantStructureCheck(currentObject, currentStructure)); >+ currentPrototype = currentStructure->prototypeForLookup(m_globalObject); >+ } >+} >+ > void IntendedStructureChain::visitChildren(SlotVisitor& visitor) > { > visitor.appendUnbarrieredPointer(&m_globalObject); >Index: Source/JavaScriptCore/runtime/IntendedStructureChain.h >=================================================================== >--- Source/JavaScriptCore/runtime/IntendedStructureChain.h (revision 169902) >+++ Source/JavaScriptCore/runtime/IntendedStructureChain.h (working copy) >@@ -26,6 +26,7 @@ > #ifndef IntendedStructureChain_h > #define IntendedStructureChain_h > >+#include "ConstantStructureCheck.h" > #include "Structure.h" > #include <wtf/RefCounted.h> > >@@ -54,8 +55,8 @@ public: > JSValue prototype() const { return m_prototype; } > > size_t size() const { return m_vector.size(); } >- Structure* at(size_t index) { return m_vector[index]; } >- Structure* operator[](size_t index) { return at(index); } >+ Structure* at(size_t index) const { return m_vector[index]; } >+ Structure* operator[](size_t index) const { return at(index); } > > JSObject* terminalPrototype() const; > >@@ -67,6 +68,8 @@ public: > return !(*this == other); > } > >+ void gatherChecks(ConstantStructureCheckVector&) const; >+ > void visitChildren(SlotVisitor&); > void dump(PrintStream&) const; > void dumpInContext(PrintStream&, DumpContext*) const; >Index: Source/WTF/wtf/ListDump.h >=================================================================== >--- Source/WTF/wtf/ListDump.h (revision 169901) >+++ Source/WTF/wtf/ListDump.h (working copy) >@@ -119,12 +119,42 @@ CString sortedMapDump(const T& map, cons > return out.toCString(); > } > >+template<typename T, typename U> >+class ListDumpInContext { >+public: >+ ListDumpInContext(const T& list, U* context, const char* comma) >+ : m_list(list) >+ , m_context(context) >+ , m_comma(comma) >+ { >+ } >+ >+ void dump(PrintStream& out) const >+ { >+ for (typename T::const_iterator iter = m_list.begin(); iter != m_list.end(); ++iter) >+ out.print(m_comma, inContext(*iter, m_context)); >+ } >+ >+private: >+ const T& m_list; >+ U* m_context; >+ CommaPrinter m_comma; >+}; >+ >+template<typename T, typename U> >+ListDumpInContext<T, U> listDumpInContext( >+ const T& list, U* context, const char* comma = ", ") >+{ >+ return ListDumpInContext<T, U>(list, context, comma); >+} >+ > } // namespace WTF > > using WTF::listDump; > using WTF::sortedListDump; > using WTF::mapDump; > using WTF::sortedMapDump; >+using WTF::listDumpInContext; > > #endif // ListDump_h > >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 169919) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,17 @@ >+2014-06-12 Filip Pizlo <fpizlo@apple.com> >+ >+ [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants >+ https://bugs.webkit.org/show_bug.cgi?id=133821 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * js/regress/poly-chain-access-different-prototypes-expected.txt: Added. >+ * js/regress/poly-chain-access-different-prototypes-simple-expected.txt: Added. >+ * js/regress/poly-chain-access-different-prototypes-simple.html: Added. >+ * js/regress/poly-chain-access-different-prototypes.html: Added. >+ * js/regress/script-tests/poly-chain-access-different-prototypes-simple.js: Added. >+ * js/regress/script-tests/poly-chain-access-different-prototypes.js: Added. >+ > 2014-06-11 Filip Pizlo <fpizlo@apple.com> > > [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base >Index: LayoutTests/js/regress/poly-chain-access-different-prototypes-expected.txt >=================================================================== >--- LayoutTests/js/regress/poly-chain-access-different-prototypes-expected.txt (revision 0) >+++ LayoutTests/js/regress/poly-chain-access-different-prototypes-expected.txt (working copy) >@@ -0,0 +1,10 @@ >+JSRegress/poly-chain-access-different-prototypes >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS no exception thrown >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/js/regress/poly-chain-access-different-prototypes-simple-expected.txt >=================================================================== >--- LayoutTests/js/regress/poly-chain-access-different-prototypes-simple-expected.txt (revision 0) >+++ LayoutTests/js/regress/poly-chain-access-different-prototypes-simple-expected.txt (working copy) >@@ -0,0 +1,10 @@ >+JSRegress/poly-chain-access-different-prototypes-simple >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS no exception thrown >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/js/regress/poly-chain-access-different-prototypes-simple.html >=================================================================== >--- LayoutTests/js/regress/poly-chain-access-different-prototypes-simple.html (revision 0) >+++ LayoutTests/js/regress/poly-chain-access-different-prototypes-simple.html (working copy) >@@ -0,0 +1,12 @@ >+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> >+<html> >+<head> >+<script src="../../resources/js-test-pre.js"></script> >+</head> >+<body> >+<script src="../../resources/regress-pre.js"></script> >+<script src="script-tests/poly-chain-access-different-prototypes-simple.js"></script> >+<script src="../../resources/regress-post.js"></script> >+<script src="../../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/js/regress/poly-chain-access-different-prototypes.html >=================================================================== >--- LayoutTests/js/regress/poly-chain-access-different-prototypes.html (revision 0) >+++ LayoutTests/js/regress/poly-chain-access-different-prototypes.html (working copy) >@@ -0,0 +1,12 @@ >+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> >+<html> >+<head> >+<script src="../../resources/js-test-pre.js"></script> >+</head> >+<body> >+<script src="../../resources/regress-pre.js"></script> >+<script src="script-tests/poly-chain-access-different-prototypes.js"></script> >+<script src="../../resources/regress-post.js"></script> >+<script src="../../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes-simple.js >=================================================================== >--- LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes-simple.js (revision 0) >+++ LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes-simple.js (working copy) >@@ -0,0 +1,24 @@ >+(function() { >+ function Foo() { } >+ Foo.prototype.f = 42; >+ function Bar() { } >+ Bar.prototype = new Foo(); >+ function Baz() { } >+ Baz.prototype = new Foo(); >+ >+ function foo(o, p) { >+ var n = 1000000; >+ var result = 0; >+ for (var i = 0; i < n; ++i) { >+ result += o.f; >+ var tmp = o; >+ o = p; >+ p = tmp; >+ } >+ >+ if (result != n * 42) >+ throw "Error: bad result: " + result; >+ } >+ >+ foo(new Bar(), new Baz()); >+})(); >Index: LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes.js >=================================================================== >--- LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes.js (revision 0) >+++ LayoutTests/js/regress/script-tests/poly-chain-access-different-prototypes.js (working copy) >@@ -0,0 +1,23 @@ >+(function() { >+ function Foo() { } >+ Foo.prototype.f = 42; >+ function Bar() { } >+ Bar.prototype = new Foo(); >+ function Baz() { } >+ Baz.prototype = new Foo(); >+ >+ var o = new Bar(); >+ var p = new Baz(); >+ >+ var n = 1000000; >+ var result = 0; >+ for (var i = 0; i < n; ++i) { >+ result += o.f; >+ var tmp = o; >+ o = p; >+ p = tmp; >+ } >+ >+ if (result != n * 42) >+ throw "Error: bad result: " + result; >+})();
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
Flags:
mhahnenberg
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 133821
:
232986
| 233006