haikuwebkit/Source/JavaScriptCore/bytecode/InstanceOfStatus.h

117 lines
3.7 KiB
C
Raw Permalink Normal View History

DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
/*
* Copyright (C) 2018 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.
*/
#pragma once
#include "ConcurrentJSLock.h"
We should support CreateThis in the FTL https://bugs.webkit.org/show_bug.cgi?id=164904 Reviewed by Yusuke Suzuki. JSTests: * microbenchmarks/polyvariant-get-by-id-shorter-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): * microbenchmarks/polyvariant-get-by-id-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): (Baz.prototype.func): (Baz): (baz): Source/JavaScriptCore: This started with Saam's patch to implement CreateThis in the FTL, but turned into a type inference adventure. CreateThis in the FTL was a massive regression in raytrace because it disturbed that benchmark's extremely perverse way of winning at type inference: - The benchmark wanted polyvariant devirtualization of an object construction helper. But, the polyvariant profiler wasn't powerful enough to reliably devirtualize that code. So, the benchmark was falling back to other mechanisms... - The construction helper could not tier up into the FTL. When the DFG compiled it, it would see that the IC had 4 cases. That's too polymorphic for the DFG. So, the DFG would emit a GetById. Shortly after the DFG compile, that get_by_id would see many more cases, but now that the helper was compiled by the DFG, the baseline get_by_id would not see those cases. The DFG's GetById would "hide" those cases. The number of cases the DFG's GetById would see is larger than our polymorphic list limit (limit = 8, case count = 13, I think). Note that if the FTL compiles that construction helper, it sees the 4 cases, turns them into a MultiGetByOffset, then suffers from exits when the new cases hit, and then exits to baseline, which then sees those cases. Luckily, the FTL was not compiling the construction helper because it had a CreateThis. - Compilations that inlined the construction helper would have gotten super lucky with parse-time constant folding, so they knew what structure the input to the get_by_id would have at parse time. This is only profitable if the get_by_id parsing computed a GetByIdStatus that had a finite number of cases. Because the 13 cases were being hidden by the DFG GetById and GetByIdStatus would only look at the baseline get_by_id, which had 4 cases, we would indeed get a finite number of cases. The parser would then prune those cases to just one - based on its knowledge of the structure - and that would result in that get_by_id being folded at parse time to a constant. - The subsequent op_call would inline based on parse-time knowledge of that constant. This patch comprehensively fixes these issues, as well as other issues that come up along the way. The short version is that raytrace was revealing sloppiness in our use of profiling for type inference. This patch fixes the sloppiness by vastly expanding *polyvariant* profiling, i.e. the profiling that considers call context. I was encouraged to do this by the fact that even the old version of polyvariant profiling was a speed-up on JetStream, ARES-6, and Speedometer 2 (it's easy to measure since it's a runtime flag). So, it seemed worthwhile to attack raytrace's problem as a shortcoming of polyvariant profiling. - Polyvariant profiling now consults every DFG or FTL code block that participated in any subset of the inline stack that includes the IC we're profiling. For example, if we have an inline stack like foo->bar->baz, with baz on top, then we will consult DFG or FTL compilations for foo, bar, and baz. In foo, we'll look up foo->bar->baz; in bar we'll look up bar->baz; etc. This fixes two problems encountered in raytrace. First, it ensures that a DFG GetById cannot hide anything from the profiling of that get_by_id, since the polyvariant profiling code will always consult it. Second, it enables raytrace to benefit from polyvariant profling. Previously, the polyvariant profiler would only look at the previous DFG compilation of foo and look up foo->bar->baz. But that only works if DFG-foo had inlined bar and then baz. It may not have done that, because those calls could have required polyvariant profiling that was only available in the FTL. - A particularly interesting case is when some IC in foo-baseline is also available in foo-DFG. This case is encountered by the polyvariant profiler as it walks the inline stack. In the case of gathering profiling for foo-FTL, the polyvariant profiler finds foo-DFG via the trivial case of no inline stack. This also means that if foo ever gets inlined, we will find foo-DFG or foo-FTL in the final case of polyvariant profiling. In those cases, we now merge the IC of foo-baseline and foo-DFG. This avoids lots of unnecessary recompilations, because it warns us of historical polymorphism. Historical polymorphism usually means future polymorphism. IC status code already had some merging functionality, but I needed to beef it up a lot to make this work right. - Inlining an inline cache now preserves as much information as profiling. One challenge of polyvariant profiling is that the FTL compile for bar (that includes bar->baz) could have inlined an inline cache based on polyvariant profiling. So, when the FTL compile for foo (that includes foo->bar->baz) asks bar what it knows about that IC inside bar->baz, it will say "I don't have such an IC". At this point the DFG compilation that included that IC that gave us the information that we used to inline the IC is no longer alive. To keep us from losing the information we learned about the IC, there is now a RecordedStatuses data structure that preserves the statuses we use for inlining ICs. We also filter those statuses according to things we learn from AI. This further reduces the risk of information about an IC being forgotten. - Exit profiling now considers whether or not an exit happened from inline code. This protects us in the case where the not-inlined version of an IC exited a lot because of polymorphism that doesn't exist in the inlined version. So, when using polyvariant profiling data, we consider only inlined exits. - CallLinkInfo now records when it's repatched to the virtual call thunk. Previously, this would clear the CallLinkInfo, so CallLinkStatus would fall back to the lastSeenCallee. It's surprising that we've had this bug. Altogether this patch is performance-neutral in run-jsc-benchmarks, except for speed-ups in microbenchmarks and a compile time regression. Octane/deltablue speeds up by ~5%. Octane/raytrace is regressed by a minuscule amount, which we could make up by implementing prototype access folding in the bytecode parser and constant folder. That would require some significant new logic in GetByIdStatus. That would also require a new benchmark - we want to have a test that captures raytrace's behavior in the case that the parser cannot fold the get_by_id. This change is a 1.2% regression on V8Spider-CompileTime. That's a smaller regression than recent compile time progressions, so I think that's an OK trade-off. Also, I would expect a compile time regression anytime we fill in FTL coverage. This is neutral on JetStream, ARES-6, and Speedometer2. JetStream agrees that deltablue speeds up and that raytrace slows down, but these changes balance out and don't affect the overall score. In ARES-6, it looks like individual tests have some significant 1-2% speed-ups or slow-downs. Air-steady is definitely ~1.5% faster. Basic-worst is probably 2% slower (p ~ 0.1, so it's not very certain). The JetStream, ARES-6, and Speedometer2 overall scores don't see a significant difference. In all three cases the difference is <0.5% with a high p value, with JetStream and Speedometer2 being insignificant infinitesimal speed-ups and ARES-6 being an insignificant infinitesimal slow-down. Oh, and this change means that the FTL now has 100% coverage of JavaScript. You could do an eval in a for-in loop in a for-of loop inside a with block that uses try/catch for control flow in a polymorphic constructor while having a bad time, and we'll still compile it. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/ByValInfo.h: * bytecode/BytecodeDumper.cpp: (JSC::BytecodeDumper<Block>::printGetByIdCacheStatus): (JSC::BytecodeDumper<Block>::printPutByIdCacheStatus): (JSC::BytecodeDumper<Block>::printInByIdCacheStatus): (JSC::BytecodeDumper<Block>::dumpCallLinkStatus): (JSC::BytecodeDumper<CodeBlock>::dumpCallLinkStatus): (JSC::BytecodeDumper<Block>::printCallOp): (JSC::BytecodeDumper<Block>::dumpBytecode): (JSC::BytecodeDumper<Block>::dumpBlock): * bytecode/BytecodeDumper.h: * bytecode/CallLinkInfo.h: * bytecode/CallLinkStatus.cpp: (JSC::CallLinkStatus::computeFor): (JSC::CallLinkStatus::computeExitSiteData): (JSC::CallLinkStatus::computeFromCallLinkInfo): (JSC::CallLinkStatus::accountForExits): (JSC::CallLinkStatus::finalize): (JSC::CallLinkStatus::filter): (JSC::CallLinkStatus::computeDFGStatuses): Deleted. * bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::operator bool const): (JSC::CallLinkStatus::operator! const): Deleted. * bytecode/CallVariant.cpp: (JSC::CallVariant::finalize): (JSC::CallVariant::filter): * bytecode/CallVariant.h: (JSC::CallVariant::operator bool const): (JSC::CallVariant::operator! const): Deleted. * bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): (JSC::CodeBlock::propagateTransitions): (JSC::CodeBlock::finalizeUnconditionally): (JSC::CodeBlock::getICStatusMap): (JSC::CodeBlock::resetJITData): (JSC::CodeBlock::getStubInfoMap): Deleted. (JSC::CodeBlock::getCallLinkInfoMap): Deleted. (JSC::CodeBlock::getByValInfoMap): Deleted. * bytecode/CodeBlock.h: * bytecode/CodeOrigin.cpp: (JSC::CodeOrigin::isApproximatelyEqualTo const): (JSC::CodeOrigin::approximateHash const): * bytecode/CodeOrigin.h: (JSC::CodeOrigin::exitingInlineKind const): * bytecode/DFGExitProfile.cpp: (JSC::DFG::FrequentExitSite::dump const): (JSC::DFG::ExitProfile::add): * bytecode/DFGExitProfile.h: (JSC::DFG::FrequentExitSite::FrequentExitSite): (JSC::DFG::FrequentExitSite::operator== const): (JSC::DFG::FrequentExitSite::subsumes const): (JSC::DFG::FrequentExitSite::hash const): (JSC::DFG::FrequentExitSite::inlineKind const): (JSC::DFG::FrequentExitSite::withInlineKind const): (JSC::DFG::QueryableExitProfile::hasExitSite const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificJITType const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificInlineKind const): * bytecode/ExitFlag.cpp: Added. (JSC::ExitFlag::dump const): * bytecode/ExitFlag.h: Added. (JSC::ExitFlag::ExitFlag): (JSC::ExitFlag::operator| const): (JSC::ExitFlag::operator|=): (JSC::ExitFlag::operator& const): (JSC::ExitFlag::operator&=): (JSC::ExitFlag::operator bool const): (JSC::ExitFlag::isSet const): * bytecode/ExitingInlineKind.cpp: Added. (WTF::printInternal): * bytecode/ExitingInlineKind.h: Added. * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::computeFor): (JSC::GetByIdStatus::computeForStubInfo): (JSC::GetByIdStatus::slowVersion const): (JSC::GetByIdStatus::markIfCheap): (JSC::GetByIdStatus::finalize): (JSC::GetByIdStatus::hasExitSite): Deleted. * bytecode/GetByIdStatus.h: * bytecode/GetByIdVariant.cpp: (JSC::GetByIdVariant::markIfCheap): (JSC::GetByIdVariant::finalize): * bytecode/GetByIdVariant.h: * bytecode/ICStatusMap.cpp: Added. (JSC::ICStatusContext::get const): (JSC::ICStatusContext::isInlined const): (JSC::ICStatusContext::inlineKind const): * bytecode/ICStatusMap.h: Added. * bytecode/ICStatusUtils.cpp: Added. (JSC::hasBadCacheExitSite): * bytecode/ICStatusUtils.h: * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::computeFor): * bytecode/InstanceOfStatus.h: * bytecode/PolyProtoAccessChain.h: * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::hasExitSite): (JSC::PutByIdStatus::computeFor): (JSC::PutByIdStatus::slowVersion const): (JSC::PutByIdStatus::markIfCheap): (JSC::PutByIdStatus::finalize): (JSC::PutByIdStatus::filter): * bytecode/PutByIdStatus.h: * bytecode/PutByIdVariant.cpp: (JSC::PutByIdVariant::markIfCheap): (JSC::PutByIdVariant::finalize): * bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::structureSet const): * bytecode/RecordedStatuses.cpp: Added. (JSC::RecordedStatuses::operator=): (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::addCallLinkStatus): (JSC::RecordedStatuses::addGetByIdStatus): (JSC::RecordedStatuses::addPutByIdStatus): (JSC::RecordedStatuses::markIfCheap): (JSC::RecordedStatuses::finalizeWithoutDeleting): (JSC::RecordedStatuses::finalize): (JSC::RecordedStatuses::shrinkToFit): * bytecode/RecordedStatuses.h: Added. (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::forEachVector): * bytecode/StructureSet.cpp: (JSC::StructureSet::markIfCheap const): (JSC::StructureSet::isStillAlive const): * bytecode/StructureSet.h: * bytecode/TerminatedCodeOrigin.h: Added. (JSC::TerminatedCodeOrigin::TerminatedCodeOrigin): (JSC::TerminatedCodeOriginHashTranslator::hash): (JSC::TerminatedCodeOriginHashTranslator::equal): * bytecode/Watchpoint.cpp: (WTF::printInternal): * bytecode/Watchpoint.h: * dfg/DFGAbstractInterpreter.h: * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::handleVarargsCall): (JSC::DFG::ByteCodeParser::handleDOMJITGetter): (JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad): (JSC::DFG::ByteCodeParser::handleGetById): (JSC::DFG::ByteCodeParser::handlePutById): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): (JSC::DFG::ByteCodeParser::InlineStackEntry::~InlineStackEntry): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGClobbersExitState.cpp: (JSC::DFG::clobbersExitState): * dfg/DFGCommonData.h: * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDesiredWatchpoints.h: (JSC::DFG::SetPointerAdaptor::hasBeenInvalidated): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGMayExit.cpp: * dfg/DFGNode.h: (JSC::DFG::Node::hasCallLinkStatus): (JSC::DFG::Node::callLinkStatus): (JSC::DFG::Node::hasGetByIdStatus): (JSC::DFG::Node::getByIdStatus): (JSC::DFG::Node::hasPutByIdStatus): (JSC::DFG::Node::putByIdStatus): * dfg/DFGNodeType.h: * dfg/DFGOSRExitBase.cpp: (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow): * dfg/DFGObjectAllocationSinkingPhase.cpp: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::reallyAdd): (JSC::DFG::Plan::checkLivenessAndVisitChildren): (JSC::DFG::Plan::finalizeInGC): * dfg/DFGPlan.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::removeDeadPlans): * ftl/FTLAbstractHeapRepository.h: * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileCreateThis): (JSC::FTL::DFG::LowerDFGToB3::compileFilterICStatus): * jit/PolymorphicCallStubRoutine.cpp: (JSC::PolymorphicCallStubRoutine::hasEdges const): (JSC::PolymorphicCallStubRoutine::edges const): * jit/PolymorphicCallStubRoutine.h: * profiler/ProfilerBytecodeSequence.cpp: (JSC::Profiler::BytecodeSequence::BytecodeSequence): * runtime/FunctionRareData.cpp: (JSC::FunctionRareData::initializeObjectAllocationProfile): * runtime/Options.h: Source/WTF: * wtf/TinyPtrSet.h: (WTF::TinyPtrSet::operator!= const): Canonical link: https://commits.webkit.org/203069@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234086 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-07-22 02:48:16 +00:00
#include "ICStatusMap.h"
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
#include "InstanceOfVariant.h"
We should support CreateThis in the FTL https://bugs.webkit.org/show_bug.cgi?id=164904 Reviewed by Yusuke Suzuki. JSTests: * microbenchmarks/polyvariant-get-by-id-shorter-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): * microbenchmarks/polyvariant-get-by-id-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): (Baz.prototype.func): (Baz): (baz): Source/JavaScriptCore: This started with Saam's patch to implement CreateThis in the FTL, but turned into a type inference adventure. CreateThis in the FTL was a massive regression in raytrace because it disturbed that benchmark's extremely perverse way of winning at type inference: - The benchmark wanted polyvariant devirtualization of an object construction helper. But, the polyvariant profiler wasn't powerful enough to reliably devirtualize that code. So, the benchmark was falling back to other mechanisms... - The construction helper could not tier up into the FTL. When the DFG compiled it, it would see that the IC had 4 cases. That's too polymorphic for the DFG. So, the DFG would emit a GetById. Shortly after the DFG compile, that get_by_id would see many more cases, but now that the helper was compiled by the DFG, the baseline get_by_id would not see those cases. The DFG's GetById would "hide" those cases. The number of cases the DFG's GetById would see is larger than our polymorphic list limit (limit = 8, case count = 13, I think). Note that if the FTL compiles that construction helper, it sees the 4 cases, turns them into a MultiGetByOffset, then suffers from exits when the new cases hit, and then exits to baseline, which then sees those cases. Luckily, the FTL was not compiling the construction helper because it had a CreateThis. - Compilations that inlined the construction helper would have gotten super lucky with parse-time constant folding, so they knew what structure the input to the get_by_id would have at parse time. This is only profitable if the get_by_id parsing computed a GetByIdStatus that had a finite number of cases. Because the 13 cases were being hidden by the DFG GetById and GetByIdStatus would only look at the baseline get_by_id, which had 4 cases, we would indeed get a finite number of cases. The parser would then prune those cases to just one - based on its knowledge of the structure - and that would result in that get_by_id being folded at parse time to a constant. - The subsequent op_call would inline based on parse-time knowledge of that constant. This patch comprehensively fixes these issues, as well as other issues that come up along the way. The short version is that raytrace was revealing sloppiness in our use of profiling for type inference. This patch fixes the sloppiness by vastly expanding *polyvariant* profiling, i.e. the profiling that considers call context. I was encouraged to do this by the fact that even the old version of polyvariant profiling was a speed-up on JetStream, ARES-6, and Speedometer 2 (it's easy to measure since it's a runtime flag). So, it seemed worthwhile to attack raytrace's problem as a shortcoming of polyvariant profiling. - Polyvariant profiling now consults every DFG or FTL code block that participated in any subset of the inline stack that includes the IC we're profiling. For example, if we have an inline stack like foo->bar->baz, with baz on top, then we will consult DFG or FTL compilations for foo, bar, and baz. In foo, we'll look up foo->bar->baz; in bar we'll look up bar->baz; etc. This fixes two problems encountered in raytrace. First, it ensures that a DFG GetById cannot hide anything from the profiling of that get_by_id, since the polyvariant profiling code will always consult it. Second, it enables raytrace to benefit from polyvariant profling. Previously, the polyvariant profiler would only look at the previous DFG compilation of foo and look up foo->bar->baz. But that only works if DFG-foo had inlined bar and then baz. It may not have done that, because those calls could have required polyvariant profiling that was only available in the FTL. - A particularly interesting case is when some IC in foo-baseline is also available in foo-DFG. This case is encountered by the polyvariant profiler as it walks the inline stack. In the case of gathering profiling for foo-FTL, the polyvariant profiler finds foo-DFG via the trivial case of no inline stack. This also means that if foo ever gets inlined, we will find foo-DFG or foo-FTL in the final case of polyvariant profiling. In those cases, we now merge the IC of foo-baseline and foo-DFG. This avoids lots of unnecessary recompilations, because it warns us of historical polymorphism. Historical polymorphism usually means future polymorphism. IC status code already had some merging functionality, but I needed to beef it up a lot to make this work right. - Inlining an inline cache now preserves as much information as profiling. One challenge of polyvariant profiling is that the FTL compile for bar (that includes bar->baz) could have inlined an inline cache based on polyvariant profiling. So, when the FTL compile for foo (that includes foo->bar->baz) asks bar what it knows about that IC inside bar->baz, it will say "I don't have such an IC". At this point the DFG compilation that included that IC that gave us the information that we used to inline the IC is no longer alive. To keep us from losing the information we learned about the IC, there is now a RecordedStatuses data structure that preserves the statuses we use for inlining ICs. We also filter those statuses according to things we learn from AI. This further reduces the risk of information about an IC being forgotten. - Exit profiling now considers whether or not an exit happened from inline code. This protects us in the case where the not-inlined version of an IC exited a lot because of polymorphism that doesn't exist in the inlined version. So, when using polyvariant profiling data, we consider only inlined exits. - CallLinkInfo now records when it's repatched to the virtual call thunk. Previously, this would clear the CallLinkInfo, so CallLinkStatus would fall back to the lastSeenCallee. It's surprising that we've had this bug. Altogether this patch is performance-neutral in run-jsc-benchmarks, except for speed-ups in microbenchmarks and a compile time regression. Octane/deltablue speeds up by ~5%. Octane/raytrace is regressed by a minuscule amount, which we could make up by implementing prototype access folding in the bytecode parser and constant folder. That would require some significant new logic in GetByIdStatus. That would also require a new benchmark - we want to have a test that captures raytrace's behavior in the case that the parser cannot fold the get_by_id. This change is a 1.2% regression on V8Spider-CompileTime. That's a smaller regression than recent compile time progressions, so I think that's an OK trade-off. Also, I would expect a compile time regression anytime we fill in FTL coverage. This is neutral on JetStream, ARES-6, and Speedometer2. JetStream agrees that deltablue speeds up and that raytrace slows down, but these changes balance out and don't affect the overall score. In ARES-6, it looks like individual tests have some significant 1-2% speed-ups or slow-downs. Air-steady is definitely ~1.5% faster. Basic-worst is probably 2% slower (p ~ 0.1, so it's not very certain). The JetStream, ARES-6, and Speedometer2 overall scores don't see a significant difference. In all three cases the difference is <0.5% with a high p value, with JetStream and Speedometer2 being insignificant infinitesimal speed-ups and ARES-6 being an insignificant infinitesimal slow-down. Oh, and this change means that the FTL now has 100% coverage of JavaScript. You could do an eval in a for-in loop in a for-of loop inside a with block that uses try/catch for control flow in a polymorphic constructor while having a bad time, and we'll still compile it. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/ByValInfo.h: * bytecode/BytecodeDumper.cpp: (JSC::BytecodeDumper<Block>::printGetByIdCacheStatus): (JSC::BytecodeDumper<Block>::printPutByIdCacheStatus): (JSC::BytecodeDumper<Block>::printInByIdCacheStatus): (JSC::BytecodeDumper<Block>::dumpCallLinkStatus): (JSC::BytecodeDumper<CodeBlock>::dumpCallLinkStatus): (JSC::BytecodeDumper<Block>::printCallOp): (JSC::BytecodeDumper<Block>::dumpBytecode): (JSC::BytecodeDumper<Block>::dumpBlock): * bytecode/BytecodeDumper.h: * bytecode/CallLinkInfo.h: * bytecode/CallLinkStatus.cpp: (JSC::CallLinkStatus::computeFor): (JSC::CallLinkStatus::computeExitSiteData): (JSC::CallLinkStatus::computeFromCallLinkInfo): (JSC::CallLinkStatus::accountForExits): (JSC::CallLinkStatus::finalize): (JSC::CallLinkStatus::filter): (JSC::CallLinkStatus::computeDFGStatuses): Deleted. * bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::operator bool const): (JSC::CallLinkStatus::operator! const): Deleted. * bytecode/CallVariant.cpp: (JSC::CallVariant::finalize): (JSC::CallVariant::filter): * bytecode/CallVariant.h: (JSC::CallVariant::operator bool const): (JSC::CallVariant::operator! const): Deleted. * bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): (JSC::CodeBlock::propagateTransitions): (JSC::CodeBlock::finalizeUnconditionally): (JSC::CodeBlock::getICStatusMap): (JSC::CodeBlock::resetJITData): (JSC::CodeBlock::getStubInfoMap): Deleted. (JSC::CodeBlock::getCallLinkInfoMap): Deleted. (JSC::CodeBlock::getByValInfoMap): Deleted. * bytecode/CodeBlock.h: * bytecode/CodeOrigin.cpp: (JSC::CodeOrigin::isApproximatelyEqualTo const): (JSC::CodeOrigin::approximateHash const): * bytecode/CodeOrigin.h: (JSC::CodeOrigin::exitingInlineKind const): * bytecode/DFGExitProfile.cpp: (JSC::DFG::FrequentExitSite::dump const): (JSC::DFG::ExitProfile::add): * bytecode/DFGExitProfile.h: (JSC::DFG::FrequentExitSite::FrequentExitSite): (JSC::DFG::FrequentExitSite::operator== const): (JSC::DFG::FrequentExitSite::subsumes const): (JSC::DFG::FrequentExitSite::hash const): (JSC::DFG::FrequentExitSite::inlineKind const): (JSC::DFG::FrequentExitSite::withInlineKind const): (JSC::DFG::QueryableExitProfile::hasExitSite const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificJITType const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificInlineKind const): * bytecode/ExitFlag.cpp: Added. (JSC::ExitFlag::dump const): * bytecode/ExitFlag.h: Added. (JSC::ExitFlag::ExitFlag): (JSC::ExitFlag::operator| const): (JSC::ExitFlag::operator|=): (JSC::ExitFlag::operator& const): (JSC::ExitFlag::operator&=): (JSC::ExitFlag::operator bool const): (JSC::ExitFlag::isSet const): * bytecode/ExitingInlineKind.cpp: Added. (WTF::printInternal): * bytecode/ExitingInlineKind.h: Added. * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::computeFor): (JSC::GetByIdStatus::computeForStubInfo): (JSC::GetByIdStatus::slowVersion const): (JSC::GetByIdStatus::markIfCheap): (JSC::GetByIdStatus::finalize): (JSC::GetByIdStatus::hasExitSite): Deleted. * bytecode/GetByIdStatus.h: * bytecode/GetByIdVariant.cpp: (JSC::GetByIdVariant::markIfCheap): (JSC::GetByIdVariant::finalize): * bytecode/GetByIdVariant.h: * bytecode/ICStatusMap.cpp: Added. (JSC::ICStatusContext::get const): (JSC::ICStatusContext::isInlined const): (JSC::ICStatusContext::inlineKind const): * bytecode/ICStatusMap.h: Added. * bytecode/ICStatusUtils.cpp: Added. (JSC::hasBadCacheExitSite): * bytecode/ICStatusUtils.h: * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::computeFor): * bytecode/InstanceOfStatus.h: * bytecode/PolyProtoAccessChain.h: * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::hasExitSite): (JSC::PutByIdStatus::computeFor): (JSC::PutByIdStatus::slowVersion const): (JSC::PutByIdStatus::markIfCheap): (JSC::PutByIdStatus::finalize): (JSC::PutByIdStatus::filter): * bytecode/PutByIdStatus.h: * bytecode/PutByIdVariant.cpp: (JSC::PutByIdVariant::markIfCheap): (JSC::PutByIdVariant::finalize): * bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::structureSet const): * bytecode/RecordedStatuses.cpp: Added. (JSC::RecordedStatuses::operator=): (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::addCallLinkStatus): (JSC::RecordedStatuses::addGetByIdStatus): (JSC::RecordedStatuses::addPutByIdStatus): (JSC::RecordedStatuses::markIfCheap): (JSC::RecordedStatuses::finalizeWithoutDeleting): (JSC::RecordedStatuses::finalize): (JSC::RecordedStatuses::shrinkToFit): * bytecode/RecordedStatuses.h: Added. (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::forEachVector): * bytecode/StructureSet.cpp: (JSC::StructureSet::markIfCheap const): (JSC::StructureSet::isStillAlive const): * bytecode/StructureSet.h: * bytecode/TerminatedCodeOrigin.h: Added. (JSC::TerminatedCodeOrigin::TerminatedCodeOrigin): (JSC::TerminatedCodeOriginHashTranslator::hash): (JSC::TerminatedCodeOriginHashTranslator::equal): * bytecode/Watchpoint.cpp: (WTF::printInternal): * bytecode/Watchpoint.h: * dfg/DFGAbstractInterpreter.h: * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::handleVarargsCall): (JSC::DFG::ByteCodeParser::handleDOMJITGetter): (JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad): (JSC::DFG::ByteCodeParser::handleGetById): (JSC::DFG::ByteCodeParser::handlePutById): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): (JSC::DFG::ByteCodeParser::InlineStackEntry::~InlineStackEntry): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGClobbersExitState.cpp: (JSC::DFG::clobbersExitState): * dfg/DFGCommonData.h: * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDesiredWatchpoints.h: (JSC::DFG::SetPointerAdaptor::hasBeenInvalidated): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGMayExit.cpp: * dfg/DFGNode.h: (JSC::DFG::Node::hasCallLinkStatus): (JSC::DFG::Node::callLinkStatus): (JSC::DFG::Node::hasGetByIdStatus): (JSC::DFG::Node::getByIdStatus): (JSC::DFG::Node::hasPutByIdStatus): (JSC::DFG::Node::putByIdStatus): * dfg/DFGNodeType.h: * dfg/DFGOSRExitBase.cpp: (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow): * dfg/DFGObjectAllocationSinkingPhase.cpp: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::reallyAdd): (JSC::DFG::Plan::checkLivenessAndVisitChildren): (JSC::DFG::Plan::finalizeInGC): * dfg/DFGPlan.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::removeDeadPlans): * ftl/FTLAbstractHeapRepository.h: * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileCreateThis): (JSC::FTL::DFG::LowerDFGToB3::compileFilterICStatus): * jit/PolymorphicCallStubRoutine.cpp: (JSC::PolymorphicCallStubRoutine::hasEdges const): (JSC::PolymorphicCallStubRoutine::edges const): * jit/PolymorphicCallStubRoutine.h: * profiler/ProfilerBytecodeSequence.cpp: (JSC::Profiler::BytecodeSequence::BytecodeSequence): * runtime/FunctionRareData.cpp: (JSC::FunctionRareData::initializeObjectAllocationProfile): * runtime/Options.h: Source/WTF: * wtf/TinyPtrSet.h: (WTF::TinyPtrSet::operator!= const): Canonical link: https://commits.webkit.org/203069@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234086 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-07-22 02:48:16 +00:00
#include "StubInfoSummary.h"
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
namespace JSC {
class AccessCase;
class CodeBlock;
class StructureStubInfo;
class InstanceOfStatus final {
[WTF][JSC] Make JSC and WTF aggressively-fast-malloced https://bugs.webkit.org/show_bug.cgi?id=200611 Reviewed by Saam Barati. Source/JavaScriptCore: This patch aggressively puts many classes into FastMalloc. In JSC side, we grep `std::make_unique` etc. to find potentially system-malloc-allocated classes. After this patch, all the JSC related allocations in JetStream2 cli is done from bmalloc. In the future, it would be nice that we add `WTF::makeUnique<T>` helper function and throw a compile error if `T` is not FastMalloc annotated[1]. Putting WebKit classes in FastMalloc has many benefits. 1. Simply, it is fast. 2. vmmap can tell the amount of memory used for WebKit. 3. bmalloc can isolate WebKit memory allocation from the rest of the world. This is useful since we can know more about what component is corrupting the memory from the memory corruption crash. [1]: https://bugs.webkit.org/show_bug.cgi?id=200620 * API/ObjCCallbackFunction.mm: * assembler/AbstractMacroAssembler.h: * b3/B3PhiChildren.h: * b3/air/AirAllocateRegistersAndStackAndGenerateCode.h: * b3/air/AirDisassembler.h: * bytecode/AccessCaseSnippetParams.h: * bytecode/CallVariant.h: * bytecode/DeferredSourceDump.h: * bytecode/ExecutionCounter.h: * bytecode/GetByIdStatus.h: * bytecode/GetByIdVariant.h: * bytecode/InByIdStatus.h: * bytecode/InByIdVariant.h: * bytecode/InstanceOfStatus.h: * bytecode/InstanceOfVariant.h: * bytecode/PutByIdStatus.h: * bytecode/PutByIdVariant.h: * bytecode/ValueProfile.h: * dfg/DFGAbstractInterpreter.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::newVariableAccessData): * dfg/DFGFlowIndexing.h: * dfg/DFGFlowMap.h: * dfg/DFGLiveCatchVariablePreservationPhase.cpp: (JSC::DFG::LiveCatchVariablePreservationPhase::newVariableAccessData): * dfg/DFGMaximalFlushInsertionPhase.cpp: (JSC::DFG::MaximalFlushInsertionPhase::newVariableAccessData): * dfg/DFGOSRExit.h: * dfg/DFGSpeculativeJIT.h: * dfg/DFGVariableAccessData.h: * disassembler/ARM64/A64DOpcode.h: * inspector/remote/socket/RemoteInspectorMessageParser.h: * inspector/remote/socket/RemoteInspectorSocket.h: * inspector/remote/socket/RemoteInspectorSocketEndpoint.h: * jit/PCToCodeOriginMap.h: * runtime/BasicBlockLocation.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/JSRunLoopTimer.h: * runtime/PromiseDeferredTimer.h: (JSC::PromiseDeferredTimer::create): PromiseDeferredTimer should be allocated as `Ref<>` instead of `std::unique_ptr` since it is inheriting ThreadSafeRefCounted<>. Holding such a class with std::unique_ptr could lead to potentially dangerous operations (like, someone holds it with Ref<> while it is deleted by std::unique_ptr<>). * runtime/RandomizingFuzzerAgent.h: * runtime/SymbolTable.h: * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: * tools/JSDollarVM.cpp: * tools/SigillCrashAnalyzer.cpp: * wasm/WasmFormat.h: * wasm/WasmMemory.cpp: * wasm/WasmSignature.h: * yarr/YarrJIT.h: Source/WebCore: Changed the accessor since we changed std::unique_ptr to Ref for this field. No behavior change. * bindings/js/WorkerScriptController.cpp: (WebCore::WorkerScriptController::addTimerSetNotification): (WebCore::WorkerScriptController::removeTimerSetNotification): Source/WTF: WTF has many data structures, in particular, containers. And these containers can be allocated like `std::make_unique<Container>()`. Without WTF_MAKE_FAST_ALLOCATED, this container itself is allocated from the system malloc. This patch attaches WTF_MAKE_FAST_ALLOCATED more aggressively not to allocate them from the system malloc. And we add some `final` to containers and classes that would be never inherited. * wtf/Assertions.cpp: * wtf/Atomics.h: * wtf/AutodrainedPool.h: * wtf/Bag.h: (WTF::Bag::Bag): Deleted. (WTF::Bag::~Bag): Deleted. (WTF::Bag::clear): Deleted. (WTF::Bag::add): Deleted. (WTF::Bag::iterator::iterator): Deleted. (WTF::Bag::iterator::operator! const): Deleted. (WTF::Bag::iterator::operator* const): Deleted. (WTF::Bag::iterator::operator++): Deleted. (WTF::Bag::iterator::operator== const): Deleted. (WTF::Bag::iterator::operator!= const): Deleted. (WTF::Bag::begin): Deleted. (WTF::Bag::begin const): Deleted. (WTF::Bag::end const): Deleted. (WTF::Bag::isEmpty const): Deleted. (WTF::Bag::unwrappedHead const): Deleted. * wtf/BitVector.h: (WTF::BitVector::BitVector): Deleted. (WTF::BitVector::~BitVector): Deleted. (WTF::BitVector::operator=): Deleted. (WTF::BitVector::size const): Deleted. (WTF::BitVector::ensureSize): Deleted. (WTF::BitVector::quickGet const): Deleted. (WTF::BitVector::quickSet): Deleted. (WTF::BitVector::quickClear): Deleted. (WTF::BitVector::get const): Deleted. (WTF::BitVector::contains const): Deleted. (WTF::BitVector::set): Deleted. (WTF::BitVector::add): Deleted. (WTF::BitVector::ensureSizeAndSet): Deleted. (WTF::BitVector::clear): Deleted. (WTF::BitVector::remove): Deleted. (WTF::BitVector::merge): Deleted. (WTF::BitVector::filter): Deleted. (WTF::BitVector::exclude): Deleted. (WTF::BitVector::bitCount const): Deleted. (WTF::BitVector::isEmpty const): Deleted. (WTF::BitVector::findBit const): Deleted. (WTF::BitVector::isEmptyValue const): Deleted. (WTF::BitVector::isDeletedValue const): Deleted. (WTF::BitVector::isEmptyOrDeletedValue const): Deleted. (WTF::BitVector::operator== const): Deleted. (WTF::BitVector::hash const): Deleted. (WTF::BitVector::iterator::iterator): Deleted. (WTF::BitVector::iterator::operator* const): Deleted. (WTF::BitVector::iterator::operator++): Deleted. (WTF::BitVector::iterator::isAtEnd const): Deleted. (WTF::BitVector::iterator::operator== const): Deleted. (WTF::BitVector::iterator::operator!= const): Deleted. (WTF::BitVector::begin const): Deleted. (WTF::BitVector::end const): Deleted. (WTF::BitVector::bitsInPointer): Deleted. (WTF::BitVector::maxInlineBits): Deleted. (WTF::BitVector::byteCount): Deleted. (WTF::BitVector::makeInlineBits): Deleted. (WTF::BitVector::cleanseInlineBits): Deleted. (WTF::BitVector::bitCount): Deleted. (WTF::BitVector::findBitFast const): Deleted. (WTF::BitVector::findBitSimple const): Deleted. (WTF::BitVector::OutOfLineBits::numBits const): Deleted. (WTF::BitVector::OutOfLineBits::numWords const): Deleted. (WTF::BitVector::OutOfLineBits::bits): Deleted. (WTF::BitVector::OutOfLineBits::bits const): Deleted. (WTF::BitVector::OutOfLineBits::OutOfLineBits): Deleted. (WTF::BitVector::isInline const): Deleted. (WTF::BitVector::outOfLineBits const): Deleted. (WTF::BitVector::outOfLineBits): Deleted. (WTF::BitVector::bits): Deleted. (WTF::BitVector::bits const): Deleted. * wtf/Bitmap.h: (WTF::Bitmap::size): Deleted. (WTF::Bitmap::iterator::iterator): Deleted. (WTF::Bitmap::iterator::operator* const): Deleted. (WTF::Bitmap::iterator::operator++): Deleted. (WTF::Bitmap::iterator::operator== const): Deleted. (WTF::Bitmap::iterator::operator!= const): Deleted. (WTF::Bitmap::begin const): Deleted. (WTF::Bitmap::end const): Deleted. * wtf/Box.h: * wtf/BumpPointerAllocator.h: * wtf/CPUTime.h: * wtf/CheckedBoolean.h: * wtf/CommaPrinter.h: (WTF::CommaPrinter::CommaPrinter): Deleted. (WTF::CommaPrinter::dump const): Deleted. (WTF::CommaPrinter::didPrint const): Deleted. * wtf/CompactPointerTuple.h: (WTF::CompactPointerTuple::encodeType): Deleted. (WTF::CompactPointerTuple::decodeType): Deleted. (WTF::CompactPointerTuple::CompactPointerTuple): Deleted. (WTF::CompactPointerTuple::pointer const): Deleted. (WTF::CompactPointerTuple::setPointer): Deleted. (WTF::CompactPointerTuple::type const): Deleted. (WTF::CompactPointerTuple::setType): Deleted. * wtf/CompilationThread.h: (WTF::CompilationScope::CompilationScope): Deleted. (WTF::CompilationScope::~CompilationScope): Deleted. (WTF::CompilationScope::leaveEarly): Deleted. * wtf/CompletionHandler.h: (WTF::CompletionHandler<Out): (WTF::Detail::CallableWrapper<CompletionHandler<Out): (WTF::CompletionHandlerCallingScope::CompletionHandlerCallingScope): Deleted. (WTF::CompletionHandlerCallingScope::~CompletionHandlerCallingScope): Deleted. (WTF::CompletionHandlerCallingScope::CompletionHandler<void): Deleted. * wtf/ConcurrentBuffer.h: (WTF::ConcurrentBuffer::ConcurrentBuffer): Deleted. (WTF::ConcurrentBuffer::~ConcurrentBuffer): Deleted. (WTF::ConcurrentBuffer::growExact): Deleted. (WTF::ConcurrentBuffer::grow): Deleted. (WTF::ConcurrentBuffer::array const): Deleted. (WTF::ConcurrentBuffer::operator[]): Deleted. (WTF::ConcurrentBuffer::operator[] const): Deleted. (WTF::ConcurrentBuffer::createArray): Deleted. * wtf/ConcurrentPtrHashSet.h: (WTF::ConcurrentPtrHashSet::contains): Deleted. (WTF::ConcurrentPtrHashSet::add): Deleted. (WTF::ConcurrentPtrHashSet::size const): Deleted. (WTF::ConcurrentPtrHashSet::Table::maxLoad const): Deleted. (WTF::ConcurrentPtrHashSet::hash): Deleted. (WTF::ConcurrentPtrHashSet::cast): Deleted. (WTF::ConcurrentPtrHashSet::containsImpl const): Deleted. (WTF::ConcurrentPtrHashSet::addImpl): Deleted. * wtf/ConcurrentVector.h: (WTF::ConcurrentVector::~ConcurrentVector): Deleted. (WTF::ConcurrentVector::size const): Deleted. (WTF::ConcurrentVector::isEmpty const): Deleted. (WTF::ConcurrentVector::at): Deleted. (WTF::ConcurrentVector::at const): Deleted. (WTF::ConcurrentVector::operator[]): Deleted. (WTF::ConcurrentVector::operator[] const): Deleted. (WTF::ConcurrentVector::first): Deleted. (WTF::ConcurrentVector::first const): Deleted. (WTF::ConcurrentVector::last): Deleted. (WTF::ConcurrentVector::last const): Deleted. (WTF::ConcurrentVector::takeLast): Deleted. (WTF::ConcurrentVector::append): Deleted. (WTF::ConcurrentVector::alloc): Deleted. (WTF::ConcurrentVector::removeLast): Deleted. (WTF::ConcurrentVector::grow): Deleted. (WTF::ConcurrentVector::begin): Deleted. (WTF::ConcurrentVector::end): Deleted. (WTF::ConcurrentVector::segmentExistsFor): Deleted. (WTF::ConcurrentVector::segmentFor): Deleted. (WTF::ConcurrentVector::subscriptFor): Deleted. (WTF::ConcurrentVector::ensureSegmentsFor): Deleted. (WTF::ConcurrentVector::ensureSegment): Deleted. (WTF::ConcurrentVector::allocateSegment): Deleted. * wtf/Condition.h: (WTF::Condition::waitUntil): Deleted. (WTF::Condition::waitFor): Deleted. (WTF::Condition::wait): Deleted. (WTF::Condition::notifyOne): Deleted. (WTF::Condition::notifyAll): Deleted. * wtf/CountingLock.h: (WTF::CountingLock::LockHooks::lockHook): Deleted. (WTF::CountingLock::LockHooks::unlockHook): Deleted. (WTF::CountingLock::LockHooks::parkHook): Deleted. (WTF::CountingLock::LockHooks::handoffHook): Deleted. (WTF::CountingLock::tryLock): Deleted. (WTF::CountingLock::lock): Deleted. (WTF::CountingLock::unlock): Deleted. (WTF::CountingLock::isHeld const): Deleted. (WTF::CountingLock::isLocked const): Deleted. (WTF::CountingLock::Count::operator bool const): Deleted. (WTF::CountingLock::Count::operator== const): Deleted. (WTF::CountingLock::Count::operator!= const): Deleted. (WTF::CountingLock::tryOptimisticRead): Deleted. (WTF::CountingLock::validate): Deleted. (WTF::CountingLock::doOptimizedRead): Deleted. (WTF::CountingLock::tryOptimisticFencelessRead): Deleted. (WTF::CountingLock::fencelessValidate): Deleted. (WTF::CountingLock::doOptimizedFencelessRead): Deleted. (WTF::CountingLock::getCount): Deleted. * wtf/CrossThreadQueue.h: * wtf/CrossThreadTask.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/DataMutex.h: * wtf/DateMath.h: * wtf/Deque.h: (WTF::Deque::size const): Deleted. (WTF::Deque::isEmpty const): Deleted. (WTF::Deque::begin): Deleted. (WTF::Deque::end): Deleted. (WTF::Deque::begin const): Deleted. (WTF::Deque::end const): Deleted. (WTF::Deque::rbegin): Deleted. (WTF::Deque::rend): Deleted. (WTF::Deque::rbegin const): Deleted. (WTF::Deque::rend const): Deleted. (WTF::Deque::first): Deleted. (WTF::Deque::first const): Deleted. (WTF::Deque::last): Deleted. (WTF::Deque::last const): Deleted. (WTF::Deque::append): Deleted. * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/Expected.h: * wtf/FastBitVector.h: * wtf/FileMetadata.h: * wtf/FileSystem.h: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.h: (WTF::GregorianDateTime::GregorianDateTime): Deleted. (WTF::GregorianDateTime::year const): Deleted. (WTF::GregorianDateTime::month const): Deleted. (WTF::GregorianDateTime::yearDay const): Deleted. (WTF::GregorianDateTime::monthDay const): Deleted. (WTF::GregorianDateTime::weekDay const): Deleted. (WTF::GregorianDateTime::hour const): Deleted. (WTF::GregorianDateTime::minute const): Deleted. (WTF::GregorianDateTime::second const): Deleted. (WTF::GregorianDateTime::utcOffset const): Deleted. (WTF::GregorianDateTime::isDST const): Deleted. (WTF::GregorianDateTime::setYear): Deleted. (WTF::GregorianDateTime::setMonth): Deleted. (WTF::GregorianDateTime::setYearDay): Deleted. (WTF::GregorianDateTime::setMonthDay): Deleted. (WTF::GregorianDateTime::setWeekDay): Deleted. (WTF::GregorianDateTime::setHour): Deleted. (WTF::GregorianDateTime::setMinute): Deleted. (WTF::GregorianDateTime::setSecond): Deleted. (WTF::GregorianDateTime::setUtcOffset): Deleted. (WTF::GregorianDateTime::setIsDST): Deleted. (WTF::GregorianDateTime::operator tm const): Deleted. (WTF::GregorianDateTime::copyFrom): Deleted. * wtf/HashTable.h: * wtf/Hasher.h: * wtf/HexNumber.h: * wtf/Indenter.h: * wtf/IndexMap.h: * wtf/IndexSet.h: * wtf/IndexSparseSet.h: * wtf/IndexedContainerIterator.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/KeyValuePair.h: * wtf/ListHashSet.h: (WTF::ListHashSet::begin): Deleted. (WTF::ListHashSet::end): Deleted. (WTF::ListHashSet::begin const): Deleted. (WTF::ListHashSet::end const): Deleted. (WTF::ListHashSet::random): Deleted. (WTF::ListHashSet::random const): Deleted. (WTF::ListHashSet::rbegin): Deleted. (WTF::ListHashSet::rend): Deleted. (WTF::ListHashSet::rbegin const): Deleted. (WTF::ListHashSet::rend const): Deleted. * wtf/Liveness.h: * wtf/LocklessBag.h: (WTF::LocklessBag::LocklessBag): Deleted. (WTF::LocklessBag::add): Deleted. (WTF::LocklessBag::iterate): Deleted. (WTF::LocklessBag::consumeAll): Deleted. (WTF::LocklessBag::consumeAllWithNode): Deleted. (WTF::LocklessBag::~LocklessBag): Deleted. * wtf/LoggingHashID.h: * wtf/MD5.h: * wtf/MachSendRight.h: * wtf/MainThreadData.h: * wtf/Markable.h: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.h: * wtf/MessageQueue.h: (WTF::MessageQueue::MessageQueue): Deleted. * wtf/MetaAllocator.h: * wtf/MonotonicTime.h: (WTF::MonotonicTime::MonotonicTime): Deleted. (WTF::MonotonicTime::fromRawSeconds): Deleted. (WTF::MonotonicTime::infinity): Deleted. (WTF::MonotonicTime::nan): Deleted. (WTF::MonotonicTime::secondsSinceEpoch const): Deleted. (WTF::MonotonicTime::approximateMonotonicTime const): Deleted. (WTF::MonotonicTime::operator bool const): Deleted. (WTF::MonotonicTime::operator+ const): Deleted. (WTF::MonotonicTime::operator- const): Deleted. (WTF::MonotonicTime::operator% const): Deleted. (WTF::MonotonicTime::operator+=): Deleted. (WTF::MonotonicTime::operator-=): Deleted. (WTF::MonotonicTime::operator== const): Deleted. (WTF::MonotonicTime::operator!= const): Deleted. (WTF::MonotonicTime::operator< const): Deleted. (WTF::MonotonicTime::operator> const): Deleted. (WTF::MonotonicTime::operator<= const): Deleted. (WTF::MonotonicTime::operator>= const): Deleted. (WTF::MonotonicTime::isolatedCopy const): Deleted. (WTF::MonotonicTime::encode const): Deleted. (WTF::MonotonicTime::decode): Deleted. * wtf/NaturalLoops.h: * wtf/NoLock.h: * wtf/OSAllocator.h: * wtf/OptionSet.h: * wtf/Optional.h: * wtf/OrderMaker.h: * wtf/Packed.h: (WTF::alignof): * wtf/PackedIntVector.h: (WTF::PackedIntVector::PackedIntVector): Deleted. (WTF::PackedIntVector::operator=): Deleted. (WTF::PackedIntVector::size const): Deleted. (WTF::PackedIntVector::ensureSize): Deleted. (WTF::PackedIntVector::resize): Deleted. (WTF::PackedIntVector::clearAll): Deleted. (WTF::PackedIntVector::get const): Deleted. (WTF::PackedIntVector::set): Deleted. (WTF::PackedIntVector::mask): Deleted. * wtf/PageBlock.h: * wtf/ParallelJobsOpenMP.h: * wtf/ParkingLot.h: * wtf/PriorityQueue.h: (WTF::PriorityQueue::size const): Deleted. (WTF::PriorityQueue::isEmpty const): Deleted. (WTF::PriorityQueue::enqueue): Deleted. (WTF::PriorityQueue::peek const): Deleted. (WTF::PriorityQueue::dequeue): Deleted. (WTF::PriorityQueue::decreaseKey): Deleted. (WTF::PriorityQueue::increaseKey): Deleted. (WTF::PriorityQueue::begin const): Deleted. (WTF::PriorityQueue::end const): Deleted. (WTF::PriorityQueue::isValidHeap const): Deleted. (WTF::PriorityQueue::parentOf): Deleted. (WTF::PriorityQueue::leftChildOf): Deleted. (WTF::PriorityQueue::rightChildOf): Deleted. (WTF::PriorityQueue::siftUp): Deleted. (WTF::PriorityQueue::siftDown): Deleted. * wtf/RandomDevice.h: * wtf/Range.h: * wtf/RangeSet.h: (WTF::RangeSet::RangeSet): Deleted. (WTF::RangeSet::~RangeSet): Deleted. (WTF::RangeSet::add): Deleted. (WTF::RangeSet::contains const): Deleted. (WTF::RangeSet::overlaps const): Deleted. (WTF::RangeSet::clear): Deleted. (WTF::RangeSet::dump const): Deleted. (WTF::RangeSet::dumpRaw const): Deleted. (WTF::RangeSet::begin const): Deleted. (WTF::RangeSet::end const): Deleted. (WTF::RangeSet::addAll): Deleted. (WTF::RangeSet::compact): Deleted. (WTF::RangeSet::overlapsNonEmpty): Deleted. (WTF::RangeSet::subsumesNonEmpty): Deleted. (WTF::RangeSet::findRange const): Deleted. * wtf/RecursableLambda.h: * wtf/RedBlackTree.h: (WTF::RedBlackTree::Node::successor const): Deleted. (WTF::RedBlackTree::Node::predecessor const): Deleted. (WTF::RedBlackTree::Node::successor): Deleted. (WTF::RedBlackTree::Node::predecessor): Deleted. (WTF::RedBlackTree::Node::reset): Deleted. (WTF::RedBlackTree::Node::parent const): Deleted. (WTF::RedBlackTree::Node::setParent): Deleted. (WTF::RedBlackTree::Node::left const): Deleted. (WTF::RedBlackTree::Node::setLeft): Deleted. (WTF::RedBlackTree::Node::right const): Deleted. (WTF::RedBlackTree::Node::setRight): Deleted. (WTF::RedBlackTree::Node::color const): Deleted. (WTF::RedBlackTree::Node::setColor): Deleted. (WTF::RedBlackTree::RedBlackTree): Deleted. (WTF::RedBlackTree::insert): Deleted. (WTF::RedBlackTree::remove): Deleted. (WTF::RedBlackTree::findExact const): Deleted. (WTF::RedBlackTree::findLeastGreaterThanOrEqual const): Deleted. (WTF::RedBlackTree::findGreatestLessThanOrEqual const): Deleted. (WTF::RedBlackTree::first const): Deleted. (WTF::RedBlackTree::last const): Deleted. (WTF::RedBlackTree::size): Deleted. (WTF::RedBlackTree::isEmpty): Deleted. (WTF::RedBlackTree::treeMinimum): Deleted. (WTF::RedBlackTree::treeMaximum): Deleted. (WTF::RedBlackTree::treeInsert): Deleted. (WTF::RedBlackTree::leftRotate): Deleted. (WTF::RedBlackTree::rightRotate): Deleted. (WTF::RedBlackTree::removeFixup): Deleted. * wtf/ResourceUsage.h: * wtf/RunLoop.cpp: * wtf/RunLoopTimer.h: * wtf/SHA1.h: * wtf/Seconds.h: (WTF::Seconds::Seconds): Deleted. (WTF::Seconds::value const): Deleted. (WTF::Seconds::minutes const): Deleted. (WTF::Seconds::seconds const): Deleted. (WTF::Seconds::milliseconds const): Deleted. (WTF::Seconds::microseconds const): Deleted. (WTF::Seconds::nanoseconds const): Deleted. (WTF::Seconds::minutesAs const): Deleted. (WTF::Seconds::secondsAs const): Deleted. (WTF::Seconds::millisecondsAs const): Deleted. (WTF::Seconds::microsecondsAs const): Deleted. (WTF::Seconds::nanosecondsAs const): Deleted. (WTF::Seconds::fromMinutes): Deleted. (WTF::Seconds::fromHours): Deleted. (WTF::Seconds::fromMilliseconds): Deleted. (WTF::Seconds::fromMicroseconds): Deleted. (WTF::Seconds::fromNanoseconds): Deleted. (WTF::Seconds::infinity): Deleted. (WTF::Seconds::nan): Deleted. (WTF::Seconds::operator bool const): Deleted. (WTF::Seconds::operator+ const): Deleted. (WTF::Seconds::operator- const): Deleted. (WTF::Seconds::operator* const): Deleted. (WTF::Seconds::operator/ const): Deleted. (WTF::Seconds::operator% const): Deleted. (WTF::Seconds::operator+=): Deleted. (WTF::Seconds::operator-=): Deleted. (WTF::Seconds::operator*=): Deleted. (WTF::Seconds::operator/=): Deleted. (WTF::Seconds::operator%=): Deleted. (WTF::Seconds::operator== const): Deleted. (WTF::Seconds::operator!= const): Deleted. (WTF::Seconds::operator< const): Deleted. (WTF::Seconds::operator> const): Deleted. (WTF::Seconds::operator<= const): Deleted. (WTF::Seconds::operator>= const): Deleted. (WTF::Seconds::isolatedCopy const): Deleted. (WTF::Seconds::encode const): Deleted. (WTF::Seconds::decode): Deleted. * wtf/SegmentedVector.h: (WTF::SegmentedVector::~SegmentedVector): Deleted. (WTF::SegmentedVector::size const): Deleted. (WTF::SegmentedVector::isEmpty const): Deleted. (WTF::SegmentedVector::at): Deleted. (WTF::SegmentedVector::at const): Deleted. (WTF::SegmentedVector::operator[]): Deleted. (WTF::SegmentedVector::operator[] const): Deleted. (WTF::SegmentedVector::first): Deleted. (WTF::SegmentedVector::first const): Deleted. (WTF::SegmentedVector::last): Deleted. (WTF::SegmentedVector::last const): Deleted. (WTF::SegmentedVector::takeLast): Deleted. (WTF::SegmentedVector::append): Deleted. (WTF::SegmentedVector::alloc): Deleted. (WTF::SegmentedVector::removeLast): Deleted. (WTF::SegmentedVector::grow): Deleted. (WTF::SegmentedVector::clear): Deleted. (WTF::SegmentedVector::begin): Deleted. (WTF::SegmentedVector::end): Deleted. (WTF::SegmentedVector::shrinkToFit): Deleted. (WTF::SegmentedVector::deleteAllSegments): Deleted. (WTF::SegmentedVector::segmentExistsFor): Deleted. (WTF::SegmentedVector::segmentFor): Deleted. (WTF::SegmentedVector::subscriptFor): Deleted. (WTF::SegmentedVector::ensureSegmentsFor): Deleted. (WTF::SegmentedVector::ensureSegment): Deleted. (WTF::SegmentedVector::allocateSegment): Deleted. * wtf/SetForScope.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SmallPtrSet.h: * wtf/SpanningTree.h: * wtf/Spectrum.h: * wtf/StackBounds.h: * wtf/StackShot.h: * wtf/StackShotProfiler.h: * wtf/StackStats.h: * wtf/StackTrace.h: * wtf/StreamBuffer.h: * wtf/SynchronizedFixedQueue.h: (WTF::SynchronizedFixedQueue::create): Deleted. (WTF::SynchronizedFixedQueue::open): Deleted. (WTF::SynchronizedFixedQueue::close): Deleted. (WTF::SynchronizedFixedQueue::isOpen): Deleted. (WTF::SynchronizedFixedQueue::enqueue): Deleted. (WTF::SynchronizedFixedQueue::dequeue): Deleted. (WTF::SynchronizedFixedQueue::SynchronizedFixedQueue): Deleted. * wtf/SystemTracing.h: * wtf/ThreadGroup.h: (WTF::ThreadGroup::create): Deleted. (WTF::ThreadGroup::threads const): Deleted. (WTF::ThreadGroup::getLock): Deleted. (WTF::ThreadGroup::weakFromThis): Deleted. * wtf/ThreadSpecific.h: * wtf/ThreadingPrimitives.h: (WTF::Mutex::impl): Deleted. * wtf/TimeWithDynamicClockType.h: (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): Deleted. (WTF::TimeWithDynamicClockType::fromRawSeconds): Deleted. (WTF::TimeWithDynamicClockType::secondsSinceEpoch const): Deleted. (WTF::TimeWithDynamicClockType::clockType const): Deleted. (WTF::TimeWithDynamicClockType::withSameClockAndRawSeconds const): Deleted. (WTF::TimeWithDynamicClockType::operator bool const): Deleted. (WTF::TimeWithDynamicClockType::operator+ const): Deleted. (WTF::TimeWithDynamicClockType::operator- const): Deleted. (WTF::TimeWithDynamicClockType::operator+=): Deleted. (WTF::TimeWithDynamicClockType::operator-=): Deleted. (WTF::TimeWithDynamicClockType::operator== const): Deleted. (WTF::TimeWithDynamicClockType::operator!= const): Deleted. * wtf/TimingScope.h: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/URLParser.cpp: * wtf/URLParser.h: * wtf/Unexpected.h: * wtf/Variant.h: * wtf/WTFSemaphore.h: (WTF::Semaphore::Semaphore): Deleted. (WTF::Semaphore::signal): Deleted. (WTF::Semaphore::waitUntil): Deleted. (WTF::Semaphore::waitFor): Deleted. (WTF::Semaphore::wait): Deleted. * wtf/WallTime.h: (WTF::WallTime::WallTime): Deleted. (WTF::WallTime::fromRawSeconds): Deleted. (WTF::WallTime::infinity): Deleted. (WTF::WallTime::nan): Deleted. (WTF::WallTime::secondsSinceEpoch const): Deleted. (WTF::WallTime::approximateWallTime const): Deleted. (WTF::WallTime::operator bool const): Deleted. (WTF::WallTime::operator+ const): Deleted. (WTF::WallTime::operator- const): Deleted. (WTF::WallTime::operator+=): Deleted. (WTF::WallTime::operator-=): Deleted. (WTF::WallTime::operator== const): Deleted. (WTF::WallTime::operator!= const): Deleted. (WTF::WallTime::operator< const): Deleted. (WTF::WallTime::operator> const): Deleted. (WTF::WallTime::operator<= const): Deleted. (WTF::WallTime::operator>= const): Deleted. (WTF::WallTime::isolatedCopy const): Deleted. * wtf/WeakHashSet.h: (WTF::WeakHashSet::WeakHashSetConstIterator::WeakHashSetConstIterator): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::get const): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::operator* const): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::operator-> const): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::operator++): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::skipEmptyBuckets): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::operator== const): Deleted. (WTF::WeakHashSet::WeakHashSetConstIterator::operator!= const): Deleted. (WTF::WeakHashSet::WeakHashSet): Deleted. (WTF::WeakHashSet::begin const): Deleted. (WTF::WeakHashSet::end const): Deleted. (WTF::WeakHashSet::add): Deleted. (WTF::WeakHashSet::remove): Deleted. (WTF::WeakHashSet::contains const): Deleted. (WTF::WeakHashSet::capacity const): Deleted. (WTF::WeakHashSet::computesEmpty const): Deleted. (WTF::WeakHashSet::hasNullReferences const): Deleted. (WTF::WeakHashSet::computeSize const): Deleted. (WTF::WeakHashSet::checkConsistency const): Deleted. * wtf/WeakRandom.h: (WTF::WeakRandom::WeakRandom): Deleted. (WTF::WeakRandom::setSeed): Deleted. (WTF::WeakRandom::seed const): Deleted. (WTF::WeakRandom::get): Deleted. (WTF::WeakRandom::getUint32): Deleted. (WTF::WeakRandom::lowOffset): Deleted. (WTF::WeakRandom::highOffset): Deleted. (WTF::WeakRandom::nextState): Deleted. (WTF::WeakRandom::generate): Deleted. (WTF::WeakRandom::advance): Deleted. * wtf/WordLock.h: (WTF::WordLock::lock): Deleted. (WTF::WordLock::unlock): Deleted. (WTF::WordLock::isHeld const): Deleted. (WTF::WordLock::isLocked const): Deleted. (WTF::WordLock::isFullyReset const): Deleted. * wtf/generic/MainThreadGeneric.cpp: * wtf/glib/GMutexLocker.h: * wtf/linux/CurrentProcessMemoryStatus.h: * wtf/posix/ThreadingPOSIX.cpp: (WTF::Semaphore::Semaphore): Deleted. (WTF::Semaphore::~Semaphore): Deleted. (WTF::Semaphore::wait): Deleted. (WTF::Semaphore::post): Deleted. * wtf/text/ASCIILiteral.h: (WTF::ASCIILiteral::operator const char* const): Deleted. (WTF::ASCIILiteral::fromLiteralUnsafe): Deleted. (WTF::ASCIILiteral::null): Deleted. (WTF::ASCIILiteral::characters const): Deleted. (WTF::ASCIILiteral::ASCIILiteral): Deleted. * wtf/text/AtomString.h: (WTF::AtomString::operator=): Deleted. (WTF::AtomString::isHashTableDeletedValue const): Deleted. (WTF::AtomString::existingHash const): Deleted. (WTF::AtomString::operator const String& const): Deleted. (WTF::AtomString::string const): Deleted. (WTF::AtomString::impl const): Deleted. (WTF::AtomString::is8Bit const): Deleted. (WTF::AtomString::characters8 const): Deleted. (WTF::AtomString::characters16 const): Deleted. (WTF::AtomString::length const): Deleted. (WTF::AtomString::operator[] const): Deleted. (WTF::AtomString::contains const): Deleted. (WTF::AtomString::containsIgnoringASCIICase const): Deleted. (WTF::AtomString::find const): Deleted. (WTF::AtomString::findIgnoringASCIICase const): Deleted. (WTF::AtomString::startsWith const): Deleted. (WTF::AtomString::startsWithIgnoringASCIICase const): Deleted. (WTF::AtomString::endsWith const): Deleted. (WTF::AtomString::endsWithIgnoringASCIICase const): Deleted. (WTF::AtomString::toInt const): Deleted. (WTF::AtomString::toDouble const): Deleted. (WTF::AtomString::toFloat const): Deleted. (WTF::AtomString::percentage const): Deleted. (WTF::AtomString::isNull const): Deleted. (WTF::AtomString::isEmpty const): Deleted. (WTF::AtomString::operator NSString * const): Deleted. * wtf/text/AtomStringImpl.h: (WTF::AtomStringImpl::lookUp): Deleted. (WTF::AtomStringImpl::add): Deleted. (WTF::AtomStringImpl::addWithStringTableProvider): Deleted. * wtf/text/CString.h: (WTF::CStringBuffer::data): Deleted. (WTF::CStringBuffer::length const): Deleted. (WTF::CStringBuffer::CStringBuffer): Deleted. (WTF::CStringBuffer::mutableData): Deleted. (WTF::CString::CString): Deleted. (WTF::CString::data const): Deleted. (WTF::CString::length const): Deleted. (WTF::CString::isNull const): Deleted. (WTF::CString::buffer const): Deleted. (WTF::CString::isHashTableDeletedValue const): Deleted. * wtf/text/ExternalStringImpl.h: (WTF::ExternalStringImpl::freeExternalBuffer): Deleted. * wtf/text/LineBreakIteratorPoolICU.h: * wtf/text/NullTextBreakIterator.h: * wtf/text/OrdinalNumber.h: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.h: * wtf/text/StringConcatenateNumbers.h: * wtf/text/StringHasher.h: * wtf/text/StringImpl.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: (WTF::StringView::left const): Deleted. (WTF::StringView::right const): Deleted. (WTF::StringView::underlyingStringIsValid const): Deleted. (WTF::StringView::setUnderlyingString): Deleted. * wtf/text/SymbolImpl.h: (WTF::SymbolImpl::StaticSymbolImpl::StaticSymbolImpl): Deleted. (WTF::SymbolImpl::StaticSymbolImpl::operator SymbolImpl&): Deleted. (WTF::PrivateSymbolImpl::PrivateSymbolImpl): Deleted. (WTF::RegisteredSymbolImpl::symbolRegistry const): Deleted. (WTF::RegisteredSymbolImpl::clearSymbolRegistry): Deleted. (WTF::RegisteredSymbolImpl::RegisteredSymbolImpl): Deleted. * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.h: * wtf/text/WTFString.h: (WTF::String::swap): Deleted. (WTF::String::adopt): Deleted. (WTF::String::isNull const): Deleted. (WTF::String::isEmpty const): Deleted. (WTF::String::impl const): Deleted. (WTF::String::releaseImpl): Deleted. (WTF::String::length const): Deleted. (WTF::String::characters8 const): Deleted. (WTF::String::characters16 const): Deleted. (WTF::String::is8Bit const): Deleted. (WTF::String::sizeInBytes const): Deleted. (WTF::String::operator[] const): Deleted. (WTF::String::find const): Deleted. (WTF::String::findIgnoringASCIICase const): Deleted. (WTF::String::reverseFind const): Deleted. (WTF::String::contains const): Deleted. (WTF::String::containsIgnoringASCIICase const): Deleted. (WTF::String::startsWith const): Deleted. (WTF::String::startsWithIgnoringASCIICase const): Deleted. (WTF::String::hasInfixStartingAt const): Deleted. (WTF::String::endsWith const): Deleted. (WTF::String::endsWithIgnoringASCIICase const): Deleted. (WTF::String::hasInfixEndingAt const): Deleted. (WTF::String::append): Deleted. (WTF::String::left const): Deleted. (WTF::String::right const): Deleted. (WTF::String::createUninitialized): Deleted. (WTF::String::fromUTF8WithLatin1Fallback): Deleted. (WTF::String::isAllASCII const): Deleted. (WTF::String::isAllLatin1 const): Deleted. (WTF::String::isSpecialCharacter const): Deleted. (WTF::String::isHashTableDeletedValue const): Deleted. (WTF::String::hash const): Deleted. (WTF::String::existingHash const): Deleted. * wtf/text/cf/TextBreakIteratorCF.h: * wtf/text/icu/TextBreakIteratorICU.h: * wtf/text/icu/UTextProviderLatin1.h: * wtf/threads/BinarySemaphore.h: (WTF::BinarySemaphore::waitFor): Deleted. (WTF::BinarySemaphore::wait): Deleted. * wtf/unicode/Collator.h: * wtf/win/GDIObject.h: * wtf/win/PathWalker.h: * wtf/win/Win32Handle.h: Canonical link: https://commits.webkit.org/214396@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248546 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-12 20:57:15 +00:00
WTF_MAKE_FAST_ALLOCATED;
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
public:
enum State {
// It's uncached so we have no information.
NoInformation,
// It's cached in a simple way.
Simple,
// It's known to often take slow path.
TakesSlowPath
};
InstanceOfStatus()
: m_state(NoInformation)
{
}
InstanceOfStatus(State state)
: m_state(state)
{
ASSERT(state == NoInformation || state == TakesSlowPath);
}
We should support CreateThis in the FTL https://bugs.webkit.org/show_bug.cgi?id=164904 Reviewed by Yusuke Suzuki. JSTests: * microbenchmarks/polyvariant-get-by-id-shorter-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): * microbenchmarks/polyvariant-get-by-id-tower.js: Added. (polyvariant): (Foo.prototype.func): (Foo): (foo): (Bar.prototype.func): (Bar): (bar): (Baz.prototype.func): (Baz): (baz): Source/JavaScriptCore: This started with Saam's patch to implement CreateThis in the FTL, but turned into a type inference adventure. CreateThis in the FTL was a massive regression in raytrace because it disturbed that benchmark's extremely perverse way of winning at type inference: - The benchmark wanted polyvariant devirtualization of an object construction helper. But, the polyvariant profiler wasn't powerful enough to reliably devirtualize that code. So, the benchmark was falling back to other mechanisms... - The construction helper could not tier up into the FTL. When the DFG compiled it, it would see that the IC had 4 cases. That's too polymorphic for the DFG. So, the DFG would emit a GetById. Shortly after the DFG compile, that get_by_id would see many more cases, but now that the helper was compiled by the DFG, the baseline get_by_id would not see those cases. The DFG's GetById would "hide" those cases. The number of cases the DFG's GetById would see is larger than our polymorphic list limit (limit = 8, case count = 13, I think). Note that if the FTL compiles that construction helper, it sees the 4 cases, turns them into a MultiGetByOffset, then suffers from exits when the new cases hit, and then exits to baseline, which then sees those cases. Luckily, the FTL was not compiling the construction helper because it had a CreateThis. - Compilations that inlined the construction helper would have gotten super lucky with parse-time constant folding, so they knew what structure the input to the get_by_id would have at parse time. This is only profitable if the get_by_id parsing computed a GetByIdStatus that had a finite number of cases. Because the 13 cases were being hidden by the DFG GetById and GetByIdStatus would only look at the baseline get_by_id, which had 4 cases, we would indeed get a finite number of cases. The parser would then prune those cases to just one - based on its knowledge of the structure - and that would result in that get_by_id being folded at parse time to a constant. - The subsequent op_call would inline based on parse-time knowledge of that constant. This patch comprehensively fixes these issues, as well as other issues that come up along the way. The short version is that raytrace was revealing sloppiness in our use of profiling for type inference. This patch fixes the sloppiness by vastly expanding *polyvariant* profiling, i.e. the profiling that considers call context. I was encouraged to do this by the fact that even the old version of polyvariant profiling was a speed-up on JetStream, ARES-6, and Speedometer 2 (it's easy to measure since it's a runtime flag). So, it seemed worthwhile to attack raytrace's problem as a shortcoming of polyvariant profiling. - Polyvariant profiling now consults every DFG or FTL code block that participated in any subset of the inline stack that includes the IC we're profiling. For example, if we have an inline stack like foo->bar->baz, with baz on top, then we will consult DFG or FTL compilations for foo, bar, and baz. In foo, we'll look up foo->bar->baz; in bar we'll look up bar->baz; etc. This fixes two problems encountered in raytrace. First, it ensures that a DFG GetById cannot hide anything from the profiling of that get_by_id, since the polyvariant profiling code will always consult it. Second, it enables raytrace to benefit from polyvariant profling. Previously, the polyvariant profiler would only look at the previous DFG compilation of foo and look up foo->bar->baz. But that only works if DFG-foo had inlined bar and then baz. It may not have done that, because those calls could have required polyvariant profiling that was only available in the FTL. - A particularly interesting case is when some IC in foo-baseline is also available in foo-DFG. This case is encountered by the polyvariant profiler as it walks the inline stack. In the case of gathering profiling for foo-FTL, the polyvariant profiler finds foo-DFG via the trivial case of no inline stack. This also means that if foo ever gets inlined, we will find foo-DFG or foo-FTL in the final case of polyvariant profiling. In those cases, we now merge the IC of foo-baseline and foo-DFG. This avoids lots of unnecessary recompilations, because it warns us of historical polymorphism. Historical polymorphism usually means future polymorphism. IC status code already had some merging functionality, but I needed to beef it up a lot to make this work right. - Inlining an inline cache now preserves as much information as profiling. One challenge of polyvariant profiling is that the FTL compile for bar (that includes bar->baz) could have inlined an inline cache based on polyvariant profiling. So, when the FTL compile for foo (that includes foo->bar->baz) asks bar what it knows about that IC inside bar->baz, it will say "I don't have such an IC". At this point the DFG compilation that included that IC that gave us the information that we used to inline the IC is no longer alive. To keep us from losing the information we learned about the IC, there is now a RecordedStatuses data structure that preserves the statuses we use for inlining ICs. We also filter those statuses according to things we learn from AI. This further reduces the risk of information about an IC being forgotten. - Exit profiling now considers whether or not an exit happened from inline code. This protects us in the case where the not-inlined version of an IC exited a lot because of polymorphism that doesn't exist in the inlined version. So, when using polyvariant profiling data, we consider only inlined exits. - CallLinkInfo now records when it's repatched to the virtual call thunk. Previously, this would clear the CallLinkInfo, so CallLinkStatus would fall back to the lastSeenCallee. It's surprising that we've had this bug. Altogether this patch is performance-neutral in run-jsc-benchmarks, except for speed-ups in microbenchmarks and a compile time regression. Octane/deltablue speeds up by ~5%. Octane/raytrace is regressed by a minuscule amount, which we could make up by implementing prototype access folding in the bytecode parser and constant folder. That would require some significant new logic in GetByIdStatus. That would also require a new benchmark - we want to have a test that captures raytrace's behavior in the case that the parser cannot fold the get_by_id. This change is a 1.2% regression on V8Spider-CompileTime. That's a smaller regression than recent compile time progressions, so I think that's an OK trade-off. Also, I would expect a compile time regression anytime we fill in FTL coverage. This is neutral on JetStream, ARES-6, and Speedometer2. JetStream agrees that deltablue speeds up and that raytrace slows down, but these changes balance out and don't affect the overall score. In ARES-6, it looks like individual tests have some significant 1-2% speed-ups or slow-downs. Air-steady is definitely ~1.5% faster. Basic-worst is probably 2% slower (p ~ 0.1, so it's not very certain). The JetStream, ARES-6, and Speedometer2 overall scores don't see a significant difference. In all three cases the difference is <0.5% with a high p value, with JetStream and Speedometer2 being insignificant infinitesimal speed-ups and ARES-6 being an insignificant infinitesimal slow-down. Oh, and this change means that the FTL now has 100% coverage of JavaScript. You could do an eval in a for-in loop in a for-of loop inside a with block that uses try/catch for control flow in a polymorphic constructor while having a bad time, and we'll still compile it. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/ByValInfo.h: * bytecode/BytecodeDumper.cpp: (JSC::BytecodeDumper<Block>::printGetByIdCacheStatus): (JSC::BytecodeDumper<Block>::printPutByIdCacheStatus): (JSC::BytecodeDumper<Block>::printInByIdCacheStatus): (JSC::BytecodeDumper<Block>::dumpCallLinkStatus): (JSC::BytecodeDumper<CodeBlock>::dumpCallLinkStatus): (JSC::BytecodeDumper<Block>::printCallOp): (JSC::BytecodeDumper<Block>::dumpBytecode): (JSC::BytecodeDumper<Block>::dumpBlock): * bytecode/BytecodeDumper.h: * bytecode/CallLinkInfo.h: * bytecode/CallLinkStatus.cpp: (JSC::CallLinkStatus::computeFor): (JSC::CallLinkStatus::computeExitSiteData): (JSC::CallLinkStatus::computeFromCallLinkInfo): (JSC::CallLinkStatus::accountForExits): (JSC::CallLinkStatus::finalize): (JSC::CallLinkStatus::filter): (JSC::CallLinkStatus::computeDFGStatuses): Deleted. * bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::operator bool const): (JSC::CallLinkStatus::operator! const): Deleted. * bytecode/CallVariant.cpp: (JSC::CallVariant::finalize): (JSC::CallVariant::filter): * bytecode/CallVariant.h: (JSC::CallVariant::operator bool const): (JSC::CallVariant::operator! const): Deleted. * bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): (JSC::CodeBlock::propagateTransitions): (JSC::CodeBlock::finalizeUnconditionally): (JSC::CodeBlock::getICStatusMap): (JSC::CodeBlock::resetJITData): (JSC::CodeBlock::getStubInfoMap): Deleted. (JSC::CodeBlock::getCallLinkInfoMap): Deleted. (JSC::CodeBlock::getByValInfoMap): Deleted. * bytecode/CodeBlock.h: * bytecode/CodeOrigin.cpp: (JSC::CodeOrigin::isApproximatelyEqualTo const): (JSC::CodeOrigin::approximateHash const): * bytecode/CodeOrigin.h: (JSC::CodeOrigin::exitingInlineKind const): * bytecode/DFGExitProfile.cpp: (JSC::DFG::FrequentExitSite::dump const): (JSC::DFG::ExitProfile::add): * bytecode/DFGExitProfile.h: (JSC::DFG::FrequentExitSite::FrequentExitSite): (JSC::DFG::FrequentExitSite::operator== const): (JSC::DFG::FrequentExitSite::subsumes const): (JSC::DFG::FrequentExitSite::hash const): (JSC::DFG::FrequentExitSite::inlineKind const): (JSC::DFG::FrequentExitSite::withInlineKind const): (JSC::DFG::QueryableExitProfile::hasExitSite const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificJITType const): (JSC::DFG::QueryableExitProfile::hasExitSiteWithSpecificInlineKind const): * bytecode/ExitFlag.cpp: Added. (JSC::ExitFlag::dump const): * bytecode/ExitFlag.h: Added. (JSC::ExitFlag::ExitFlag): (JSC::ExitFlag::operator| const): (JSC::ExitFlag::operator|=): (JSC::ExitFlag::operator& const): (JSC::ExitFlag::operator&=): (JSC::ExitFlag::operator bool const): (JSC::ExitFlag::isSet const): * bytecode/ExitingInlineKind.cpp: Added. (WTF::printInternal): * bytecode/ExitingInlineKind.h: Added. * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::computeFor): (JSC::GetByIdStatus::computeForStubInfo): (JSC::GetByIdStatus::slowVersion const): (JSC::GetByIdStatus::markIfCheap): (JSC::GetByIdStatus::finalize): (JSC::GetByIdStatus::hasExitSite): Deleted. * bytecode/GetByIdStatus.h: * bytecode/GetByIdVariant.cpp: (JSC::GetByIdVariant::markIfCheap): (JSC::GetByIdVariant::finalize): * bytecode/GetByIdVariant.h: * bytecode/ICStatusMap.cpp: Added. (JSC::ICStatusContext::get const): (JSC::ICStatusContext::isInlined const): (JSC::ICStatusContext::inlineKind const): * bytecode/ICStatusMap.h: Added. * bytecode/ICStatusUtils.cpp: Added. (JSC::hasBadCacheExitSite): * bytecode/ICStatusUtils.h: * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::computeFor): * bytecode/InstanceOfStatus.h: * bytecode/PolyProtoAccessChain.h: * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::hasExitSite): (JSC::PutByIdStatus::computeFor): (JSC::PutByIdStatus::slowVersion const): (JSC::PutByIdStatus::markIfCheap): (JSC::PutByIdStatus::finalize): (JSC::PutByIdStatus::filter): * bytecode/PutByIdStatus.h: * bytecode/PutByIdVariant.cpp: (JSC::PutByIdVariant::markIfCheap): (JSC::PutByIdVariant::finalize): * bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::structureSet const): * bytecode/RecordedStatuses.cpp: Added. (JSC::RecordedStatuses::operator=): (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::addCallLinkStatus): (JSC::RecordedStatuses::addGetByIdStatus): (JSC::RecordedStatuses::addPutByIdStatus): (JSC::RecordedStatuses::markIfCheap): (JSC::RecordedStatuses::finalizeWithoutDeleting): (JSC::RecordedStatuses::finalize): (JSC::RecordedStatuses::shrinkToFit): * bytecode/RecordedStatuses.h: Added. (JSC::RecordedStatuses::RecordedStatuses): (JSC::RecordedStatuses::forEachVector): * bytecode/StructureSet.cpp: (JSC::StructureSet::markIfCheap const): (JSC::StructureSet::isStillAlive const): * bytecode/StructureSet.h: * bytecode/TerminatedCodeOrigin.h: Added. (JSC::TerminatedCodeOrigin::TerminatedCodeOrigin): (JSC::TerminatedCodeOriginHashTranslator::hash): (JSC::TerminatedCodeOriginHashTranslator::equal): * bytecode/Watchpoint.cpp: (WTF::printInternal): * bytecode/Watchpoint.h: * dfg/DFGAbstractInterpreter.h: * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::handleVarargsCall): (JSC::DFG::ByteCodeParser::handleDOMJITGetter): (JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad): (JSC::DFG::ByteCodeParser::handleGetById): (JSC::DFG::ByteCodeParser::handlePutById): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): (JSC::DFG::ByteCodeParser::InlineStackEntry::~InlineStackEntry): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGClobbersExitState.cpp: (JSC::DFG::clobbersExitState): * dfg/DFGCommonData.h: * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDesiredWatchpoints.h: (JSC::DFG::SetPointerAdaptor::hasBeenInvalidated): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGMayExit.cpp: * dfg/DFGNode.h: (JSC::DFG::Node::hasCallLinkStatus): (JSC::DFG::Node::callLinkStatus): (JSC::DFG::Node::hasGetByIdStatus): (JSC::DFG::Node::getByIdStatus): (JSC::DFG::Node::hasPutByIdStatus): (JSC::DFG::Node::putByIdStatus): * dfg/DFGNodeType.h: * dfg/DFGOSRExitBase.cpp: (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow): * dfg/DFGObjectAllocationSinkingPhase.cpp: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::reallyAdd): (JSC::DFG::Plan::checkLivenessAndVisitChildren): (JSC::DFG::Plan::finalizeInGC): * dfg/DFGPlan.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::removeDeadPlans): * ftl/FTLAbstractHeapRepository.h: * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileCreateThis): (JSC::FTL::DFG::LowerDFGToB3::compileFilterICStatus): * jit/PolymorphicCallStubRoutine.cpp: (JSC::PolymorphicCallStubRoutine::hasEdges const): (JSC::PolymorphicCallStubRoutine::edges const): * jit/PolymorphicCallStubRoutine.h: * profiler/ProfilerBytecodeSequence.cpp: (JSC::Profiler::BytecodeSequence::BytecodeSequence): * runtime/FunctionRareData.cpp: (JSC::FunctionRareData::initializeObjectAllocationProfile): * runtime/Options.h: Source/WTF: * wtf/TinyPtrSet.h: (WTF::TinyPtrSet::operator!= const): Canonical link: https://commits.webkit.org/203069@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234086 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-07-22 02:48:16 +00:00
explicit InstanceOfStatus(StubInfoSummary summary)
{
switch (summary) {
case StubInfoSummary::NoInformation:
m_state = NoInformation;
return;
case StubInfoSummary::Simple:
case StubInfoSummary::MakesCalls:
RELEASE_ASSERT_NOT_REACHED();
return;
case StubInfoSummary::TakesSlowPath:
case StubInfoSummary::TakesSlowPathAndMakesCalls:
m_state = TakesSlowPath;
return;
}
RELEASE_ASSERT_NOT_REACHED();
}
BytecodeIndex should be a proper C++ class https://bugs.webkit.org/show_bug.cgi?id=203276 Reviewed by Mark Lam. This patch makes a change to how we refer to the bytecode index in a bytecode stream. Previously we just used an unsigned number to represent the index, this patch changes most of the code to use a BytecodeIndex class instead. The only places where this patch does not change this is for jump and switch targets / deltas. Additionally, this patch attempts to canonicalize the terminology around how we refer to bytecode indices. Now we use the word index to refer to the bytecode index class and offset to refer to the unsigned byte offset into the instruction stream. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/ByValInfo.h: (JSC::ByValInfo::ByValInfo): (JSC::getByValInfoBytecodeIndex): * bytecode/BytecodeBasicBlock.cpp: (JSC::BytecodeBasicBlock::computeImpl): * bytecode/BytecodeGeneratorification.cpp: (JSC::GeneratorLivenessAnalysis::run): * bytecode/BytecodeIndex.cpp: Added. (JSC::BytecodeIndex::dump const): * bytecode/BytecodeIndex.h: Added. (JSC::BytecodeIndex::BytecodeIndex): (JSC::BytecodeIndex::offset const): (JSC::BytecodeIndex::asBits const): (JSC::BytecodeIndex::hash const): (JSC::BytecodeIndex::deletedValue): (JSC::BytecodeIndex::isHashTableDeletedValue const): (JSC::BytecodeIndex::operator bool const): (JSC::BytecodeIndex::operator == const): (JSC::BytecodeIndex::operator != const): (JSC::BytecodeIndex::operator < const): (JSC::BytecodeIndex::operator > const): (JSC::BytecodeIndex::operator <= const): (JSC::BytecodeIndex::operator >= const): (JSC::BytecodeIndex::fromBits): (JSC::BytecodeIndexHash::hash): (JSC::BytecodeIndexHash::equal): * bytecode/BytecodeLivenessAnalysis.cpp: (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeIndex): (JSC::BytecodeLivenessAnalysis::computeFullLiveness): (JSC::BytecodeLivenessAnalysis::computeKills): (JSC::BytecodeLivenessAnalysis::dumpResults): (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset): Deleted. * bytecode/BytecodeLivenessAnalysis.h: * bytecode/BytecodeLivenessAnalysisInlines.h: (JSC::BytecodeLivenessPropagation::stepOverInstruction): (JSC::BytecodeLivenessPropagation::computeLocalLivenessForBytecodeIndex): (JSC::BytecodeLivenessPropagation::computeLocalLivenessForBlock): (JSC::BytecodeLivenessPropagation::getLivenessInfoAtBytecodeIndex): (JSC::BytecodeLivenessPropagation::computeLocalLivenessForBytecodeOffset): Deleted. (JSC::BytecodeLivenessPropagation::getLivenessInfoAtBytecodeOffset): Deleted. * bytecode/BytecodeUseDef.h: (JSC::computeUsesForBytecodeIndex): (JSC::computeDefsForBytecodeIndex): (JSC::computeUsesForBytecodeOffset): Deleted. (JSC::computeDefsForBytecodeOffset): Deleted. * bytecode/CallLinkStatus.cpp: (JSC::CallLinkStatus::computeFromLLInt): (JSC::CallLinkStatus::computeFor): (JSC::CallLinkStatus::computeExitSiteData): * bytecode/CallLinkStatus.h: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex): (JSC::CodeBlock::addRareCaseProfile): (JSC::CodeBlock::rareCaseProfileForBytecodeIndex): (JSC::CodeBlock::rareCaseProfileCountForBytecodeIndex): (JSC::CodeBlock::handlerForBytecodeIndex): (JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeIndex): (JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeIndexSlow): (JSC::CodeBlock::lineNumberForBytecodeIndex): (JSC::CodeBlock::columnNumberForBytecodeIndex): (JSC::CodeBlock::expressionRangeForBytecodeIndex const): (JSC::CodeBlock::hasOpDebugForLineAndColumn): (JSC::CodeBlock::getArrayProfile): (JSC::CodeBlock::tryGetValueProfileForBytecodeIndex): (JSC::CodeBlock::valueProfilePredictionForBytecodeIndex): (JSC::CodeBlock::valueProfileForBytecodeIndex): (JSC::CodeBlock::validate): (JSC::CodeBlock::arithProfileForBytecodeIndex): (JSC::CodeBlock::couldTakeSpecialArithFastCase): (JSC::CodeBlock::bytecodeIndexFromCallSiteIndex): (JSC::CodeBlock::rareCaseProfileForBytecodeOffset): Deleted. (JSC::CodeBlock::rareCaseProfileCountForBytecodeOffset): Deleted. (JSC::CodeBlock::handlerForBytecodeOffset): Deleted. (JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeOffset): Deleted. (JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeOffsetSlow): Deleted. (JSC::CodeBlock::lineNumberForBytecodeOffset): Deleted. (JSC::CodeBlock::columnNumberForBytecodeOffset): Deleted. (JSC::CodeBlock::expressionRangeForBytecodeOffset const): Deleted. (JSC::CodeBlock::tryGetValueProfileForBytecodeOffset): Deleted. (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset): Deleted. (JSC::CodeBlock::valueProfileForBytecodeOffset): Deleted. (JSC::CodeBlock::arithProfileForBytecodeOffset): Deleted. (JSC::CodeBlock::couldTakeSpecialFastCase): Deleted. (JSC::CodeBlock::bytecodeOffsetFromCallSiteIndex): Deleted. * bytecode/CodeBlock.h: (JSC::CodeBlock::likelyToTakeSlowCase): (JSC::CodeBlock::couldTakeSlowCase): (JSC::CodeBlock::bytecodeIndex): * bytecode/CodeOrigin.cpp: (JSC::CodeOrigin::approximateHash const): (JSC::CodeOrigin::dump const): * bytecode/CodeOrigin.h: (JSC::CodeOrigin::CodeOrigin): (JSC::CodeOrigin::isSet const): (JSC::CodeOrigin::isHashTableDeletedValue const): (JSC::CodeOrigin::bytecodeIndex const): (JSC::CodeOrigin::OutOfLineCodeOrigin::OutOfLineCodeOrigin): (JSC::CodeOrigin::buildCompositeValue): (JSC::CodeOrigin::hash const): * bytecode/DFGExitProfile.cpp: (JSC::DFG::FrequentExitSite::dump const): (JSC::DFG::ExitProfile::exitSitesFor): * bytecode/DFGExitProfile.h: (JSC::DFG::FrequentExitSite::FrequentExitSite): (JSC::DFG::FrequentExitSite::operator== const): (JSC::DFG::FrequentExitSite::subsumes const): (JSC::DFG::FrequentExitSite::hash const): (JSC::DFG::FrequentExitSite::bytecodeIndex const): (JSC::DFG::FrequentExitSite::isHashTableDeletedValue const): (JSC::DFG::QueryableExitProfile::hasExitSite const): (JSC::DFG::FrequentExitSite::bytecodeOffset const): Deleted. * bytecode/DeferredSourceDump.cpp: (JSC::DeferredSourceDump::DeferredSourceDump): (JSC::DeferredSourceDump::dump): * bytecode/DeferredSourceDump.h: (): Deleted. * bytecode/FullBytecodeLiveness.h: (JSC::FullBytecodeLiveness::getLiveness const): (JSC::FullBytecodeLiveness::operandIsLive const): * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::computeFromLLInt): (JSC::GetByIdStatus::computeFor): (JSC::GetByIdStatus::computeForStubInfo): * bytecode/GetByIdStatus.h: * bytecode/ICStatusUtils.cpp: (JSC::hasBadCacheExitSite): * bytecode/ICStatusUtils.h: * bytecode/InByIdStatus.cpp: (JSC::InByIdStatus::computeFor): * bytecode/InByIdStatus.h: * bytecode/InlineCallFrame.cpp: (JSC::InlineCallFrame::dumpInContext const): * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::computeFor): * bytecode/InstanceOfStatus.h: * bytecode/InstructionStream.h: (JSC::InstructionStream::BaseRef::offset const): (JSC::InstructionStream::BaseRef::index const): (JSC::InstructionStream::at const): * bytecode/LazyOperandValueProfile.h: (JSC::LazyOperandValueProfileKey::LazyOperandValueProfileKey): (JSC::LazyOperandValueProfileKey::operator== const): (JSC::LazyOperandValueProfileKey::hash const): (JSC::LazyOperandValueProfileKey::bytecodeIndex const): (JSC::LazyOperandValueProfileKey::isHashTableDeletedValue const): (JSC::LazyOperandValueProfileKey::bytecodeOffset const): Deleted. * bytecode/MethodOfGettingAValueProfile.cpp: (JSC::MethodOfGettingAValueProfile::fromLazyOperand): * bytecode/MethodOfGettingAValueProfile.h: * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::computeFromLLInt): (JSC::PutByIdStatus::computeFor): * bytecode/PutByIdStatus.h: * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/UnlinkedCodeBlock.cpp: (JSC::UnlinkedCodeBlock::lineNumberForBytecodeIndex): (JSC::UnlinkedCodeBlock::expressionRangeForBytecodeIndex const): (JSC::UnlinkedCodeBlock::handlerForBytecodeIndex): (JSC::UnlinkedCodeBlock::lineNumberForBytecodeOffset): Deleted. (JSC::UnlinkedCodeBlock::expressionRangeForBytecodeOffset const): Deleted. (JSC::UnlinkedCodeBlock::handlerForBytecodeOffset): Deleted. * bytecode/UnlinkedCodeBlock.h: * bytecode/ValueProfile.h: (JSC::RareCaseProfile::RareCaseProfile): (JSC::getRareCaseProfileBytecodeIndex): (JSC::getRareCaseProfileBytecodeOffset): Deleted. * bytecompiler/BytecodeGenerator.cpp: (JSC::ForInContext::finalize): * debugger/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::currentPosition): * dfg/DFGBasicBlock.cpp: (JSC::DFG::BasicBlock::BasicBlock): * dfg/DFGBasicBlock.h: (JSC::DFG::getBytecodeBeginForBlock): (JSC::DFG::blockForBytecodeIndex): (JSC::DFG::blockForBytecodeOffset): Deleted. * dfg/DFGBlockInsertionSet.cpp: (JSC::DFG::BlockInsertionSet::insert): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::flushForTerminalImpl): (JSC::DFG::ByteCodeParser::flushIfTerminal): (JSC::DFG::ByteCodeParser::branchData): (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit): (JSC::DFG::ByteCodeParser::getPrediction): (JSC::DFG::ByteCodeParser::getArrayMode): (JSC::DFG::ByteCodeParser::makeSafe): (JSC::DFG::ByteCodeParser::makeDivSafe): (JSC::DFG::ByteCodeParser::allocateTargetableBlock): (JSC::DFG::ByteCodeParser::allocateUntargetableBlock): (JSC::DFG::ByteCodeParser::makeBlockTargetable): (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::handleRecursiveTailCall): (JSC::DFG::ByteCodeParser::inlineCall): (JSC::DFG::ByteCodeParser::handleCallVariant): (JSC::DFG::ByteCodeParser::handleInlining): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::linkBlock): (JSC::DFG::ByteCodeParser::parseCodeBlock): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::addCodeOrigin): (JSC::DFG::CommonData::addUniqueCallSiteIndex): (JSC::DFG::CommonData::lastCallSite const): * dfg/DFGCommonData.h: (JSC::DFG::CommonData::catchOSREntryDataForBytecodeIndex): (JSC::DFG::CommonData::appendCatchEntrypoint): * dfg/DFGDriver.cpp: (JSC::DFG::compileImpl): (JSC::DFG::compile): * dfg/DFGDriver.h: * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): (JSC::DFG::Graph::methodOfGettingAValueProfileFor): (JSC::DFG::Graph::willCatchExceptionInMachineFrame): * dfg/DFGGraph.h: * dfg/DFGJITCode.cpp: (JSC::DFG::JITCode::clearOSREntryBlockAndResetThresholds): * dfg/DFGJITCode.h: (JSC::DFG::JITCode::appendOSREntryData): (JSC::DFG::JITCode::osrEntryDataForBytecodeIndex): * dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::JITCompiler): (JSC::DFG::JITCompiler::compile): (JSC::DFG::JITCompiler::compileFunction): * dfg/DFGJITCompiler.h: (JSC::DFG::JITCompiler::setStartOfCode): * dfg/DFGLiveCatchVariablePreservationPhase.cpp: (JSC::DFG::LiveCatchVariablePreservationPhase::handleBlockForTryCatch): * dfg/DFGOSREntry.cpp: (JSC::DFG::OSREntryData::dumpInContext const): (JSC::DFG::prepareOSREntry): (JSC::DFG::prepareCatchOSREntry): * dfg/DFGOSREntry.h: (JSC::DFG::getOSREntryDataBytecodeIndex): (JSC::DFG::prepareOSREntry): * dfg/DFGOSREntrypointCreationPhase.cpp: (JSC::DFG::OSREntrypointCreationPhase::run): * dfg/DFGOSRExit.cpp: (JSC::DFG::OSRExit::executeOSRExit): (JSC::DFG::reifyInlinedCallFrames): (JSC::DFG::adjustAndJumpToTarget): (JSC::DFG::printOSRExit): (JSC::DFG::OSRExit::compileExit): (JSC::DFG::OSRExit::debugOperationPrintSpeculationFailure): * dfg/DFGOSRExit.h: * dfg/DFGOSRExitCompilerCommon.cpp: (JSC::DFG::callerReturnPC): (JSC::DFG::reifyInlinedCallFrames): (JSC::DFG::adjustAndJumpToTarget): * dfg/DFGOSRExitCompilerCommon.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::Plan): (JSC::DFG::Plan::compileInThreadImpl): (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGPlan.h: (JSC::DFG::Plan::osrEntryBytecodeIndex const): (JSC::DFG::Plan::tierUpInLoopHierarchy): (JSC::DFG::Plan::tierUpAndOSREnterBytecodes): * dfg/DFGSSAConversionPhase.cpp: (JSC::DFG::SSAConversionPhase::run): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileCurrentBlock): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::compileValueAdd): (JSC::DFG::SpeculativeJIT::compileValueSub): (JSC::DFG::SpeculativeJIT::compileValueNegate): (JSC::DFG::SpeculativeJIT::compileValueMul): (JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGTierUpCheckInjectionPhase.cpp: (JSC::DFG::TierUpCheckInjectionPhase::run): (JSC::DFG::TierUpCheckInjectionPhase::buildNaturalLoopToLoopHintMap): * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp: (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete): * dfg/DFGValidate.cpp: * ftl/FTLCompile.cpp: (JSC::FTL::compile): * ftl/FTLForOSREntryJITCode.h: (JSC::FTL::ForOSREntryJITCode::setBytecodeIndex): (JSC::FTL::ForOSREntryJITCode::bytecodeIndex const): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::lower): (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub): (JSC::FTL::DFG::LowerDFGToB3::compileValueNegate): * ftl/FTLOSREntry.cpp: (JSC::FTL::prepareOSREntry): * ftl/FTLOSREntry.h: * interpreter/CallFrame.cpp: (JSC::CallFrame::callSiteIndex const): (JSC::CallFrame::unsafeCallSiteIndex const): (JSC::CallFrame::setCurrentVPC): (JSC::CallFrame::bytecodeIndex): (JSC::CallFrame::codeOrigin): (JSC::CallFrame::dump): (JSC::CallFrame::bytecodeOffset): Deleted. * interpreter/CallFrame.h: (JSC::CallSiteIndex::CallSiteIndex): (JSC::CallSiteIndex::operator bool const): (JSC::CallSiteIndex::operator== const): (JSC::CallSiteIndex::bits const): (JSC::CallSiteIndex::bytecodeIndex const): (JSC::DisposableCallSiteIndex::DisposableCallSiteIndex): (): Deleted. * interpreter/Interpreter.cpp: (JSC::GetStackTraceFunctor::operator() const): (JSC::findExceptionHandler): * interpreter/ShadowChicken.cpp: (JSC::ShadowChicken::update): * interpreter/StackVisitor.cpp: (JSC::StackVisitor::readNonInlinedFrame): (JSC::StackVisitor::readInlinedFrame): (JSC::StackVisitor::Frame::retrieveExpressionInfo const): (JSC::StackVisitor::Frame::dump const): * interpreter/StackVisitor.h: (JSC::StackVisitor::Frame::bytecodeIndex const): (JSC::StackVisitor::Frame::bytecodeOffset const): Deleted. * jit/JIT.cpp: (JSC::JIT::JIT): (JSC::JIT::emitEnterOptimizationCheck): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::compileWithoutLinking): (JSC::JIT::link): (JSC::JIT::privateCompileExceptionHandlers): * jit/JIT.h: (JSC::CallRecord::CallRecord): (JSC::SlowCaseEntry::SlowCaseEntry): (JSC::SwitchRecord::SwitchRecord): (JSC::ByValCompilationInfo::ByValCompilationInfo): * jit/JITCall.cpp: (JSC::JIT::compileCallEvalSlowCase): (JSC::JIT::compileOpCall): * jit/JITCodeMap.h: (JSC::JITCodeMap::Entry::Entry): (JSC::JITCodeMap::Entry::bytecodeIndex const): (JSC::JITCodeMap::append): (JSC::JITCodeMap::find const): * jit/JITDisassembler.cpp: (JSC::JITDisassembler::dumpVectorForInstructions): (JSC::JITDisassembler::reportInstructions): * jit/JITDisassembler.h: * jit/JITInlines.h: (JSC::JIT::emitNakedCall): (JSC::JIT::emitNakedTailCall): (JSC::JIT::updateTopCallFrame): (JSC::JIT::linkAllSlowCasesForBytecodeIndex): (JSC::JIT::addSlowCase): (JSC::JIT::addJump): (JSC::JIT::emitJumpSlowToHot): (JSC::JIT::emitGetVirtualRegister): (JSC::JIT::linkAllSlowCasesForBytecodeOffset): Deleted. * jit/JITOpcodes.cpp: (JSC::JIT::emit_op_instanceof): (JSC::JIT::emit_op_catch): (JSC::JIT::emit_op_switch_imm): (JSC::JIT::emit_op_switch_char): (JSC::JIT::emit_op_switch_string): (JSC::JIT::emitSlow_op_loop_hint): (JSC::JIT::emit_op_has_indexed_property): (JSC::JIT::emit_op_log_shadow_chicken_tail): * jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_instanceof): (JSC::JIT::emit_op_catch): (JSC::JIT::emit_op_switch_imm): (JSC::JIT::emit_op_switch_char): (JSC::JIT::emit_op_switch_string): (JSC::JIT::emit_op_has_indexed_property): * jit/JITOperations.cpp: (JSC::getByVal): (JSC::tryGetByValOptimize): * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_get_by_val): (JSC::JIT::emitGetByValWithCachedId): (JSC::JIT::emit_op_put_by_val): (JSC::JIT::emitPutByValWithCachedId): (JSC::JIT::emit_op_try_get_by_id): (JSC::JIT::emit_op_get_by_id_direct): (JSC::JIT::emit_op_get_by_id): (JSC::JIT::emit_op_get_by_id_with_this): (JSC::JIT::emit_op_put_by_id): (JSC::JIT::emit_op_in_by_id): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::Plan): (JSC::JITWorklist::Plan::compileNow): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::compileNow): * jit/JITWorklist.h: * jit/PCToCodeOriginMap.cpp: (JSC::PCToCodeOriginMap::PCToCodeOriginMap): (JSC::PCToCodeOriginMap::findPC const): * jit/PCToCodeOriginMap.h: (JSC::PCToCodeOriginMapBuilder::defaultCodeOrigin): * jit/SlowPathCall.h: (JSC::JITSlowPathCall::call): * llint/LLIntSlowPaths.cpp: (JSC::LLInt::jitCompileAndSetHeuristics): (JSC::LLInt::LLINT_SLOW_PATH_DECL): * profiler/ProfilerOrigin.cpp: (JSC::Profiler::Origin::Origin): (JSC::Profiler::Origin::dump const): (JSC::Profiler::Origin::toJS const): * profiler/ProfilerOrigin.h: (JSC::Profiler::Origin::Origin): (JSC::Profiler::Origin::operator! const): (JSC::Profiler::Origin::bytecodeIndex const): (JSC::Profiler::Origin::hash const): (JSC::Profiler::Origin::isHashTableDeletedValue const): * runtime/Error.cpp: (JSC::getBytecodeIndex): (JSC::getBytecodeOffset): Deleted. * runtime/Error.h: * runtime/ErrorInstance.cpp: (JSC::appendSourceToError): (JSC::ErrorInstance::finishCreation): * runtime/SamplingProfiler.cpp: (JSC::tryGetBytecodeIndex): (JSC::SamplingProfiler::processUnverifiedStackTraces): (JSC::SamplingProfiler::reportTopBytecodes): * runtime/SamplingProfiler.h: (JSC::SamplingProfiler::StackFrame::CodeLocation::hasBytecodeIndex const): * runtime/StackFrame.cpp: (JSC::StackFrame::StackFrame): (JSC::StackFrame::computeLineAndColumn const): * runtime/StackFrame.h: (JSC::StackFrame::hasBytecodeIndex const): (JSC::StackFrame::bytecodeIndex): (JSC::StackFrame::hasBytecodeOffset const): Deleted. (JSC::StackFrame::bytecodeOffset): Deleted. * tools/VMInspector.cpp: (JSC::VMInspector::dumpRegisters): Canonical link: https://commits.webkit.org/216705@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251468 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-23 00:55:38 +00:00
static InstanceOfStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex);
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
#if ENABLE(DFG_JIT)
[JSC] Hold StructureID instead of Structure* in PolyProtoAccessChain and DFG::CommonData https://bugs.webkit.org/show_bug.cgi?id=207086 Reviewed by Mark Lam. PolyProtoAccessChain and DFG::CommonData are kept alive so long as associated AccessCase / DFG/FTL CodeBlock is alive. They hold Vector<Structure*> / Vector<WriteBarrier<Structure*>>, but access frequency is low. And We should hold Vector<StructureID> instead to cut 50% of the size. * bytecode/AccessCase.cpp: (JSC::AccessCase::commit): (JSC::AccessCase::forEachDependentCell const): (JSC::AccessCase::doesCalls const): (JSC::AccessCase::visitWeak const): (JSC::AccessCase::propagateTransitions const): (JSC::AccessCase::generateWithGuard): * bytecode/AccessCase.h: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::propagateTransitions): (JSC::CodeBlock::determineLiveness): (JSC::CodeBlock::stronglyVisitWeakReferences): * bytecode/GetByStatus.cpp: (JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback): * bytecode/InByIdStatus.cpp: (JSC::InByIdStatus::computeFor): (JSC::InByIdStatus::computeForStubInfo): (JSC::InByIdStatus::computeForStubInfoWithoutExitSiteFeedback): * bytecode/InByIdStatus.h: * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): * bytecode/InstanceOfStatus.h: * bytecode/PolyProtoAccessChain.cpp: (JSC::PolyProtoAccessChain::create): (JSC::PolyProtoAccessChain::needImpurePropertyWatchpoint const): (JSC::PolyProtoAccessChain::dump const): * bytecode/PolyProtoAccessChain.h: (JSC::PolyProtoAccessChain::chain const): (JSC::PolyProtoAccessChain::forEach const): (JSC::PolyProtoAccessChain::slotBaseStructure const): (JSC::PolyProtoAccessChain:: const): Deleted. * bytecode/PolymorphicAccess.cpp: (JSC::PolymorphicAccess::regenerate): * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::computeForStubInfo): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::summary const): (JSC::StructureStubInfo::summary): * bytecode/StructureStubInfo.h: * dfg/DFGCommonData.h: * dfg/DFGDesiredWeakReferences.cpp: (JSC::DFG::DesiredWeakReferences::reallyAdd): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::finalizeWithoutNotifyingCallback): * jit/Repatch.cpp: (JSC::tryCacheGetBy): (JSC::tryCachePutByID): (JSC::tryCacheInByID): Canonical link: https://commits.webkit.org/220098@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@255542 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-01 06:18:18 +00:00
static InstanceOfStatus computeForStubInfo(const ConcurrentJSLocker&, VM&, StructureStubInfo*);
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
#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; }
bool takesSlowPath() const { return m_state == TakesSlowPath; }
JSObject* commonPrototype() const;
size_t numVariants() const { return m_variants.size(); }
const Vector<InstanceOfVariant, 2>& variants() const { return m_variants; }
const InstanceOfVariant& at(size_t index) const { return m_variants[index]; }
const InstanceOfVariant& operator[](size_t index) const { return at(index); }
void filter(const StructureSet&);
void dump(PrintStream&) const;
private:
void appendVariant(const InstanceOfVariant&);
[JSC] Shrink some of Vectors in JSC https://bugs.webkit.org/show_bug.cgi?id=224162 Reviewed by Simon Fraser. Source/JavaScriptCore: 1. Add XXXStatus::shrinkToFit to shrink underlying dynamic Vectors. 2. Replace tierUpInLoopHierarchy's Vector with RefCountedArray since it is constructed-once-lookup-only data. 3. Use MemoryCompactLookupOnlyRobinHoodHashSet for StringTables since this is constructed-once-lookup-only data. We also add MemoryCompactLookupOnlyRobinHoodHashSet support for CachedTypes. 4. Use resizeToFit for StringSwitchJumpTables and SwitchJumpTables. 5. JITStubRoutineSet's Vector should be shrunk. 6. BlockDirectoryBits's Vector's initial size should be small. 7. Make PolyProtoAccessChain RefCounted, and use RefCountedArray for its Vector<StructureID>. And remove PolyProtoAccessChain::clone. Just having Ref is enough since this is immutable data. 8. Use RefCountedArray for UnlinkedFunctionExecutable's m_classFieldLocations. 9. Use RefCountedArray for JSWebAssemblyInstance. * bytecode/AccessCase.cpp: (JSC::AccessCase::AccessCase): (JSC::AccessCase::create): (JSC::AccessCase::createTransition): * bytecode/AccessCase.h: (JSC::AccessCase::AccessCase): Deleted. * bytecode/CallLinkInfo.cpp: (JSC::CallLinkInfo::setFrameShuffleData): * bytecode/CheckPrivateBrandStatus.cpp: (JSC::CheckPrivateBrandStatus::shrinkToFit): (JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback): (JSC::CheckPrivateBrandStatus::merge): * bytecode/CheckPrivateBrandStatus.h: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::finishCreation): * bytecode/DeleteByStatus.cpp: (JSC::DeleteByStatus::shrinkToFit): (JSC::DeleteByStatus::computeForStubInfoWithoutExitSiteFeedback): (JSC::DeleteByStatus::merge): * bytecode/DeleteByStatus.h: * bytecode/GetByStatus.cpp: (JSC::GetByStatus::shrinkToFit): (JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback): (JSC::GetByStatus::computeFor): (JSC::GetByStatus::merge): * bytecode/GetByStatus.h: * bytecode/GetterSetterAccessCase.cpp: (JSC::GetterSetterAccessCase::GetterSetterAccessCase): (JSC::GetterSetterAccessCase::create): * bytecode/GetterSetterAccessCase.h: * bytecode/InByIdStatus.cpp: (JSC::InByIdStatus::shrinkToFit): (JSC::InByIdStatus::computeForStubInfoWithoutExitSiteFeedback): (JSC::InByIdStatus::merge): * bytecode/InByIdStatus.h: * bytecode/InstanceOfStatus.cpp: (JSC::InstanceOfStatus::shrinkToFit): (JSC::InstanceOfStatus::computeForStubInfo): * bytecode/InstanceOfStatus.h: * bytecode/IntrinsicGetterAccessCase.cpp: (JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase): (JSC::IntrinsicGetterAccessCase::create): * bytecode/IntrinsicGetterAccessCase.h: * bytecode/JumpTable.h: * bytecode/PolyProtoAccessChain.cpp: (JSC::PolyProtoAccessChain::tryCreate): (JSC::PolyProtoAccessChain::create): Deleted. * bytecode/PolyProtoAccessChain.h: (JSC::PolyProtoAccessChain::clone): Deleted. (JSC::PolyProtoAccessChain::chain const): Deleted. (JSC::PolyProtoAccessChain::operator!= const): Deleted. (JSC::PolyProtoAccessChain::forEach const): Deleted. (JSC::PolyProtoAccessChain::slotBaseStructure const): Deleted. * bytecode/PolymorphicAccess.cpp: (JSC::PolymorphicAccess::visitWeak const): (JSC::PolymorphicAccess::regenerate): * bytecode/PolymorphicAccess.h: * bytecode/ProxyableAccessCase.cpp: (JSC::ProxyableAccessCase::ProxyableAccessCase): (JSC::ProxyableAccessCase::create): * bytecode/ProxyableAccessCase.h: * bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::shrinkToFit): (JSC::PutByIdStatus::computeForStubInfo): (JSC::PutByIdStatus::computeFor): (JSC::PutByIdStatus::merge): * bytecode/PutByIdStatus.h: * bytecode/SetPrivateBrandStatus.cpp: (JSC::SetPrivateBrandStatus::shrinkToFit): (JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback): (JSC::SetPrivateBrandStatus::merge): * bytecode/SetPrivateBrandStatus.h: * bytecode/UnlinkedCodeBlock.h: * bytecode/UnlinkedFunctionExecutable.cpp: (JSC::generateUnlinkedFunctionCodeBlock): * bytecode/UnlinkedFunctionExecutable.h: * dfg/DFGJITCode.h: * dfg/DFGPlan.h: (JSC::DFG::Plan::tierUpInLoopHierarchy): * dfg/DFGTierUpCheckInjectionPhase.cpp: (JSC::DFG::TierUpCheckInjectionPhase::run): * heap/BlockDirectoryBits.h: * heap/JITStubRoutineSet.cpp: (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): * jit/CallFrameShuffleData.h: (JSC::CallFrameShuffleData::shrinkToFit): * jit/GCAwareJITStubRoutine.h: * jit/PolymorphicCallStubRoutine.h: * jit/Repatch.cpp: (JSC::tryCacheGetBy): (JSC::tryCachePutByID): (JSC::tryCacheInByID): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseInner): (JSC::Parser<LexerType>::parseClassFieldInitializerSourceElements): * parser/Parser.h: (JSC::Parser<LexerType>::parse): (JSC::parse): * runtime/CachedTypes.cpp: (JSC::CachedFunctionExecutableRareData::encode): (JSC::CachedFunctionExecutableRareData::decode const): * runtime/VM.cpp: (JSC::VM::popAllCheckpointOSRSideStateUntil): * wasm/js/JSWebAssemblyInstance.cpp: (JSC::JSWebAssemblyInstance::visitChildrenImpl): * wasm/js/JSWebAssemblyInstance.h: Source/WTF: Add rbegin and rend to make RefCountedArray usable for Vector clients who use these features. * wtf/RefCountedArray.h: (WTF::RefCountedArray::begin): (WTF::RefCountedArray::end): (WTF::RefCountedArray::begin const): (WTF::RefCountedArray::end const): (WTF::RefCountedArray::rbegin): (WTF::RefCountedArray::rend): (WTF::RefCountedArray::rbegin const): (WTF::RefCountedArray::rend const): Canonical link: https://commits.webkit.org/236147@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275490 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-06 04:25:33 +00:00
void shrinkToFit();
DFG should inline InstanceOf ICs https://bugs.webkit.org/show_bug.cgi?id=185695 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then be folded to a CheckStructure + JSConstant. In the process of testing this, I found a bug where LICM was not hoisting things that depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching LICM how to materialize CheckNotEmpty on demand whenever !HoistingFailed. This is a ~5% speed-up on boyer. ~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and instanceof-sometimes-hit microbenchmarks. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::appendVariant): (JSC::GetByIdStatus::filter): * bytecode/GetByIdStatus.h: (JSC::GetByIdStatus::operator bool const): (JSC::GetByIdStatus::operator! const): Deleted. * bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::operator bool const): (JSC::GetByIdVariant::operator! const): Deleted. * bytecode/ICStatusUtils.h: Added. (JSC::appendICStatusVariant): (JSC::filterICStatusVariants): * bytecode/InstanceOfStatus.cpp: Added. (JSC::InstanceOfStatus::appendVariant): (JSC::InstanceOfStatus::computeFor): (JSC::InstanceOfStatus::computeForStubInfo): (JSC::InstanceOfStatus::commonPrototype const): (JSC::InstanceOfStatus::filter): * bytecode/InstanceOfStatus.h: Added. (JSC::InstanceOfStatus::InstanceOfStatus): (JSC::InstanceOfStatus::state const): (JSC::InstanceOfStatus::isSet const): (JSC::InstanceOfStatus::operator bool const): (JSC::InstanceOfStatus::isSimple const): (JSC::InstanceOfStatus::takesSlowPath const): (JSC::InstanceOfStatus::numVariants const): (JSC::InstanceOfStatus::variants const): (JSC::InstanceOfStatus::at const): (JSC::InstanceOfStatus::operator[] const): * bytecode/InstanceOfVariant.cpp: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::attemptToMerge): (JSC::InstanceOfVariant::dump const): (JSC::InstanceOfVariant::dumpInContext const): * bytecode/InstanceOfVariant.h: Added. (JSC::InstanceOfVariant::InstanceOfVariant): (JSC::InstanceOfVariant::operator bool const): (JSC::InstanceOfVariant::structureSet const): (JSC::InstanceOfVariant::structureSet): (JSC::InstanceOfVariant::conditionSet const): (JSC::InstanceOfVariant::prototype const): (JSC::InstanceOfVariant::isHit const): * bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::StructureStubInfo): * bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::considerCaching): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: * dfg/DFGLICMPhase.cpp: (JSC::DFG::LICMPhase::attemptHoist): * dfg/DFGNode.cpp: (JSC::DFG::Node::remove): * dfg/DFGNode.h: (JSC::DFG::Node::hasMatchStructureData): (JSC::DFG::Node::matchStructureData): * dfg/DFGNodeType.h: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileMatchStructure): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure): Source/WTF: I found myself needing a way to represent bottom/false/true/top, so I created it. * WTF.xcodeproj/project.pbxproj: * wtf/BooleanLattice.h: Added. (WTF::lubBooleanLattice): (WTF::printInternal): * wtf/CMakeLists.txt: Canonical link: https://commits.webkit.org/201263@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-19 22:00:21 +00:00
State m_state;
Vector<InstanceOfVariant, 2> m_variants;
};
} // namespace JSC