2021-05-26 15:15:22 +00:00
|
|
|
// Copyright (C) 2017-2021 Apple Inc. All rights reserved.
|
2017-10-18 19:14:51 +00:00
|
|
|
//
|
|
|
|
// 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
2017-09-20 23:08:50 +00:00
|
|
|
|
2019-01-14 20:27:17 +00:00
|
|
|
API/JSAPIGlobalObject.cpp
|
2018-09-13 13:39:55 +00:00
|
|
|
API/JSAPIValueWrapper.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
API/JSBase.cpp
|
|
|
|
API/JSCTestRunnerUtils.cpp
|
|
|
|
API/JSCallbackConstructor.cpp
|
|
|
|
API/JSCallbackFunction.cpp
|
|
|
|
API/JSCallbackObject.cpp
|
|
|
|
API/JSClassRef.cpp
|
|
|
|
API/JSContextRef.cpp
|
|
|
|
API/JSHeapFinalizerPrivate.cpp
|
2020-12-10 23:10:36 +00:00
|
|
|
API/JSLockRef.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
API/JSMarkingConstraintPrivate.cpp
|
|
|
|
API/JSObjectRef.cpp
|
|
|
|
API/JSTypedArray.cpp
|
|
|
|
API/JSScriptRef.cpp
|
|
|
|
API/JSStringRef.cpp
|
|
|
|
API/JSValueRef.cpp
|
|
|
|
API/JSWeakObjectMapRefPrivate.cpp
|
|
|
|
API/JSWeakPrivate.cpp
|
2018-03-28 09:16:15 +00:00
|
|
|
API/JSWeakValue.cpp
|
2020-03-15 10:16:52 +00:00
|
|
|
API/MarkedJSValueRefArray.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
API/OpaqueJSString.cpp
|
|
|
|
|
|
|
|
assembler/AbstractMacroAssembler.cpp
|
Experiment: create lots of different malloc zones for easier accounting of memory use
https://bugs.webkit.org/show_bug.cgi?id=186422
Patch by Yusuke Suzuki <ysuzuki@apple.com> and Simon Fraser <simon.fraser@apple.com> on 2020-01-02
Reviewed by Saam Barati.
Source/bmalloc:
* bmalloc/BPlatform.h:
* bmalloc/Environment.cpp:
(bmalloc::Environment::computeIsDebugHeapEnabled):
* bmalloc/IsoHeap.h:
(bmalloc::api::IsoHeap::IsoHeap):
* bmalloc/IsoHeapInlines.h:
(bmalloc::api::IsoHeap<Type>::IsoHeap):
* bmalloc/IsoTLSInlines.h:
(bmalloc::IsoTLS::allocateSlow):
(bmalloc::IsoTLS::deallocateSlow):
Source/JavaScriptCore:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/AssemblerBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* assembler/AssemblerBuffer.h:
(JSC::AssemblerData::AssemblerData):
(JSC::AssemblerData::operator=):
(JSC::AssemblerData::~AssemblerData):
(JSC::AssemblerData::grow):
* bytecode/AccessCase.cpp:
* bytecode/AccessCase.h:
* bytecode/BytecodeBasicBlock.cpp:
* bytecode/BytecodeBasicBlock.h:
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* bytecode/InstructionStream.cpp:
* bytecode/InstructionStream.h:
* bytecode/PolymorphicAccess.cpp:
* bytecode/PolymorphicAccess.h:
* bytecode/UnlinkedMetadataTable.cpp:
(JSC::UnlinkedMetadataTable::finalize):
* bytecode/UnlinkedMetadataTable.h:
* bytecode/UnlinkedMetadataTableInlines.h:
(JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::~UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::link):
(JSC::UnlinkedMetadataTable::unlink):
* bytecode/ValueProfile.h:
(JSC::ValueProfileAndVirtualRegisterBuffer::ValueProfileAndVirtualRegisterBuffer):
* bytecode/Watchpoint.cpp:
* bytecode/Watchpoint.h:
* dfg/DFGBasicBlock.cpp:
* dfg/DFGBasicBlock.h:
* dfg/DFGNode.cpp:
* dfg/DFGNode.h:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
* heap/BlockDirectory.cpp:
* heap/BlockDirectory.h:
* heap/FastMallocAlignedMemoryAllocator.cpp:
(JSC::FastMallocAlignedMemoryAllocator::FastMallocAlignedMemoryAllocator):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryReallocateMemory):
* heap/FastMallocAlignedMemoryAllocator.h:
* heap/GCSegmentedArray.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* heap/GCSegmentedArray.h:
* heap/GCSegmentedArrayInlines.h:
(JSC::GCArraySegment<T>::create):
(JSC::GCArraySegment<T>::destroy):
* heap/GigacageAlignedMemoryAllocator.cpp:
(JSC::GigacageAlignedMemoryAllocator::GigacageAlignedMemoryAllocator):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::freeAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateMemory):
(JSC::GigacageAlignedMemoryAllocator::freeMemory):
(JSC::GigacageAlignedMemoryAllocator::tryReallocateMemory):
* heap/GigacageAlignedMemoryAllocator.h:
* heap/IsoAlignedMemoryAllocator.cpp:
(JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::freeAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::tryAllocateMemory):
(JSC::IsoAlignedMemoryAllocator::freeMemory):
* heap/IsoAlignedMemoryAllocator.h:
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
* heap/MarkedBlock.cpp:
* heap/MarkedBlock.h:
* heap/WeakBlock.cpp:
(JSC::WeakBlock::create):
(JSC::WeakBlock::destroy):
* heap/WeakBlock.h:
* jit/JITCode.cpp:
* jit/JITCode.h:
* jit/RegisterAtOffsetList.cpp:
* jit/RegisterAtOffsetList.h:
* parser/Nodes.cpp:
* parser/Nodes.h:
* parser/ParserArena.cpp:
(JSC::ParserArena::deallocateObjects):
(JSC::ParserArena::allocateFreeablePool):
* parser/ParserArena.h:
* parser/SourceProvider.cpp:
* parser/SourceProvider.h:
* parser/SourceProviderCache.cpp:
* parser/SourceProviderCache.h:
* parser/SourceProviderCacheItem.h:
(JSC::SourceProviderCacheItem::create):
* runtime/CachePayload.cpp:
(JSC::CachePayload::makeMallocPayload):
* runtime/CachePayload.h:
* runtime/CachedBytecode.h:
(JSC::CachedBytecode::create):
* runtime/CachedTypes.cpp:
(JSC::Encoder::release):
(JSC::Encoder::Page::Page):
(JSC::CachedVector::encode):
(JSC::CachedVector::decode const):
(JSC::CachedInstructionStream::decode const):
* runtime/PropertyMapHashTable.h:
(JSC::PropertyTable::rehash):
* runtime/PropertyTable.cpp:
(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::~PropertyTable):
* runtime/SymbolTable.cpp:
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::ScratchBuffer::create):
(JSC::VM::exceptionFuzzingBuffer):
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
* wasm/WasmInstance.h:
* wasm/WasmTable.cpp:
(JSC::Wasm::Table::Table):
(JSC::Wasm::FuncRefTable::FuncRefTable):
* wasm/WasmTable.h:
Source/WebCore:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/SerializedScriptValue.cpp:
* bindings/js/SerializedScriptValue.h:
* css/CSSFontFace.cpp:
* css/CSSFontFace.h:
* css/CSSSelector.cpp:
* css/CSSSelector.h:
* css/CSSValue.cpp:
* css/CSSValue.h:
* css/StyleProperties.cpp:
(WebCore::ImmutableStyleProperties::create):
* css/StyleProperties.h:
* css/StyleRule.cpp:
* css/StyleRule.h:
* dom/ElementData.cpp:
(WebCore::ShareableElementData::createWithAttributes):
(WebCore::UniqueElementData::makeShareableCopy const):
* dom/ElementData.h:
* dom/NodeRareData.cpp:
* dom/NodeRareData.h:
* dom/QualifiedName.cpp:
* dom/QualifiedName.h:
* html/parser/HTMLDocumentParser.cpp:
* html/parser/HTMLDocumentParser.h:
* loader/DocumentLoader.cpp:
* loader/DocumentLoader.h:
* loader/ResourceLoader.cpp:
* loader/ResourceLoader.h:
* loader/cache/CachedResource.cpp:
* loader/cache/CachedResource.h:
* page/PerformanceEntry.cpp:
* page/PerformanceEntry.h:
* platform/graphics/Font.cpp:
* platform/graphics/Font.h:
* platform/graphics/FontCascadeFonts.cpp:
* platform/graphics/FontCascadeFonts.h:
* platform/graphics/Region.cpp:
* platform/graphics/Region.h:
* platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
(WebCore::releaseUint8Vector):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/nicosia/NicosiaBuffer.cpp:
(Nicosia::Buffer::Buffer):
* platform/network/ResourceHandle.cpp:
* platform/network/ResourceHandleInternal.h:
* platform/network/cf/FormDataStreamCFNet.cpp:
(WebCore::closeCurrentStream):
(WebCore::advanceCurrentStream):
* rendering/RenderLayer.cpp:
* rendering/RenderLayer.h:
* rendering/TableLayout.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* rendering/TableLayout.h:
* rendering/style/RenderStyle.cpp:
* rendering/style/RenderStyle.h:
* rendering/style/SVGRenderStyle.cpp:
* rendering/style/SVGRenderStyle.h:
* rendering/style/SVGRenderStyleDefs.cpp:
* rendering/style/SVGRenderStyleDefs.h:
* rendering/style/StyleBoxData.cpp:
* rendering/style/StyleBoxData.h:
* rendering/style/StyleInheritedData.cpp:
* rendering/style/StyleInheritedData.h:
* rendering/style/StyleRareInheritedData.cpp:
* rendering/style/StyleRareInheritedData.h:
* rendering/style/StyleRareNonInheritedData.cpp:
* rendering/style/StyleRareNonInheritedData.h:
* rendering/style/StyleSurroundData.cpp:
* rendering/style/StyleSurroundData.h:
* rendering/style/StyleTransformData.cpp:
* rendering/style/StyleTransformData.h:
* style/StyleTreeResolver.cpp:
* style/StyleTreeResolver.h:
* svg/animation/SMILTimeContainer.cpp:
* svg/animation/SMILTimeContainer.h:
Source/WebKit:
* Shared/ShareableBitmap.cpp:
(WebKit::ShareableBitmap::create):
(WebKit::ShareableBitmap::~ShareableBitmap):
* UIProcess/mac/LegacySessionStateCoding.cpp:
(WebKit::HistoryEntryDataEncoder::HistoryEntryDataEncoder):
(WebKit::HistoryEntryDataEncoder::finishEncoding):
(WebKit::encodeSessionHistoryEntryData):
(WebKit::encodeLegacySessionState):
Source/WTF:
This patch introduces ENABLE(MALLOC_HEAP_BREAKDOWN). If this is enabled, we allocate malloc_zone per malloc kind.
This offers the way to investigate the usage of memory per kind by using vmmap, like the following.
VIRTUAL RESIDENT DIRTY SWAPPED ALLOCATION BYTES DIRTY+SWAP REGION
MALLOC ZONE SIZE SIZE SIZE SIZE COUNT ALLOCATED FRAG SIZE % FRAG COUNT
=========== ======= ========= ========= ========= ========= ========= ========= ====== ======
StringImpl_0x116efd000 188.0M 69.3M 30.9M 0K 139456 18.0M 12.9M 42% 34
DefaultMallocZone_0x10f487000 176.0M 53.9M 14.1M 0K 115956 9955K 4497K 32% 22
Vector_0x116eff000 162.0M 56.3M 55.3M 0K 140715 17.3M 37.9M 69% 36
MetadataTable_0x11843b000 152.0M 17.5M 17.5M 0K 14200 2353K 15.2M 87% 26
WebKit Using System Malloc_0x114cbe000 150.0M 31.6M 21.8M 0K 87422 16.7M 5278K 24% 23
InstructionStream_0x118469000 150.0M 5764K 5764K 0K 14470 4688K 1076K 19% 24
AssemblerData_0x117ee6000 150.0M 1928K 1928K 0K 1 16 1928K 100% 24
To achieve this goal without making very large change, we put a template type in various containers.
For example, Vector will take Malloc parameter (the default one is FastMalloc allocator). If ENABLE(MALLOC_HEAP_BREAKDOWN) is enabled, we change this to
specific VectorMalloc allocator, and vmmap can show memory usage of this allocator. This patch also supports malloc_zone per IsoHeap. So we can see memory
allocation per IsoHeap in vmmap.
To use this feature, we need to flip two compile time flags, ENABLE(MALLOC_HEAP_BREAKDOWN) in WTF and BENABLE_MALLOC_HEAP_BREAKDOWN in bmalloc.
And use `vmmap $PID` to dump malloc zones. To allocate objects of a class with a specific malloc-zone, use WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(HeapIdentifier) for the class,
and define allocator by DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a header and DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a cpp file.
This patch also introduce callstack collector for malloc. Vector, HashMap etc. are used to allocate various things, but the above malloc_zone feature only tells thing like "Vector
takes XXX MB memory". But what we want to know in this case is what Vector is consuming memory. We collect StackShot for each malloc call, and combine these information to tell
which callsite is consuming much memory, which tell us that what Vector is consuming memory.
* WTF.xcodeproj/project.pbxproj:
* wtf/Bag.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/Bag.h:
(WTF::Private::BagNode::BagNode): Deleted.
* wtf/BitVector.cpp:
(WTF::BitVector::OutOfLineBits::create):
(WTF::BitVector::OutOfLineBits::destroy):
* wtf/CMakeLists.txt:
* wtf/ConcurrentBuffer.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/ConcurrentBuffer.h:
* wtf/DebugHeap.cpp: Copied from Source/JavaScriptCore/runtime/CachePayload.cpp.
(WTF::DebugHeap::DebugHeap):
(WTF::DebugHeap::malloc):
(WTF::DebugHeap::calloc):
(WTF::DebugHeap::memalign):
(WTF::DebugHeap::realloc):
(WTF::DebugHeap::free):
* wtf/DebugHeap.h: Added.
* wtf/FastBitVector.cpp:
(WTF::FastBitVectorWordOwner::setEqualsSlow):
(WTF::FastBitVectorWordOwner::resizeSlow):
* wtf/FastBitVector.h:
(WTF::FastBitVectorWordOwner::~FastBitVectorWordOwner):
* wtf/FastMalloc.cpp:
(WTF::fastMallocDumpMallocStats):
(WTF::AvoidRecordingScope::AvoidRecordingScope):
(WTF::AvoidRecordingScope::~AvoidRecordingScope):
(WTF::MallocCallTracker::MallocSiteData::MallocSiteData):
(WTF::MallocCallTracker::singleton):
(WTF::MallocCallTracker::MallocCallTracker):
(WTF::MallocCallTracker::recordMalloc):
(WTF::MallocCallTracker::recordRealloc):
(WTF::MallocCallTracker::recordFree):
(WTF::MallocCallTracker::dumpStats):
(WTF::fastMalloc):
(WTF::fastRealloc):
(WTF::fastFree):
(WTF::fastAlignedMalloc):
(WTF::tryFastAlignedMalloc):
(WTF::fastAlignedFree):
* wtf/FastMalloc.h:
(WTF::FastMalloc::zeroedMalloc):
(WTF::FastMalloc::tryZeroedMalloc):
* wtf/Forward.h:
* wtf/HashTable.cpp:
* wtf/HashTable.h:
(WTF::KeyTraits>::allocateTable):
(WTF::KeyTraits>::deallocateTable):
(WTF::KeyTraits>::rehash):
* wtf/MallocPtr.h:
(WTF::MallocPtr::MallocPtr):
(WTF::MallocPtr::malloc):
(WTF::MallocPtr::zeroedMalloc):
(WTF::MallocPtr::tryMalloc):
(WTF::MallocPtr::tryZeroedMalloc):
(WTF::adoptMallocPtr):
* wtf/MetaAllocator.cpp:
(WTF::MetaAllocator::allocFreeSpaceNode):
(WTF::MetaAllocator::freeFreeSpaceNode):
* wtf/MetaAllocatorHandle.h:
* wtf/Platform.h:
* wtf/RefCountedArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/RefCountedArray.h:
(WTF::RefCountedArray::RefCountedArray):
(WTF::RefCountedArray::~RefCountedArray):
(WTF::RefCountedArray::assign):
* wtf/SegmentedVector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SegmentedVector.h:
* wtf/SmallPtrSet.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SmallPtrSet.h:
(WTF::SmallPtrSet::~SmallPtrSet):
(WTF::SmallPtrSet::grow):
* wtf/UniqueArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/UniqueArray.h:
(WTF::UniqueArrayFree::operator() const):
(WTF::UniqueArrayFree<T::operator() const):
* wtf/Vector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/Vector.h:
(WTF::VectorBufferBase::allocateBuffer):
(WTF::VectorBufferBase::tryAllocateBuffer):
(WTF::VectorBufferBase::reallocateBuffer):
(WTF::VectorBufferBase::deallocateBuffer):
(WTF::VectorBufferBase::releaseBuffer):
(WTF::VectorBuffer::releaseBuffer):
(WTF::Vector::swap):
(WTF::Malloc>::Vector):
(WTF::=):
(WTF::Malloc>::contains const):
(WTF::Malloc>::findMatching const):
(WTF::Malloc>::find const):
(WTF::Malloc>::reverseFind const):
(WTF::Malloc>::appendIfNotContains):
(WTF::Malloc>::fill):
(WTF::Malloc>::appendRange):
(WTF::Malloc>::expandCapacity):
(WTF::Malloc>::tryExpandCapacity):
(WTF::Malloc>::resize):
(WTF::Malloc>::resizeToFit):
(WTF::Malloc>::shrink):
(WTF::Malloc>::grow):
(WTF::Malloc>::asanSetInitialBufferSizeTo):
(WTF::Malloc>::asanSetBufferSizeToFullCapacity):
(WTF::Malloc>::asanBufferSizeWillChangeTo):
(WTF::Malloc>::reserveCapacity):
(WTF::Malloc>::tryReserveCapacity):
(WTF::Malloc>::reserveInitialCapacity):
(WTF::Malloc>::shrinkCapacity):
(WTF::Malloc>::append):
(WTF::Malloc>::tryAppend):
(WTF::Malloc>::constructAndAppend):
(WTF::Malloc>::tryConstructAndAppend):
(WTF::Malloc>::appendSlowCase):
(WTF::Malloc>::constructAndAppendSlowCase):
(WTF::Malloc>::tryConstructAndAppendSlowCase):
(WTF::Malloc>::uncheckedAppend):
(WTF::Malloc>::uncheckedConstructAndAppend):
(WTF::Malloc>::appendVector):
(WTF::Malloc>::insert):
(WTF::Malloc>::insertVector):
(WTF::Malloc>::remove):
(WTF::Malloc>::removeFirst):
(WTF::Malloc>::removeFirstMatching):
(WTF::Malloc>::removeAll):
(WTF::Malloc>::removeAllMatching):
(WTF::Malloc>::reverse):
(WTF::Malloc>::map const):
(WTF::Malloc>::releaseBuffer):
(WTF::Malloc>::checkConsistency):
(WTF::swap):
(WTF::operator==):
(WTF::operator!=):
(WTF::Malloc>::isolatedCopy const):
(WTF::removeRepeatedElements):
(WTF::minCapacity>::Vector): Deleted.
(WTF::minCapacity>::contains const): Deleted.
(WTF::minCapacity>::findMatching const): Deleted.
(WTF::minCapacity>::find const): Deleted.
(WTF::minCapacity>::reverseFind const): Deleted.
(WTF::minCapacity>::appendIfNotContains): Deleted.
(WTF::minCapacity>::fill): Deleted.
(WTF::minCapacity>::appendRange): Deleted.
(WTF::minCapacity>::expandCapacity): Deleted.
(WTF::minCapacity>::tryExpandCapacity): Deleted.
(WTF::minCapacity>::resize): Deleted.
(WTF::minCapacity>::resizeToFit): Deleted.
(WTF::minCapacity>::shrink): Deleted.
(WTF::minCapacity>::grow): Deleted.
(WTF::minCapacity>::asanSetInitialBufferSizeTo): Deleted.
(WTF::minCapacity>::asanSetBufferSizeToFullCapacity): Deleted.
(WTF::minCapacity>::asanBufferSizeWillChangeTo): Deleted.
(WTF::minCapacity>::reserveCapacity): Deleted.
(WTF::minCapacity>::tryReserveCapacity): Deleted.
(WTF::minCapacity>::reserveInitialCapacity): Deleted.
(WTF::minCapacity>::shrinkCapacity): Deleted.
(WTF::minCapacity>::append): Deleted.
(WTF::minCapacity>::tryAppend): Deleted.
(WTF::minCapacity>::constructAndAppend): Deleted.
(WTF::minCapacity>::tryConstructAndAppend): Deleted.
(WTF::minCapacity>::appendSlowCase): Deleted.
(WTF::minCapacity>::constructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::tryConstructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::uncheckedAppend): Deleted.
(WTF::minCapacity>::uncheckedConstructAndAppend): Deleted.
(WTF::minCapacity>::appendVector): Deleted.
(WTF::minCapacity>::insert): Deleted.
(WTF::minCapacity>::insertVector): Deleted.
(WTF::minCapacity>::remove): Deleted.
(WTF::minCapacity>::removeFirst): Deleted.
(WTF::minCapacity>::removeFirstMatching): Deleted.
(WTF::minCapacity>::removeAll): Deleted.
(WTF::minCapacity>::removeAllMatching): Deleted.
(WTF::minCapacity>::reverse): Deleted.
(WTF::minCapacity>::map const): Deleted.
(WTF::minCapacity>::releaseBuffer): Deleted.
(WTF::minCapacity>::checkConsistency): Deleted.
(WTF::minCapacity>::isolatedCopy const): Deleted.
* wtf/text/CString.cpp:
(WTF::CStringBuffer::createUninitialized):
* wtf/text/CString.h:
* wtf/text/StringBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/text/StringBuffer.h:
(WTF::StringBuffer::StringBuffer):
(WTF::StringBuffer::~StringBuffer):
(WTF::StringBuffer::resize):
(WTF::StringBuffer::release):
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::~StringImpl):
(WTF::StringImpl::destroy):
(WTF::StringImpl::createUninitializedInternalNonEmpty):
(WTF::StringImpl::reallocateInternal):
* wtf/text/StringImpl.h:
(WTF::StringImpl::StringImpl):
(WTF::StringImpl::createSubstringSharingImpl):
(WTF::StringImpl::tryCreateUninitialized):
(WTF::StringImpl::adopt):
* wtf/text/cf/StringImplCF.cpp:
(WTF::StringWrapperCFAllocator::allocate):
(WTF::StringWrapperCFAllocator::reallocate):
(WTF::StringWrapperCFAllocator::deallocate):
Canonical link: https://commits.webkit.org/218863@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253987 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-01-03 02:36:43 +00:00
|
|
|
assembler/AssemblerBuffer.cpp
|
2019-04-12 23:26:43 +00:00
|
|
|
assembler/CPU.cpp
|
2020-10-03 23:51:12 +00:00
|
|
|
assembler/JITOperationList.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
assembler/LinkBuffer.cpp
|
|
|
|
assembler/MacroAssembler.cpp
|
|
|
|
assembler/MacroAssemblerARM64.cpp
|
|
|
|
assembler/MacroAssemblerARMv7.cpp
|
|
|
|
assembler/MacroAssemblerCodeRef.cpp
|
2017-11-30 00:16:19 +00:00
|
|
|
assembler/MacroAssemblerMIPS.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
assembler/MacroAssemblerPrinter.cpp
|
|
|
|
assembler/MacroAssemblerX86Common.cpp
|
2018-10-05 19:59:04 +00:00
|
|
|
assembler/PerfLog.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
assembler/Printer.cpp
|
|
|
|
assembler/ProbeContext.cpp
|
|
|
|
assembler/ProbeStack.cpp
|
|
|
|
|
2019-02-15 08:26:17 +00:00
|
|
|
b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/air/AirAllocateRegistersAndStackByLinearScan.cpp
|
|
|
|
b3/air/AirAllocateRegistersByGraphColoring.cpp
|
|
|
|
b3/air/AirAllocateStackByGraphColoring.cpp
|
|
|
|
b3/air/AirArg.cpp
|
|
|
|
b3/air/AirBasicBlock.cpp
|
|
|
|
b3/air/AirBlockInsertionSet.cpp
|
|
|
|
b3/air/AirBreakCriticalEdges.cpp
|
|
|
|
b3/air/AirCCallSpecial.cpp
|
|
|
|
b3/air/AirCCallingConvention.cpp
|
|
|
|
b3/air/AirCode.cpp
|
|
|
|
b3/air/AirCustom.cpp
|
|
|
|
b3/air/AirDisassembler.cpp
|
|
|
|
b3/air/AirEliminateDeadCode.cpp
|
|
|
|
b3/air/AirEmitShuffle.cpp
|
|
|
|
b3/air/AirFixObviousSpills.cpp
|
|
|
|
b3/air/AirFixPartialRegisterStalls.cpp
|
|
|
|
b3/air/AirFixSpillsAfterTerminals.cpp
|
|
|
|
b3/air/AirGenerate.cpp
|
|
|
|
b3/air/AirGenerated.cpp
|
|
|
|
b3/air/AirHandleCalleeSaves.cpp
|
|
|
|
b3/air/AirInsertionSet.cpp
|
|
|
|
b3/air/AirInst.cpp
|
|
|
|
b3/air/AirKind.cpp
|
|
|
|
b3/air/AirLogRegisterPressure.cpp
|
|
|
|
b3/air/AirLowerAfterRegAlloc.cpp
|
|
|
|
b3/air/AirLowerEntrySwitch.cpp
|
|
|
|
b3/air/AirLowerMacros.cpp
|
|
|
|
b3/air/AirLowerStackArgs.cpp
|
|
|
|
b3/air/AirOptimizeBlockOrder.cpp
|
|
|
|
b3/air/AirPadInterference.cpp
|
|
|
|
b3/air/AirPhaseInsertionSet.cpp
|
|
|
|
b3/air/AirPhaseScope.cpp
|
|
|
|
b3/air/AirPrintSpecial.cpp
|
|
|
|
b3/air/AirRegLiveness.cpp
|
|
|
|
b3/air/AirReportUsedRegisters.cpp
|
|
|
|
b3/air/AirSimplifyCFG.cpp
|
|
|
|
b3/air/AirSpecial.cpp
|
|
|
|
b3/air/AirStackAllocation.cpp
|
|
|
|
b3/air/AirStackSlot.cpp
|
|
|
|
b3/air/AirStackSlotKind.cpp
|
|
|
|
b3/air/AirTmp.cpp
|
|
|
|
b3/air/AirTmpWidth.cpp
|
|
|
|
b3/air/AirValidate.cpp
|
|
|
|
|
|
|
|
b3/B3ArgumentRegValue.cpp
|
|
|
|
b3/B3AtomicValue.cpp
|
|
|
|
b3/B3Bank.cpp
|
|
|
|
b3/B3BasicBlock.cpp
|
|
|
|
b3/B3BlockInsertionSet.cpp
|
[JSC] Add B3::BottomTupleValue node
https://bugs.webkit.org/show_bug.cgi?id=214956
<rdar://problem/65192877>
Reviewed by Keith Miller.
JSTests:
* wasm/stress/bottom-tuple.js: Added.
(try.main):
(catch):
Source/JavaScriptCore:
In B3 strength reduction, we convert B3 values to bottom value based on type after Oops kind, and then they are *typically* removed later.
While we support bottom values for usual types, we do not have a bottom value for tuple type. So when replaceWithBottom is called, we
fail to replace Patchpoints producing tuples with bottom values.
This patch newly adds B3 BottomTupleValue, which is just a BottomValue for tuple. We can extend it to generate arbitrary constant
tuple values, but for now, we just support bottom tuple values. We add a new node instead of generating patchpoint which generates bottom
values since BottomTupleValues implementation is simpler: BottomTupleValue just emits bunch of zero clear for Air tmps and Air does everything
automatically. On the other hand, implementing a patchpoint needs to add code which clears things with zero while checking the ValueRep. And
since we have Const32, Const64, etc. values, having this kind of value for tuple too is natural. Plus, this design allows us to remove bunch
of unnecessary instructions after lowering this to Air since Air knows what instructions will be emitted by this BottomTupleValue, and Air
can remove a lot of zero clear instructions if they are not read later by Extract.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3BottomTupleValue.cpp: Copied from Source/JavaScriptCore/b3/B3InsertionSet.cpp.
(JSC::B3::BottomTupleValue::dumpMeta const):
* b3/B3BottomTupleValue.h: Copied from Source/JavaScriptCore/b3/B3InsertionSet.cpp.
* b3/B3InsertionSet.cpp:
(JSC::B3::InsertionSet::insertBottom):
* b3/B3LowerToAir.cpp:
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::addBottom):
* b3/B3TypeMap.h:
(JSC::B3::TypeMap::TypeMap): Deleted.
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::effects const):
(JSC::B3::Value::key const):
* b3/B3Value.h:
* b3/B3ValueInlines.h:
* b3/B3ValueKey.cpp:
(JSC::B3::ValueKey::materialize const):
* b3/testb3_7.cpp:
(testBottomTupleValue):
(addTupleTests):
Canonical link: https://commits.webkit.org/227774@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-30 04:42:46 +00:00
|
|
|
b3/B3BottomTupleValue.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3BreakCriticalEdges.cpp
|
Add Pre/Post-Indexed Address Mode to Air for ARM64
https://bugs.webkit.org/show_bug.cgi?id=228047
Reviewed by Phil Pizlo.
Pre-indexed addressing means that the address is the sum of the value in the 64-bit base register
and an offset, and the address is then written back to the base register. And post-indexed
addressing means that the address is the value in the 64-bit base register, and the sum of the
address and the offset is then written back to the base register. They are relatively common for
loops to iterate over an array by increasing/decreasing a pointer into the array at each iteration.
With such an addressing mode, the instruction selector can merge the increment and access the array.
#####################################
## Pre-Index Address Mode For Load ##
#####################################
LDR Wt, [Xn, #imm]!
In B3 Reduction Strength, since we have this reduction rule:
Turn this: Load(Add(address, offset1), offset = offset2)
Into this: Load(address, offset = offset1 + offset2)
Then, the equivalent pattern is:
address = Add(base, offset)
...
memory = Load(base, offset)
First, we convert it to the canonical form:
address = Add(base, offset)
newMemory = Load(base, offset) // move the memory to just after the address
...
memory = Identity(newMemory)
Next, lower to Air:
Move %base, %address
Move (%address, prefix(offset)), %newMemory
######################################
## Post-Index Address Mode For Load ##
######################################
LDR Wt, [Xn], #imm
Then, the equivalent pattern is:
memory = Load(base, 0)
...
address = Add(base, offset)
First, we convert it to the canonical form:
newOffset = Constant
newAddress = Add(base, offset)
memory = Load(base, 0) // move the offset and address to just before the memory
...
offset = Identity(newOffset)
address = Identity(newAddress)
Next, lower to Air:
Move %base, %newAddress
Move (%newAddress, postfix(offset)), %memory
#############################
## Pattern Match Algorithm ##
#############################
To detect the pattern for prefix/postfix increment address is tricky due to the structure in B3 IR. The
algorithm used in this patch is to collect the first valid values (add/load), then search for any
paired value (load/add) to match all of them. In worst case, the runtime complexity is O(n^2)
when n is the number of all values.
After collecting two sets of candidates, we match the prefix incremental address first since it seems
more beneficial to the compiler (shown in the next section). And then, go for the postfix one.
##############################################
## Test for Pre/Post-Increment Address Mode ##
##############################################
Given Loop with Pre-Increment:
int64_t ldr_pre(int64_t *p) {
int64_t res = 0;
while (res < 10)
res += *++p;
return res;
}
B3 IR:
------------------------------------------------------
BB#0: ; frequency = 1.000000
Int64 b@0 = Const64(0)
Int64 b@2 = ArgumentReg(%x0)
Void b@20 = Upsilon($0(b@0), ^18, WritesLocalState)
Void b@21 = Upsilon(b@2, ^19, WritesLocalState)
Void b@4 = Jump(Terminal)
Successors: #1
BB#1: ; frequency = 1.000000
Predecessors: #0, #2
Int64 b@18 = Phi(ReadsLocalState)
Int64 b@19 = Phi(ReadsLocalState)
Int64 b@7 = Const64(10)
Int32 b@8 = AboveEqual(b@18, $10(b@7))
Void b@9 = Branch(b@8, Terminal)
Successors: Then:#3, Else:#2
BB#2: ; frequency = 1.000000
Predecessors: #1
Int64 b@10 = Const64(8)
Int64 b@11 = Add(b@19, $8(b@10))
Int64 b@13 = Load(b@11, ControlDependent|Reads:Top)
Int64 b@14 = Add(b@18, b@13)
Void b@22 = Upsilon(b@14, ^18, WritesLocalState)
Void b@23 = Upsilon(b@11, ^19, WritesLocalState)
Void b@16 = Jump(Terminal)
Successors: #1
BB#3: ; frequency = 1.000000
Predecessors: #1
Void b@17 = Return(b@18, Terminal)
Variables:
Int64 var0
Int64 var1
------------------------------------------------------
W/O Pre-Increment Address Mode:
------------------------------------------------------
...
BB#2: ; frequency = 1.000000
Predecessors: #1
Move $8, %x3, $8(b@12)
Add64 $8, %x0, %x1, b@11
Move (%x0,%x3), %x0, b@13
Add64 %x0, %x2, %x2, b@14
Move %x1, %x0, b@23
Jump b@16
Successors: #1
...
------------------------------------------------------
W/ Pre-Increment Address Mode:
------------------------------------------------------
...
BB#2: ; frequency = 1.000000
Predecessors: #1
MoveWithIncrement64 (%x0,Pre($8)), %x2, b@13
Add64 %x2, %x1, %x1, b@14
Jump b@16
Successors: #1
...
------------------------------------------------------
Given Loop with Post-Increment:
int64_t ldr_pre(int64_t *p) {
int64_t res = 0;
while (res < 10)
res += *p++;
return res;
}
B3 IR:
------------------------------------------------------
BB#0: ; frequency = 1.000000
Int64 b@0 = Const64(0)
Int64 b@2 = ArgumentReg(%x0)
Void b@20 = Upsilon($0(b@0), ^18, WritesLocalState)
Void b@21 = Upsilon(b@2, ^19, WritesLocalState)
Void b@4 = Jump(Terminal)
Successors: #1
BB#1: ; frequency = 1.000000
Predecessors: #0, #2
Int64 b@18 = Phi(ReadsLocalState)
Int64 b@19 = Phi(ReadsLocalState)
Int64 b@7 = Const64(10)
Int32 b@8 = AboveEqual(b@18, $10(b@7))
Void b@9 = Branch(b@8, Terminal)
Successors: Then:#3, Else:#2
BB#2: ; frequency = 1.000000
Predecessors: #1
Int64 b@10 = Load(b@19, ControlDependent|Reads:Top)
Int64 b@11 = Add(b@18, b@10)
Int64 b@12 = Const64(8)
Int64 b@13 = Add(b@19, $8(b@12))
Void b@22 = Upsilon(b@11, ^18, WritesLocalState)
Void b@23 = Upsilon(b@13, ^19, WritesLocalState)
Void b@16 = Jump(Terminal)
Successors: #1
BB#3: ; frequency = 1.000000
Predecessors: #1
Void b@17 = Return(b@18, Terminal)
Variables:
Int64 var0
Int64 var1
------------------------------------------------------
W/O Post-Increment Address Mode:
------------------------------------------------------
...
BB#2: ; frequency = 1.000000
Predecessors: #1
Move (%x0), %x2, b@10
Add64 %x2, %x1, %x1, b@11
Add64 $8, %x0, %x0, b@13
Jump b@16
Successors: #1
...
------------------------------------------------------
W/ Post-Increment Address Mode:
------------------------------------------------------
...
BB#2: ; frequency = 1.000000
Predecessors: #1
MoveWithIncrement64 (%x0,Post($8)), %x2, b@10
Add64 %x2, %x1, %x1, b@11
Jump b@16
Successors: #1
...
------------------------------------------------------
* Sources.txt:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::PreIndexAddress::PreIndexAddress):
(JSC::AbstractMacroAssembler::PostIndexAddress::PostIndexAddress):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::load64):
(JSC::MacroAssemblerARM64::load32):
(JSC::MacroAssemblerARM64::store64):
(JSC::MacroAssemblerARM64::store32):
* assembler/testmasm.cpp:
(JSC::testStorePrePostIndex32):
(JSC::testStorePrePostIndex64):
(JSC::testLoadPrePostIndex32):
(JSC::testLoadPrePostIndex64):
* b3/B3CanonicalizePrePostIncrements.cpp: Added.
(JSC::B3::canonicalizePrePostIncrements):
* b3/B3CanonicalizePrePostIncrements.h: Copied from Source/JavaScriptCore/b3/B3ValueKeyInlines.h.
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3LowerToAir.cpp:
* b3/B3ValueKey.h:
* b3/B3ValueKeyInlines.h:
(JSC::B3::ValueKey::ValueKey):
* b3/air/AirArg.cpp:
(JSC::B3::Air::Arg::jsHash const):
(JSC::B3::Air::Arg::dump const):
(WTF::printInternal):
* b3/air/AirArg.h:
(JSC::B3::Air::Arg::preIndex):
(JSC::B3::Air::Arg::postIndex):
(JSC::B3::Air::Arg::isPreIndex const):
(JSC::B3::Air::Arg::isPostIndex const):
(JSC::B3::Air::Arg::isMemory const):
(JSC::B3::Air::Arg::base const):
(JSC::B3::Air::Arg::offset const):
(JSC::B3::Air::Arg::isGP const):
(JSC::B3::Air::Arg::isFP const):
(JSC::B3::Air::Arg::isValidPreIndexForm):
(JSC::B3::Air::Arg::isValidPostIndexForm):
(JSC::B3::Air::Arg::isValidForm const):
(JSC::B3::Air::Arg::forEachTmpFast):
(JSC::B3::Air::Arg::forEachTmp):
(JSC::B3::Air::Arg::asPreIndexAddress const):
(JSC::B3::Air::Arg::asPostIndexAddress const):
* b3/air/AirOpcode.opcodes:
* b3/air/opcode_generator.rb:
* b3/testb3.h:
* b3/testb3_3.cpp:
(testLoadPreIndex32):
(testLoadPreIndex64):
(testLoadPostIndex32):
(testLoadPostIndex64):
(addShrTests):
* jit/ExecutableAllocator.cpp:
(JSC::jitWriteThunkGenerator):
Canonical link: https://commits.webkit.org/240125@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280493 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-30 20:44:47 +00:00
|
|
|
b3/B3CanonicalizePrePostIncrements.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3CCallValue.cpp
|
|
|
|
b3/B3CaseCollection.cpp
|
|
|
|
b3/B3CheckSpecial.cpp
|
|
|
|
b3/B3CheckValue.cpp
|
|
|
|
b3/B3Common.cpp
|
|
|
|
b3/B3Commutativity.cpp
|
|
|
|
b3/B3Compile.cpp
|
|
|
|
b3/B3Const32Value.cpp
|
|
|
|
b3/B3Const64Value.cpp
|
|
|
|
b3/B3ConstDoubleValue.cpp
|
|
|
|
b3/B3ConstFloatValue.cpp
|
|
|
|
b3/B3ConstrainedValue.cpp
|
|
|
|
b3/B3DataSection.cpp
|
|
|
|
b3/B3DuplicateTails.cpp
|
|
|
|
b3/B3Effects.cpp
|
|
|
|
b3/B3EliminateCommonSubexpressions.cpp
|
B3 should use associativity to optimize expression trees
https://bugs.webkit.org/show_bug.cgi?id=194081
Reviewed by Filip Pizlo.
JSTests:
Added three microbenchmarks:
- add-tree should be the ideal case, but there is no speedup because we are currently unable to prove that the CheckAdd won't overflow
- bit-xor-tree most closely matches the situation where the optimization triggers on the JetStream2 subtests where it triggers:
an unbalanced expression tree of size 8 that can be balanced, with no other optimizations being unlocked. 16% speedup
- bit-or-tree is an ideal case, where the reassociation also enables a ton of further simplifications. 42% speedup
* microbenchmarks/add-tree.js: Added.
* microbenchmarks/bit-or-tree.js: Added.
* microbenchmarks/bit-xor-tree.js: Added.
Source/JavaScriptCore:
This patch adds a new B3 pass, that tries to find and optimize expression trees made purely of any one associative and commutative operator (Add/Mul/BitOr/BitAnd/BitXor).
The pass only runs in O2, and runs once, after lowerMacros and just before a run of B3ReduceStrength (which helps clean up the dead code it tends to leave behind).
I had to separate killDeadCode out of B3ReduceStrength (as a new B3EliminateDeadCode pass) to run it before B3OptimizeAssociativeExpressionTrees, as otherwise it is stopped by high use counts
inherited from CSE.
This extra run of DCE is by itself a win, most notably on microbenchmarks/instanceof-always-hit-two (1.5x faster), and on microbenchmarks/licm-dragons(-out-of-bounds) (both get 1.16x speedup).
I suspect it is because it runs between CSE and tail-dedup, and as a result allows a lot more tail-dedup to occur.
The pass is currently extremely conservative, not trying anything if it would cause _any_ code duplication.
For this purpose, it starts by computing use counts for the potentially interesting nodes (those with the right opcodes), and segregate them into expression trees.
The root of an expression tree is a node that is either used in multiple places, or is used by a value with a different opcode.
The leaves of an expression tree are nodes that are either used in multiple places, or have a different opcode.
All constant leaves of a tree are combined, as well as all leaves that are identical. What remains is then laid out into a balanced binary tree, hopefully maximizing ILP.
This optimization was implemented as a stand-alone pass and not as part of B3ReduceStrength mostly because it needs use counts to avoid code duplication.
It also benefits from finding all tree roots first, and not trying to repeatedly optimize subtrees.
I added several tests to testB3 with varying patterns of trees. It is also tested in a less focused way by lots of older tests.
In the future this pass could be expanded to allow some bounded amount of code duplication, and merging more leaves (e.g. Mul(a, 3) and a in an Add tree, into Mul(a, 4))
The latter will need exposing the peephole optimizations out of B3ReduceStrength to avoid duplicating code.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3Common.cpp:
(JSC::B3::shouldDumpIR):
(JSC::B3::shouldDumpIRAtEachPhase):
* b3/B3Common.h:
* b3/B3EliminateDeadCode.cpp: Added.
(JSC::B3::EliminateDeadCode::run):
(JSC::B3::eliminateDeadCode):
* b3/B3EliminateDeadCode.h: Added.
(JSC::B3::EliminateDeadCode::EliminateDeadCode):
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3OptimizeAssociativeExpressionTrees.cpp: Added.
(JSC::B3::OptimizeAssociativeExpressionTrees::OptimizeAssociativeExpressionTrees):
(JSC::B3::OptimizeAssociativeExpressionTrees::neutralElement):
(JSC::B3::OptimizeAssociativeExpressionTrees::isAbsorbingElement):
(JSC::B3::OptimizeAssociativeExpressionTrees::combineConstants):
(JSC::B3::OptimizeAssociativeExpressionTrees::emitValue):
(JSC::B3::OptimizeAssociativeExpressionTrees::optimizeRootedTree):
(JSC::B3::OptimizeAssociativeExpressionTrees::run):
(JSC::B3::optimizeAssociativeExpressionTrees):
* b3/B3OptimizeAssociativeExpressionTrees.h: Added.
* b3/B3ReduceStrength.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::replaceWithIdentity):
* b3/testb3.cpp:
(JSC::B3::testBitXorTreeArgs):
(JSC::B3::testBitXorTreeArgsEven):
(JSC::B3::testBitXorTreeArgImm):
(JSC::B3::testAddTreeArg32):
(JSC::B3::testMulTreeArg32):
(JSC::B3::testBitAndTreeArg32):
(JSC::B3::testBitOrTreeArg32):
(JSC::B3::run):
Canonical link: https://commits.webkit.org/210847@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243851 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-04 03:37:23 +00:00
|
|
|
b3/B3EliminateDeadCode.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3EnsureLoopPreHeaders.cpp
|
B3 should support tuple types
https://bugs.webkit.org/show_bug.cgi?id=200327
Reviewed by Filip Pizlo.
As part of the Wasm multi-value proposal, we need to teach B3 that
patchpoints can return more than one value. This is done by
adding a new B3::Type called Tuple. Unlike, other B3 types Tuple
is actually an encoded index into a numeric B3::Type vector on the
procedure. This lets us distinguish any two tuples from each
other, moreover, it's possible to get the vector of types with
just the B3::Tuple type and the procedure.
Since most B3 operations only expect to see a single numeric child
there is a new Opcode, Extract, that takes yields the some, fixed,
entry from a tuple value. Extract would be the only other change
needed to make tuples work in B3 except that some optimizations
expect to be able to take any non-Void value and stick it into a
Variable of the same type. This means both Get/Set from a variable
have to support Tuples as well. For simplicity and consistency,
the ability to accept tuples is also applied to Phi and Upsilon.
In order to lower a Tuple, B3Lowering needs to have a Tmp for each
nested type in a Tuple. While we could reuse the existing
IndexedTables to hold the extra information we need to lower
Tuples, we instead use a two new HashTables for Value->Tmp(s) and
Phi->Tmp(s). It's expected that Tuples will be sufficiently
uncommon the overhead of tracking everything together would be
prohibitive. On the other hand, we don't worry about this for
Variables because we don't expect those to make it to lowering.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3Bank.h:
(JSC::B3::bankForType):
* b3/B3CheckValue.cpp:
(JSC::B3::CheckValue::CheckValue):
* b3/B3ExtractValue.cpp: Copied from Source/JavaScriptCore/b3/B3ProcedureInlines.h.
(JSC::B3::ExtractValue::~ExtractValue):
(JSC::B3::ExtractValue::dumpMeta const):
* b3/B3ExtractValue.h: Copied from Source/JavaScriptCore/b3/B3FixSSA.h.
* b3/B3FixSSA.h:
* b3/B3LowerMacros.cpp:
* b3/B3LowerMacrosAfterOptimizations.cpp:
* b3/B3LowerToAir.cpp:
* b3/B3NativeTraits.h:
* b3/B3Opcode.cpp:
(JSC::B3::invertedCompare):
(WTF::printInternal):
* b3/B3Opcode.h:
(JSC::B3::opcodeForConstant):
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::forEachArg):
(JSC::B3::PatchpointSpecial::isValid):
(JSC::B3::PatchpointSpecial::admitsStack):
(JSC::B3::PatchpointSpecial::generate):
* b3/B3PatchpointValue.cpp:
(JSC::B3::PatchpointValue::dumpMeta const):
(JSC::B3::PatchpointValue::PatchpointValue):
* b3/B3PatchpointValue.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::addTuple):
(JSC::B3::Procedure::isValidTuple const):
(JSC::B3::Procedure::tupleForType const):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::addConstant):
* b3/B3Procedure.h:
(JSC::B3::Procedure::returnCount const):
* b3/B3ProcedureInlines.h:
(JSC::B3::Procedure::extractFromTuple const):
* b3/B3ReduceStrength.cpp:
* b3/B3StackmapSpecial.cpp:
(JSC::B3::StackmapSpecial::isValidImpl):
(JSC::B3::StackmapSpecial::isArgValidForType):
(JSC::B3::StackmapSpecial::isArgValidForRep):
(JSC::B3::StackmapSpecial::isArgValidForValue): Deleted.
* b3/B3StackmapSpecial.h:
* b3/B3StackmapValue.h:
* b3/B3Type.cpp:
(WTF::printInternal):
* b3/B3Type.h:
(JSC::B3::Type::Type):
(JSC::B3::Type::tupleFromIndex):
(JSC::B3::Type::kind const):
(JSC::B3::Type::tupleIndex const):
(JSC::B3::Type::hash const):
(JSC::B3::Type::operator== const):
(JSC::B3::Type::operator!= const):
(JSC::B3::Type::isInt const):
(JSC::B3::Type::isFloat const):
(JSC::B3::Type::isNumeric const):
(JSC::B3::Type::isTuple const):
(JSC::B3::sizeofType):
(JSC::B3::isInt): Deleted.
(JSC::B3::isFloat): Deleted.
* b3/B3TypeMap.h:
(JSC::B3::TypeMap::at):
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::isRounded const):
(JSC::B3::Value::effects const):
(JSC::B3::Value::typeFor):
* b3/B3Value.h:
* b3/B3ValueInlines.h:
* b3/B3ValueKey.cpp:
(JSC::B3::ValueKey::intConstant):
* b3/B3ValueKey.h:
(JSC::B3::ValueKey::hash const):
* b3/B3ValueRep.h:
* b3/B3Width.h:
(JSC::B3::widthForType):
* b3/air/AirArg.cpp:
(JSC::B3::Air::Arg::canRepresent const):
* b3/air/AirArg.h:
* b3/air/AirCCallingConvention.cpp:
(JSC::B3::Air::cCallResult):
* b3/air/AirLowerMacros.cpp:
(JSC::B3::Air::lowerMacros):
* b3/testb3.h:
(populateWithInterestingValues):
* b3/testb3_1.cpp:
(run):
* b3/testb3_3.cpp:
(testStorePartial8BitRegisterOnX86):
* b3/testb3_5.cpp:
(testPatchpointWithRegisterResult):
(testPatchpointWithStackArgumentResult):
(testPatchpointWithAnyResult):
* b3/testb3_6.cpp:
(testPatchpointDoubleRegs):
(testSomeEarlyRegister):
* b3/testb3_7.cpp:
(testShuffleDoesntTrashCalleeSaves):
(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead):
(testSimpleTuplePair):
(testSimpleTuplePairUnused):
(testSimpleTuplePairStack):
(tailDupedTuplePair):
(tuplePairVariableLoop):
(tupleNestedLoop):
(addTupleTests):
* b3/testb3_8.cpp:
(testLoad):
(addLoadTests):
* ftl/FTLAbbreviatedTypes.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargsSpread):
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargs):
(JSC::FTL::DFG::LowerDFGToB3::compileCallEval):
(JSC::FTL::DFG::LowerDFGToB3::compileCPUIntrinsic):
(JSC::FTL::DFG::LowerDFGToB3::compileInstanceOf):
(JSC::FTL::DFG::LowerDFGToB3::compileCallDOMGetter):
(JSC::FTL::DFG::LowerDFGToB3::emitBinarySnippet):
(JSC::FTL::DFG::LowerDFGToB3::emitBinaryBitOpSnippet):
(JSC::FTL::DFG::LowerDFGToB3::emitRightShiftSnippet):
(JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::emitPatchpoint):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
* wasm/WasmCallingConvention.h:
(JSC::Wasm::CallingConvention::marshallArgument const):
(JSC::Wasm::CallingConvention::setupFrameInPrologue const):
(JSC::Wasm::CallingConvention::setupCall const):
(JSC::Wasm::CallingConventionAir::setupCall const):
Canonical link: https://commits.webkit.org/214174@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248178 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-02 21:02:05 +00:00
|
|
|
b3/B3ExtractValue.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3FenceValue.cpp
|
|
|
|
b3/B3FixSSA.cpp
|
|
|
|
b3/B3FoldPathConstants.cpp
|
|
|
|
b3/B3FrequencyClass.cpp
|
|
|
|
b3/B3Generate.cpp
|
|
|
|
b3/B3HoistLoopInvariantValues.cpp
|
|
|
|
b3/B3InferSwitches.cpp
|
|
|
|
b3/B3InsertionSet.cpp
|
|
|
|
b3/B3Kind.cpp
|
|
|
|
b3/B3LegalizeMemoryOffsets.cpp
|
|
|
|
b3/B3LowerMacros.cpp
|
|
|
|
b3/B3LowerMacrosAfterOptimizations.cpp
|
|
|
|
b3/B3LowerToAir.cpp
|
|
|
|
b3/B3MathExtras.cpp
|
|
|
|
b3/B3MemoryValue.cpp
|
|
|
|
b3/B3MoveConstants.cpp
|
|
|
|
b3/B3Opcode.cpp
|
B3 should use associativity to optimize expression trees
https://bugs.webkit.org/show_bug.cgi?id=194081
Reviewed by Filip Pizlo.
JSTests:
Added three microbenchmarks:
- add-tree should be the ideal case, but there is no speedup because we are currently unable to prove that the CheckAdd won't overflow
- bit-xor-tree most closely matches the situation where the optimization triggers on the JetStream2 subtests where it triggers:
an unbalanced expression tree of size 8 that can be balanced, with no other optimizations being unlocked. 16% speedup
- bit-or-tree is an ideal case, where the reassociation also enables a ton of further simplifications. 42% speedup
* microbenchmarks/add-tree.js: Added.
* microbenchmarks/bit-or-tree.js: Added.
* microbenchmarks/bit-xor-tree.js: Added.
Source/JavaScriptCore:
This patch adds a new B3 pass, that tries to find and optimize expression trees made purely of any one associative and commutative operator (Add/Mul/BitOr/BitAnd/BitXor).
The pass only runs in O2, and runs once, after lowerMacros and just before a run of B3ReduceStrength (which helps clean up the dead code it tends to leave behind).
I had to separate killDeadCode out of B3ReduceStrength (as a new B3EliminateDeadCode pass) to run it before B3OptimizeAssociativeExpressionTrees, as otherwise it is stopped by high use counts
inherited from CSE.
This extra run of DCE is by itself a win, most notably on microbenchmarks/instanceof-always-hit-two (1.5x faster), and on microbenchmarks/licm-dragons(-out-of-bounds) (both get 1.16x speedup).
I suspect it is because it runs between CSE and tail-dedup, and as a result allows a lot more tail-dedup to occur.
The pass is currently extremely conservative, not trying anything if it would cause _any_ code duplication.
For this purpose, it starts by computing use counts for the potentially interesting nodes (those with the right opcodes), and segregate them into expression trees.
The root of an expression tree is a node that is either used in multiple places, or is used by a value with a different opcode.
The leaves of an expression tree are nodes that are either used in multiple places, or have a different opcode.
All constant leaves of a tree are combined, as well as all leaves that are identical. What remains is then laid out into a balanced binary tree, hopefully maximizing ILP.
This optimization was implemented as a stand-alone pass and not as part of B3ReduceStrength mostly because it needs use counts to avoid code duplication.
It also benefits from finding all tree roots first, and not trying to repeatedly optimize subtrees.
I added several tests to testB3 with varying patterns of trees. It is also tested in a less focused way by lots of older tests.
In the future this pass could be expanded to allow some bounded amount of code duplication, and merging more leaves (e.g. Mul(a, 3) and a in an Add tree, into Mul(a, 4))
The latter will need exposing the peephole optimizations out of B3ReduceStrength to avoid duplicating code.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3Common.cpp:
(JSC::B3::shouldDumpIR):
(JSC::B3::shouldDumpIRAtEachPhase):
* b3/B3Common.h:
* b3/B3EliminateDeadCode.cpp: Added.
(JSC::B3::EliminateDeadCode::run):
(JSC::B3::eliminateDeadCode):
* b3/B3EliminateDeadCode.h: Added.
(JSC::B3::EliminateDeadCode::EliminateDeadCode):
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3OptimizeAssociativeExpressionTrees.cpp: Added.
(JSC::B3::OptimizeAssociativeExpressionTrees::OptimizeAssociativeExpressionTrees):
(JSC::B3::OptimizeAssociativeExpressionTrees::neutralElement):
(JSC::B3::OptimizeAssociativeExpressionTrees::isAbsorbingElement):
(JSC::B3::OptimizeAssociativeExpressionTrees::combineConstants):
(JSC::B3::OptimizeAssociativeExpressionTrees::emitValue):
(JSC::B3::OptimizeAssociativeExpressionTrees::optimizeRootedTree):
(JSC::B3::OptimizeAssociativeExpressionTrees::run):
(JSC::B3::optimizeAssociativeExpressionTrees):
* b3/B3OptimizeAssociativeExpressionTrees.h: Added.
* b3/B3ReduceStrength.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::replaceWithIdentity):
* b3/testb3.cpp:
(JSC::B3::testBitXorTreeArgs):
(JSC::B3::testBitXorTreeArgsEven):
(JSC::B3::testBitXorTreeArgImm):
(JSC::B3::testAddTreeArg32):
(JSC::B3::testMulTreeArg32):
(JSC::B3::testBitAndTreeArg32):
(JSC::B3::testBitOrTreeArg32):
(JSC::B3::run):
Canonical link: https://commits.webkit.org/210847@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243851 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-04 03:37:23 +00:00
|
|
|
b3/B3OptimizeAssociativeExpressionTrees.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3Origin.cpp
|
|
|
|
b3/B3OriginDump.cpp
|
|
|
|
b3/B3PatchpointSpecial.cpp
|
|
|
|
b3/B3PatchpointValue.cpp
|
|
|
|
b3/B3PhaseScope.cpp
|
|
|
|
b3/B3PhiChildren.cpp
|
|
|
|
b3/B3Procedure.cpp
|
|
|
|
b3/B3PureCSE.cpp
|
|
|
|
b3/B3ReduceDoubleToFloat.cpp
|
2019-08-21 06:30:05 +00:00
|
|
|
b3/B3ReduceLoopStrength.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
b3/B3ReduceStrength.cpp
|
|
|
|
b3/B3SSACalculator.cpp
|
|
|
|
b3/B3SlotBaseValue.cpp
|
|
|
|
b3/B3StackmapGenerationParams.cpp
|
|
|
|
b3/B3StackmapSpecial.cpp
|
|
|
|
b3/B3StackmapValue.cpp
|
|
|
|
b3/B3SwitchCase.cpp
|
|
|
|
b3/B3SwitchValue.cpp
|
|
|
|
b3/B3Type.cpp
|
|
|
|
b3/B3UpsilonValue.cpp
|
|
|
|
b3/B3UseCounts.cpp
|
|
|
|
b3/B3Validate.cpp
|
|
|
|
b3/B3Value.cpp
|
|
|
|
b3/B3ValueKey.cpp
|
|
|
|
b3/B3ValueRep.cpp
|
|
|
|
b3/B3Variable.cpp
|
|
|
|
b3/B3VariableLiveness.cpp
|
|
|
|
b3/B3VariableValue.cpp
|
|
|
|
b3/B3WasmAddressValue.cpp
|
|
|
|
b3/B3WasmBoundsCheckValue.cpp
|
|
|
|
b3/B3Width.cpp
|
|
|
|
|
|
|
|
bindings/ScriptFunctionCall.cpp
|
|
|
|
bindings/ScriptObject.cpp
|
|
|
|
bindings/ScriptValue.cpp
|
|
|
|
|
|
|
|
builtins/BuiltinExecutables.cpp
|
2018-03-30 16:05:22 +00:00
|
|
|
builtins/BuiltinExecutableCreator.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
builtins/BuiltinNames.cpp
|
|
|
|
|
|
|
|
bytecode/AccessCase.cpp
|
|
|
|
bytecode/AccessCaseSnippetParams.cpp
|
|
|
|
bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp
|
|
|
|
bytecode/ArithProfile.cpp
|
|
|
|
bytecode/ArrayAllocationProfile.cpp
|
|
|
|
bytecode/ArrayProfile.cpp
|
2020-03-12 18:33:40 +00:00
|
|
|
bytecode/ByValInfo.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/BytecodeBasicBlock.cpp
|
|
|
|
bytecode/BytecodeDumper.cpp
|
|
|
|
bytecode/BytecodeGeneratorification.cpp
|
2019-10-23 00:55:38 +00:00
|
|
|
bytecode/BytecodeIndex.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/BytecodeIntrinsicRegistry.cpp
|
|
|
|
bytecode/BytecodeLivenessAnalysis.cpp
|
|
|
|
bytecode/BytecodeRewriter.cpp
|
2019-12-10 19:41:40 +00:00
|
|
|
bytecode/BytecodeUseDef.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/CallEdge.cpp
|
|
|
|
bytecode/CallLinkInfo.cpp
|
|
|
|
bytecode/CallLinkStatus.cpp
|
|
|
|
bytecode/CallMode.cpp
|
|
|
|
bytecode/CallVariant.cpp
|
[ESNext] Implement private methods
https://bugs.webkit.org/show_bug.cgi?id=194434
Reviewed by Filip Pizlo.
JSTests:
* stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
* stress/private-brand-installed-after-super-call-from-eval.js: Added.
* stress/private-method-brand-check.js: Added.
* stress/private-method-change-attribute-from-branded-structure.js: Added.
* stress/private-method-change-prototype-from-branded-structure.js: Added.
* stress/private-method-check-private-brand-ic.js: Added.
* stress/private-method-check-structure-miss.js: Added.
* stress/private-method-comparison.js: Added.
* stress/private-method-delete-property-from-branded-structure.js: Added.
* stress/private-method-extends-brand-check.js: Added.
* stress/private-method-get-and-call.js: Added.
* stress/private-method-invalid-multiple-brand-installation.js: Added.
* stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
* stress/private-method-nested-class.js: Added.
* stress/private-method-on-sealed-objects.js: Added.
* stress/private-method-on-uncacheable-dictionary.js: Added.
* stress/private-method-polymorphic-with-constant-symbol.js: Added.
* stress/private-method-set-brand-should-have-write-barrier.js: Added.
* stress/private-method-untyped-use.js: Added.
* stress/private-method-with-uncacheable-dictionary-transition.js: Added.
* stress/private-methods-inline-cache.js: Added.
* stress/private-methods-megamorphic-ic.js: Added.
* stress/private-methods-on-proxy.js: Added.
* stress/private-methods-poly-ic-multiple-classes.js: Added.
* stress/private-methods-poly-ic-single-class.js: Added.
* stress/private-names-available-on-direct-eval.js: Added.
* test262/config.yaml:
Source/JavaScriptCore:
This patch is adding support to private methods following the
specification on https://tc39.es/proposal-private-methods/.
This is introducing a new way to declare private methods on
class syntax. Private methods are only accessible within
classes they were declared, and only can be called from
objects that are instance of these classes.
To guarantee such rules, the proposal presents the concept of
Brand Check. During class evaluation, if a private method is present,
a `brand` is installed in this class. Every instance of such class
then gets this brand installed during `[[Construct]]` operation. It
means that an object can have multiple brands (e.g when there is also
private methods declared on super class). Before accessing a private
method, there is a check to validate if the target of the call has the
brand of callee method.
The brand check mechanism is implemented using a `@privateBrand`
stored on class scope. Here is a representation of how this mechanism
works:
```
class C {
#m() { return 3; }
method() { return this.#m(); }
}
let c = new C();
console.log(c.method()); // prints 3
```
Generated bytecode for the following representation:
```
{ // class lexical scope
const @privateBrand = @createPrivateSymbol();
const #m = function () { return 3; }
C.prototype.method = function() {
@check_private_brand(this, @privateBrand);
return #m.call(this);
}
C = function() {
@set_private_brand(this, @privateBrand);
}
}
let c = new C();
console.log(c.method()); // prints 3
```
# Resolving correct brand to check
In the case of shadowing or nested scope, we need to emit brand
checks to the right private brand. See code below:
```
class C {
#m() { return 3; }
method() { return this.#m();}
A = class {
#m2() { return 3; }
foo(o) { return o.#m(); }
}
}
```
The call of "#m" in `foo` refers to "C::#m". In such case, we need to
check C's private brand, instead of A's private brand.
To perform the proper check, we first resolve scope of "#m" and then
check the private brand of this scope (the scope where the private
method and brand are stored is the same).
So the bytecode to lookup the right brand is:
```
mov loc9, arg1
resolve_scope loc10, "#m"
get_from_scope loc11, loc10, "@privateBrand"
check_private_brand loc9, loc11
get_from_scope loc11, loc10, "#m"
// setup call frame
call loc11, ...
// ...
```
# Brand check mechanism
We are introducing in this patch 2 new bytecodes to allow brand check
of objects: `op_set_brand` and `op_check_brand`.
`op_set_brand` sets a new brand in an object, so we can perform the brand
check later when accessing private methods. This operations throws when
trying to add the same brand twice in an Object.
`op_check_brand` checks if the given object contains the brand we are
looking for. It traverses the brand chain to verify if the brand is
present, and throws `TypeError` otherwise.
We are also introducing a subclass for Structure called BrandedStructure.
It is used to store brands and to allow brand check mechanism. BrandedStructure
stores a brand and a parent pointer to another BrandedStructure that allow
us traverse the brand chain. With `BrandedStructure`, we can then
infer that a given object has the brand we are looking for just
checking its structureId. This is a very good optimization, since we can
reduce most of brand checks to structure checks.
We created a new kind of transition called `SetBrand` that happens when
`op_set_brand` is executed. This allow us to cache such kind of
trasitions on trasition table using the key `<brand->uid, 0,
TransitionKind::SetBrand>`. During this transition, we take previous
structure and apply one of the following rules:
1. If it's a BrandedStructure, we then set it to `m_parentBrand`,
to allow proper brand chain check.
2. If it's not a BrandedStructure, we set `m_parentBrand` to `nullptr`,
meaning that this is the first brand being added to the object
with this structure.
For now, we are using the flag `isBrandedStructure` to identify that a
given Structure is a BrandedStructure. This is done to avoid changes
on places where we are checking for `vm.structureStructure()`.
However, if we ever need space on Structure, this flag is a good
candidate to be deleted and we can move to a solution that uses
`vm.brandedStructureStructure()`;
# JIT Support
This patch also includes initial JIT support for `set_private_brand`
and `check_private_brand`. On Baseline JIT, we are using
`JITPravateBrandAccessGenerator` to support IC for both operands.
On `DFGByteCodeParser` we are trying to inline brand access whenever
possible, and fallbacking to `SetPrivateBrand` and
`CheckPrivateBrand` otherwise. Those nodes are not being optimized at
their full potential, but the code generated by them is also relying on
`JITPrivateBrandAccessGenerator` to have IC support for both DFG and
FTL. During DFG parsing, we try to reduce those access to `CheckIsConstant`
and `CheckStructure` (with `PutStructure` for `set_private_brand` cases)
based on available profiled data. This is meant to make brand checks
almost free on DFG/FTL tiers when we have a single evaluation of a
class, since the `CheckIsConstant` can be eliminated by the constant-folded
scope load, and the `CheckStructure` is very likely to be redundant
to any other `CheckStructure` that can be performed on receiver
when we have a finite structure set.
For instance, when we have a brand check on a path-of-no-return to
a `GetByOffset` sequence on the same receiver, the `CheckStructure`
for the brand check will enable CSE of the `CheckStructure` that
would happen for that `GetByOffset`. Such design is possible because brand
checks supports polymorphic access very similr to what we have for
`GetByOffset` sequences.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):
* builtins/BuiltinExecutables.h:
We are adding a new parameter `PrivateBrandRequirement` to propagate
when a default constructor needs to emit code to setup private brand
on instances.
* builtins/BuiltinNames.h:
Adding `@privateBrand` that we use to store private brand on
class's scope.
* bytecode/AccessCase.cpp:
(JSC::AccessCase::createCheckPrivateBrand):
(JSC::AccessCase::createSetPrivateBrand):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::structure const):
(JSC::AccessCase::newStructure const):
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CheckPrivateBrandStatus.cpp: Added.
(JSC::CheckPrivateBrandStatus::appendVariant):
(JSC::CheckPrivateBrandStatus::computeForBaseline):
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
(JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::CheckPrivateBrandStatus::computeFor):
(JSC::CheckPrivateBrandStatus::slowVersion const):
(JSC::CheckPrivateBrandStatus::merge):
(JSC::CheckPrivateBrandStatus::filter):
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
(JSC::CheckPrivateBrandStatus::visitAggregate):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::finalize):
(JSC::CheckPrivateBrandStatus::dump const):
* bytecode/CheckPrivateBrandStatus.h: Added.
* bytecode/CheckPrivateBrandVariant.cpp: Added.
(JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::attemptToMerge):
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::finalize):
(JSC::CheckPrivateBrandVariant::visitAggregate):
(JSC::CheckPrivateBrandVariant::dump const):
(JSC::CheckPrivateBrandVariant::dumpInContext const):
* bytecode/CheckPrivateBrandVariant.h: Added.
(JSC::CheckPrivateBrandVariant::structureSet const):
(JSC::CheckPrivateBrandVariant::structureSet):
(JSC::CheckPrivateBrandVariant::identifier const):
(JSC::CheckPrivateBrandVariant::overlaps):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::privateBrandRequirement const):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addCheckPrivateBrandStatus):
(JSC::RecordedStatuses::addSetPrivateBrandStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):
* bytecode/RecordedStatuses.h:
(JSC::RecordedStatuses::forEachVector):
* bytecode/SetPrivateBrandStatus.cpp: Added.
(JSC::SetPrivateBrandStatus::appendVariant):
(JSC::SetPrivateBrandStatus::computeForBaseline):
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
(JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::SetPrivateBrandStatus::computeFor):
(JSC::SetPrivateBrandStatus::slowVersion const):
(JSC::SetPrivateBrandStatus::merge):
(JSC::SetPrivateBrandStatus::filter):
(JSC::SetPrivateBrandStatus::singleIdentifier const):
(JSC::SetPrivateBrandStatus::visitAggregate):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::finalize):
(JSC::SetPrivateBrandStatus::dump const):
* bytecode/SetPrivateBrandStatus.h: Added.
* bytecode/SetPrivateBrandVariant.cpp: Added.
(JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::attemptToMerge):
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::finalize):
(JSC::SetPrivateBrandVariant::visitAggregate):
(JSC::SetPrivateBrandVariant::dump const):
(JSC::SetPrivateBrandVariant::dumpInContext const):
* bytecode/SetPrivateBrandVariant.h: Added.
(JSC::SetPrivateBrandVariant::oldStructure const):
(JSC::SetPrivateBrandVariant::newStructure const):
(JSC::SetPrivateBrandVariant::identifier const):
(JSC::SetPrivateBrandVariant::overlaps):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::privateBrandRequirement const):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
We changed BytecodeGenerator for FunctionNode and EvalNode to
propagate parentScope PrivateNameEnvironment. These environments stores
private name entries that are visible into the scope of the
function/eval.
This is required to identify the kind of access a private name is
referring to, since it can be a private field or a private method.
(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::emitGetPrivateName):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):
The process to create a private brand is as follows:
1. Create a PrivateSymbol using `@createPrivateSymbol`.
2. Store this symbol into a given scope (i.e class lexical scope)
on `@privateBrand` variable.
(JSC::BytecodeGenerator::emitInstallPrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):
We added `m_privateNamesStack` to BytecodeGenerator to represent the
scope chain of available private names while generating bytecode.
(JSC::BytecodeGenerator::emitCheckPrivateBrand):
(JSC::BytecodeGenerator::isPrivateMethod):
(JSC::BytecodeGenerator::pushPrivateAccessNames):
(JSC::BytecodeGenerator::popPrivateAccessNames):
(JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
(JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::privateBrandRequirement const):
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):
This change is required to properly propagate PrivateBrandRequirement
to arrow functions that can potentially call `super()`.
* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitDeclarePrivateFieldNames):
(JSC::PropertyListNode::emitBytecode):
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BaseDotNode::emitGetPropertyValue):
Adding support to properly access private method. Since we store
private methods on class lexical scope, we need a different set of
instructions to access a private method.
(JSC::BaseDotNode::emitPutProperty):
In the case of we trying to write in a private method, we need to
throw a TypeError according to specification
(https://tc39.es/proposal-private-methods/#sec-privatefieldset).
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::ClassExprNode::emitBytecode):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addPrivateBrandAccess):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCheckPrivateBrandStatus):
(JSC::DFG::Node::checkPrivateBrandStatus):
(JSC::DFG::Node::hasSetPrivateBrandStatus):
(JSC::DFG::Node::setPrivateBrandStatus):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
(JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
(JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):
* interpreter/Interpreter.cpp:
(JSC::eval):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::generateFastPath):
(JSC::JITPrivateBrandAccessGenerator::finalize):
* jit/JITInlineCacheGenerator.h:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::slowPathJump const):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::getPrivateName):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/Repatch.cpp:
(JSC::tryCacheCheckPrivateBrand):
(JSC::repatchCheckPrivateBrand):
(JSC::tryCacheSetPrivateBrand):
(JSC::repatchSetPrivateBrand):
(JSC::resetCheckPrivateBrand):
(JSC::resetSetPrivateBrand):
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
(JSC::Scope::declarePrivateMethod):
(JSC::Scope::declarePrivateField):
(JSC::Parser<LexerType>::parse):
(JSC::parse):
(JSC::Scope::declarePrivateName): Deleted.
* parser/ParserModes.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createDotAccess):
* parser/VariableEnvironment.cpp:
(JSC::VariableEnvironment::declarePrivateMethod):
* parser/VariableEnvironment.h:
(JSC::VariableEnvironmentEntry::isPrivateField const):
(JSC::VariableEnvironmentEntry::isPrivateMethod const):
(JSC::VariableEnvironmentEntry::setIsPrivateField):
(JSC::VariableEnvironmentEntry::setIsPrivateMethod):
(JSC::PrivateNameEntry::isMethod const):
(JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
(JSC::VariableEnvironment::addPrivateName):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::privateNameEnvironment const):
(JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
(JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
(JSC::VariableEnvironment::declarePrivateName): Deleted.
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
(JSC::CachedFunctionExecutable::privateBrandRequirement const):
(JSC::CachedCodeBlock::derivedContextType const):
(JSC::CachedFunctionExecutable::encode):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.
* runtime/CodeCache.cpp:
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):
(JSC::generateUnlinkedCodeBlockForDirectEval):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
* runtime/CodeCache.h:
* runtime/DirectEvalExecutable.cpp:
(JSC::DirectEvalExecutable::create):
(JSC::DirectEvalExecutable::DirectEvalExecutable):
* runtime/DirectEvalExecutable.h:
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::EvalExecutable):
* runtime/EvalExecutable.h:
(JSC::EvalExecutable::executableInfo const):
(JSC::EvalExecutable::privateBrandRequirement const):
* runtime/ExceptionHelpers.cpp:
(JSC::createInvalidPrivateNameError):
* runtime/IndirectEvalExecutable.cpp:
(JSC::IndirectEvalExecutable::IndirectEvalExecutable):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::checkPrivateBrand):
(JSC::JSObject::setPrivateBrand):
* runtime/JSScope.cpp:
(JSC::JSScope::collectClosureVariablesUnderTDZ):
* runtime/JSScope.h:
* runtime/ModuleProgramExecutable.h:
* runtime/Options.cpp:
(JSC::Options::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/ProgramExecutable.h:
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyTable):
(JSC::BrandedStructure::BrandedStructure):
(JSC::BrandedStructure::create):
(JSC::BrandedStructure::checkBrand):
(JSC::Structure::setBrandTransitionFromExistingStructureImpl):
(JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
(JSC::Structure::setBrandTransition):
* runtime/Structure.h:
(JSC::Structure::finishCreation):
* runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::forEachPropertyConcurrently):
* runtime/StructureTransitionTable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::cloneScopePart):
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Canonical link: https://commits.webkit.org/233852@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 16:30:24 +00:00
|
|
|
bytecode/CheckPrivateBrandStatus.cpp
|
|
|
|
bytecode/CheckPrivateBrandVariant.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/CodeBlock.cpp
|
|
|
|
bytecode/CodeBlockHash.cpp
|
|
|
|
bytecode/CodeBlockJettisoningWatchpoint.cpp
|
|
|
|
bytecode/CodeOrigin.cpp
|
|
|
|
bytecode/CodeType.cpp
|
|
|
|
bytecode/ComplexGetStatus.cpp
|
|
|
|
bytecode/DFGExitProfile.cpp
|
|
|
|
bytecode/DataFormat.cpp
|
|
|
|
bytecode/DeferredCompilationCallback.cpp
|
|
|
|
bytecode/DeferredSourceDump.cpp
|
Allow deleteById to be cached in the DFG
https://bugs.webkit.org/show_bug.cgi?id=208664
Reviewed by Saam Barati.
JSTests:
* microbenchmarks/delete-property-allocation-sinking.js: Added.
(assert):
(noInline.assert.blackbox):
(noInline.blackbox.doAlloc1):
(noInline.doAlloc1):
* microbenchmarks/polyvariant-delete-property.js: Added.
(assert):
(blackbox):
(noInline.blackbox.polyvariant):
(doAlloc1):
(noInline.doAlloc1.doAlloc2):
(noInline.doAlloc2):
* stress/delete-property-dfg-inline.js: Added.
(assert):
(noInline.assert.assert_throws):
(noInline.assert_throws.blackbox):
(noInline.blackbox.testSingleStructure.doAlloc1):
(noInline.blackbox.testSingleStructure):
(noInline.testSingleStructure.testInlineSingleStructure.doDelete2):
(noInline.testSingleStructure.testInlineSingleStructure.doAlloc2):
(noInline.testSingleStructure.testInlineSingleStructure):
(noInline.testInlineSingleStructure.testExit.doDelete3):
(noInline.testInlineSingleStructure.testExit):
(noInline.testExit.testSingleStructureMiss.doAlloc4):
(noInline.testExit.testSingleStructureMiss):
(noInline.testSingleStructureMiss.testSingleStructureMissStrict.string_appeared_here.doAlloc5):
(noInline.testSingleStructureMiss.testSingleStructureMissStrict):
(noInline.testSingleStructureMissStrict.testSingleStructureMissNonConfigurable.doAlloc6):
(noInline.testSingleStructureMissStrict.testSingleStructureMissNonConfigurable):
(noInline.testSingleStructureMissNonConfigurable.testSingleStructureEmpty.doAlloc7):
(noInline.testSingleStructureMissNonConfigurable.testSingleStructureEmpty):
(noInline.testSingleStructureEmpty.testPolymorphic.doDelete8):
(noInline.testSingleStructureEmpty.testPolymorphic):
(noInline.testPolymorphic.testPolyvariant.doDelete9):
(noInline.testPolymorphic.testPolyvariant.polyvariant):
(noInline.testPolymorphic.testPolyvariant):
(noInline.testPolyvariant.testConstantFolding.doDelete10):
(noInline.testPolyvariant.testConstantFolding):
(noInline.testConstantFolding.testObjectSinking.doAlloc11):
(noInline.testConstantFolding.testObjectSinking):
(noInline.testObjectSinking.testProxy.doAlloc12):
(noInline.testObjectSinking.testProxy.noInline.doDelete12):
(noInline.testObjectSinking.testProxy):
(noInline.testProxy.testTypedArray.doDelete12):
(noInline.testProxy.testTypedArray):
(noInline.testTypedArray.testMissMixed.doDelete13):
(noInline.testTypedArray.testMissMixed):
(noInline.testMissMixed.testMissNonMixed.doDelete14):
(noInline.testMissMixed.testMissNonMixed):
(noInline.testMissNonMixed.testByVal.doDelete15):
(noInline.testMissNonMixed.testByVal):
Source/JavaScriptCore:
When we see that the deleteById inline cache only saw one structure, we inline it into the DFG. This involves
creating a new node, FilterDeleteByStatus, and then turning these DeleteById nodes into a FilterDeleteByStatus,
CheckStructure, PutByOffset, then PutStructure (or just a CheckStructure in the case of a miss). The logic for
pessimising this optimization is the same as for PutById, giving inlined functions the opportunity to use only
the DFG profiling information, while everything else uses the DFG+Baseline information.
This also adds a MultiDeleteByOffset node, for the case when there are multiple structures seen by the delete. If
all of the cases are the same kind of miss, then we only emit a CheckStructure and constant.
Finally, if we see a delete by val with a single identifier, we inline that too.
This patch removes a dead code path from deleteProperty that checks if we need to nuke the object's butterfly.
This also fixes a bug where we were checking the neutering status of typed arrays for named properties when we should
only check for indexed properties. The behavior of this now matches for all tiers including when cached.
The benchmark shows a 2x improvement on polyvariant-delete-property, and a 50% improvement on delete-property-allocation-sinking.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::createDelete):
(JSC::AccessCase::generateImpl):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::getICStatusMap):
* bytecode/DeleteByIdVariant.cpp: Added.
(JSC::DeleteByIdVariant::DeleteByIdVariant):
(JSC::DeleteByIdVariant::~DeleteByIdVariant):
(JSC::DeleteByIdVariant::operator=):
(JSC::DeleteByIdVariant::attemptToMerge):
(JSC::DeleteByIdVariant::writesStructures const):
(JSC::DeleteByIdVariant::visitAggregate):
(JSC::DeleteByIdVariant::markIfCheap):
(JSC::DeleteByIdVariant::dump const):
(JSC::DeleteByIdVariant::finalize):
(JSC::DeleteByIdVariant::dumpInContext const):
* bytecode/DeleteByIdVariant.h: Added.
(JSC::DeleteByIdVariant::oldStructure const):
(JSC::DeleteByIdVariant::newStructure const):
(JSC::DeleteByIdVariant::result const):
(JSC::DeleteByIdVariant::offset const):
(JSC::DeleteByIdVariant::isPropertyUnset const):
(JSC::DeleteByIdVariant::identifier const):
(JSC::DeleteByIdVariant::overlaps):
* bytecode/DeleteByStatus.cpp: Added.
(JSC::DeleteByStatus::appendVariant):
(JSC::DeleteByStatus::computeForBaseline):
(JSC::DeleteByStatus::DeleteByStatus):
(JSC::DeleteByStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::DeleteByStatus::computeFor):
(JSC::DeleteByStatus::slowVersion const):
(JSC::DeleteByStatus::merge):
(JSC::DeleteByStatus::filter):
(JSC::DeleteByStatus::singleIdentifier const):
(JSC::DeleteByStatus::visitAggregate):
(JSC::DeleteByStatus::markIfCheap):
(JSC::DeleteByStatus::finalize):
(JSC::DeleteByStatus::dump const):
* bytecode/DeleteByStatus.h: Added.
* bytecode/ICStatusMap.h:
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addDeleteByStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):
* bytecode/RecordedStatuses.h:
(JSC::RecordedStatuses::forEachVector):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleDeleteById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::emitDeleteByOffset):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.cpp:
(JSC::DFG::MultiDeleteByOffsetData::writesStructures const):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasMultiDeleteByOffsetData):
(JSC::DFG::Node::multiDeleteByOffsetData):
(JSC::DFG::Node::hasDeleteByStatus):
(JSC::DFG::Node::deleteByStatus):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* 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/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* dfg/DFGValidate.cpp:
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileMultiDeleteByOffset):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):
* runtime/JSObject.cpp:
(JSC::JSObject::deleteProperty):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::mayHaveIndexingHeader const): Deleted.
(JSC::Structure::canCacheDeleteIC const): Deleted.
Canonical link: https://commits.webkit.org/222974@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259583 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-06 18:48:04 +00:00
|
|
|
bytecode/DeleteByStatus.cpp
|
2021-06-10 06:26:12 +00:00
|
|
|
bytecode/DeleteByVariant.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/DirectEvalCodeCache.cpp
|
|
|
|
bytecode/EvalCodeBlock.cpp
|
2018-01-11 16:43:07 +00:00
|
|
|
bytecode/ExecutableToCodeBlockEdge.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/ExecutionCounter.cpp
|
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
|
|
|
bytecode/ExitFlag.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/ExitKind.cpp
|
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
|
|
|
bytecode/ExitingInlineKind.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/ExitingJITType.cpp
|
|
|
|
bytecode/FullCodeOrigin.cpp
|
|
|
|
bytecode/FunctionCodeBlock.cpp
|
GetByVal should use polymorphic access and hook into a status object
https://bugs.webkit.org/show_bug.cgi?id=202767
Reviewed by Keith Miller.
This patch puts get_by_val in our normal IC caching infrastructure. This means
building it on top of StructureStubInfo and PolymorphicAccess. For this to
work, AccessCase now supports all the array load variants that we used to have
fast paths for. For identifier based variants, it we just fall back to the
code we've already implemented, but only after doing a runtime check that
the identifier matches the expected identifier. This allows us to reuse all
the IC infrastructure we have for get_by_id.
Our compilation strategy is that the baseline JIT always emits a get_by_val
IC. If that IC goes to the slow path, the DFG/FTL won't also emit the same IC,
since it's probable that we're seeing a megamorphic switch over strings. This
was needed to keep this patch neutral on Speedometer 2. It's likely there is
room to improve this heuristic: https://bugs.webkit.org/show_bug.cgi?id=204336
This now allows us to have inline caches which contain array loads, and uses
of different identifiers. They just show up as different access cases inside
polymorphic access.
This patch is a progression on various microbenchmarks, especially those with
uses of a fixed set of multiple identifiers. It's neutral on JetStream 2 and
Speedometer 2.
This patch also hooks in get_by_val ICs to our ICStatus infrastructure. This
is going to pave the way to allow us to eagerly throw away baseline code, since
when we go for an FTL compile, we will be able to use the IC status from the
prior compile without relying on baseline specific data structures.
There are a few interesting tidbits in this patch that are worth
highlighting.
- Unlike get_by_id, when we take an IC snapshot for a get_by_val
IC, we're not guaranteed the various identifiers in question will outlive
the compile (get_by_id ensures this since they're in the constant pool of
CodeBlock). For get_by_val, the Identifiers in question are dynamic fields
of AccessCase, and AccessCase may get destroyed as we're compiling concurrently.
Also, String's reference counting isn't thread safe, so we can't just ref it.
Instead, we use a Box<Identifier> inside AccessCase. This allows us to safely
ref the Box without refing the underlying String. We're not worried about the
Box being destroyed while we're doing this, since we're holding a lock while
taking an IC snapshot inside GetByStatus.
- We no longer hold onto the actual JS symbol object in the inline cache.
This is what we used to do for inlining by val infos. Instead, this patch
extends the CheckStringIdent node to be able to handle symbols as well. This
patch also renames CheckStringIdent to CheckIdent.
This patch also renames various IC related helpers from GetById* to GetBy*,
since they can both be used by get_by_val and get_by_id.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::create):
(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::commit):
(JSC::AccessCase::guardedByStructureCheck const):
(JSC::AccessCase::guardedByStructureCheckSkippingConstantIdentifierCheck const):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generate):
(JSC::AccessCase::generateImpl):
(JSC::AccessCase::toTypedArrayType):
(JSC::AccessCase::checkConsistency):
* bytecode/AccessCase.h:
(JSC::AccessCase::uid const):
(JSC::AccessCase::identifier const):
(JSC::AccessCase::checkConsistency):
(JSC::AccessCase::AccessCase):
* bytecode/GetByIdStatus.cpp: Removed.
* bytecode/GetByIdStatus.h: Removed.
* bytecode/GetByIdVariant.cpp:
(JSC::GetByIdVariant::GetByIdVariant):
(JSC::GetByIdVariant::operator=):
(JSC::GetByIdVariant::attemptToMerge):
* bytecode/GetByIdVariant.h:
(JSC::GetByIdVariant::domAttribute const):
(JSC::GetByIdVariant::identifier const):
* bytecode/GetByStatus.cpp: Copied from Source/JavaScriptCore/bytecode/GetByIdStatus.cpp.
(JSC::GetByStatus::appendVariant):
(JSC::GetByStatus::computeFromLLInt):
(JSC::GetByStatus::computeFor):
(JSC::GetByStatus::GetByStatus):
(JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByStatus::makesCalls const):
(JSC::GetByStatus::slowVersion const):
(JSC::GetByStatus::merge):
(JSC::GetByStatus::filter):
(JSC::GetByStatus::markIfCheap):
(JSC::GetByStatus::finalize):
(JSC::GetByStatus::singleIdentifier const):
(JSC::GetByStatus::dump const):
(JSC::GetByIdStatus::appendVariant): Deleted.
(JSC::GetByIdStatus::computeFromLLInt): Deleted.
(JSC::GetByIdStatus::computeFor): Deleted.
(JSC::GetByIdStatus::computeForStubInfo): Deleted.
(JSC::GetByIdStatus::GetByIdStatus): Deleted.
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback): Deleted.
(JSC::GetByIdStatus::makesCalls const): Deleted.
(JSC::GetByIdStatus::slowVersion const): Deleted.
(JSC::GetByIdStatus::merge): Deleted.
(JSC::GetByIdStatus::filter): Deleted.
(JSC::GetByIdStatus::markIfCheap): Deleted.
(JSC::GetByIdStatus::finalize): Deleted.
(JSC::GetByIdStatus::dump const): Deleted.
* bytecode/GetByStatus.h: Copied from Source/JavaScriptCore/bytecode/GetByIdStatus.h.
(JSC::GetByStatus::GetByStatus):
(JSC::GetByStatus::moduleNamespaceObject const):
(JSC::GetByStatus::moduleEnvironment const):
(JSC::GetByStatus::scopeOffset const):
(JSC::GetByIdStatus::GetByIdStatus): Deleted.
(JSC::GetByIdStatus::state const): Deleted.
(JSC::GetByIdStatus::isSet const): Deleted.
(JSC::GetByIdStatus::operator bool const): Deleted.
(JSC::GetByIdStatus::isSimple const): Deleted.
(JSC::GetByIdStatus::isCustom const): Deleted.
(JSC::GetByIdStatus::isModuleNamespace const): Deleted.
(JSC::GetByIdStatus::numVariants const): Deleted.
(JSC::GetByIdStatus::variants const): Deleted.
(JSC::GetByIdStatus::at const): Deleted.
(JSC::GetByIdStatus::operator[] const): Deleted.
(JSC::GetByIdStatus::takesSlowPath const): Deleted.
(JSC::GetByIdStatus::wasSeenInJIT const): Deleted.
(JSC::GetByIdStatus::moduleNamespaceObject const): Deleted.
(JSC::GetByIdStatus::moduleEnvironment const): Deleted.
(JSC::GetByIdStatus::scopeOffset const): Deleted.
* bytecode/GetterSetterAccessCase.cpp:
(JSC::GetterSetterAccessCase::GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::create):
* bytecode/GetterSetterAccessCase.h:
* bytecode/ICStatusMap.h:
* bytecode/InByIdStatus.cpp:
(JSC::InByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
* bytecode/InlineAccess.cpp:
(JSC::InlineAccess::generateSelfPropertyAccess):
(JSC::InlineAccess::canGenerateSelfPropertyReplace):
(JSC::InlineAccess::generateSelfPropertyReplace):
(JSC::InlineAccess::isCacheableArrayLength):
(JSC::InlineAccess::generateArrayLength):
(JSC::InlineAccess::isCacheableStringLength):
(JSC::InlineAccess::generateStringLength):
(JSC::InlineAccess::generateSelfInAccess):
* bytecode/InstanceOfAccessCase.cpp:
(JSC::InstanceOfAccessCase::InstanceOfAccessCase):
* bytecode/InstanceOfStatus.cpp:
(JSC::InstanceOfStatus::computeForStubInfo):
* bytecode/IntrinsicGetterAccessCase.cpp:
(JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
(JSC::IntrinsicGetterAccessCase::create):
* bytecode/IntrinsicGetterAccessCase.h:
* bytecode/ModuleNamespaceAccessCase.cpp:
(JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
(JSC::ModuleNamespaceAccessCase::create):
* bytecode/ModuleNamespaceAccessCase.h:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::preserveLiveRegistersToStackForCall):
(JSC::PolymorphicAccess::addCases):
(JSC::PolymorphicAccess::addCase):
(JSC::PolymorphicAccess::commit):
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/PolymorphicAccess.h:
* bytecode/ProxyableAccessCase.cpp:
(JSC::ProxyableAccessCase::ProxyableAccessCase):
(JSC::ProxyableAccessCase::create):
* bytecode/ProxyableAccessCase.h:
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeForStubInfo):
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::addGetByStatus):
(JSC::RecordedStatuses::addGetByIdStatus): Deleted.
* bytecode/RecordedStatuses.h:
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::StructureStubInfo):
(JSC::StructureStubInfo::initGetByIdSelf):
(JSC::StructureStubInfo::initArrayLength):
(JSC::StructureStubInfo::initStringLength):
(JSC::StructureStubInfo::initPutByIdReplace):
(JSC::StructureStubInfo::initInByIdSelf):
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::aboutToDie):
(JSC::StructureStubInfo::addAccessCase):
(JSC::StructureStubInfo::reset):
(JSC::StructureStubInfo::visitWeakReferences):
(JSC::StructureStubInfo::propagateTransitions):
(JSC::StructureStubInfo::summary const):
(JSC::StructureStubInfo::containsPC const):
(JSC::StructureStubInfo::setCacheType):
(JSC::StructureStubInfo::checkConsistency):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::getByIdSelfIdentifier):
(JSC::StructureStubInfo::thisValueIsInThisGPR const):
(JSC::StructureStubInfo::checkConsistency):
(JSC::StructureStubInfo::cacheType const):
(JSC::appropriateOptimizingGetByIdFunction):
(JSC::appropriateGenericGetByIdFunction):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleDOMJITGetter):
(JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad):
(JSC::DFG::ByteCodeParser::load):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::handlePutByVal):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDesiredIdentifiers.cpp:
(JSC::DFG::DesiredIdentifiers::processCodeBlockIdentifiersIfNeeded):
(JSC::DFG::DesiredIdentifiers::ensure):
(JSC::DFG::DesiredIdentifiers::at const):
(JSC::DFG::DesiredIdentifiers::reallyAdd):
* dfg/DFGDesiredIdentifiers.h:
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
* dfg/DFGInPlaceAbstractState.cpp:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addGetByVal):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasUidOperand):
(JSC::DFG::Node::hasGetByStatus):
(JSC::DFG::Node::getByStatus):
(JSC::DFG::Node::hasGetByIdStatus): Deleted.
(JSC::DFG::Node::getByIdStatus): Deleted.
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetById):
(JSC::DFG::SpeculativeJIT::compileCheckIdent):
(JSC::DFG::SpeculativeJIT::compileCheckStringIdent): Deleted.
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckIdent):
(JSC::FTL::DFG::LowerDFGToB3::compileGetById):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToB3::getByIdWithThis):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckStringIdent): Deleted.
* jit/ICStats.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::garbageStubInfo):
(JSC::JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator):
(JSC::JITInstanceOfGenerator::JITInstanceOfGenerator):
(JSC::JITGetByValGenerator::JITGetByValGenerator):
(JSC::JITGetByValGenerator::generateFastPath):
(JSC::JITGetByValGenerator::finalize):
* jit/JITInlineCacheGenerator.h:
(JSC::JITGetByValGenerator::JITGetByValGenerator):
(JSC::JITGetByValGenerator::slowPathJump const):
* jit/JITInlines.h:
(JSC::JIT::emitDoubleGetByVal): Deleted.
(JSC::JIT::emitContiguousGetByVal): Deleted.
(JSC::JIT::emitArrayStorageGetByVal): Deleted.
* jit/JITOperations.cpp:
(JSC::getByVal):
(JSC::tryGetByValOptimize): Deleted.
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(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::emitGetByValWithCachedId): Deleted.
(JSC::JIT::privateCompileGetByVal): Deleted.
(JSC::JIT::privateCompileGetByValWithCachedId): Deleted.
(JSC::JIT::emitDirectArgumentsGetByVal): Deleted.
(JSC::JIT::emitScopedArgumentsGetByVal): Deleted.
(JSC::JIT::emitIntTypedArrayGetByVal): Deleted.
(JSC::JIT::emitFloatTypedArrayGetByVal): Deleted.
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_get_by_val):
(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::emitGetByValWithCachedId): Deleted.
* jit/Repatch.cpp:
(JSC::appropriateOptimizingGetByFunction):
(JSC::appropriateGetByFunction):
(JSC::tryCacheGetBy):
(JSC::repatchGetBy):
(JSC::tryCacheArrayGetByVal):
(JSC::repatchArrayGetByVal):
(JSC::tryCachePutByID):
(JSC::tryCacheInByID):
(JSC::tryCacheInstanceOf):
(JSC::resetGetBy):
(JSC::appropriateOptimizingGetByIdFunction): Deleted.
(JSC::appropriateGetByIdFunction): Deleted.
(JSC::tryCacheGetByID): Deleted.
(JSC::repatchGetByID): Deleted.
(JSC::resetGetByID): Deleted.
* jit/Repatch.h:
* llint/LowLevelInterpreter.h:
* runtime/DOMAnnotation.h:
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dumpInContextAssumingStructure const):
* runtime/Structure.h:
Canonical link: https://commits.webkit.org/217668@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252684 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-20 05:53:38 +00:00
|
|
|
bytecode/GetByStatus.cpp
|
2021-06-10 06:26:12 +00:00
|
|
|
bytecode/GetByVariant.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/GetterSetterAccessCase.cpp
|
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
|
|
|
bytecode/ICStatusMap.cpp
|
|
|
|
bytecode/ICStatusUtils.cpp
|
2021-06-04 03:10:54 +00:00
|
|
|
bytecode/InByStatus.cpp
|
2021-06-10 06:26:12 +00:00
|
|
|
bytecode/InByVariant.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/InlineAccess.cpp
|
|
|
|
bytecode/InlineCallFrame.cpp
|
|
|
|
bytecode/InlineCallFrameSet.cpp
|
2018-05-18 17:29:56 +00:00
|
|
|
bytecode/InstanceOfAccessCase.cpp
|
2018-05-19 22:00:21 +00:00
|
|
|
bytecode/InstanceOfStatus.cpp
|
|
|
|
bytecode/InstanceOfVariant.cpp
|
2018-10-29 13:16:03 +00:00
|
|
|
bytecode/InstructionStream.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/IntrinsicGetterAccessCase.cpp
|
|
|
|
bytecode/JumpTable.cpp
|
2018-05-11 21:16:05 +00:00
|
|
|
bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/LazyOperandValueProfile.cpp
|
[JSC] Introduce LinkTimeConstant mechanism
https://bugs.webkit.org/show_bug.cgi?id=153792
Reviewed by Saam Barati.
Source/JavaScriptCore:
We are using private-name-variables of JSGlobalObject as a way to access to constants that are materialized per JSGlobalObject.
And we also have special-pointers and old link-time-constants to access to per JSGlobalObject constants.
We have bytecode intrinsic constants, but it is only available for per VM values.
However, these ones have multiple problems.
1. private-name-variables is too costly. We need to have an entry in JSGlobalObject's variable, this makes SymbolTable of JSGlobalObject large.
It also requires WatchpointSet to make it constant-fold in DFG. And accessing these variables from builtin JS takes op_resolve_scope and op_get_from_scope,
enlarging bytecode and slow in interpreter and baseline compared to just getting them as a constant register.
2. special-pointers are tailored to op_jne_ptr opcode, and not usable in the other bytecode since this is completely separate from VirtualRegister.
3. Old link-time-constants implementation is putting array of all link-time-constants on each UnlinkedCodeBlock, even if it is not used. If you increase # of
link-time-constant, it increases sizeof(UnlinkedCodeBlock).
In this patch, we introduce a new link-time-constant mechanism and remove the above old ones mostly. (private-name-variables still exists for WebCore and @assert).
We manage link-time-constants in BytecodeIntrinsicRegistry, and emit Int32:LinkTimeConstantID constant when generating an UnlinkedCodeBlock. Later, this constant
is alternated to an actual value when we link UnlinkedCodeBlock to CodeBlock with specific JSGlobalObject. private-name-variables accesses are now converted to
constant register so that it is very efficiently accessed and it reduces memory used for SymbolTable and WatchpointSet. op_jne_ptr takes link-time-constant
VirtualRegisters instead of special-pointers, so that we can remove special-pointers mechanism. We also replace old link-time-constants with new one, which reduces
sizeof(UnlinkedCodeBlock).
Furthermore, new link-time-constant supports lazy initialization by using LazyProperty in JSGlobalObject. This allows us to lazily generate many internal functions
that are previously initialized eagerly. This reduces # of allocated JSFunction significantly when initializing JSGlobalObject.
This patch also manually adds 256 to MarkedSpace's size-class. We empirically know that adding 256 here makes sequence of size-class better for memory consumption.
But this was achieved by adding `sizeof(UnlinkedFunctionCodeBlock)`. Now sizeof(UnlinkedFunctionCodeBlock) is changed by this patch, and this patch unintentionally
breaks that sequence. We should explicitly add 256 instead of adding sizeof(UnlinkedFunctionCodeBlock) adhocly.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Scripts/wkbuiltins/builtins_generate_combined_header.py:
(generate_section_for_global_private_code_name_macro):
* Sources.txt:
* builtins/BuiltinNames.h:
* builtins/PromiseConstructor.js:
(nakedConstructor.Promise):
(nakedConstructor.InternalPromise):
(nakedConstructor.Promise.reject): Deleted.
(nakedConstructor.InternalPromise.reject): Deleted.
* bytecode/BytecodeDumper.cpp:
(JSC::CodeBlockBytecodeDumper<Block>::dumpConstants):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
(JSC::BytecodeIntrinsicRegistry::lookup const):
* bytecode/BytecodeIntrinsicRegistry.h:
(JSC::BytecodeIntrinsicRegistry::Entry::Entry):
(JSC::BytecodeIntrinsicRegistry::Entry::type const):
(JSC::BytecodeIntrinsicRegistry::Entry::linkTimeConstant const):
(JSC::BytecodeIntrinsicRegistry::Entry::emitter const):
* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantRegisters):
* bytecode/Fits.h:
* bytecode/LinkTimeConstant.cpp: Renamed from Source/JavaScriptCore/bytecode/SpecialPointer.h.
(WTF::printInternal):
* bytecode/LinkTimeConstant.h: Added.
* bytecode/SpecialPointer.cpp: Removed.
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::addConstant):
(JSC::UnlinkedCodeBlock::registerIndexForLinkTimeConstant): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
(JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
(JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
(JSC::BytecodeGenerator::emitCallDefineProperty):
(JSC::BytecodeGenerator::emitGetAsyncIterator):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ImportNode::emitBytecode):
(JSC::BytecodeIntrinsicNode::emitBytecode):
(JSC::promiseInternalFieldIndex):
(JSC::generatorInternalFieldIndex):
(JSC::asyncGeneratorInternalFieldIndex):
(JSC::FunctionNode::emitBytecode):
(JSC::ObjectPatternNode::bindValue const):
(JSC::ObjectSpreadExpressionNode::emitBytecode):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* heap/MarkedSpace.cpp:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_jneq_ptr):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_jneq_ptr):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createResolve):
(JSC::ASTBuilder::makeFunctionCallNode):
* parser/NodeConstructors.h:
(JSC::BytecodeIntrinsicNode::BytecodeIntrinsicNode):
* parser/Nodes.h:
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlock<CodeBlockType>::decode const):
(JSC::CachedCodeBlock<CodeBlockType>::encode):
* runtime/JSCJSValue.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::linkTimeConstant const):
(JSC::JSGlobalObject::callFunction const): Deleted.
(JSC::JSGlobalObject::applyFunction const): Deleted.
(JSC::JSGlobalObject::throwTypeErrorFunction const): Deleted.
(JSC::JSGlobalObject::newPromiseCapabilityFunction const): Deleted.
(JSC::JSGlobalObject::resolvePromiseFunction const): Deleted.
(JSC::JSGlobalObject::rejectPromiseFunction const): Deleted.
(JSC::JSGlobalObject::promiseProtoThenFunction const): Deleted.
(JSC::JSGlobalObject::regExpProtoExecFunction const): Deleted.
(JSC::JSGlobalObject::regExpProtoGlobalGetter const): Deleted.
(JSC::JSGlobalObject::regExpProtoUnicodeGetter const): Deleted.
(JSC::JSGlobalObject::actualPointerFor): Deleted.
(JSC::JSGlobalObject::jsCellForLinkTimeConstant): Deleted.
* runtime/JSGlobalObjectInlines.h:
(JSC::JSGlobalObject::throwTypeErrorFunction const):
(JSC::JSGlobalObject::newPromiseCapabilityFunction const):
(JSC::JSGlobalObject::resolvePromiseFunction const):
(JSC::JSGlobalObject::rejectPromiseFunction const):
(JSC::JSGlobalObject::promiseProtoThenFunction const):
(JSC::JSGlobalObject::regExpProtoExecFunction const):
(JSC::JSGlobalObject::regExpProtoGlobalGetter const):
(JSC::JSGlobalObject::regExpProtoUnicodeGetter const):
LayoutTests:
* inspector/debugger/tail-deleted-frames/tail-deleted-frames-this-value-expected.txt:
Canonical link: https://commits.webkit.org/217190@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252032 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-05 02:52:02 +00:00
|
|
|
bytecode/LinkTimeConstant.cpp
|
2018-10-29 13:16:03 +00:00
|
|
|
bytecode/MetadataTable.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/MethodOfGettingAValueProfile.cpp
|
|
|
|
bytecode/ModuleNamespaceAccessCase.cpp
|
|
|
|
bytecode/ModuleProgramCodeBlock.cpp
|
|
|
|
bytecode/ObjectPropertyCondition.cpp
|
|
|
|
bytecode/ObjectPropertyConditionSet.cpp
|
|
|
|
bytecode/Opcode.cpp
|
2018-03-24 19:04:18 +00:00
|
|
|
bytecode/ParseHash.cpp
|
Implement polymorphic prototypes
https://bugs.webkit.org/show_bug.cgi?id=176391
Reviewed by Filip Pizlo.
JSTests:
* microbenchmarks/poly-proto-access.js: Added.
(assert):
(foo.C):
(foo.C.prototype.get bar):
(foo):
(bar):
* microbenchmarks/poly-proto-put-transition-speed.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(performSet):
* microbenchmarks/poly-proto-setter-speed.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo.C.prototype.set p):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(performSet):
* stress/constructor-with-return.js:
(i.tests.forEach.Constructor):
(i.tests.forEach):
(tests.forEach.Constructor): Deleted.
(tests.forEach): Deleted.
* stress/dom-jit-with-poly-proto.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(validate):
* stress/poly-proto-custom-value-and-accessor.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(items.forEach):
(set get for):
* stress/poly-proto-intrinsic-getter-correctness.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(foo):
* stress/poly-proto-miss.js: Added.
(makePolyProtoInstanceWithNullPrototype.foo.C):
(makePolyProtoInstanceWithNullPrototype.foo):
(makePolyProtoInstanceWithNullPrototype):
(assert):
(validate):
* stress/poly-proto-op-in-caching.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(validate):
(validate2):
* stress/poly-proto-put-transition.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(performSet):
(i.obj.__proto__.set p):
* stress/poly-proto-set-prototype.js: Added.
(assert):
(let.alternateProto.get x):
(let.alternateProto2.get y):
(let.alternateProto2.get x):
(foo.C):
(foo):
(validate):
* stress/poly-proto-setter.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo.C.prototype.set p):
(makePolyProtoObject.foo.C.prototype.get p):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(performSet):
* stress/poly-proto-using-inheritance.js: Added.
(assert):
(foo.C):
(foo.C.prototype.get baz):
(foo):
(bar.C):
(bar):
(validate):
* stress/primitive-poly-proto.js: Added.
(makePolyProtoInstance.foo.C):
(makePolyProtoInstance.foo):
(makePolyProtoInstance):
(assert):
(validate):
* stress/prototype-is-not-js-object.js: Added.
(foo.bar):
(foo):
(assert):
(validate):
* stress/try-get-by-id-poly-proto.js: Added.
(assert):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(tryGetByIdText):
(x.__proto__.get bar):
(validate):
* typeProfiler/overflow.js:
Source/JavaScriptCore:
This patch changes JSC's object model with respect to where the prototype
of an object is stored. Previously, it was always stored as
a constant value inside Structure. So an object's structure used to
always tell you what its prototype is. Anytime an object changed
its prototype, it would do a structure transition. This enables
a large class of optimizations: just by doing a structure check,
we know what the prototype is.
However, this design falls down when you have many objects that
have the same shape, but only differ in what their prototype value
is. This arises in many JS programs. A simple, and probably common, example
is when the program has a constructor inside of a function:
```
function foo() {
class C {
constructor() { this.field1 = 42; ...; this.fieldN = 42; }
method1() { doStuffWith(this.field); }
method2() { doStuffWith(this.field); }
}
let c = new C;
do things with c;
}
repeatedly call foo() here.
```
Before this patch, in the above program, each time `new C` created an
object, it would create an object with a different structure. The
reason for this is that each time foo is called, there is a new
instance of C.prototype. However, each `new C` that was created
with have identical shape sans its prototype value. This would
cause all ICs that used `c` to quickly give up on any form of caching
because they would see too many structures and give up and permanently
divert control flow to the slow path.
This patch fixes this issue by expanding the notion of where the prototype
of an object is stored. There are now two notions of where the prototype
is stored. A Structure can now be in two modes:
1. Mono proto mode. This is the same mode as we used to have. It means
the structure itself has a constant prototype value.
2. Poly proto mode. This means the structure knows nothing about the
prototype value itself. Objects with this structure store their prototype
in normal object field storage. The structure will tell you the offset of
this prototype inside the object's storage. As of today, we only reserve
inline slots for the prototype field because poly proto only occurs
for JSFinalObject. However, this will be expanded to support out of line
offsets in a future patch when we extend poly proto to work when we inherit
from builtin types like Map and Array.
In this initial patch, we do poly proto style inline caching whenever
we see an object that is poly proto or if an object in its prototype lookup
chain is poly proto. Poly proto ICs work by verifying the lookup chain
at runtime. This essentially boils down to performing structure checks
up the prototype chain. In a future patch, we're going to extend object
property condition set to work with objects that don't have poly proto bases.
Initially, accesses that have poly proto access chains will always turn
into GetById/PutById in the DFG. In a future patch, I'm going to teach
the DFG how to inline certain accesses that have poly proto in the access
chain.
One of most interesting parts about this patch is how we decide when to go
poly proto. This patch uses a profiling based approach. An IC will inform
a watchpoint that it sees an opportunity when two Structure's are structurally
the same, sans the base object's prototype. This means that two structures
have equivalent shapes all the way up the prototype chain. To support fast
structural comparison, we compute a hash for a structure based on the properties
it has. We compute this hash as we add properties to the structure. This
computation is nearly free since we always add UniquedStringImpl*'s which
already have their hashes computed. To compare structural equivalence, we
just compare hash values all the way up the prototype chain. This means we
can get hash conflicts between two structures, but it's extremely rare. First,
it'll be rare for two structures to have the same hash. Secondly, we only
consider structures originating from the same executable.
How we set up this poly proto watchpoint is crucial to its design. When we create_this
an object originating from some executable, that executable will create a Box<InlineWatchpointSet>.
Each structure that originates from this executable will get a copy of that
Box<InlineWatchpointSet>. As that structure transitions to new structures,
they too will get a copy of that Box<InilneWatchpointSet>. Therefore, when
invalidating an arbitrary structure's poly proto watchpoint, we will know
the next time we create_this from that executable that it had been
invalidated, and that we should create an object with a poly proto
structure. We also use the pointer value of this Box<InlineWatchpointSet>
to determine if two structures originated from the same executable. This
pruning will severely limit the chances of getting a hash conflict in practice.
This patch is neutral on my MBP on traditional JS benchmarks like Octane/Kraken/Sunspider.
It may be a 1-2% ARES-6 progression.
This patch is between neutral and a 9x progression on the various tests
I added. Most of the microbenchmarks are progressed by at least 50%.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinNames.cpp:
* builtins/BuiltinNames.h:
(JSC::BuiltinNames::BuiltinNames):
(JSC::BuiltinNames::underscoreProtoPrivateName const):
* bytecode/AccessCase.cpp:
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::create):
(JSC::AccessCase::commit):
(JSC::AccessCase::guardedByStructureCheck const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::visitWeak const):
(JSC::AccessCase::propagateTransitions const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::usesPolyProto const):
(JSC::AccessCase::AccessCase):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
* bytecode/GetterSetterAccessCase.cpp:
(JSC::GetterSetterAccessCase::GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::create):
* bytecode/GetterSetterAccessCase.h:
* bytecode/InternalFunctionAllocationProfile.h:
(JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase):
* bytecode/IntrinsicGetterAccessCase.cpp:
(JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
* bytecode/IntrinsicGetterAccessCase.h:
* bytecode/ModuleNamespaceAccessCase.cpp:
(JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
* bytecode/ObjectAllocationProfile.cpp: Added.
(JSC::ObjectAllocationProfile::initializeProfile):
(JSC::ObjectAllocationProfile::possibleDefaultPropertyCount):
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfile::clear):
(JSC::ObjectAllocationProfile::initialize): Deleted.
(JSC::ObjectAllocationProfile::possibleDefaultPropertyCount): Deleted.
* bytecode/ObjectPropertyConditionSet.cpp:
* bytecode/PolyProtoAccessChain.cpp: Added.
(JSC::PolyProtoAccessChain::create):
(JSC::PolyProtoAccessChain::needImpurePropertyWatchpoint const):
(JSC::PolyProtoAccessChain::operator== const):
(JSC::PolyProtoAccessChain::dump const):
* bytecode/PolyProtoAccessChain.h: Added.
(JSC::PolyProtoAccessChain::clone):
(JSC::PolyProtoAccessChain:: const):
(JSC::PolyProtoAccessChain::operator!= const):
(JSC::PolyProtoAccessChain::forEach const):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::addCases):
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/PolymorphicAccess.h:
(JSC::AccessGenerationResult::shouldResetStub const):
(JSC::AccessGenerationState::AccessGenerationState):
* bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
* bytecode/ProxyableAccessCase.cpp:
(JSC::ProxyableAccessCase::ProxyableAccessCase):
(JSC::ProxyableAccessCase::create):
* bytecode/ProxyableAccessCase.h:
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeForStubInfo):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::addAccessCase):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::load):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::canDoFastSpread):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
(JSC::DFG::SpeculativeJIT::compileInstanceOf):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileInstanceOf):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_instanceof):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_instanceof):
* jit/Repatch.cpp:
(JSC::tryCacheGetByID):
(JSC::tryCachePutByID):
(JSC::tryRepatchIn):
* jsc.cpp:
(WTF::DOMJITGetterBaseJSObject::DOMJITGetterBaseJSObject):
(WTF::DOMJITGetterBaseJSObject::createStructure):
(WTF::DOMJITGetterBaseJSObject::create):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::DOMJITAttribute):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::slowCall):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::callDOMGetter):
(WTF::DOMJITGetterBaseJSObject::customGetter):
(WTF::DOMJITGetterBaseJSObject::finishCreation):
(GlobalObject::finishCreation):
(functionCreateDOMJITGetterBaseJSObject):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/ArrayPrototype.cpp:
(JSC::holesMustForwardToPrototype):
(JSC::fastJoin):
(JSC::arrayProtoFuncReverse):
(JSC::moveElements):
* runtime/ClonedArguments.cpp:
(JSC::ClonedArguments::createEmpty):
(JSC::ClonedArguments::createWithInlineFrame):
(JSC::ClonedArguments::createWithMachineFrame):
(JSC::ClonedArguments::createByCopyingFrom):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/FunctionExecutable.cpp:
(JSC::FunctionExecutable::visitChildren):
* runtime/FunctionExecutable.h:
* runtime/FunctionRareData.cpp:
(JSC::FunctionRareData::initializeObjectAllocationProfile):
* runtime/FunctionRareData.h:
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::createSubclassStructureSlow):
* runtime/JSArray.cpp:
(JSC::JSArray::fastSlice):
(JSC::JSArray::shiftCountWithArrayStorage):
(JSC::JSArray::shiftCountWithAnyIndexingType):
(JSC::JSArray::isIteratorProtocolFastAndNonObservable):
* runtime/JSArrayInlines.h:
(JSC::JSArray::canFastCopy):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dumpInContextAssumingStructure const):
* runtime/JSFunction.cpp:
(JSC::JSFunction::prototypeForConstruction):
(JSC::JSFunction::allocateAndInitializeRareData):
(JSC::JSFunction::initializeRareData):
(JSC::JSFunction::getOwnPropertySlot):
* runtime/JSFunction.h:
* runtime/JSMap.cpp:
(JSC::JSMap::isIteratorProtocolFastAndNonObservable):
(JSC::JSMap::canCloneFastAndNonObservable):
* runtime/JSObject.cpp:
(JSC::JSObject::putInlineSlow):
(JSC::JSObject::createInitialIndexedStorage):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::convertUndecidedToArrayStorage):
(JSC::JSObject::convertInt32ToArrayStorage):
(JSC::JSObject::convertDoubleToArrayStorage):
(JSC::JSObject::convertContiguousToArrayStorage):
(JSC::JSObject::ensureInt32Slow):
(JSC::JSObject::ensureDoubleSlow):
(JSC::JSObject::ensureContiguousSlow):
(JSC::JSObject::ensureArrayStorageSlow):
(JSC::JSObject::setPrototypeDirect):
(JSC::JSObject::ordinaryToPrimitive const):
(JSC::JSObject::putByIndexBeyondVectorLength):
(JSC::JSObject::putDirectIndexSlowOrBeyondVectorLength):
(JSC::JSObject::getEnumerableLength):
(JSC::JSObject::anyObjectInChainMayInterceptIndexedAccesses const):
(JSC::JSObject::prototypeChainMayInterceptStoreTo):
(JSC::JSObject::needsSlowPutIndexing const):
(JSC::JSObject::suggestedArrayStorageTransition const):
* runtime/JSObject.h:
(JSC::JSObject::finishCreation):
(JSC::JSObject::getPrototypeDirect const):
(JSC::JSObject::getPropertySlot):
* runtime/JSObjectInlines.h:
(JSC::JSObject::getPropertySlot):
(JSC::JSObject::getNonIndexPropertySlot):
(JSC::JSObject::putInlineForJSObject):
* runtime/JSPropertyNameEnumerator.h:
(JSC::propertyNameEnumerator):
* runtime/JSSet.cpp:
(JSC::JSSet::isIteratorProtocolFastAndNonObservable):
(JSC::JSSet::canCloneFastAndNonObservable):
* runtime/LazyClassStructure.h:
(JSC::LazyClassStructure::prototypeConcurrently const): Deleted.
* runtime/Operations.cpp:
(JSC::normalizePrototypeChain):
* runtime/Operations.h:
* runtime/Options.h:
* runtime/PrototypeMap.cpp:
(JSC::PrototypeMap::createEmptyStructure):
(JSC::PrototypeMap::emptyStructureForPrototypeFromBaseStructure):
(JSC::PrototypeMap::emptyObjectStructureForPrototype):
(JSC::PrototypeMap::clearEmptyObjectStructureForPrototype):
* runtime/PrototypeMap.h:
* runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::create):
(JSC::Structure::holesMustForwardToPrototype const):
(JSC::Structure::changePrototypeTransition):
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::toStructureShape):
(JSC::Structure::dump const):
(JSC::Structure::canCachePropertyNameEnumerator const):
(JSC::Structure::anyObjectInChainMayInterceptIndexedAccesses const): Deleted.
(JSC::Structure::needsSlowPutIndexing const): Deleted.
(JSC::Structure::suggestedArrayStorageTransition const): Deleted.
(JSC::Structure::prototypeForLookup const): Deleted.
(JSC::Structure::prototypeChainMayInterceptStoreTo): Deleted.
(JSC::Structure::canUseForAllocationsOf): Deleted.
* runtime/Structure.h:
* runtime/StructureChain.h:
* runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::storedPrototypeObject const):
(JSC::Structure::storedPrototypeStructure const):
(JSC::Structure::storedPrototype const):
(JSC::prototypeForLookupPrimitiveImpl):
(JSC::Structure::prototypeForLookup const):
(JSC::Structure::prototypeChain const):
(JSC::Structure::isValid const):
(JSC::Structure::add):
(JSC::Structure::setPropertyTable):
(JSC::Structure::shouldConvertToPolyProto):
* runtime/StructureRareData.h:
* runtime/TypeProfilerLog.cpp:
(JSC::TypeProfilerLog::processLogEntries):
* runtime/TypeSet.cpp:
(JSC::TypeSet::addTypeInformation):
* runtime/TypeSet.h:
* runtime/WriteBarrier.h:
(JSC::WriteBarrierBase<Unknown>::isInt32 const):
Source/WTF:
* wtf/Box.h:
(WTF::Box::operator bool const):
(WTF::Box::operator bool): Deleted.
Make Box movable. Also ensure its operator bool doesn't do an atomic increment.
* wtf/RefPtr.h:
(WTF::RefPtr::operator bool const):
Add `explicit operator bool()` for RefPtr.
Tools:
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/194106@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222827 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-04 01:53:18 +00:00
|
|
|
bytecode/PolyProtoAccessChain.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/PolymorphicAccess.cpp
|
|
|
|
bytecode/PreciseJumpTargets.cpp
|
|
|
|
bytecode/ProgramCodeBlock.cpp
|
|
|
|
bytecode/PropertyCondition.cpp
|
|
|
|
bytecode/ProxyableAccessCase.cpp
|
|
|
|
bytecode/PutByIdFlags.cpp
|
|
|
|
bytecode/PutByIdStatus.cpp
|
|
|
|
bytecode/PutByIdVariant.cpp
|
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
|
|
|
bytecode/RecordedStatuses.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/ReduceWhitespace.cpp
|
[ESNext] Implement private methods
https://bugs.webkit.org/show_bug.cgi?id=194434
Reviewed by Filip Pizlo.
JSTests:
* stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
* stress/private-brand-installed-after-super-call-from-eval.js: Added.
* stress/private-method-brand-check.js: Added.
* stress/private-method-change-attribute-from-branded-structure.js: Added.
* stress/private-method-change-prototype-from-branded-structure.js: Added.
* stress/private-method-check-private-brand-ic.js: Added.
* stress/private-method-check-structure-miss.js: Added.
* stress/private-method-comparison.js: Added.
* stress/private-method-delete-property-from-branded-structure.js: Added.
* stress/private-method-extends-brand-check.js: Added.
* stress/private-method-get-and-call.js: Added.
* stress/private-method-invalid-multiple-brand-installation.js: Added.
* stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
* stress/private-method-nested-class.js: Added.
* stress/private-method-on-sealed-objects.js: Added.
* stress/private-method-on-uncacheable-dictionary.js: Added.
* stress/private-method-polymorphic-with-constant-symbol.js: Added.
* stress/private-method-set-brand-should-have-write-barrier.js: Added.
* stress/private-method-untyped-use.js: Added.
* stress/private-method-with-uncacheable-dictionary-transition.js: Added.
* stress/private-methods-inline-cache.js: Added.
* stress/private-methods-megamorphic-ic.js: Added.
* stress/private-methods-on-proxy.js: Added.
* stress/private-methods-poly-ic-multiple-classes.js: Added.
* stress/private-methods-poly-ic-single-class.js: Added.
* stress/private-names-available-on-direct-eval.js: Added.
* test262/config.yaml:
Source/JavaScriptCore:
This patch is adding support to private methods following the
specification on https://tc39.es/proposal-private-methods/.
This is introducing a new way to declare private methods on
class syntax. Private methods are only accessible within
classes they were declared, and only can be called from
objects that are instance of these classes.
To guarantee such rules, the proposal presents the concept of
Brand Check. During class evaluation, if a private method is present,
a `brand` is installed in this class. Every instance of such class
then gets this brand installed during `[[Construct]]` operation. It
means that an object can have multiple brands (e.g when there is also
private methods declared on super class). Before accessing a private
method, there is a check to validate if the target of the call has the
brand of callee method.
The brand check mechanism is implemented using a `@privateBrand`
stored on class scope. Here is a representation of how this mechanism
works:
```
class C {
#m() { return 3; }
method() { return this.#m(); }
}
let c = new C();
console.log(c.method()); // prints 3
```
Generated bytecode for the following representation:
```
{ // class lexical scope
const @privateBrand = @createPrivateSymbol();
const #m = function () { return 3; }
C.prototype.method = function() {
@check_private_brand(this, @privateBrand);
return #m.call(this);
}
C = function() {
@set_private_brand(this, @privateBrand);
}
}
let c = new C();
console.log(c.method()); // prints 3
```
# Resolving correct brand to check
In the case of shadowing or nested scope, we need to emit brand
checks to the right private brand. See code below:
```
class C {
#m() { return 3; }
method() { return this.#m();}
A = class {
#m2() { return 3; }
foo(o) { return o.#m(); }
}
}
```
The call of "#m" in `foo` refers to "C::#m". In such case, we need to
check C's private brand, instead of A's private brand.
To perform the proper check, we first resolve scope of "#m" and then
check the private brand of this scope (the scope where the private
method and brand are stored is the same).
So the bytecode to lookup the right brand is:
```
mov loc9, arg1
resolve_scope loc10, "#m"
get_from_scope loc11, loc10, "@privateBrand"
check_private_brand loc9, loc11
get_from_scope loc11, loc10, "#m"
// setup call frame
call loc11, ...
// ...
```
# Brand check mechanism
We are introducing in this patch 2 new bytecodes to allow brand check
of objects: `op_set_brand` and `op_check_brand`.
`op_set_brand` sets a new brand in an object, so we can perform the brand
check later when accessing private methods. This operations throws when
trying to add the same brand twice in an Object.
`op_check_brand` checks if the given object contains the brand we are
looking for. It traverses the brand chain to verify if the brand is
present, and throws `TypeError` otherwise.
We are also introducing a subclass for Structure called BrandedStructure.
It is used to store brands and to allow brand check mechanism. BrandedStructure
stores a brand and a parent pointer to another BrandedStructure that allow
us traverse the brand chain. With `BrandedStructure`, we can then
infer that a given object has the brand we are looking for just
checking its structureId. This is a very good optimization, since we can
reduce most of brand checks to structure checks.
We created a new kind of transition called `SetBrand` that happens when
`op_set_brand` is executed. This allow us to cache such kind of
trasitions on trasition table using the key `<brand->uid, 0,
TransitionKind::SetBrand>`. During this transition, we take previous
structure and apply one of the following rules:
1. If it's a BrandedStructure, we then set it to `m_parentBrand`,
to allow proper brand chain check.
2. If it's not a BrandedStructure, we set `m_parentBrand` to `nullptr`,
meaning that this is the first brand being added to the object
with this structure.
For now, we are using the flag `isBrandedStructure` to identify that a
given Structure is a BrandedStructure. This is done to avoid changes
on places where we are checking for `vm.structureStructure()`.
However, if we ever need space on Structure, this flag is a good
candidate to be deleted and we can move to a solution that uses
`vm.brandedStructureStructure()`;
# JIT Support
This patch also includes initial JIT support for `set_private_brand`
and `check_private_brand`. On Baseline JIT, we are using
`JITPravateBrandAccessGenerator` to support IC for both operands.
On `DFGByteCodeParser` we are trying to inline brand access whenever
possible, and fallbacking to `SetPrivateBrand` and
`CheckPrivateBrand` otherwise. Those nodes are not being optimized at
their full potential, but the code generated by them is also relying on
`JITPrivateBrandAccessGenerator` to have IC support for both DFG and
FTL. During DFG parsing, we try to reduce those access to `CheckIsConstant`
and `CheckStructure` (with `PutStructure` for `set_private_brand` cases)
based on available profiled data. This is meant to make brand checks
almost free on DFG/FTL tiers when we have a single evaluation of a
class, since the `CheckIsConstant` can be eliminated by the constant-folded
scope load, and the `CheckStructure` is very likely to be redundant
to any other `CheckStructure` that can be performed on receiver
when we have a finite structure set.
For instance, when we have a brand check on a path-of-no-return to
a `GetByOffset` sequence on the same receiver, the `CheckStructure`
for the brand check will enable CSE of the `CheckStructure` that
would happen for that `GetByOffset`. Such design is possible because brand
checks supports polymorphic access very similr to what we have for
`GetByOffset` sequences.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):
* builtins/BuiltinExecutables.h:
We are adding a new parameter `PrivateBrandRequirement` to propagate
when a default constructor needs to emit code to setup private brand
on instances.
* builtins/BuiltinNames.h:
Adding `@privateBrand` that we use to store private brand on
class's scope.
* bytecode/AccessCase.cpp:
(JSC::AccessCase::createCheckPrivateBrand):
(JSC::AccessCase::createSetPrivateBrand):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::structure const):
(JSC::AccessCase::newStructure const):
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CheckPrivateBrandStatus.cpp: Added.
(JSC::CheckPrivateBrandStatus::appendVariant):
(JSC::CheckPrivateBrandStatus::computeForBaseline):
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
(JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::CheckPrivateBrandStatus::computeFor):
(JSC::CheckPrivateBrandStatus::slowVersion const):
(JSC::CheckPrivateBrandStatus::merge):
(JSC::CheckPrivateBrandStatus::filter):
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
(JSC::CheckPrivateBrandStatus::visitAggregate):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::finalize):
(JSC::CheckPrivateBrandStatus::dump const):
* bytecode/CheckPrivateBrandStatus.h: Added.
* bytecode/CheckPrivateBrandVariant.cpp: Added.
(JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::attemptToMerge):
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::finalize):
(JSC::CheckPrivateBrandVariant::visitAggregate):
(JSC::CheckPrivateBrandVariant::dump const):
(JSC::CheckPrivateBrandVariant::dumpInContext const):
* bytecode/CheckPrivateBrandVariant.h: Added.
(JSC::CheckPrivateBrandVariant::structureSet const):
(JSC::CheckPrivateBrandVariant::structureSet):
(JSC::CheckPrivateBrandVariant::identifier const):
(JSC::CheckPrivateBrandVariant::overlaps):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::privateBrandRequirement const):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addCheckPrivateBrandStatus):
(JSC::RecordedStatuses::addSetPrivateBrandStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):
* bytecode/RecordedStatuses.h:
(JSC::RecordedStatuses::forEachVector):
* bytecode/SetPrivateBrandStatus.cpp: Added.
(JSC::SetPrivateBrandStatus::appendVariant):
(JSC::SetPrivateBrandStatus::computeForBaseline):
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
(JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::SetPrivateBrandStatus::computeFor):
(JSC::SetPrivateBrandStatus::slowVersion const):
(JSC::SetPrivateBrandStatus::merge):
(JSC::SetPrivateBrandStatus::filter):
(JSC::SetPrivateBrandStatus::singleIdentifier const):
(JSC::SetPrivateBrandStatus::visitAggregate):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::finalize):
(JSC::SetPrivateBrandStatus::dump const):
* bytecode/SetPrivateBrandStatus.h: Added.
* bytecode/SetPrivateBrandVariant.cpp: Added.
(JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::attemptToMerge):
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::finalize):
(JSC::SetPrivateBrandVariant::visitAggregate):
(JSC::SetPrivateBrandVariant::dump const):
(JSC::SetPrivateBrandVariant::dumpInContext const):
* bytecode/SetPrivateBrandVariant.h: Added.
(JSC::SetPrivateBrandVariant::oldStructure const):
(JSC::SetPrivateBrandVariant::newStructure const):
(JSC::SetPrivateBrandVariant::identifier const):
(JSC::SetPrivateBrandVariant::overlaps):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::privateBrandRequirement const):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
We changed BytecodeGenerator for FunctionNode and EvalNode to
propagate parentScope PrivateNameEnvironment. These environments stores
private name entries that are visible into the scope of the
function/eval.
This is required to identify the kind of access a private name is
referring to, since it can be a private field or a private method.
(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::emitGetPrivateName):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):
The process to create a private brand is as follows:
1. Create a PrivateSymbol using `@createPrivateSymbol`.
2. Store this symbol into a given scope (i.e class lexical scope)
on `@privateBrand` variable.
(JSC::BytecodeGenerator::emitInstallPrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):
We added `m_privateNamesStack` to BytecodeGenerator to represent the
scope chain of available private names while generating bytecode.
(JSC::BytecodeGenerator::emitCheckPrivateBrand):
(JSC::BytecodeGenerator::isPrivateMethod):
(JSC::BytecodeGenerator::pushPrivateAccessNames):
(JSC::BytecodeGenerator::popPrivateAccessNames):
(JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
(JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::privateBrandRequirement const):
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):
This change is required to properly propagate PrivateBrandRequirement
to arrow functions that can potentially call `super()`.
* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitDeclarePrivateFieldNames):
(JSC::PropertyListNode::emitBytecode):
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BaseDotNode::emitGetPropertyValue):
Adding support to properly access private method. Since we store
private methods on class lexical scope, we need a different set of
instructions to access a private method.
(JSC::BaseDotNode::emitPutProperty):
In the case of we trying to write in a private method, we need to
throw a TypeError according to specification
(https://tc39.es/proposal-private-methods/#sec-privatefieldset).
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::ClassExprNode::emitBytecode):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addPrivateBrandAccess):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCheckPrivateBrandStatus):
(JSC::DFG::Node::checkPrivateBrandStatus):
(JSC::DFG::Node::hasSetPrivateBrandStatus):
(JSC::DFG::Node::setPrivateBrandStatus):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
(JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
(JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):
* interpreter/Interpreter.cpp:
(JSC::eval):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::generateFastPath):
(JSC::JITPrivateBrandAccessGenerator::finalize):
* jit/JITInlineCacheGenerator.h:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::slowPathJump const):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::getPrivateName):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/Repatch.cpp:
(JSC::tryCacheCheckPrivateBrand):
(JSC::repatchCheckPrivateBrand):
(JSC::tryCacheSetPrivateBrand):
(JSC::repatchSetPrivateBrand):
(JSC::resetCheckPrivateBrand):
(JSC::resetSetPrivateBrand):
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
(JSC::Scope::declarePrivateMethod):
(JSC::Scope::declarePrivateField):
(JSC::Parser<LexerType>::parse):
(JSC::parse):
(JSC::Scope::declarePrivateName): Deleted.
* parser/ParserModes.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createDotAccess):
* parser/VariableEnvironment.cpp:
(JSC::VariableEnvironment::declarePrivateMethod):
* parser/VariableEnvironment.h:
(JSC::VariableEnvironmentEntry::isPrivateField const):
(JSC::VariableEnvironmentEntry::isPrivateMethod const):
(JSC::VariableEnvironmentEntry::setIsPrivateField):
(JSC::VariableEnvironmentEntry::setIsPrivateMethod):
(JSC::PrivateNameEntry::isMethod const):
(JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
(JSC::VariableEnvironment::addPrivateName):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::privateNameEnvironment const):
(JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
(JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
(JSC::VariableEnvironment::declarePrivateName): Deleted.
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
(JSC::CachedFunctionExecutable::privateBrandRequirement const):
(JSC::CachedCodeBlock::derivedContextType const):
(JSC::CachedFunctionExecutable::encode):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.
* runtime/CodeCache.cpp:
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):
(JSC::generateUnlinkedCodeBlockForDirectEval):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
* runtime/CodeCache.h:
* runtime/DirectEvalExecutable.cpp:
(JSC::DirectEvalExecutable::create):
(JSC::DirectEvalExecutable::DirectEvalExecutable):
* runtime/DirectEvalExecutable.h:
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::EvalExecutable):
* runtime/EvalExecutable.h:
(JSC::EvalExecutable::executableInfo const):
(JSC::EvalExecutable::privateBrandRequirement const):
* runtime/ExceptionHelpers.cpp:
(JSC::createInvalidPrivateNameError):
* runtime/IndirectEvalExecutable.cpp:
(JSC::IndirectEvalExecutable::IndirectEvalExecutable):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::checkPrivateBrand):
(JSC::JSObject::setPrivateBrand):
* runtime/JSScope.cpp:
(JSC::JSScope::collectClosureVariablesUnderTDZ):
* runtime/JSScope.h:
* runtime/ModuleProgramExecutable.h:
* runtime/Options.cpp:
(JSC::Options::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/ProgramExecutable.h:
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyTable):
(JSC::BrandedStructure::BrandedStructure):
(JSC::BrandedStructure::create):
(JSC::BrandedStructure::checkBrand):
(JSC::Structure::setBrandTransitionFromExistingStructureImpl):
(JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
(JSC::Structure::setBrandTransition):
* runtime/Structure.h:
(JSC::Structure::finishCreation):
* runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::forEachPropertyConcurrently):
* runtime/StructureTransitionTable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::cloneScopePart):
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Canonical link: https://commits.webkit.org/233852@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 16:30:24 +00:00
|
|
|
bytecode/SetPrivateBrandStatus.cpp
|
|
|
|
bytecode/SetPrivateBrandVariant.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/SpeculatedType.cpp
|
|
|
|
bytecode/StructureSet.cpp
|
|
|
|
bytecode/StructureStubClearingWatchpoint.cpp
|
|
|
|
bytecode/StructureStubInfo.cpp
|
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
|
|
|
bytecode/StubInfoSummary.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/SuperSampler.cpp
|
|
|
|
bytecode/ToThisStatus.cpp
|
|
|
|
bytecode/TrackedReferences.cpp
|
|
|
|
bytecode/UnlinkedCodeBlock.cpp
|
2020-02-04 19:05:17 +00:00
|
|
|
bytecode/UnlinkedCodeBlockGenerator.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/UnlinkedEvalCodeBlock.cpp
|
|
|
|
bytecode/UnlinkedFunctionCodeBlock.cpp
|
|
|
|
bytecode/UnlinkedFunctionExecutable.cpp
|
2019-05-23 01:47:29 +00:00
|
|
|
bytecode/UnlinkedMetadataTable.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecode/UnlinkedModuleProgramCodeBlock.cpp
|
|
|
|
bytecode/UnlinkedProgramCodeBlock.cpp
|
|
|
|
bytecode/ValueRecovery.cpp
|
|
|
|
bytecode/VariableWriteFireDetail.cpp
|
|
|
|
bytecode/VirtualRegister.cpp
|
|
|
|
bytecode/Watchpoint.cpp
|
|
|
|
|
2019-12-10 19:41:40 +00:00
|
|
|
// Derived Sources
|
|
|
|
BytecodeDumperGenerated.cpp
|
|
|
|
|
2017-09-20 23:08:50 +00:00
|
|
|
bytecompiler/BytecodeGenerator.cpp
|
|
|
|
bytecompiler/NodesCodegen.cpp
|
2018-10-29 13:16:03 +00:00
|
|
|
bytecompiler/ProfileTypeBytecodeFlag.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
|
Web Inspector: allow event breakpoints to be configured
https://bugs.webkit.org/show_bug.cgi?id=215362
<rdar://problem/66932921>
Reviewed by Brian Burg.
Source/JavaScriptCore:
This allows developers to do things like:
- only pause when `window.event.type` is a certain value
- ignore the first N pauses
- evaluate JavaScript whenever an event listener is invoked without pausing
* inspector/protocol/DOM.json:
Add an `options` paramater to `DOM.setBreakpointForEventListener` to allow configuration.
* inspector/protocol/DOMDebugger.json:
Add an `options` paramater to `DOMDebugger.setEventBreakpoint` to allow configuration.
* debugger/Breakpoint.h:
(JSC::Breakpoint::id const): Added.
(JSC::Breakpoint::sourceID const): Added.
(JSC::Breakpoint::lineNumber const): Added.
(JSC::Breakpoint::columnNumber const): Added.
(JSC::Breakpoint::condition const): Added.
(JSC::Breakpoint::actions const): Added.
(JSC::Breakpoint::isAutoContinue const): Added.
(JSC::Breakpoint::resetHitCount): Added.
(JSC::Breakpoint::isLinked const): Added.
(JSC::Breakpoint::isResolved const): Added.
(JSC::BreakpointsList::~BreakpointsList): Deleted.
* debugger/Breakpoint.cpp: Added.
(JSC::Breakpoint::Action::Action): Added.
(JSC::Breakpoint::create): Added.
(JSC::Breakpoint::Breakpoint): Added.
(JSC::Breakpoint::link): Added.
(JSC::Breakpoint::resolve): Added.
(JSC::Breakpoint::shouldPause): Added.
Unify `JSC::Breakpoint` and `Inspector::ScriptBreakpoint`.
* debugger/DebuggerPrimitives.h:
* debugger/Debugger.h:
* debugger/Debugger.cpp:
(JSC::Debugger::Debugger):
(JSC::Debugger::addObserver): Added.
(JSC::Debugger::removeObserver): Added.
(JSC::Debugger::canDispatchFunctionToObservers const): Added.
(JSC::Debugger::dispatchFunctionToObservers): Added.
(JSC::Debugger::sourceParsed): Added.
(JSC::Debugger::toggleBreakpoint):
(JSC::Debugger::applyBreakpoints):
(JSC::Debugger::resolveBreakpoint):
(JSC::Debugger::setBreakpoint):
(JSC::Debugger::removeBreakpoint):
(JSC::Debugger::didHitBreakpoint): Added.
(JSC::Debugger::clearBreakpoints):
(JSC::Debugger::evaluateBreakpointCondition): Added.
(JSC::Debugger::evaluateBreakpointActions): Added.
(JSC::Debugger::schedulePauseAtNextOpportunity): Added.
(JSC::Debugger::cancelPauseAtNextOpportunity): Added.
(JSC::Debugger::schedulePauseForSpecialBreakpoint): Added.
(JSC::Debugger::cancelPauseForSpecialBreakpoint): Added.
(JSC::Debugger::continueProgram):
(JSC::Debugger::stepNextExpression):
(JSC::Debugger::stepIntoStatement):
(JSC::Debugger::stepOverStatement):
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::pauseIfNeeded):
(JSC::Debugger::handlePause): Added.
(JSC::Debugger::exceptionOrCaughtValue): Added.
(JSC::Debugger::atExpression):
(JSC::Debugger::clearNextPauseState):
(JSC::Debugger::willRunMicrotask): Added.
(JSC::Debugger::didRunMicrotask): Added.
(JSC::Debugger::hasBreakpoint): Deleted.
(JSC::Debugger::setPauseOnNextStatement): Deleted.
Unify `JSC::Debugger` and `Inspector::ScriptDebugServer` to simplify breakpoint logic.
Introduce the concept of a "special breakpoint", which is essentially a `JSC::Breakpoint`
that is expected to pause at the next opportunity but isn't tied to a particular location.
As an example, whenever an event breakpoint is hit, instead of just pausing at the next
opportunity, the newly managed `JSC::Breakpoint` is used as a "special breakpoint", allowing
for it's configuration (ie.g. condition, ignore count, actions, auto-continue) to be used.
* inspector/agents/InspectorDebuggerAgent.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::objectGroupForBreakpointAction):
(Inspector::breakpointActionTypeForString): Added.
(Inspector::parseBreakpointOptions): Added.
(Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::fromPayload): Added.
(Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::ProtocolBreakpoint): Added.
(Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::createDebuggerBreakpoint const): Added.
(Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::matchesScriptURL const): Added.
(Inspector::InspectorDebuggerAgent::debuggerBreakpointFromPayload): Added.
(Inspector::InspectorDebuggerAgent::enable):
(Inspector::InspectorDebuggerAgent::disable):
(Inspector::InspectorDebuggerAgent::buildBreakpointPauseReason):
(Inspector::InspectorDebuggerAgent::handleConsoleAssert):
(Inspector::InspectorDebuggerAgent::didScheduleAsyncCall):
(Inspector::buildDebuggerLocation):
(Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
(Inspector::InspectorDebuggerAgent::setBreakpoint):
(Inspector::InspectorDebuggerAgent::didSetBreakpoint):
(Inspector::InspectorDebuggerAgent::resolveBreakpoint):
(Inspector::InspectorDebuggerAgent::removeBreakpoint):
(Inspector::InspectorDebuggerAgent::continueToLocation):
(Inspector::InspectorDebuggerAgent::schedulePauseAtNextOpportunity): Added.
(Inspector::InspectorDebuggerAgent::cancelPauseAtNextOpportunity): Added.
(Inspector::InspectorDebuggerAgent::schedulePauseForSpecialBreakpoint): Added.
(Inspector::InspectorDebuggerAgent::cancelPauseForSpecialBreakpoint): Added.
(Inspector::InspectorDebuggerAgent::pause):
(Inspector::InspectorDebuggerAgent::resume):
(Inspector::InspectorDebuggerAgent::didBecomeIdle):
(Inspector::InspectorDebuggerAgent::sourceMapURLForScript):
(Inspector::InspectorDebuggerAgent::didParseSource):
(Inspector::InspectorDebuggerAgent::willRunMicrotask):
(Inspector::InspectorDebuggerAgent::didRunMicrotask):
(Inspector::InspectorDebuggerAgent::didPause):
(Inspector::InspectorDebuggerAgent::breakpointActionSound):
(Inspector::InspectorDebuggerAgent::breakpointActionProbe):
(Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
(Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
(Inspector::matches): Deleted.
(Inspector::buildObjectForBreakpointCookie): Deleted.
(Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol): Deleted.
(Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement): Deleted.
(Inspector::InspectorDebuggerAgent::cancelPauseOnNextStatement): Deleted.
Create a private `ProtocolBreakpoint` class that holds the data sent by the frontend. This
is necessary because breakpoints in the frontend have a potentially one-to-many relationship
with breakpoints in the backend, as the same script can be loaded many times on a page. Each
of those scripts is independent, however, and can execute differently, meaning that the same
breakpoint for each script also needs a different state (e.g. ignore count). As such, the
`ProtocolBreakpoint` is effectively a template that is actualized whenever a new script is
parsed that matches the URL of the `ProtocolBreakpoint` to create a `JSC::Breakpoint` that
is used by the `JSC::Debugger`. `ProtocolBreakpoint` also parses breakpoint configurations.
* inspector/InspectorEnvironment.h:
* inspector/JSGlobalObjectScriptDebugServer.h:
* inspector/JSGlobalObjectScriptDebugServer.cpp:
(Inspector::JSGlobalObjectScriptDebugServer::JSGlobalObjectScriptDebugServer):
(Inspector::JSGlobalObjectScriptDebugServer::attachDebugger):
(Inspector::JSGlobalObjectScriptDebugServer::detachDebugger):
(Inspector::JSGlobalObjectScriptDebugServer::runEventLoopWhilePaused):
* inspector/agents/InspectorAuditAgent.h:
* inspector/agents/InspectorAuditAgent.cpp:
(Inspector::InspectorAuditAgent::run):
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::setPauseOnExceptionsState):
(Inspector::InspectorRuntimeAgent::evaluate):
(Inspector::InspectorRuntimeAgent::callFunctionOn):
(Inspector::InspectorRuntimeAgent::getPreview):
(Inspector::InspectorRuntimeAgent::getProperties):
(Inspector::InspectorRuntimeAgent::getDisplayableProperties):
* inspector/agents/InspectorScriptProfilerAgent.cpp:
* inspector/agents/JSGlobalObjectDebuggerAgent.h:
Replace `Inspector::ScriptDebugServer` with `JSC::Debugger`.
* runtime/JSMicrotask.cpp:
(JSC::JSMicrotask::run):
Drive-by: r248894 mistakenly omitted the call to notify the debugger that the microtask ran.
* inspector/ScriptBreakpoint.h: Removed.
* inspector/ScriptDebugListener.h: Removed.
* inspector/ScriptDebugServer.h: Removed.
* inspector/ScriptDebugServer.cpp: Removed.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
Source/WebCore:
This allows developers to do things like:
- only pause when `window.event.type` is a certain value
- ignore the first N pauses
- evaluate JavaScript whenever an event listener is invoked without pausing
Tests: inspector/dom/breakpoint-for-event-listener.html
inspector/dom-debugger/event-animation-frame-breakpoints.html
inspector/dom-debugger/event-interval-breakpoints.html
inspector/dom-debugger/event-listener-breakpoints.html
inspector/dom-debugger/event-timeout-breakpoints.html
* inspector/agents/InspectorDOMAgent.h:
* inspector/agents/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::getEventListenersForNode):
(WebCore::InspectorDOMAgent::setBreakpointForEventListener):
(WebCore::InspectorDOMAgent::removeBreakpointForEventListener):
(WebCore::InspectorDOMAgent::buildObjectForEventListener):
(WebCore::InspectorDOMAgent::breakpointForEventListener):
(WebCore::InspectorDOMAgent::hasBreakpointForEventListener): Deleted.
* inspector/agents/InspectorDOMDebuggerAgent.h:
* inspector/agents/InspectorDOMDebuggerAgent.cpp:
(WebCore::InspectorDOMDebuggerAgent::disable):
(WebCore::InspectorDOMDebuggerAgent::mainFrameNavigated):
(WebCore::InspectorDOMDebuggerAgent::setEventBreakpoint):
(WebCore::InspectorDOMDebuggerAgent::removeEventBreakpoint):
(WebCore::InspectorDOMDebuggerAgent::willHandleEvent):
(WebCore::InspectorDOMDebuggerAgent::didHandleEvent):
(WebCore::InspectorDOMDebuggerAgent::willFireTimer):
(WebCore::InspectorDOMDebuggerAgent::didFireTimer):
* inspector/agents/page/PageDOMDebuggerAgent.h:
* inspector/agents/page/PageDOMDebuggerAgent.cpp:
(WebCore::PageDOMDebuggerAgent::disable):
(WebCore::PageDOMDebuggerAgent::mainFrameNavigated):
(WebCore::PageDOMDebuggerAgent::willFireAnimationFrame):
(WebCore::PageDOMDebuggerAgent::didFireAnimationFrame):
(WebCore::PageDOMDebuggerAgent::setAnimationFrameBreakpoint):
* inspector/agents/worker/WorkerDOMDebuggerAgent.h:
* inspector/agents/worker/WorkerDOMDebuggerAgent.cpp:
(WebCore::WorkerDOMDebuggerAgent::setAnimationFrameBreakpoint):
Keep a `JSC::Breakpoint` for each event breakpoint instead of a simple `bool`, allowing for
configuration when the breakpoint is first set. When any of these breakpoints are hit, pass
it to the `JSC::Debugger` as a "special breakpoint", which behaves the same as "pause ASAP"
but also supports a condition, an ignore count, actions, and auto-continue. Reset the hit
count for any of these "special breakpoints" that persist across Web Inspector sessions
when the main frame navigates.
* inspector/PageScriptDebugServer.h:
* inspector/PageScriptDebugServer.cpp:
(WebCore::PageScriptDebugServer::PageScriptDebugServer):
(WebCore::PageScriptDebugServer::attachDebugger):
(WebCore::PageScriptDebugServer::detachDebugger):
(WebCore::PageScriptDebugServer::didPause):
(WebCore::PageScriptDebugServer::didContinue):
(WebCore::PageScriptDebugServer::runEventLoopWhilePaused):
(WebCore::PageScriptDebugServer::runEventLoopWhilePausedInternal):
(WebCore::PageScriptDebugServer::isContentScript const):
(WebCore::PageScriptDebugServer::reportException const):
* inspector/WorkerScriptDebugServer.h:
* inspector/WorkerScriptDebugServer.cpp:
(WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer):
(WebCore::WorkerScriptDebugServer::attachDebugger):
(WebCore::WorkerScriptDebugServer::detachDebugger):
(WebCore::WorkerScriptDebugServer::runEventLoopWhilePaused):
(WebCore::WorkerScriptDebugServer::reportException const):
* inspector/agents/page/PageDebuggerAgent.h:
* inspector/agents/page/PageDebuggerAgent.cpp:
(WebCore::PageDebuggerAgent::sourceMapURLForScript):
Replace `Inspector::ScriptDebugServer` with `JSC::Debugger`.
* inspector/TimelineRecordFactory.h:
* inspector/TimelineRecordFactory.cpp:
(WebCore::TimelineRecordFactory::createProbeSampleData):
* inspector/agents/InspectorTimelineAgent.h:
* inspector/agents/InspectorTimelineAgent.cpp:
(WebCore::InspectorTimelineAgent::internalStart):
(WebCore::InspectorTimelineAgent::internalStop):
(WebCore::InspectorTimelineAgent::breakpointActionProbe):
Replace `Inspector::ScriptBreakpoint` with `JSC::Breakpoint`.
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didHandleEvent):
(WebCore::InspectorInstrumentation::didFireTimer):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didHandleEventImpl):
(WebCore::InspectorInstrumentation::didFireTimerImpl):
(WebCore::InspectorInstrumentation::didCommitLoadImpl):
(WebCore::InspectorInstrumentation::didFireAnimationFrameImpl):
* dom/EventTarget.cpp:
(WebCore::EventTarget::innerInvokeEventListeners):
* page/DOMTimer.cpp:
(WebCore::DOMTimer::fired):
When notifying Web Inspector that activity did occur, include all information previously
included when notifying Web Inspector that that activity was about to occur so that Web
Inspector can know whether a pause for the "special breakpoint" for that activity is still
scheduled and if so cancel it.
Source/WebInspectorUI:
This allows developers to do things like:
- only pause when `window.event.type` is a certain value
- ignore the first N pauses
- evaluate JavaScript whenever an event listener is invoked without pausing
* UserInterface/Models/Breakpoint.js:
(WI.Breakpoint):
(WI.Breakpoint.prototype.toJSON):
(WI.Breakpoint.prototype.get special): Added.
(WI.Breakpoint.prototype.get removable): Added.
(WI.Breakpoint.prototype.get editable): Added.
(WI.Breakpoint.prototype.set condition):
(WI.Breakpoint.prototype.get ignoreCount):
(WI.Breakpoint.prototype.set ignoreCount):
(WI.Breakpoint.prototype.get autoContinue):
(WI.Breakpoint.prototype.set autoContinue):
(WI.Breakpoint.prototype.get actions):
(WI.Breakpoint.prototype.get probeActions):
(WI.Breakpoint.prototype.cycleToNextMode):
(WI.Breakpoint.prototype.createAction):
(WI.Breakpoint.prototype.recreateAction):
(WI.Breakpoint.prototype.removeAction):
(WI.Breakpoint.prototype.clearActions):
(WI.Breakpoint.prototype.remove): Added.
(WI.Breakpoint.prototype.optionsToProtocol): Added.
(WI.Breakpoint.prototype.breakpointActionDidChange):
(WI.Breakpoint.fromJSON): Deleted.
(WI.Breakpoint.prototype.get sourceCodeLocation): Deleted.
(WI.Breakpoint.prototype.get contentIdentifier): Deleted.
(WI.Breakpoint.prototype.get scriptIdentifier): Deleted.
(WI.Breakpoint.prototype.get target): Deleted.
(WI.Breakpoint.prototype.get identifier): Deleted.
(WI.Breakpoint.prototype.set identifier): Deleted.
(WI.Breakpoint.prototype.get resolved): Deleted.
(WI.Breakpoint.prototype.set resolved): Deleted.
(WI.Breakpoint.prototype.saveIdentityToCookie): Deleted.
(WI.Breakpoint.prototype._isSpecial): Deleted.
(WI.Breakpoint.prototype._sourceCodeLocationLocationChanged): Deleted.
(WI.Breakpoint.prototype._sourceCodeLocationDisplayLocationChanged): Deleted.
* UserInterface/Models/DOMBreakpoint.js:
(WI.DOMBreakpoint):
(WI.DOMBreakpoint.fromJSON): Added.
(WI.DOMBreakpoint.prototype.remove): Added.
(WI.DOMBreakpoint.prototype.toJSON):
(WI.DOMBreakpoint.deserialize): Deleted.
(WI.DOMBreakpoint.prototype.get disabled): Deleted.
(WI.DOMBreakpoint.prototype.set disabled): Deleted.
* UserInterface/Models/EventBreakpoint.js:
(WI.EventBreakpoint):
(WI.EventBreakpoint.fromJSON): Added.
(WI.EventBreakpoint.prototype.get special): Added.
(WI.EventBreakpoint.prototype.get editable): Added.
(WI.EventBreakpoint.prototype.remove): Added.
(WI.EventBreakpoint.prototype.saveIdentityToCookie):
(WI.EventBreakpoint.prototype.toJSON):
(WI.EventBreakpoint.deserialize): Deleted.
(WI.EventBreakpoint.prototype.get disabled): Deleted.
(WI.EventBreakpoint.prototype.set disabled): Deleted.
* UserInterface/Models/JavaScriptBreakpoint.js: Copied from UserInterface/Models/Breakpoint.js.
(WI.JavaScriptBreakpoint):
(WI.JavaScriptBreakpoint.fromJSON):
(WI.JavaScriptBreakpoint.prototype.toJSON):
(WI.JavaScriptBreakpoint.prototype.get sourceCodeLocation):
(WI.JavaScriptBreakpoint.prototype.get contentIdentifier):
(WI.JavaScriptBreakpoint.prototype.get scriptIdentifier):
(WI.JavaScriptBreakpoint.prototype.get target):
(WI.JavaScriptBreakpoint.prototype.get special): Added.
(WI.JavaScriptBreakpoint.prototype.get removable): Added.
(WI.JavaScriptBreakpoint.prototype.get editable): Added.
(WI.JavaScriptBreakpoint.prototype.get identifier):
(WI.JavaScriptBreakpoint.prototype.set identifier):
(WI.JavaScriptBreakpoint.prototype.get resolved):
(WI.JavaScriptBreakpoint.prototype.set resolved):
(WI.JavaScriptBreakpoint.prototype.remove): Added.
(WI.JavaScriptBreakpoint.prototype.saveIdentityToCookie):
(WI.JavaScriptBreakpoint.prototype._isSpecial):
(WI.JavaScriptBreakpoint.prototype._sourceCodeLocationLocationChanged):
(WI.JavaScriptBreakpoint.prototype._sourceCodeLocationDisplayLocationChanged):
* UserInterface/Models/URLBreakpoint.js:
(WI.URLBreakpoint):
(WI.URLBreakpoint.fromJSON): Added.
(WI.URLBreakpoint.prototype.get special): Added.
(WI.URLBreakpoint.prototype.remove): Added.
(WI.URLBreakpoint.prototype.toJSON):
(WI.URLBreakpoint.deserialize): Deleted.
(WI.URLBreakpoint.prototype.get disabled): Deleted.
(WI.URLBreakpoint.prototype.set disabled): Deleted.
Rename `WI.Breakpoint` to `WI.JavaScriptBreakpoint` and use `WI.Breakpoint` as a new common
base class for all breakpoint types, allowing more logic to be shared (e.g. disabled state).
Additionally, breakpoints are now able to
- determine whether or not they're
- special
- removable
- editable (i.e. configurable)
- remove themselves
without the caller needing to know what manager to consult with.
* UserInterface/Controllers/DOMManager.js:
(WI.DOMManager):
(WI.DOMManager.supportsEventListenerBreakpointConfiguration): Added.
(WI.DOMManager.prototype.setBreakpointForEventListener):
(WI.DOMManager.prototype.removeBreakpointForEventListener):
(WI.DOMManager.prototype._setEventBreakpoint): Added.
(WI.DOMManager.prototype._removeEventBreakpoint): Added.
(WI.DOMManager.prototype._handleEventBreakpointEditablePropertyChanged): Added.
(WI.DOMManager.prototype._handleEventBreakpointActionsChanged): Added.
(WI.DOMManager.prototype._updateEventBreakpoint): Deleted.
Keep track of configuration changes for specific listener breakpoints.
* UserInterface/Controllers/DOMDebuggerManager.js:
(WI.DOMDebuggerManager):
(WI.DOMDebuggerManager.prototype.initializeTarget):
(WI.DOMDebuggerManager.prototype.addDOMBreakpoint):
(WI.DOMDebuggerManager.prototype.removeDOMBreakpoint):
(WI.DOMDebuggerManager.prototype.addEventBreakpoint):
(WI.DOMDebuggerManager.prototype.removeEventBreakpoint):
(WI.DOMDebuggerManager.prototype.addURLBreakpoint):
(WI.DOMDebuggerManager.prototype.removeURLBreakpoint):
(WI.DOMDebuggerManager.prototype._commandArgumentsForEventBreakpoint): Added.
(WI.DOMDebuggerManager.prototype._setEventBreakpoint): Added.
(WI.DOMDebuggerManager.prototype._removeEventBreakpoint): Added.
(WI.DOMDebuggerManager.prototype._handleEventBreakpointDisabledStateChanged): Added.
(WI.DOMDebuggerManager.prototype._handleEventBreakpointEditablePropertyChanged): Added.
(WI.DOMDebuggerManager.prototype._handleEventBreakpointActionsChanged): Added.
(WI.DOMDebuggerManager.prototype.isBreakpointSpecial): Deleted.
(WI.DOMDebuggerManager.prototype._updateEventBreakpoint): Deleted.
Keep track of configuration changes for special event breakpoints.
Store special event breakpoints inside `WI.objectStores.eventBreakpoints`.
* UserInterface/Controllers/DebuggerManager.js:
(WI.DebuggerManager):
(WI.DebuggerManager.prototype.addBreakpoint):
(WI.DebuggerManager.prototype.removeBreakpoint):
(WI.DebuggerManager.prototype.addProbesForBreakpoint): Added.
(WI.DebuggerManager.prototype.removeProbesForBreakpoint): Added.
(WI.DebuggerManager.prototype.updateProbesForBreakpoint): Added.
(WI.DebuggerManager.prototype._setBreakpoint):
(WI.DebuggerManager.prototype._breakpointEditablePropertyDidChange):
(WI.DebuggerManager.prototype._handleBreakpointActionsDidChange):
(WI.DebuggerManager.prototype.isBreakpointRemovable): Deleted.
(WI.DebuggerManager.prototype.isBreakpointSpecial): Deleted.
(WI.DebuggerManager.prototype.isBreakpointEditable): Deleted.
(WI.DebuggerManager.prototype._debuggerBreakpointActionType): Deleted.
(WI.DebuggerManager.prototype._debuggerBreakpointOptions): Deleted.
(WI.DebuggerManager.prototype._addProbesForBreakpoint): Deleted.
(WI.DebuggerManager.prototype._removeProbesForBreakpoint): Deleted.
(WI.DebuggerManager.prototype._updateProbesForBreakpoint): Deleted.
Replace `WI.Breakpoint` with `WI.JavaScriptBreakpoint`.
Probes now support `WI.EventBreakpoint` in addition to `WI.JavaScriptBreakpoint`.
* UserInterface/Controllers/BreakpointPopoverController.js:
(WI.BreakpointPopoverController.prototype.appendContextMenuItems):
(WI.BreakpointPopoverController.prototype._createPopoverContent):
Allow any breakpoint instead of only `WI.JavaScriptBreakpoint`.
Drive-by: the existing `ignoreCount` value wasn't being used to populate the `<input>`.
* UserInterface/Views/BreakpointTreeElement.js:
(WI.BreakpointTreeElement.prototype.ondelete):
(WI.BreakpointTreeElement.prototype.get listenerSet): Added.
(WI.BreakpointTreeElement.prototype.updateStatus): Added.
(WI.BreakpointTreeElement.prototype.updateTitles): Added.
(WI.BreakpointTreeElement.prototype.get breakpoint): Deleted.
(WI.BreakpointTreeElement.prototype.get filterableData): Deleted.
(WI.BreakpointTreeElement.prototype._updateTitles): Deleted.
(WI.BreakpointTreeElement.prototype._updateStatus): Deleted.
(WI.BreakpointTreeElement.prototype._breakpointLocationDidChange): Deleted.
* UserInterface/Views/BreakpointTreeElement.css:
(.item.breakpoint .status > .status-image):
(.item.breakpoint.paused .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.paused .icon): Added.
(.item.breakpoint .status > .status-image.resolved): Deleted.
(body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.selected .status > .status-image.resolved): Deleted.
(.item.breakpoint .subtitle.formatted-location): Deleted.
(.breakpoint-debugger-statement-icon .icon): Deleted.
(.breakpoint-exception-icon .icon): Deleted.
(.breakpoint-assertion-icon .icon): Deleted.
(.breakpoint-microtask-icon .icon): Deleted.
(.breakpoint-paused-icon .icon): Deleted.
(.breakpoint-generic-line-icon .icon): Deleted.
(.breakpoint-generic-line-icon .icon > span): Deleted.
(.data-updated.breakpoint-generic-line-icon .icon > span): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-debugger-statement-icon .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-exception-icon .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-assertion-icon .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-microtask-icon .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-paused-icon .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint-generic-line-icon .icon): Deleted.
* UserInterface/Views/DOMBreakpointTreeElement.js:
(WI.DOMBreakpointTreeElement):
(WI.DOMBreakpointTreeElement.prototype.onattach): Deleted.
(WI.DOMBreakpointTreeElement.prototype.ondetach): Deleted.
(WI.DOMBreakpointTreeElement.prototype.ondelete): Deleted.
(WI.DOMBreakpointTreeElement.prototype.onenter): Deleted.
(WI.DOMBreakpointTreeElement.prototype.onspace): Deleted.
(WI.DOMBreakpointTreeElement.prototype.populateContextMenu): Deleted.
(WI.DOMBreakpointTreeElement.prototype._statusImageElementClicked): Deleted.
(WI.DOMBreakpointTreeElement.prototype._statusImageElementFocused): Deleted.
(WI.DOMBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted.
(WI.DOMBreakpointTreeElement.prototype._toggleBreakpoint): Deleted.
(WI.DOMBreakpointTreeElement.prototype._updateStatus): Deleted.
* UserInterface/Views/DOMBreakpointTreeElement.css:
(.item.breakpoint.dom.subtree-modified:not(.paused) .icon): Added.
(.item.breakpoint.dom.attribute-modified:not(.paused) .icon): Added.
(.item.breakpoint.dom.node-removed:not(.paused) .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.dom.subtree-modified:not(.paused) .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.dom.attribute-modified:not(.paused) .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.dom.node-removed:not(.paused) .icon): Added.
(.breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon): Deleted.
(.breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon): Deleted.
(.breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon): Deleted.
* UserInterface/Views/EventBreakpointTreeElement.js:
(WI.EventBreakpointTreeElement):
(WI.EventBreakpointTreeElement.prototype.onattach): Deleted.
(WI.EventBreakpointTreeElement.prototype.ondetach): Deleted.
(WI.EventBreakpointTreeElement.prototype.ondelete): Deleted.
(WI.EventBreakpointTreeElement.prototype.onenter): Deleted.
(WI.EventBreakpointTreeElement.prototype.onspace): Deleted.
(WI.EventBreakpointTreeElement.prototype.populateContextMenu): Deleted.
(WI.EventBreakpointTreeElement.prototype._statusImageElementClicked): Deleted.
(WI.EventBreakpointTreeElement.prototype._statusImageElementFocused): Deleted.
(WI.EventBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted.
(WI.EventBreakpointTreeElement.prototype._toggleBreakpoint): Deleted.
(WI.EventBreakpointTreeElement.prototype._updateStatus): Deleted.
* UserInterface/Views/EventBreakpointTreeElement.css:
(.item.breakpoint.event.animation-frame:not(.paused) .icon): Added.
(.item.breakpoint.event.interval:not(.paused) .icon): Added.
(.item.breakpoint.event.listener:not(.paused) .icon): Added.
(.item.breakpoint.event.timeout:not(.paused) .icon): Added.
(@media(prefers-color-scheme: dark) .item.breakpoint.event.animation-frame:not(.paused) .icon): Added.
(@media(prefers-color-scheme: dark) .item.breakpoint.event.interval:not(.paused) .icon): Added.
(@media(prefers-color-scheme: dark) .item.breakpoint.event.listener:not(.paused) .icon): Added.
(@media(prefers-color-scheme: dark) .item.breakpoint.event.timeout:not(.paused) .icon): Added.
(.breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon): Deleted.
(.breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon): Deleted.
(.breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon): Deleted.
(.breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon): Deleted.
(@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon): Deleted.
(@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon): Deleted.
(@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon): Deleted.
(@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon): Deleted.
* UserInterface/Views/JavaScriptBreakpointTreeElement.js: Copied from Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js.
(WI.JavaScriptBreakpointTreeElement):
(WI.JavaScriptBreakpointTreeElement.prototype.get filterableData):
(WI.JavaScriptBreakpointTreeElement.prototype.updateStatus): Added.
(WI.JavaScriptBreakpointTreeElement.prototype.updateTitles): Added.
(WI.JavaScriptBreakpointTreeElement.prototype._breakpointLocationDidChange):
* UserInterface/Views/JavaScriptBreakpointTreeElement.css: Copied from Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.css.
(.item.breakpoint.javascript .status > .status-image): Added.
(.item.breakpoint.javascript .status > .status-image.resolved): Added.
(body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.javascript.selected .status > .status-image.resolved): Added.
(.item.breakpoint.javascript .subtitle.formatted-location): Added.
(.item.breakpoint.javascript.line .icon): Added.
(.item.breakpoint.javascript.line .icon > span): Added.
(.data-updated.item.breakpoint.javascript.line .icon > span): Added.
(.item.breakpoint.javascript.debugger-statement .icon): Added.
(.item.breakpoint.javascript.exception .icon): Added.
(.item.breakpoint.javascript.assertion .icon): Added.
(.item.breakpoint.javascript.microtask .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.javascript.line .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.javascript.debugger-statement .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.javascript.exception .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.javascript.assertion .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.javascript.microtask .icon): Added.
* UserInterface/Views/URLBreakpointTreeElement.js:
(WI.URLBreakpointTreeElement):
(WI.URLBreakpointTreeElement.prototype.onattach): Deleted.
(WI.URLBreakpointTreeElement.prototype.ondetach): Deleted.
(WI.URLBreakpointTreeElement.prototype.ondelete): Deleted.
(WI.URLBreakpointTreeElement.prototype.onenter): Deleted.
(WI.URLBreakpointTreeElement.prototype.onspace): Deleted.
(WI.URLBreakpointTreeElement.prototype.populateContextMenu): Deleted.
(WI.URLBreakpointTreeElement.prototype._statusImageElementClicked): Deleted.
(WI.URLBreakpointTreeElement.prototype._statusImageElementFocused): Deleted.
(WI.URLBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted.
(WI.URLBreakpointTreeElement.prototype._toggleBreakpoint): Deleted.
(WI.URLBreakpointTreeElement.prototype._updateStatus): Deleted.
* UserInterface/Views/URLBreakpointTreeElement.css:
(.item.breakpoint.url .subtitle): Added.
(.item.breakpoint.url:not(.paused) .icon): Added.
(@media (prefers-color-scheme: dark) .item.breakpoint.url:not(.paused) .icon): Added.
(.breakpoint.url .subtitle): Deleted.
(.breakpoint.url:not(.breakpoint-paused-icon) .icon): Deleted.
(@media (prefers-color-scheme: dark) .breakpoint.url:not(.breakpoint-paused-icon) .icon): Deleted.
Rename `WI.BreakpointTreeElement` to `WI.JavaScriptBreakpointTreeElement` and use
`WI.BreakpointTreeElement` as a new common base class for all breakpoint tree elements,
allowing more logic and styles to be shared (e.g. disabled state).
* UserInterface/Views/SourcesNavigationSidebarPanel.js:
(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype.closed):
(WI.SourcesNavigationSidebarPanel.prototype._insertDebuggerTreeElement):
(WI.SourcesNavigationSidebarPanel.prototype._compareJavaScriptBreakpointTreeElements): Added.
(WI.SourcesNavigationSidebarPanel.prototype._addBreakpoint):
(WI.SourcesNavigationSidebarPanel.prototype._removeAllBreakpoints):
(WI.SourcesNavigationSidebarPanel.prototype._breakpointsBeneathTreeElement):
(WI.SourcesNavigationSidebarPanel.prototype._addIssue):
(WI.SourcesNavigationSidebarPanel.prototype._updatePauseReasonSection):
(WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
(WI.SourcesNavigationSidebarPanel.prototype._handleBreakpointElementAddedOrRemoved):
(WI.SourcesNavigationSidebarPanel.prototype._populateCreateBreakpointContextMenu.addToggleForSpecialEventBreakpoint):
(WI.SourcesNavigationSidebarPanel.prototype._populateCreateBreakpointContextMenu):
(WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerObjectDisplayLocationDidChange):
(WI.SourcesNavigationSidebarPanel.prototype._compareBreakpointTreeElements): Deleted.
* UserInterface/Models/ProbeSet.js:
(WI.ProbeSet):
(WI.ProbeSet.prototype.createProbe):
(WI.ProbeSet.prototype.willRemove):
* UserInterface/Controllers/TimelineManager.js:
(WI.TimelineManager.prototype._processRecord):
* UserInterface/Views/ProbeSetDetailsSection.js:
(WI.ProbeSetDetailsSection):
* UserInterface/Views/ProbeDetailsSidebarPanel.js:
(WI.ProbeDetailsSidebarPanel.prototype.inspect):
* UserInterface/Views/SourceCodeTextEditor.js:
(WI.SourceCodeTextEditor):
(WI.SourceCodeTextEditor.prototype.close):
(WI.SourceCodeTextEditor.prototype.textEditorBreakpointAdded):
* UserInterface/Views/TextResourceContentView.js:
(WI.TextResourceContentView.prototype.get supplementalRepresentedObjects):
(WI.TextResourceContentView.prototype._probeSetsChanged):
Probes now support `WI.EventBreakpoint` in addition to `WI.JavaScriptBreakpoint`.
* UserInterface/Views/ContentView.js:
(WI.ContentView.createFromRepresentedObject):
(WI.ContentView.resolvedRepresentedObjectForRepresentedObject):
(WI.ContentView.isViewable):
* UserInterface/Views/ContextMenuUtilities.js:
(WI.appendContextMenuItemsForSourceCode):
Replace `WI.Breakpoint` with `WI.JavaScriptBreakpoint`.
* UserInterface/Views/DOMTreeContentView.js:
(WI.DOMTreeContentView):
Replace `WI.DOMBreakpoint` with `WI.Breakpoint`.
* UserInterface/Views/EventListenerSectionGroup.js:
(WI.EventListenerSectionGroup):
* UserInterface/Views/EventListenerSectionGroup.css:
(.event-listener-section > .content input[type="checkbox"] + .go-to-arrow): Added.
(.event-listener-section > .content input[type="checkbox"]:not(:checked) + .go-to-arrow): Added.
Add a go-to arrow next to the Breakpoint checkbox that reveals the `WI.EventBreakpoint` in
the Sources Tab.
* UserInterface/Views/BreakpointActionView.js:
(WI.BreakpointActionView.prototype._appendActionButtonClicked):
Drive-by: minor code cleanup.
* UserInterface/Views/CallFrameTreeElement.js:
(WI.CallFrameTreeElement.prototype.populateContextMenu):
Drive-by: include source code location context menu items.
* UserInterface/Base/Setting.js:
* UserInterface/Main.html:
* UserInterface/Test.html:
LayoutTests:
* inspector/dom-debugger/resources/event-breakpoint-utilities.js:
(TestPage.registerInitializer.InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases): Added.
(TestPage.registerInitializer.InspectorTest.EventBreakpoint.async teardown):
(TestPage.registerInitializer.InspectorTest.EventBreakpoint.createBreakpoint):
(TestPage.registerInitializer.InspectorTest.EventBreakpoint.removeBreakpoint):
* inspector/dom/breakpoint-for-event-listener.html:
* inspector/dom/breakpoint-for-event-listener-expected.txt:
* inspector/dom-debugger/event-animation-frame-breakpoints.html:
* inspector/dom-debugger/event-animation-frame-breakpoints-expected.txt:
* inspector/dom-debugger/event-interval-breakpoints.html:
* inspector/dom-debugger/event-interval-breakpoints-expected.txt:
* inspector/dom-debugger/event-listener-breakpoints.html:
* inspector/dom-debugger/event-listener-breakpoints-expected.txt:
* inspector/dom-debugger/event-timeout-breakpoints.html:
* inspector/dom-debugger/event-timeout-breakpoints-expected.txt:
Add tests for new event breakpoint configuration options.
* http/tests/inspector/debugger/debugger-test.js:
(TestPage.registerInitializer.InspectorTest.startTracingBreakpoints):
* http/tests/inspector/resources/probe-test.js:
(TestPage.registerInitializer.ProtocolTest.Probe.installTracingListeners):
* inspector/debugger/breakpoint-action-eval.html:
* inspector/debugger/breakpoint-action-log.html:
* inspector/debugger/breakpoint-columns.html:
* inspector/debugger/breakpoint-scope.html:
* inspector/debugger/debugger-stack-overflow.html:
* inspector/debugger/pause-reason.html:
* inspector/debugger/probe-manager-add-remove-actions.html:
* inspector/debugger/stepping/stepping-through-autoContinue-breakpoint.html:
* inspector/debugger/tail-deleted-frames-this-value.html:
* inspector/debugger/tail-recursion.html:
* inspector/worker/debugger-pause.html:
* inspector/worker/debugger-shared-breakpoint.html:
Update existing breakpoint tests to use new model objects.
Canonical link: https://commits.webkit.org/228551@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-24 17:34:12 +00:00
|
|
|
debugger/Breakpoint.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
debugger/Debugger.cpp
|
|
|
|
debugger/DebuggerCallFrame.cpp
|
|
|
|
debugger/DebuggerLocation.cpp
|
|
|
|
debugger/DebuggerParseData.cpp
|
|
|
|
debugger/DebuggerScope.cpp
|
|
|
|
|
|
|
|
dfg/DFGAbstractHeap.cpp
|
2018-04-10 19:45:54 +00:00
|
|
|
dfg/DFGAbstractInterpreterClobberState.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGAbstractValue.cpp
|
2018-05-08 01:05:21 +00:00
|
|
|
dfg/DFGAbstractValueClobberEpoch.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp
|
|
|
|
dfg/DFGAdaptiveStructureWatchpoint.cpp
|
|
|
|
dfg/DFGArgumentsEliminationPhase.cpp
|
|
|
|
dfg/DFGArgumentsUtilities.cpp
|
|
|
|
dfg/DFGArithMode.cpp
|
|
|
|
dfg/DFGArrayMode.cpp
|
|
|
|
dfg/DFGAtTailAbstractState.cpp
|
|
|
|
dfg/DFGAvailability.cpp
|
|
|
|
dfg/DFGAvailabilityMap.cpp
|
|
|
|
dfg/DFGBackwardsPropagationPhase.cpp
|
|
|
|
dfg/DFGBasicBlock.cpp
|
|
|
|
dfg/DFGBlockInsertionSet.cpp
|
|
|
|
dfg/DFGBlockSet.cpp
|
|
|
|
dfg/DFGByteCodeParser.cpp
|
|
|
|
dfg/DFGCFAPhase.cpp
|
|
|
|
dfg/DFGCFGSimplificationPhase.cpp
|
|
|
|
dfg/DFGCPSRethreadingPhase.cpp
|
|
|
|
dfg/DFGCSEPhase.cpp
|
|
|
|
dfg/DFGCapabilities.cpp
|
|
|
|
dfg/DFGCleanUpPhase.cpp
|
|
|
|
dfg/DFGClobberSet.cpp
|
|
|
|
dfg/DFGClobberize.cpp
|
|
|
|
dfg/DFGClobbersExitState.cpp
|
2020-06-11 20:11:34 +00:00
|
|
|
dfg/DFGCodeOriginPool.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGCombinedLiveness.cpp
|
|
|
|
dfg/DFGCommon.cpp
|
|
|
|
dfg/DFGCommonData.cpp
|
|
|
|
dfg/DFGConstantFoldingPhase.cpp
|
|
|
|
dfg/DFGConstantHoistingPhase.cpp
|
|
|
|
dfg/DFGCriticalEdgeBreakingPhase.cpp
|
|
|
|
dfg/DFGDCEPhase.cpp
|
[JSC] Global lexical bindings can shadow global variables if it is `configurable = true`
https://bugs.webkit.org/show_bug.cgi?id=193308
<rdar://problem/45546542>
Reviewed by Saam Barati.
JSTests:
* stress/const-lexical-binding-shadow-existing-global-property-ftl.js: Added.
(shouldThrow):
(shouldBe):
(foo):
(get shouldThrow):
* stress/const-lexical-binding-shadow-existing-global-property-tdz-ftl.js: Added.
(shouldThrow):
(shouldBe):
(foo):
(get shouldBe):
(get shouldThrow):
(get return):
* stress/const-lexical-binding-shadow-existing-global-property-tdz.js: Added.
(shouldThrow):
(shouldBe):
(foo):
(get shouldBe):
(get shouldThrow):
* stress/const-lexical-binding-shadow-existing-global-property.js: Added.
(shouldThrow):
(shouldBe):
(foo):
* stress/const-lexical-binding-shadowing-global-properties-and-eval-injection.js: Added.
(shouldThrow):
(shouldBe):
(foo):
* stress/global-add-function-should-not-be-shadowed-by-lexical-bindings.js: Added.
(shouldThrow):
* stress/global-static-variables-should-not-be-shadowed-by-lexical-bindings.js: Added.
(shouldThrow):
* stress/let-lexical-binding-shadow-existing-global-property-ftl.js: Added.
(shouldThrow):
(shouldBe):
(foo):
* stress/let-lexical-binding-shadow-existing-global-property-tdz-ftl.js: Added.
(shouldThrow):
(shouldBe):
(foo):
(get shouldBe):
(get shouldThrow):
(get return):
* stress/let-lexical-binding-shadow-existing-global-property-tdz.js: Added.
(shouldThrow):
(shouldBe):
(foo):
(get shouldBe):
(get shouldThrow):
* stress/let-lexical-binding-shadow-existing-global-property.js: Added.
(shouldThrow):
(shouldBe):
(foo):
* stress/let-lexical-binding-shadowing-global-properties-and-eval-injection.js: Added.
(shouldThrow):
(shouldBe):
(foo):
Source/JavaScriptCore:
Previously, we assumed that lexical bindings in JSGlobalLexicalEnvironment cannot shadow existing global properties.
However, it is wrong. According to the spec, we can shadow global properties if a property's attribute is configurable = true.
For example, we execute two scripts.
script1.js
bar = 42;
function load() { return bar; }
print(bar); // 42
print(load()); // 42
script2.js
let bar = 0; // This lexical binding can shadow the global.bar defined in script1.js
print(bar); // 0
print(load()); // 0
In JSC, we cache GlobalProperty resolve type and its associated information in op_resolve_type, op_get_from_scope, and op_put_to_scope.
They attempt to load a property from JSGlobalObject directly. However, once the newly added lexical binding starts shadowing this, our existing instructions
become invalid since they do not respect JSGlobalLexicalEnvironment.
In this patch, we fix this issue by introducing the following mechanisms.
1. We have a HashMap<property name, watchpoint set> in JSGlobalObject. DFG and FTL create a watchpoint set with the property name if the generated code
depends on GlobalProperty condition of op_resolve_scope etc. These watchpoint will be fired when the shadowing happens, so that our generated DFG and FTL
code will be invalidated if it depends on the condition which is no longer valid.
2. When we detect shadowing, we iterate all the live CodeBlocks which globalObject is the target one. And we rewrite instructions in them from GlobalProperty
to GlobalLexicalVar (or Dynamic precisely). So, the subsequent LLInt code just works well. "Dynamic" conversion happens when your op_put_to_scope attempts to
put a value onto a const lexical binding. This fails and it should throw a type error.
3. GlobalProperty scope operations in Baseline JIT start checking ResolveType in metadata, and emit code for GlobalProperty and GlobalLexicalVar. Once the rewrite
happens, baseline JIT continues working because it checks the rewritten metadata's ResolveType.
We use this mechanism (which is similar to haveABadTime() thing) because,
1. Shadowing should be super rare. Before r214145, we made these cases as SytaxError. Thus, before r214145, this type of code cannot be executed in WebKit.
And the number of the live CodeBlocks for the given JSGlobalObject should be small. This supports introducing rather simple (but not so efficient) mechanism
instead of the complicated one.
2. Rewriting instructions immediately forces GlobalProperty => GlobalLexicalVar / Dynamic conversion in all the possible CodeBlock. This allows us to avoid
compilation failure loop in DFG and FTL: DFG and FTL codes are invalidated by the watchpoint, but we may attempt to compile the code with the invalidated watchpoint
and GlobalProperty status if we do not rewrite it. One possible other implementation is having and checking a counter in instruction, and every time we introduce
a new shadow binding, bump the counter. And eventually executed instruction will go to the slow path and rewrite itself. However, this way leaves the not-executed-again-yet
instructions as is, and DFG and FTL repeatedly fail to compile if we just watch the invalidated watchpoint for that. Rewriting all the existing GlobalProperty immediately
avoids this situation easily.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::notifyLexicalBindingShadowing):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::scriptMode const):
* bytecode/Watchpoint.h:
(JSC::WatchpointSet::create):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDesiredGlobalProperties.cpp: Added.
(JSC::DFG::DesiredGlobalProperties::isStillValidOnMainThread):
(JSC::DFG::DesiredGlobalProperties::reallyAdd):
* dfg/DFGDesiredGlobalProperties.h: Added.
(JSC::DFG::DesiredGlobalProperties::addLazily):
We need this DesiredGlobalProperties mechanism since we do not want to ref() the UniquedStringImpl in DFG and FTL thread.
We keep JSGlobalObject* and identifierNumber, and materialize WatchpointSets for each JSGlobalObject's property referenced
from DFG and FTL and inject CodeBlock jettison watchpoints in the main thread.
* dfg/DFGDesiredGlobalProperty.h: Added.
(JSC::DFG::DesiredGlobalProperty::DesiredGlobalProperty):
(JSC::DFG::DesiredGlobalProperty::globalObject const):
(JSC::DFG::DesiredGlobalProperty::identifierNumber const):
(JSC::DFG::DesiredGlobalProperty::operator== const):
(JSC::DFG::DesiredGlobalProperty::operator!= const):
(JSC::DFG::DesiredGlobalProperty::isHashTableDeletedValue const):
(JSC::DFG::DesiredGlobalProperty::hash const):
(JSC::DFG::DesiredGlobalProperty::dumpInContext const):
(JSC::DFG::DesiredGlobalProperty::dump const):
(JSC::DFG::DesiredGlobalPropertyHash::hash):
(JSC::DFG::DesiredGlobalPropertyHash::equal):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::globalProperties):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::reallyAdd):
(JSC::DFG::Plan::isStillValidOnMainThread):
(JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
(JSC::DFG::Plan::cancel):
* dfg/DFGPlan.h:
(JSC::DFG::Plan::globalProperties):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emit_op_put_to_scope):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emit_op_put_to_scope):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::addStaticGlobals):
(JSC::JSGlobalObject::notifyLexicalBindingShadowing):
(JSC::JSGlobalObject::getReferencedPropertyWatchpointSet):
(JSC::JSGlobalObject::ensureReferencedPropertyWatchpointSet):
* runtime/JSGlobalObject.h:
* runtime/ProgramExecutable.cpp:
(JSC::hasRestrictedGlobalProperty):
(JSC::ProgramExecutable::initializeGlobalProperties):
Canonical link: https://commits.webkit.org/207863@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239879 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-11 23:10:31 +00:00
|
|
|
dfg/DFGDesiredGlobalProperties.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGDesiredIdentifiers.cpp
|
|
|
|
dfg/DFGDesiredTransitions.cpp
|
|
|
|
dfg/DFGDesiredWatchpoints.cpp
|
|
|
|
dfg/DFGDesiredWeakReferences.cpp
|
|
|
|
dfg/DFGDisassembler.cpp
|
|
|
|
dfg/DFGDoesGC.cpp
|
[Re-landing] Enhance DoesGC verification to print more useful info when verification fails.
https://bugs.webkit.org/show_bug.cgi?id=212680
Reviewed by Yusuke Susuki.
When DoesGC verification fails, the first step of debugging it would be to find
out what and which DFG node resulted in the failed verification. In pre-existing
code, all we get is an assertion failure.
This patch makes it so that the verifier will dump useful info. Here's an example:
Error: DoesGC failed @ D@34 DateGetInt32OrNaN in #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
[0] frame 0x7ffee8285660 {
name:
sourceURL:
isInlinedFrame: false
callee: 0x1135f6820
returnPC: 0x50ce61248ae6
callerFrame: 0x7ffee82856f0
rawLocationBits: 5 0x5
codeBlock: 0x1135bd1d0 #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
hasCodeOrigins: true
callSiteIndex: 5 of 13
jitCode: 0x113020200 start 0x50ce61214c60 end 0x50ce61219b00
line: 1
column: 60
EntryFrame: 0x7ffee8285860
}
[1] frame 0x7ffee82856f0 {
name:
sourceURL: date-format-xparb.js
isInlinedFrame: false
callee: 0x1135f65a0
returnPC: 0x50ce61227e99
callerFrame: 0x7ffee8285770
rawLocationBits: 4 0x4
codeBlock: 0x1135bd0a0 #BU6Zcd:[0x1135bd0a0->0x1135bc260->0x1135e5180, DFGFunctionCall, 112 (DidTryToEnterInLoop)]
hasCodeOrigins: true
callSiteIndex: 4 of 12
jitCode: 0x113004000 start 0x50ce61212c60 end 0x50ce61214960
line: 26
column: 22
EntryFrame: 0x7ffee8285860
}
[2] frame 0x7ffee8285770 {
name:
sourceURL: date-format-xparb.js
isInlinedFrame: false
callee: 0x1135f64e0
returnPC: 0x108058eb1
callerFrame: 0x7ffee82857e0
rawLocationBits: 1001 0x3e9
codeBlock: 0x1135bc130 #DAS9xe:[0x1135bc130->0x1135e5100, BaselineFunctionCall, 1149]
bc#1001 of 1149
line: 417
column: 38
EntryFrame: 0x7ffee8285860
}
[3] frame 0x7ffee82857e0 {
name: global code
sourceURL: date-format-xparb.js
isInlinedFrame: false
callee: 0x1130f97b8
returnPC: 0x108039043
callerFrame: 0x0
rawLocationBits: 23 0x17
codeBlock: 0x1135bc000 <global>#CukXvt:[0x1135bc000->0x1130cd768, LLIntGlobal, 81]
bc#23 of 81
line: 425
column: 3
EntryFrame: 0x7ffee8285860
}
ASSERTION FAILED: expectDoesGC()
The error message now comes with the node index, NodeType, codeBlock which this
failure was found in, and the JS call stack that led to the failure.
Changes made:
1. Introduced a DoesGCCheck value that is used to encode some of the above data.
Previously, we only recorded whether doesGC() returns true or false for the
Node. Now, we record the nodeIndex and nodeOp as well.
Note that we also set DoesGC expectations for OSR exits. So, DoesGCCheck
includes Special cases for those.
2. Added store64(TrustedImm64 imm, const void* address) emitters for X86_64 and ARM64.
Also added a test for this new emitter in testmasm.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::store64):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::store64):
* assembler/testmasm.cpp:
(JSC::testStore64Imm64AddressPointer):
(JSC::run):
* dfg/DFGDoesGCCheck.cpp: Copied from Source/JavaScriptCore/dfg/DFGDoesGCCheck.cpp.
* dfg/DFGDoesGCCheck.h: Copied from Source/JavaScriptCore/dfg/DFGDoesGCCheck.h.
* dfg/DFGGraph.cpp:
* dfg/DFGOSRExit.cpp:
(JSC::DFG::operationCompileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
(JSC::FTL::operationCompileFTLOSRExit):
* heap/CompleteSubspace.cpp:
(JSC::CompleteSubspace::tryAllocateSlow):
(JSC::CompleteSubspace::reallocatePreciseAllocationNonVirtual):
* heap/CompleteSubspaceInlines.h:
(JSC::CompleteSubspace::allocateNonVirtual):
* heap/DeferGC.h:
(JSC::DeferGC::~DeferGC):
* heap/GCDeferralContextInlines.h:
(JSC::GCDeferralContext::~GCDeferralContext):
* heap/Heap.cpp:
(JSC::Heap::collectNow):
(JSC::Heap::collectAsync):
(JSC::Heap::collectSync):
(JSC::Heap::stopIfNecessarySlow):
(JSC::Heap::collectIfNecessaryOrDefer):
* heap/Heap.h:
(JSC::Heap::addressOfDoesGC):
(JSC::Heap::setDoesGCExpectation):
(JSC::Heap::verifyCanGC):
(JSC::Heap::expectDoesGC const): Deleted.
(JSC::Heap::setExpectDoesGC): Deleted.
(JSC::Heap::addressOfExpectDoesGC): Deleted.
* heap/HeapInlines.h:
(JSC::Heap::acquireAccess):
(JSC::Heap::stopIfNecessary):
* heap/LocalAllocatorInlines.h:
(JSC::LocalAllocator::allocate):
* heap/PreciseAllocation.cpp:
(JSC::PreciseAllocation::tryCreate):
(JSC::PreciseAllocation::createForLowerTier):
* runtime/JSString.h:
(JSC::jsSingleCharacterString):
(JSC::JSString::toAtomString const):
(JSC::JSString::toExistingAtomString const):
(JSC::JSString::value const):
(JSC::JSString::tryGetValue const):
(JSC::JSRopeString::unsafeView const):
(JSC::JSRopeString::viewWithUnderlyingString const):
(JSC::JSString::unsafeView const):
* runtime/RegExpMatchesArray.h:
(JSC::createRegExpMatchesArray):
Canonical link: https://commits.webkit.org/225537@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262513 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 20:23:30 +00:00
|
|
|
dfg/DFGDoesGCCheck.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGDriver.cpp
|
|
|
|
dfg/DFGEdge.cpp
|
|
|
|
dfg/DFGEpoch.cpp
|
|
|
|
dfg/DFGFailedFinalizer.cpp
|
|
|
|
dfg/DFGFinalizer.cpp
|
|
|
|
dfg/DFGFixupPhase.cpp
|
|
|
|
dfg/DFGFlowIndexing.cpp
|
|
|
|
dfg/DFGFlushFormat.cpp
|
|
|
|
dfg/DFGFlushedAt.cpp
|
|
|
|
dfg/DFGLiveCatchVariablePreservationPhase.cpp
|
|
|
|
dfg/DFGFrozenValue.cpp
|
|
|
|
dfg/DFGGraph.cpp
|
|
|
|
dfg/DFGGraphSafepoint.cpp
|
|
|
|
dfg/DFGHeapLocation.cpp
|
|
|
|
dfg/DFGInPlaceAbstractState.cpp
|
|
|
|
dfg/DFGInsertionSet.cpp
|
|
|
|
dfg/DFGIntegerCheckCombiningPhase.cpp
|
|
|
|
dfg/DFGIntegerRangeOptimizationPhase.cpp
|
|
|
|
dfg/DFGInvalidationPointInjectionPhase.cpp
|
|
|
|
dfg/DFGJITCode.cpp
|
|
|
|
dfg/DFGJITCompiler.cpp
|
|
|
|
dfg/DFGJITFinalizer.cpp
|
|
|
|
dfg/DFGJumpReplacement.cpp
|
|
|
|
dfg/DFGLICMPhase.cpp
|
|
|
|
dfg/DFGLazyJSValue.cpp
|
|
|
|
dfg/DFGLazyNode.cpp
|
|
|
|
dfg/DFGLivenessAnalysisPhase.cpp
|
|
|
|
dfg/DFGLoopPreHeaderCreationPhase.cpp
|
|
|
|
dfg/DFGMayExit.cpp
|
|
|
|
dfg/DFGMinifiedGraph.cpp
|
|
|
|
dfg/DFGMinifiedNode.cpp
|
|
|
|
dfg/DFGMultiGetByOffsetData.cpp
|
|
|
|
dfg/DFGNode.cpp
|
|
|
|
dfg/DFGNodeAbstractValuePair.cpp
|
|
|
|
dfg/DFGNodeFlags.cpp
|
|
|
|
dfg/DFGNodeFlowProjection.cpp
|
|
|
|
dfg/DFGNodeOrigin.cpp
|
|
|
|
dfg/DFGOSRAvailabilityAnalysisPhase.cpp
|
|
|
|
dfg/DFGOSREntry.cpp
|
|
|
|
dfg/DFGOSREntrypointCreationPhase.cpp
|
|
|
|
dfg/DFGOSRExit.cpp
|
|
|
|
dfg/DFGOSRExitBase.cpp
|
|
|
|
dfg/DFGOSRExitCompilerCommon.cpp
|
|
|
|
dfg/DFGOSRExitFuzz.cpp
|
|
|
|
dfg/DFGOSRExitJumpPlaceholder.cpp
|
|
|
|
dfg/DFGObjectAllocationSinkingPhase.cpp
|
|
|
|
dfg/DFGObjectMaterializationData.cpp
|
|
|
|
dfg/DFGOperations.cpp
|
|
|
|
dfg/DFGPhantomInsertionPhase.cpp
|
|
|
|
dfg/DFGPhase.cpp
|
|
|
|
dfg/DFGPhiChildren.cpp
|
|
|
|
dfg/DFGPlan.cpp
|
|
|
|
dfg/DFGPredictionInjectionPhase.cpp
|
|
|
|
dfg/DFGPredictionPropagationPhase.cpp
|
|
|
|
dfg/DFGPromotedHeapLocation.cpp
|
|
|
|
dfg/DFGPureValue.cpp
|
|
|
|
dfg/DFGPutStackSinkingPhase.cpp
|
|
|
|
dfg/DFGRegisteredStructureSet.cpp
|
|
|
|
dfg/DFGSSACalculator.cpp
|
|
|
|
dfg/DFGSSAConversionPhase.cpp
|
|
|
|
dfg/DFGSSALoweringPhase.cpp
|
|
|
|
dfg/DFGSnippetParams.cpp
|
2018-07-31 20:21:50 +00:00
|
|
|
// These files take a long time to compile so we do them individually.
|
|
|
|
dfg/DFGSpeculativeJIT.cpp @no-unify
|
|
|
|
dfg/DFGSpeculativeJIT32_64.cpp @no-unify
|
|
|
|
dfg/DFGSpeculativeJIT64.cpp @no-unify
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGStackLayoutPhase.cpp
|
|
|
|
dfg/DFGStaticExecutionCountEstimationPhase.cpp
|
|
|
|
dfg/DFGStoreBarrierClusteringPhase.cpp
|
|
|
|
dfg/DFGStoreBarrierInsertionPhase.cpp
|
|
|
|
dfg/DFGStrengthReductionPhase.cpp
|
|
|
|
dfg/DFGStructureAbstractValue.cpp
|
|
|
|
dfg/DFGThunks.cpp
|
|
|
|
dfg/DFGTierUpCheckInjectionPhase.cpp
|
|
|
|
dfg/DFGToFTLDeferredCompilationCallback.cpp
|
|
|
|
dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp
|
|
|
|
dfg/DFGTransition.cpp
|
|
|
|
dfg/DFGTypeCheckHoistingPhase.cpp
|
|
|
|
dfg/DFGUnificationPhase.cpp
|
|
|
|
dfg/DFGUseKind.cpp
|
|
|
|
dfg/DFGValidate.cpp
|
2019-04-02 15:58:34 +00:00
|
|
|
dfg/DFGValueRepReductionPhase.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
dfg/DFGValueSource.cpp
|
|
|
|
dfg/DFGValueStrength.cpp
|
|
|
|
dfg/DFGVarargsForwardingPhase.cpp
|
|
|
|
dfg/DFGVariableAccessData.cpp
|
|
|
|
dfg/DFGVariableAccessDataDump.cpp
|
|
|
|
dfg/DFGVariableEvent.cpp
|
|
|
|
dfg/DFGVariableEventStream.cpp
|
|
|
|
dfg/DFGVirtualRegisterAllocationPhase.cpp
|
|
|
|
dfg/DFGWatchpointCollectionPhase.cpp
|
|
|
|
|
|
|
|
disassembler/ARM64Disassembler.cpp
|
[JSC][GTK][JSCONLY] Use capstone disassembler
https://bugs.webkit.org/show_bug.cgi?id=185283
Reviewed by Michael Catanzaro.
.:
* Source/CMakeLists.txt:
* Source/cmake/FindLLVM.cmake: Removed.
* Source/cmake/OptionsCommon.cmake:
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsJSCOnly.cmake:
* Source/cmake/OptionsWPE.cmake:
Source/JavaScriptCore:
Instead of adding MIPS disassembler baked by ourselves, we import capstone disassembler.
And use capstone disassembler for MIPS, ARM, and ARMv7 in GTK, WPE, WinCairo and JSCOnly ports.
And we remove ARM LLVM disassembler.
Capstone is licensed under 3-clause BSD, which is acceptable in WebKit tree.
* CMakeLists.txt:
* Sources.txt:
* disassembler/ARMLLVMDisassembler.cpp: Removed.
* disassembler/CapstoneDisassembler.cpp: Added.
(JSC::tryToDisassemble):
Source/ThirdParty:
Add capstone to ThirdParty. We build capstone as a static library,
and link it against JSC. We only build disassembler for target architecture.
So for MIPS target, we only enable MIPS part of capstone.
We also remove unnecessary architectures in capstone, XCore, PowerPC, SystemZ, etc.
This is simply done by deleting these architecture directories.
We pick "next" branch instead of "master" branch since "next" branch is actively
developed.
* capstone/CMakeLists.txt: Added.
* capstone/Source/.appveyor.yml: Added.
* capstone/Source/.gitattributes: Added.
* capstone/Source/.gitignore: Added.
* capstone/Source/.travis.yml: Added.
* capstone/Source/CMakeLists.txt: Added.
* capstone/Source/COMPILE.TXT: Added.
* capstone/Source/COMPILE_CMAKE.TXT: Added.
* capstone/Source/COMPILE_MSVC.TXT: Added.
* capstone/Source/CREDITS.TXT: Added.
* capstone/Source/ChangeLog-capstone: Added.
* capstone/Source/HACK.TXT: Added.
* capstone/Source/LEB128.h: Added.
(decodeULEB128):
* capstone/Source/LICENSE.TXT: Added.
* capstone/Source/LICENSE_LLVM.TXT: Added.
* capstone/Source/MCDisassembler.h: Added.
* capstone/Source/MCFixedLenDisassembler.h: Added.
* capstone/Source/MCInst.c: Added.
(MCInst_Init):
(MCInst_clear):
(MCInst_insert0):
(MCInst_setOpcode):
(MCInst_setOpcodePub):
(MCInst_getOpcode):
(MCInst_getOpcodePub):
(MCInst_getOperand):
(MCInst_getNumOperands):
(MCInst_addOperand2):
(MCOperand_Init):
(MCOperand_isValid):
(MCOperand_isReg):
(MCOperand_isImm):
(MCOperand_isFPImm):
(MCOperand_getReg):
(MCOperand_setReg):
(MCOperand_getImm):
(MCOperand_setImm):
(MCOperand_getFPImm):
(MCOperand_setFPImm):
(MCOperand_CreateReg1):
(MCOperand_CreateReg0):
(MCOperand_CreateImm1):
(MCOperand_CreateImm0):
* capstone/Source/MCInst.h: Added.
* capstone/Source/MCInstrDesc.c: Added.
(MCOperandInfo_isPredicate):
(MCOperandInfo_isOptionalDef):
* capstone/Source/MCInstrDesc.h: Added.
* capstone/Source/MCRegisterInfo.c: Added.
(MCRegisterInfo_InitMCRegisterInfo):
(DiffListIterator_init):
(DiffListIterator_getVal):
(DiffListIterator_next):
(DiffListIterator_isValid):
(MCRegisterInfo_getMatchingSuperReg):
(MCRegisterInfo_getSubReg):
(MCRegisterInfo_getRegClass):
(MCRegisterClass_contains):
* capstone/Source/MCRegisterInfo.h: Added.
* capstone/Source/Makefile: Added.
* capstone/Source/MathExtras.h: Added.
(Hi_32):
(Lo_32):
(isUIntN):
(isMask_32):
(isMask_64):
(isShiftedMask_32):
(isShiftedMask_64):
(isPowerOf2_32):
(CountLeadingZeros_32):
(CountLeadingOnes_32):
(CountLeadingZeros_64):
(CountLeadingOnes_64):
(CountTrailingZeros_32):
(CountTrailingOnes_32):
(CountTrailingZeros_64):
(CountTrailingOnes_64):
(CountPopulation_32):
(CountPopulation_64):
(Log2_32):
(Log2_64):
(Log2_32_Ceil):
(Log2_64_Ceil):
(GreatestCommonDivisor64):
(BitsToDouble):
(BitsToFloat):
(DoubleToBits):
(FloatToBits):
(MinAlign):
(NextPowerOf2):
(RoundUpToAlignment):
(OffsetToAlignment):
(abs64):
(SignExtend32):
(SignExtend64):
(countLeadingZeros):
* capstone/Source/README.md: Added.
* capstone/Source/RELEASE_NOTES: Added.
* capstone/Source/SStream.c: Added.
(SStream_Init):
(SStream_concat0):
(SStream_concat):
(printInt64Bang):
(printUInt64Bang):
(printInt64):
(printInt32BangDec):
(printInt32Bang):
(printInt32):
(printUInt32Bang):
(printUInt32):
* capstone/Source/SStream.h: Added.
* capstone/Source/TODO: Added.
* capstone/Source/arch/ARM/ARMAddressingModes.h: Added.
(ARM_AM_getAddrOpcStr):
(ARM_AM_getShiftOpcStr):
(ARM_AM_getShiftOpcEncoding):
(ARM_AM_getAMSubModeStr):
(rotr32):
(rotl32):
(getSORegOpc):
(getSORegOffset):
(ARM_AM_getSORegShOp):
(getSOImmValImm):
(getSOImmValRot):
(getSOImmValRotate):
(getSOImmVal):
(isSOImmTwoPartVal):
(getSOImmTwoPartFirst):
(getSOImmTwoPartSecond):
(getThumbImmValShift):
(isThumbImmShiftedVal):
(getThumbImm16ValShift):
(isThumbImm16ShiftedVal):
(getThumbImmNonShiftedVal):
(getT2SOImmValSplatVal):
(getT2SOImmValRotateVal):
(getT2SOImmVal):
(getT2SOImmValRotate):
(isT2SOImmTwoPartVal):
(getT2SOImmTwoPartFirst):
(getT2SOImmTwoPartSecond):
(ARM_AM_getAM2Opc):
(getAM2Offset):
(getAM2Op):
(getAM2ShiftOpc):
(getAM2IdxMode):
(getAM3Opc):
(getAM3Offset):
(getAM3Op):
(getAM3IdxMode):
(getAM4SubMode):
(getAM4ModeImm):
(ARM_AM_getAM5Opc):
(ARM_AM_getAM5Offset):
(ARM_AM_getAM5Op):
(createNEONModImm):
(getNEONModImmOpCmode):
(getNEONModImmVal):
(ARM_AM_decodeNEONModImm):
(getFPImmFloat):
* capstone/Source/arch/ARM/ARMBaseInfo.h: Added.
(ARMCC_getOppositeCondition):
(ARMCC_ARMCondCodeToString):
(ARM_PROC_IFlagsToString):
(ARM_PROC_IModToString):
(ARM_MB_MemBOptToString):
(ARM_ISB_InstSyncBOptToString):
(isARMLowRegister):
(ARMII_AddrModeToString):
* capstone/Source/arch/ARM/ARMDisassembler.c: Added.
(ITStatus_push_back):
(ITStatus_instrInITBlock):
(ITStatus_instrLastInITBlock):
(ITStatus_getITCC):
(ITStatus_advanceITState):
(ITStatus_setITState):
(Check):
(ARM_getFeatureBits):
(DecodePredicateOperand):
(ARM_init):
(checkDecodedInstruction):
(_ARM_getInstruction):
(AddThumb1SBit):
(AddThumbPredicate):
(UpdateThumbVFPPredicate):
(_Thumb_getInstruction):
(Thumb_getInstruction):
(ARM_getInstruction):
(DecodeGPRnopcRegisterClass):
(DecodeGPRwithAPSRRegisterClass):
(DecodetGPRRegisterClass):
(DecodetcGPRRegisterClass):
(DecoderGPRRegisterClass):
(DecodeDPRRegisterClass):
(DecodeDPR_8RegisterClass):
(DecodeDPR_VFP2RegisterClass):
(DecodeDPairRegisterClass):
(DecodeCCOutOperand):
(DecodeSORegImmOperand):
(DecodeSORegRegOperand):
(DecodeRegListOperand):
(DecodeSPRRegListOperand):
(DecodeDPRRegListOperand):
(DecodeBitfieldMaskOperand):
(DecodeCopMemInstruction):
(DecodeAddrMode2IdxInstruction):
(DecodeSORegMemOperand):
(DecodeAddrMode3Instruction):
(DecodeRFEInstruction):
(DecodeQADDInstruction):
(DecodeMemMultipleWritebackInstruction):
(DecodeCPSInstruction):
(DecodeT2CPSInstruction):
(DecodeT2MOVTWInstruction):
(DecodeArmMOVTWInstruction):
(DecodeSMLAInstruction):
(DecodeAddrModeImm12Operand):
(DecodeAddrMode5Operand):
(DecodeAddrMode7Operand):
(DecodeT2BInstruction):
(DecodeBranchImmInstruction):
(DecodeAddrMode6Operand):
(DecodeVLDInstruction):
(DecodeVLDST1Instruction):
(DecodeVLDST2Instruction):
(DecodeVLDST3Instruction):
(DecodeVLDST4Instruction):
(DecodeVSTInstruction):
(DecodeVLD1DupInstruction):
(DecodeVLD2DupInstruction):
(DecodeVLD3DupInstruction):
(DecodeVLD4DupInstruction):
(DecodeNEONModImmInstruction):
(DecodeVSHLMaxInstruction):
(DecodeShiftRight8Imm):
(DecodeShiftRight16Imm):
(DecodeShiftRight32Imm):
(DecodeShiftRight64Imm):
(DecodeTBLInstruction):
(DecodeThumbAddSpecialReg):
(DecodeThumbBROperand):
(DecodeT2BROperand):
(DecodeThumbCmpBROperand):
(DecodeThumbAddrModeRR):
(DecodeThumbAddrModeIS):
(DecodeThumbAddrModePC):
(DecodeThumbAddrModeSP):
(DecodeT2AddrModeSOReg):
(DecodeT2LoadShift):
(DecodeT2LoadImm8):
(DecodeT2LoadImm12):
(DecodeT2LoadT):
(DecodeT2LoadLabel):
(DecodeT2Imm8S4):
(DecodeT2AddrModeImm8s4):
(DecodeT2AddrModeImm0_1020s4):
(DecodeT2Imm8):
(DecodeT2AddrModeImm8):
(DecodeT2LdStPre):
(DecodeT2AddrModeImm12):
(DecodeThumbAddSPImm):
(DecodeThumbAddSPReg):
(DecodeThumbCPS):
(DecodePostIdxReg):
(DecodeThumbBLXOffset):
(DecodeCoprocessor):
(DecodeThumbTableBranch):
(DecodeThumb2BCCInstruction):
(DecodeT2SOImm):
(DecodeThumbBCCTargetOperand):
(DecodeThumbBLTargetOperand):
(DecodeMemBarrierOption):
(DecodeInstSyncBarrierOption):
(DecodeMSRMask):
(DecodeBankedReg):
(DecodeDoubleRegLoad):
(DecodeDoubleRegStore):
(DecodeLDRPreImm):
(DecodeLDRPreReg):
(DecodeSTRPreImm):
(DecodeSTRPreReg):
(DecodeVLD1LN):
(DecodeVST1LN):
(DecodeVLD2LN):
(DecodeVST2LN):
(DecodeVLD3LN):
(DecodeVST3LN):
(DecodeVLD4LN):
(DecodeVST4LN):
(DecodeVMOVSRR):
(DecodeVMOVRRS):
(DecodeIT):
(DecodeT2LDRDPreInstruction):
(DecodeT2STRDPreInstruction):
(DecodeT2Adr):
(DecodeT2ShifterImmOperand):
(DecodeSwap):
(DecodeVCVTD):
(DecodeVCVTQ):
(DecodeLDR):
(DecodeMRRC2):
* capstone/Source/arch/ARM/ARMDisassembler.h: Added.
* capstone/Source/arch/ARM/ARMGenAsmWriter.inc: Added.
* capstone/Source/arch/ARM/ARMGenDisassemblerTables.inc: Added.
* capstone/Source/arch/ARM/ARMGenInstrInfo.inc: Added.
* capstone/Source/arch/ARM/ARMGenRegisterInfo.inc: Added.
* capstone/Source/arch/ARM/ARMGenSubtargetInfo.inc: Added.
* capstone/Source/arch/ARM/ARMInstPrinter.c: Added.
(get_op_access):
(set_mem_access):
(op_addImm):
(ARM_getRegName):
(translateShiftImm):
(printRegImmShift):
(printRegName):
(ARM_printInst):
(printOperand):
(printThumbLdrLabelOperand):
(printSORegRegOperand):
(printSORegImmOperand):
(printAM2PreOrOffsetIndexOp):
(printAddrModeTBB):
(printAddrModeTBH):
(printAddrMode2Operand):
(printAddrMode2OffsetOperand):
(printAM3PreOrOffsetIndexOp):
(printAddrMode3Operand):
(printAddrMode3OffsetOperand):
(printPostIdxImm8Operand):
(printPostIdxRegOperand):
(printPostIdxImm8s4Operand):
(printAddrMode5Operand):
(printAddrMode6Operand):
(printAddrMode7Operand):
(printAddrMode6OffsetOperand):
(printBitfieldInvMaskImmOperand):
(printMemBOption):
(printInstSyncBOption):
(printShiftImmOperand):
(printPKHLSLShiftImm):
(printPKHASRShiftImm):
(printRegisterList):
(printGPRPairOperand):
(printSetendOperand):
(printCPSIMod):
(printCPSIFlag):
(printMSRMaskOperand):
(printBankedRegOperand):
(printPredicateOperand):
(printMandatoryPredicateOperand):
(printSBitModifierOperand):
(printNoHashImmediate):
(printPImmediate):
(printCImmediate):
(printCoprocOptionImm):
(printAdrLabelOperand):
(printThumbS4ImmOperand):
(printThumbSRImm):
(printThumbITMask):
(printThumbAddrModeRROperand):
(printThumbAddrModeImm5SOperand):
(printThumbAddrModeImm5S1Operand):
(printThumbAddrModeImm5S2Operand):
(printThumbAddrModeImm5S4Operand):
(printThumbAddrModeSPOperand):
(printT2SOOperand):
(printAddrModeImm12Operand):
(printT2AddrModeImm8Operand):
(printT2AddrModeImm8s4Operand):
(printT2AddrModeImm0_1020s4Operand):
(printT2AddrModeImm8OffsetOperand):
(printT2AddrModeImm8s4OffsetOperand):
(printT2AddrModeSoRegOperand):
(printFPImmOperand):
(printNEONModImmOperand):
(printImmPlusOneOperand):
(printRotImmOperand):
(printModImmOperand):
(printFBits16):
(printFBits32):
(printVectorIndex):
(printVectorListOne):
(printVectorListTwo):
(printVectorListTwoSpaced):
(printVectorListThree):
(printVectorListFour):
(printVectorListOneAllLanes):
(printVectorListTwoAllLanes):
(printVectorListThreeAllLanes):
(printVectorListFourAllLanes):
(printVectorListTwoSpacedAllLanes):
(printVectorListThreeSpacedAllLanes):
(printVectorListFourSpacedAllLanes):
(printVectorListThreeSpaced):
(printVectorListFourSpaced):
(ARM_addVectorDataType):
(ARM_addVectorDataSize):
(ARM_addReg):
(ARM_addUserMode):
(ARM_addSysReg):
* capstone/Source/arch/ARM/ARMInstPrinter.h: Added.
* capstone/Source/arch/ARM/ARMMapping.c: Added.
(ARM_reg_name2):
(ARM_insn_name):
(ARM_rel_branch):
(ARM_blx_to_arm_mode):
(ARM_reg_access):
* capstone/Source/arch/ARM/ARMMapping.h: Added.
* capstone/Source/arch/ARM/ARMMappingInsn.inc: Added.
* capstone/Source/arch/ARM/ARMMappingInsnOp.inc: Added.
* capstone/Source/arch/ARM/ARMModule.c: Added.
(init):
(option):
(ARM_enable):
* capstone/Source/arch/Mips/MipsDisassembler.c: Added.
(getFeatureBits):
(Mips_init):
(readInstruction16):
(readInstruction32):
(MipsDisassembler_getInstruction):
(Mips_getInstruction):
(getReg):
(DecodeINSVE_DF_4):
(DecodeAddiGroupBranch_4):
(DecodeDaddiGroupBranch_4):
(DecodeBlezlGroupBranch_4):
(DecodeBgtzlGroupBranch_4):
(DecodeBgtzGroupBranch_4):
(DecodeBlezGroupBranch_4):
(DecodeCPU16RegsRegisterClass):
(DecodeGPR64RegisterClass):
(DecodeGPRMM16RegisterClass):
(DecodeGPRMM16ZeroRegisterClass):
(DecodeGPRMM16MovePRegisterClass):
(DecodeGPR32RegisterClass):
(DecodePtrRegisterClass):
(DecodeDSPRRegisterClass):
(DecodeFGR64RegisterClass):
(DecodeFGR32RegisterClass):
(DecodeCCRRegisterClass):
(DecodeFCCRegisterClass):
(DecodeCCRegisterClass):
(DecodeFGRCCRegisterClass):
(DecodeMem):
(DecodeCacheOp):
(DecodeCacheOpMM):
(DecodeCacheOpR6):
(DecodeSyncI):
(DecodeMSA128Mem):
(DecodeMemMMImm4):
(DecodeMemMMSPImm5Lsl2):
(DecodeMemMMGPImm7Lsl2):
(DecodeMemMMReglistImm4Lsl2):
(DecodeMemMMImm12):
(DecodeMemMMImm16):
(DecodeFMem):
(DecodeFMem2):
(DecodeFMem3):
(DecodeFMemCop2R6):
(DecodeSpecial3LlSc):
(DecodeHWRegsRegisterClass):
(DecodeAFGR64RegisterClass):
(DecodeACC64DSPRegisterClass):
(DecodeHI32DSPRegisterClass):
(DecodeLO32DSPRegisterClass):
(DecodeMSA128BRegisterClass):
(DecodeMSA128HRegisterClass):
(DecodeMSA128WRegisterClass):
(DecodeMSA128DRegisterClass):
(DecodeMSACtrlRegisterClass):
(DecodeCOP2RegisterClass):
(DecodeBranchTarget):
(DecodeJumpTarget):
(DecodeBranchTarget21):
(DecodeBranchTarget26):
(DecodeBranchTarget7MM):
(DecodeBranchTarget10MM):
(DecodeBranchTargetMM):
(DecodeJumpTargetMM):
(DecodeAddiur2Simm7):
(DecodeUImm6Lsl2):
(DecodeLiSimm7):
(DecodeSimm4):
(DecodeSimm16):
(DecodeLSAImm):
(DecodeInsSize):
(DecodeExtSize):
(DecodeSimm19Lsl2):
(DecodeSimm18Lsl3):
(DecodeSimm9SP):
(DecodeANDI16Imm):
(DecodeUImm5lsl2):
(DecodeRegListOperand):
(DecodeRegListOperand16):
(DecodeMovePRegPair):
(DecodeSimm23Lsl2):
* capstone/Source/arch/Mips/MipsDisassembler.h: Added.
* capstone/Source/arch/Mips/MipsGenAsmWriter.inc: Added.
* capstone/Source/arch/Mips/MipsGenDisassemblerTables.inc: Added.
* capstone/Source/arch/Mips/MipsGenInstrInfo.inc: Added.
* capstone/Source/arch/Mips/MipsGenRegisterInfo.inc: Added.
* capstone/Source/arch/Mips/MipsGenSubtargetInfo.inc: Added.
* capstone/Source/arch/Mips/MipsInstPrinter.c: Added.
(set_mem_access):
(isReg):
(MipsFCCToString):
(printRegName):
(Mips_printInst):
(printOperand):
(printUnsignedImm):
(printUnsignedImm8):
(printMemOperand):
(printMemOperandEA):
(printFCCOperand):
(printRegisterPair):
(printAlias1):
(printAlias2):
(printAlias):
(printRegisterList):
* capstone/Source/arch/Mips/MipsInstPrinter.h: Added.
* capstone/Source/arch/Mips/MipsMapping.c: Added.
(Mips_get_insn_id):
(Mips_group_name):
(Mips_map_insn):
(Mips_map_register):
* capstone/Source/arch/Mips/MipsMapping.h: Added.
* capstone/Source/arch/Mips/MipsMappingInsn.inc: Added.
* capstone/Source/arch/Mips/MipsModule.c: Added.
(init):
(option):
(Mips_enable):
* capstone/Source/capstone.pc.in: Added.
* capstone/Source/config.mk: Added.
* capstone/Source/cs.c: Added.
(cs_kern_os_calloc):
(cs_version):
(cs_support):
(cs_errno):
(cs_strerror):
(cs_open):
(cs_close):
(fill_insn):
(skipdata_size):
(cs_option):
(skipdata_opstr):
(cs_disasm):
(cs_disasm_ex):
(cs_free):
(cs_malloc):
(cs_disasm_iter):
(cs_reg_name):
(cs_insn_name):
(cs_group_name):
(cs_insn_group):
(cs_reg_read):
(cs_reg_write):
(cs_op_count):
(cs_op_index):
(cs_regs_access):
* capstone/Source/cs_priv.h: Added.
* capstone/Source/functions.mk: Added.
* capstone/Source/include/capstone/arm.h: Added.
* capstone/Source/include/capstone/arm64.h: Added.
* capstone/Source/include/capstone/capstone.h: Added.
* capstone/Source/include/capstone/evm.h: Added.
* capstone/Source/include/capstone/m680x.h: Added.
* capstone/Source/include/capstone/m68k.h: Added.
* capstone/Source/include/capstone/mips.h: Added.
* capstone/Source/include/capstone/platform.h: Added.
* capstone/Source/include/capstone/ppc.h: Added.
* capstone/Source/include/capstone/sparc.h: Added.
* capstone/Source/include/capstone/systemz.h: Added.
* capstone/Source/include/capstone/tms320c64x.h: Added.
* capstone/Source/include/capstone/x86.h: Added.
* capstone/Source/include/capstone/xcore.h: Added.
* capstone/Source/include/windowsce/intrin.h: Added.
* capstone/Source/include/windowsce/stdint.h: Added.
* capstone/Source/make.sh: Added.
* capstone/Source/nmake-x86.bat: Added.
* capstone/Source/nmake.bat: Added.
* capstone/Source/pkgconfig.mk: Added.
* capstone/Source/utils.c: Added.
(make_id2insn):
(insn_find):
(name2id):
(id2name):
(count_positive):
(count_positive8):
(cs_strdup):
(cs_snprintf):
(arr_exist8):
(arr_exist):
* capstone/Source/utils.h: Added.
* capstone/capstone-Revision.txt: Added.
Source/WTF:
Add USE_CAPSTONE used for MIPS and ARM.
* wtf/Platform.h:
Tools:
* gtk/manifest.txt.in:
* wpe/manifest.txt.in:
Canonical link: https://commits.webkit.org/200942@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231553 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-09 11:42:09 +00:00
|
|
|
disassembler/CapstoneDisassembler.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
disassembler/Disassembler.cpp
|
|
|
|
disassembler/UDis86Disassembler.cpp
|
|
|
|
disassembler/X86Disassembler.cpp
|
|
|
|
|
|
|
|
disassembler/ARM64/A64DOpcode.cpp
|
|
|
|
|
|
|
|
disassembler/udis86/udis86.c
|
|
|
|
disassembler/udis86/udis86_decode.c
|
|
|
|
disassembler/udis86/udis86_itab_holder.c
|
|
|
|
disassembler/udis86/udis86_syn-att.c
|
|
|
|
disassembler/udis86/udis86_syn-intel.c
|
|
|
|
disassembler/udis86/udis86_syn.c
|
|
|
|
|
|
|
|
domjit/DOMJITAbstractHeap.cpp
|
|
|
|
domjit/DOMJITHeapRange.cpp
|
|
|
|
|
|
|
|
ftl/FTLAbstractHeap.cpp
|
|
|
|
ftl/FTLAbstractHeapRepository.cpp
|
|
|
|
ftl/FTLAvailableRecovery.cpp
|
|
|
|
ftl/FTLCapabilities.cpp
|
|
|
|
ftl/FTLCommonValues.cpp
|
|
|
|
ftl/FTLCompile.cpp
|
|
|
|
ftl/FTLExceptionTarget.cpp
|
|
|
|
ftl/FTLExitArgument.cpp
|
|
|
|
ftl/FTLExitArgumentForOperand.cpp
|
|
|
|
ftl/FTLExitPropertyValue.cpp
|
|
|
|
ftl/FTLExitTimeObjectMaterialization.cpp
|
|
|
|
ftl/FTLExitValue.cpp
|
|
|
|
ftl/FTLFail.cpp
|
|
|
|
ftl/FTLForOSREntryJITCode.cpp
|
|
|
|
ftl/FTLJITCode.cpp
|
|
|
|
ftl/FTLJITFinalizer.cpp
|
|
|
|
ftl/FTLLazySlowPath.cpp
|
|
|
|
ftl/FTLLink.cpp
|
|
|
|
ftl/FTLLocation.cpp
|
2018-07-31 20:21:50 +00:00
|
|
|
// This file takes a long time to compile so we do it individually.
|
|
|
|
ftl/FTLLowerDFGToB3.cpp @no-unify
|
2017-09-20 23:08:50 +00:00
|
|
|
ftl/FTLOSREntry.cpp
|
|
|
|
ftl/FTLOSRExit.cpp
|
|
|
|
ftl/FTLOSRExitCompiler.cpp
|
|
|
|
ftl/FTLOSRExitHandle.cpp
|
|
|
|
ftl/FTLOperations.cpp
|
|
|
|
ftl/FTLOutput.cpp
|
|
|
|
ftl/FTLPatchpointExceptionHandle.cpp
|
|
|
|
ftl/FTLRecoveryOpcode.cpp
|
|
|
|
ftl/FTLSaveRestore.cpp
|
|
|
|
ftl/FTLSlowPathCall.cpp
|
|
|
|
ftl/FTLSlowPathCallKey.cpp
|
|
|
|
ftl/FTLSnippetParams.cpp
|
|
|
|
ftl/FTLState.cpp
|
|
|
|
ftl/FTLThunks.cpp
|
|
|
|
ftl/FTLValueRange.cpp
|
|
|
|
|
|
|
|
heap/AlignedMemoryAllocator.cpp
|
JSC GC should support TLCs (thread local caches)
https://bugs.webkit.org/show_bug.cgi?id=181559
Reviewed by Mark Lam and Saam Barati.
Source/JavaScriptCore:
This is a big step towards object distancing by site origin. This patch implements TLCs, or
thread-local caches, which allow each thread to allocate from its own free lists. It also
means that any given thread can context-switch TLCs. This will allow us to do separate
allocation for separate site origins. Eventually, once we reshape how MarkedBlock looks, this
will allow us to have a hard distancing constraint between objects from different origins.
In this new design, every "size class" is represented as a BlockDirectory (formerly known as
MarkedAllocator, prior to r226822). This contains a bag of blocks allocated using some
aligned memory allocator (which roughly represents which cage you came out of), and anyone
using the same allocator can share those blocks - but so long as they are in that
BlockDirectory, they will have the size and type of that directory. Previously, each
BlockDirectory had exactly one FreeList. Now, each BlockDirectory has a double-linked-list of
LocalAllocators, each of which has a FreeList.
To decide which LocalAllocator to allocate out of, we need a ThreadLocalCache and a
BlockDirectory. The directory gives us an offset-within-the-ThreadLocalCache, which we simply
call the Allocator (which is just a POD type that contains a 32-bit offset). Each allocation
starts by figuring out what Allocator it wants (often we have this information at JIT time).
Then the allocation loads its ThreadLocalCache::Data from a fast TLS slot. Then we add the
Allocator offset to the ThreadLocalCache::Data to get the LocalAllocator. Note that we use
offsets as opposed to indices to make it easy to do the math on each allocation (if
LocalAllocator had a weird size then every allocation would have to do an imul).
This is a definite slow-down on GC-heavy benchmarks, but by a small margin, and only on
unusually heavy tests. For example, boyer and splay are both 3% regressed, but the Octane
geomean is just fine. The JetStream score regressed by 0.5% with p = 0.08 (so maybe there is
something there, but it's not significant according to our threshold).
Relanding after fixing ARM64 bug in AssemblyHelpers::emitAllocateWithNonNullAllocator(). That
function needs to be careful to avoid using the scratch register because the FTL will call it
in disallow-scratch-register mode.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3LowerToAir.cpp:
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::admitsStack):
* b3/B3StackmapSpecial.cpp:
(JSC::B3::StackmapSpecial::forEachArgImpl):
(JSC::B3::StackmapSpecial::isArgValidForRep):
* b3/B3StackmapValue.cpp:
(JSC::B3::StackmapValue::appendSomeRegisterWithClobber):
* b3/B3StackmapValue.h:
* b3/B3Validate.cpp:
* b3/B3ValueRep.cpp:
(JSC::B3::ValueRep::addUsedRegistersTo const):
(JSC::B3::ValueRep::dump const):
(WTF::printInternal):
* b3/B3ValueRep.h:
(JSC::B3::ValueRep::ValueRep):
* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfile::ObjectAllocationProfile):
(JSC::ObjectAllocationProfile::clear):
* bytecode/ObjectAllocationProfileInlines.h:
(JSC::ObjectAllocationProfile::initializeProfile):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
(JSC::DFG::SpeculativeJIT::compileMakeRope):
(JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
(JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
(JSC::DFG::SpeculativeJIT::compileCreateThis):
(JSC::DFG::SpeculativeJIT::compileNewObject):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMakeRope):
(JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
(JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl):
(JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell):
(JSC::FTL::DFG::LowerDFGToB3::allocateObject):
(JSC::FTL::DFG::LowerDFGToB3::allocatorForSize):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
* heap/Allocator.cpp: Added.
(JSC::Allocator::cellSize const):
* heap/Allocator.h: Added.
(JSC::Allocator::Allocator):
(JSC::Allocator::offset const):
(JSC::Allocator::operator== const):
(JSC::Allocator::operator!= const):
(JSC::Allocator::operator bool const):
* heap/AllocatorInlines.h: Added.
(JSC::Allocator::allocate const):
(JSC::Allocator::tryAllocate const):
* heap/BlockDirectory.cpp:
(JSC::BlockDirectory::BlockDirectory):
(JSC::BlockDirectory::findBlockForAllocation):
(JSC::BlockDirectory::stopAllocating):
(JSC::BlockDirectory::prepareForAllocation):
(JSC::BlockDirectory::stopAllocatingForGood):
(JSC::BlockDirectory::resumeAllocating):
(JSC::BlockDirectory::endMarking):
(JSC::BlockDirectory::isFreeListedCell):
(JSC::BlockDirectory::didConsumeFreeList): Deleted.
(JSC::BlockDirectory::tryAllocateWithoutCollecting): Deleted.
(JSC::BlockDirectory::allocateIn): Deleted.
(JSC::BlockDirectory::tryAllocateIn): Deleted.
(JSC::BlockDirectory::doTestCollectionsIfNeeded): Deleted.
(JSC::BlockDirectory::allocateSlowCase): Deleted.
* heap/BlockDirectory.h:
(JSC::BlockDirectory::cellKind const):
(JSC::BlockDirectory::allocator const):
(JSC::BlockDirectory::freeList const): Deleted.
(JSC::BlockDirectory::offsetOfFreeList): Deleted.
(JSC::BlockDirectory::offsetOfCellSize): Deleted.
* heap/BlockDirectoryInlines.h:
(JSC::BlockDirectory::isFreeListedCell const): Deleted.
(JSC::BlockDirectory::allocate): Deleted.
* heap/CompleteSubspace.cpp:
(JSC::CompleteSubspace::CompleteSubspace):
(JSC::CompleteSubspace::allocatorFor):
(JSC::CompleteSubspace::allocate):
(JSC::CompleteSubspace::allocateNonVirtual):
(JSC::CompleteSubspace::allocatorForSlow):
(JSC::CompleteSubspace::allocateSlow):
(JSC::CompleteSubspace::tryAllocateSlow):
* heap/CompleteSubspace.h:
(JSC::CompleteSubspace::allocatorForSizeStep):
(JSC::CompleteSubspace::allocatorForNonVirtual):
* heap/FreeList.h:
* heap/GCDeferralContext.h:
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::lastChanceToFinalize):
* heap/Heap.h:
(JSC::Heap::threadLocalCacheLayout):
* heap/IsoCellSet.h:
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
(JSC::IsoSubspace::allocatorFor):
(JSC::IsoSubspace::allocate):
(JSC::IsoSubspace::allocateNonVirtual):
* heap/IsoSubspace.h:
(JSC::IsoSubspace::allocatorForNonVirtual):
* heap/LocalAllocator.cpp: Added.
(JSC::LocalAllocator::LocalAllocator):
(JSC::LocalAllocator::reset):
(JSC::LocalAllocator::~LocalAllocator):
(JSC::LocalAllocator::stopAllocating):
(JSC::LocalAllocator::resumeAllocating):
(JSC::LocalAllocator::prepareForAllocation):
(JSC::LocalAllocator::stopAllocatingForGood):
(JSC::LocalAllocator::allocateSlowCase):
(JSC::LocalAllocator::didConsumeFreeList):
(JSC::LocalAllocator::tryAllocateWithoutCollecting):
(JSC::LocalAllocator::allocateIn):
(JSC::LocalAllocator::tryAllocateIn):
(JSC::LocalAllocator::doTestCollectionsIfNeeded):
(JSC::LocalAllocator::isFreeListedCell const):
* heap/LocalAllocator.h: Added.
(JSC::LocalAllocator::offsetOfFreeList):
(JSC::LocalAllocator::offsetOfCellSize):
* heap/LocalAllocatorInlines.h: Added.
(JSC::LocalAllocator::allocate):
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::stopAllocatingForGood):
* heap/MarkedSpace.h:
* heap/SlotVisitor.cpp:
* heap/SlotVisitor.h:
* heap/Subspace.h:
* heap/ThreadLocalCache.cpp: Added.
(JSC::ThreadLocalCache::create):
(JSC::ThreadLocalCache::ThreadLocalCache):
(JSC::ThreadLocalCache::~ThreadLocalCache):
(JSC::ThreadLocalCache::allocateData):
(JSC::ThreadLocalCache::destroyData):
(JSC::ThreadLocalCache::installSlow):
(JSC::ThreadLocalCache::installData):
(JSC::ThreadLocalCache::allocatorSlow):
(JSC::ThreadLocalCache::destructor):
* heap/ThreadLocalCache.h: Added.
(JSC::ThreadLocalCache::offsetOfSize):
(JSC::ThreadLocalCache::offsetOfFirstAllocator):
* heap/ThreadLocalCacheInlines.h: Added.
(JSC::ThreadLocalCache::getImpl):
(JSC::ThreadLocalCache::get):
(JSC::ThreadLocalCache::install):
(JSC::ThreadLocalCache::allocator):
(JSC::ThreadLocalCache::tryGetAllocator):
* heap/ThreadLocalCacheLayout.cpp: Added.
(JSC::ThreadLocalCacheLayout::ThreadLocalCacheLayout):
(JSC::ThreadLocalCacheLayout::~ThreadLocalCacheLayout):
(JSC::ThreadLocalCacheLayout::allocateOffset):
(JSC::ThreadLocalCacheLayout::snapshot):
(JSC::ThreadLocalCacheLayout::directory):
* heap/ThreadLocalCacheLayout.h: Added.
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator):
(JSC::AssemblyHelpers::emitAllocate):
(JSC::AssemblyHelpers::emitAllocateVariableSized):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::vm):
(JSC::AssemblyHelpers::emitAllocateJSCell):
(JSC::AssemblyHelpers::emitAllocateJSObject):
(JSC::AssemblyHelpers::emitAllocateJSObjectWithKnownSize):
(JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator): Deleted.
(JSC::AssemblyHelpers::emitAllocate): Deleted.
(JSC::AssemblyHelpers::emitAllocateVariableSized): Deleted.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_new_object):
(JSC::JIT::emit_op_create_this):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_new_object):
(JSC::JIT::emit_op_create_this):
* runtime/ButterflyInlines.h:
(JSC::Butterfly::createUninitialized):
(JSC::Butterfly::tryCreate):
(JSC::Butterfly::growArrayRight):
* runtime/DirectArguments.cpp:
(JSC::DirectArguments::overrideThings):
* runtime/GenericArgumentsInlines.h:
(JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor):
* runtime/HashMapImpl.h:
(JSC::HashMapBuffer::create):
* runtime/JSArray.cpp:
(JSC::JSArray::tryCreateUninitializedRestricted):
(JSC::JSArray::unshiftCountSlowCase):
* runtime/JSArray.h:
(JSC::JSArray::tryCreate):
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
* runtime/JSCellInlines.h:
(JSC::tryAllocateCellHelper):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::threadLocalCache const):
* runtime/JSLock.cpp:
(JSC::JSLock::didAcquireLock):
* runtime/Options.h:
* runtime/RegExpMatchesArray.h:
(JSC::tryCreateUninitializedRegExpMatchesArray):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* runtime/VMEntryScope.cpp:
(JSC::VMEntryScope::VMEntryScope):
Source/WTF:
* wtf/Bitmap.h: Just fixing a compile error.
Canonical link: https://commits.webkit.org/197951@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227617 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-01-25 19:32:00 +00:00
|
|
|
heap/Allocator.cpp
|
2018-01-12 00:32:33 +00:00
|
|
|
heap/BlockDirectory.cpp
|
|
|
|
heap/CellAttributes.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/CellContainer.cpp
|
|
|
|
heap/CodeBlockSet.cpp
|
|
|
|
heap/CollectionScope.cpp
|
|
|
|
heap/CollectorPhase.cpp
|
2017-11-30 04:39:50 +00:00
|
|
|
heap/CompleteSubspace.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/ConservativeRoots.cpp
|
|
|
|
heap/DeferGC.cpp
|
|
|
|
heap/DestructionMode.cpp
|
|
|
|
heap/EdenGCActivityCallback.cpp
|
|
|
|
heap/FastMallocAlignedMemoryAllocator.cpp
|
|
|
|
heap/FullGCActivityCallback.cpp
|
|
|
|
heap/FreeList.cpp
|
|
|
|
heap/GCActivityCallback.cpp
|
|
|
|
heap/GCConductor.cpp
|
|
|
|
heap/GCLogging.cpp
|
|
|
|
heap/GCRequest.cpp
|
Experiment: create lots of different malloc zones for easier accounting of memory use
https://bugs.webkit.org/show_bug.cgi?id=186422
Patch by Yusuke Suzuki <ysuzuki@apple.com> and Simon Fraser <simon.fraser@apple.com> on 2020-01-02
Reviewed by Saam Barati.
Source/bmalloc:
* bmalloc/BPlatform.h:
* bmalloc/Environment.cpp:
(bmalloc::Environment::computeIsDebugHeapEnabled):
* bmalloc/IsoHeap.h:
(bmalloc::api::IsoHeap::IsoHeap):
* bmalloc/IsoHeapInlines.h:
(bmalloc::api::IsoHeap<Type>::IsoHeap):
* bmalloc/IsoTLSInlines.h:
(bmalloc::IsoTLS::allocateSlow):
(bmalloc::IsoTLS::deallocateSlow):
Source/JavaScriptCore:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/AssemblerBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* assembler/AssemblerBuffer.h:
(JSC::AssemblerData::AssemblerData):
(JSC::AssemblerData::operator=):
(JSC::AssemblerData::~AssemblerData):
(JSC::AssemblerData::grow):
* bytecode/AccessCase.cpp:
* bytecode/AccessCase.h:
* bytecode/BytecodeBasicBlock.cpp:
* bytecode/BytecodeBasicBlock.h:
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* bytecode/InstructionStream.cpp:
* bytecode/InstructionStream.h:
* bytecode/PolymorphicAccess.cpp:
* bytecode/PolymorphicAccess.h:
* bytecode/UnlinkedMetadataTable.cpp:
(JSC::UnlinkedMetadataTable::finalize):
* bytecode/UnlinkedMetadataTable.h:
* bytecode/UnlinkedMetadataTableInlines.h:
(JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::~UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::link):
(JSC::UnlinkedMetadataTable::unlink):
* bytecode/ValueProfile.h:
(JSC::ValueProfileAndVirtualRegisterBuffer::ValueProfileAndVirtualRegisterBuffer):
* bytecode/Watchpoint.cpp:
* bytecode/Watchpoint.h:
* dfg/DFGBasicBlock.cpp:
* dfg/DFGBasicBlock.h:
* dfg/DFGNode.cpp:
* dfg/DFGNode.h:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
* heap/BlockDirectory.cpp:
* heap/BlockDirectory.h:
* heap/FastMallocAlignedMemoryAllocator.cpp:
(JSC::FastMallocAlignedMemoryAllocator::FastMallocAlignedMemoryAllocator):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryReallocateMemory):
* heap/FastMallocAlignedMemoryAllocator.h:
* heap/GCSegmentedArray.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* heap/GCSegmentedArray.h:
* heap/GCSegmentedArrayInlines.h:
(JSC::GCArraySegment<T>::create):
(JSC::GCArraySegment<T>::destroy):
* heap/GigacageAlignedMemoryAllocator.cpp:
(JSC::GigacageAlignedMemoryAllocator::GigacageAlignedMemoryAllocator):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::freeAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateMemory):
(JSC::GigacageAlignedMemoryAllocator::freeMemory):
(JSC::GigacageAlignedMemoryAllocator::tryReallocateMemory):
* heap/GigacageAlignedMemoryAllocator.h:
* heap/IsoAlignedMemoryAllocator.cpp:
(JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::freeAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::tryAllocateMemory):
(JSC::IsoAlignedMemoryAllocator::freeMemory):
* heap/IsoAlignedMemoryAllocator.h:
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
* heap/MarkedBlock.cpp:
* heap/MarkedBlock.h:
* heap/WeakBlock.cpp:
(JSC::WeakBlock::create):
(JSC::WeakBlock::destroy):
* heap/WeakBlock.h:
* jit/JITCode.cpp:
* jit/JITCode.h:
* jit/RegisterAtOffsetList.cpp:
* jit/RegisterAtOffsetList.h:
* parser/Nodes.cpp:
* parser/Nodes.h:
* parser/ParserArena.cpp:
(JSC::ParserArena::deallocateObjects):
(JSC::ParserArena::allocateFreeablePool):
* parser/ParserArena.h:
* parser/SourceProvider.cpp:
* parser/SourceProvider.h:
* parser/SourceProviderCache.cpp:
* parser/SourceProviderCache.h:
* parser/SourceProviderCacheItem.h:
(JSC::SourceProviderCacheItem::create):
* runtime/CachePayload.cpp:
(JSC::CachePayload::makeMallocPayload):
* runtime/CachePayload.h:
* runtime/CachedBytecode.h:
(JSC::CachedBytecode::create):
* runtime/CachedTypes.cpp:
(JSC::Encoder::release):
(JSC::Encoder::Page::Page):
(JSC::CachedVector::encode):
(JSC::CachedVector::decode const):
(JSC::CachedInstructionStream::decode const):
* runtime/PropertyMapHashTable.h:
(JSC::PropertyTable::rehash):
* runtime/PropertyTable.cpp:
(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::~PropertyTable):
* runtime/SymbolTable.cpp:
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::ScratchBuffer::create):
(JSC::VM::exceptionFuzzingBuffer):
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
* wasm/WasmInstance.h:
* wasm/WasmTable.cpp:
(JSC::Wasm::Table::Table):
(JSC::Wasm::FuncRefTable::FuncRefTable):
* wasm/WasmTable.h:
Source/WebCore:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/SerializedScriptValue.cpp:
* bindings/js/SerializedScriptValue.h:
* css/CSSFontFace.cpp:
* css/CSSFontFace.h:
* css/CSSSelector.cpp:
* css/CSSSelector.h:
* css/CSSValue.cpp:
* css/CSSValue.h:
* css/StyleProperties.cpp:
(WebCore::ImmutableStyleProperties::create):
* css/StyleProperties.h:
* css/StyleRule.cpp:
* css/StyleRule.h:
* dom/ElementData.cpp:
(WebCore::ShareableElementData::createWithAttributes):
(WebCore::UniqueElementData::makeShareableCopy const):
* dom/ElementData.h:
* dom/NodeRareData.cpp:
* dom/NodeRareData.h:
* dom/QualifiedName.cpp:
* dom/QualifiedName.h:
* html/parser/HTMLDocumentParser.cpp:
* html/parser/HTMLDocumentParser.h:
* loader/DocumentLoader.cpp:
* loader/DocumentLoader.h:
* loader/ResourceLoader.cpp:
* loader/ResourceLoader.h:
* loader/cache/CachedResource.cpp:
* loader/cache/CachedResource.h:
* page/PerformanceEntry.cpp:
* page/PerformanceEntry.h:
* platform/graphics/Font.cpp:
* platform/graphics/Font.h:
* platform/graphics/FontCascadeFonts.cpp:
* platform/graphics/FontCascadeFonts.h:
* platform/graphics/Region.cpp:
* platform/graphics/Region.h:
* platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
(WebCore::releaseUint8Vector):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/nicosia/NicosiaBuffer.cpp:
(Nicosia::Buffer::Buffer):
* platform/network/ResourceHandle.cpp:
* platform/network/ResourceHandleInternal.h:
* platform/network/cf/FormDataStreamCFNet.cpp:
(WebCore::closeCurrentStream):
(WebCore::advanceCurrentStream):
* rendering/RenderLayer.cpp:
* rendering/RenderLayer.h:
* rendering/TableLayout.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* rendering/TableLayout.h:
* rendering/style/RenderStyle.cpp:
* rendering/style/RenderStyle.h:
* rendering/style/SVGRenderStyle.cpp:
* rendering/style/SVGRenderStyle.h:
* rendering/style/SVGRenderStyleDefs.cpp:
* rendering/style/SVGRenderStyleDefs.h:
* rendering/style/StyleBoxData.cpp:
* rendering/style/StyleBoxData.h:
* rendering/style/StyleInheritedData.cpp:
* rendering/style/StyleInheritedData.h:
* rendering/style/StyleRareInheritedData.cpp:
* rendering/style/StyleRareInheritedData.h:
* rendering/style/StyleRareNonInheritedData.cpp:
* rendering/style/StyleRareNonInheritedData.h:
* rendering/style/StyleSurroundData.cpp:
* rendering/style/StyleSurroundData.h:
* rendering/style/StyleTransformData.cpp:
* rendering/style/StyleTransformData.h:
* style/StyleTreeResolver.cpp:
* style/StyleTreeResolver.h:
* svg/animation/SMILTimeContainer.cpp:
* svg/animation/SMILTimeContainer.h:
Source/WebKit:
* Shared/ShareableBitmap.cpp:
(WebKit::ShareableBitmap::create):
(WebKit::ShareableBitmap::~ShareableBitmap):
* UIProcess/mac/LegacySessionStateCoding.cpp:
(WebKit::HistoryEntryDataEncoder::HistoryEntryDataEncoder):
(WebKit::HistoryEntryDataEncoder::finishEncoding):
(WebKit::encodeSessionHistoryEntryData):
(WebKit::encodeLegacySessionState):
Source/WTF:
This patch introduces ENABLE(MALLOC_HEAP_BREAKDOWN). If this is enabled, we allocate malloc_zone per malloc kind.
This offers the way to investigate the usage of memory per kind by using vmmap, like the following.
VIRTUAL RESIDENT DIRTY SWAPPED ALLOCATION BYTES DIRTY+SWAP REGION
MALLOC ZONE SIZE SIZE SIZE SIZE COUNT ALLOCATED FRAG SIZE % FRAG COUNT
=========== ======= ========= ========= ========= ========= ========= ========= ====== ======
StringImpl_0x116efd000 188.0M 69.3M 30.9M 0K 139456 18.0M 12.9M 42% 34
DefaultMallocZone_0x10f487000 176.0M 53.9M 14.1M 0K 115956 9955K 4497K 32% 22
Vector_0x116eff000 162.0M 56.3M 55.3M 0K 140715 17.3M 37.9M 69% 36
MetadataTable_0x11843b000 152.0M 17.5M 17.5M 0K 14200 2353K 15.2M 87% 26
WebKit Using System Malloc_0x114cbe000 150.0M 31.6M 21.8M 0K 87422 16.7M 5278K 24% 23
InstructionStream_0x118469000 150.0M 5764K 5764K 0K 14470 4688K 1076K 19% 24
AssemblerData_0x117ee6000 150.0M 1928K 1928K 0K 1 16 1928K 100% 24
To achieve this goal without making very large change, we put a template type in various containers.
For example, Vector will take Malloc parameter (the default one is FastMalloc allocator). If ENABLE(MALLOC_HEAP_BREAKDOWN) is enabled, we change this to
specific VectorMalloc allocator, and vmmap can show memory usage of this allocator. This patch also supports malloc_zone per IsoHeap. So we can see memory
allocation per IsoHeap in vmmap.
To use this feature, we need to flip two compile time flags, ENABLE(MALLOC_HEAP_BREAKDOWN) in WTF and BENABLE_MALLOC_HEAP_BREAKDOWN in bmalloc.
And use `vmmap $PID` to dump malloc zones. To allocate objects of a class with a specific malloc-zone, use WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(HeapIdentifier) for the class,
and define allocator by DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a header and DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a cpp file.
This patch also introduce callstack collector for malloc. Vector, HashMap etc. are used to allocate various things, but the above malloc_zone feature only tells thing like "Vector
takes XXX MB memory". But what we want to know in this case is what Vector is consuming memory. We collect StackShot for each malloc call, and combine these information to tell
which callsite is consuming much memory, which tell us that what Vector is consuming memory.
* WTF.xcodeproj/project.pbxproj:
* wtf/Bag.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/Bag.h:
(WTF::Private::BagNode::BagNode): Deleted.
* wtf/BitVector.cpp:
(WTF::BitVector::OutOfLineBits::create):
(WTF::BitVector::OutOfLineBits::destroy):
* wtf/CMakeLists.txt:
* wtf/ConcurrentBuffer.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/ConcurrentBuffer.h:
* wtf/DebugHeap.cpp: Copied from Source/JavaScriptCore/runtime/CachePayload.cpp.
(WTF::DebugHeap::DebugHeap):
(WTF::DebugHeap::malloc):
(WTF::DebugHeap::calloc):
(WTF::DebugHeap::memalign):
(WTF::DebugHeap::realloc):
(WTF::DebugHeap::free):
* wtf/DebugHeap.h: Added.
* wtf/FastBitVector.cpp:
(WTF::FastBitVectorWordOwner::setEqualsSlow):
(WTF::FastBitVectorWordOwner::resizeSlow):
* wtf/FastBitVector.h:
(WTF::FastBitVectorWordOwner::~FastBitVectorWordOwner):
* wtf/FastMalloc.cpp:
(WTF::fastMallocDumpMallocStats):
(WTF::AvoidRecordingScope::AvoidRecordingScope):
(WTF::AvoidRecordingScope::~AvoidRecordingScope):
(WTF::MallocCallTracker::MallocSiteData::MallocSiteData):
(WTF::MallocCallTracker::singleton):
(WTF::MallocCallTracker::MallocCallTracker):
(WTF::MallocCallTracker::recordMalloc):
(WTF::MallocCallTracker::recordRealloc):
(WTF::MallocCallTracker::recordFree):
(WTF::MallocCallTracker::dumpStats):
(WTF::fastMalloc):
(WTF::fastRealloc):
(WTF::fastFree):
(WTF::fastAlignedMalloc):
(WTF::tryFastAlignedMalloc):
(WTF::fastAlignedFree):
* wtf/FastMalloc.h:
(WTF::FastMalloc::zeroedMalloc):
(WTF::FastMalloc::tryZeroedMalloc):
* wtf/Forward.h:
* wtf/HashTable.cpp:
* wtf/HashTable.h:
(WTF::KeyTraits>::allocateTable):
(WTF::KeyTraits>::deallocateTable):
(WTF::KeyTraits>::rehash):
* wtf/MallocPtr.h:
(WTF::MallocPtr::MallocPtr):
(WTF::MallocPtr::malloc):
(WTF::MallocPtr::zeroedMalloc):
(WTF::MallocPtr::tryMalloc):
(WTF::MallocPtr::tryZeroedMalloc):
(WTF::adoptMallocPtr):
* wtf/MetaAllocator.cpp:
(WTF::MetaAllocator::allocFreeSpaceNode):
(WTF::MetaAllocator::freeFreeSpaceNode):
* wtf/MetaAllocatorHandle.h:
* wtf/Platform.h:
* wtf/RefCountedArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/RefCountedArray.h:
(WTF::RefCountedArray::RefCountedArray):
(WTF::RefCountedArray::~RefCountedArray):
(WTF::RefCountedArray::assign):
* wtf/SegmentedVector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SegmentedVector.h:
* wtf/SmallPtrSet.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SmallPtrSet.h:
(WTF::SmallPtrSet::~SmallPtrSet):
(WTF::SmallPtrSet::grow):
* wtf/UniqueArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/UniqueArray.h:
(WTF::UniqueArrayFree::operator() const):
(WTF::UniqueArrayFree<T::operator() const):
* wtf/Vector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/Vector.h:
(WTF::VectorBufferBase::allocateBuffer):
(WTF::VectorBufferBase::tryAllocateBuffer):
(WTF::VectorBufferBase::reallocateBuffer):
(WTF::VectorBufferBase::deallocateBuffer):
(WTF::VectorBufferBase::releaseBuffer):
(WTF::VectorBuffer::releaseBuffer):
(WTF::Vector::swap):
(WTF::Malloc>::Vector):
(WTF::=):
(WTF::Malloc>::contains const):
(WTF::Malloc>::findMatching const):
(WTF::Malloc>::find const):
(WTF::Malloc>::reverseFind const):
(WTF::Malloc>::appendIfNotContains):
(WTF::Malloc>::fill):
(WTF::Malloc>::appendRange):
(WTF::Malloc>::expandCapacity):
(WTF::Malloc>::tryExpandCapacity):
(WTF::Malloc>::resize):
(WTF::Malloc>::resizeToFit):
(WTF::Malloc>::shrink):
(WTF::Malloc>::grow):
(WTF::Malloc>::asanSetInitialBufferSizeTo):
(WTF::Malloc>::asanSetBufferSizeToFullCapacity):
(WTF::Malloc>::asanBufferSizeWillChangeTo):
(WTF::Malloc>::reserveCapacity):
(WTF::Malloc>::tryReserveCapacity):
(WTF::Malloc>::reserveInitialCapacity):
(WTF::Malloc>::shrinkCapacity):
(WTF::Malloc>::append):
(WTF::Malloc>::tryAppend):
(WTF::Malloc>::constructAndAppend):
(WTF::Malloc>::tryConstructAndAppend):
(WTF::Malloc>::appendSlowCase):
(WTF::Malloc>::constructAndAppendSlowCase):
(WTF::Malloc>::tryConstructAndAppendSlowCase):
(WTF::Malloc>::uncheckedAppend):
(WTF::Malloc>::uncheckedConstructAndAppend):
(WTF::Malloc>::appendVector):
(WTF::Malloc>::insert):
(WTF::Malloc>::insertVector):
(WTF::Malloc>::remove):
(WTF::Malloc>::removeFirst):
(WTF::Malloc>::removeFirstMatching):
(WTF::Malloc>::removeAll):
(WTF::Malloc>::removeAllMatching):
(WTF::Malloc>::reverse):
(WTF::Malloc>::map const):
(WTF::Malloc>::releaseBuffer):
(WTF::Malloc>::checkConsistency):
(WTF::swap):
(WTF::operator==):
(WTF::operator!=):
(WTF::Malloc>::isolatedCopy const):
(WTF::removeRepeatedElements):
(WTF::minCapacity>::Vector): Deleted.
(WTF::minCapacity>::contains const): Deleted.
(WTF::minCapacity>::findMatching const): Deleted.
(WTF::minCapacity>::find const): Deleted.
(WTF::minCapacity>::reverseFind const): Deleted.
(WTF::minCapacity>::appendIfNotContains): Deleted.
(WTF::minCapacity>::fill): Deleted.
(WTF::minCapacity>::appendRange): Deleted.
(WTF::minCapacity>::expandCapacity): Deleted.
(WTF::minCapacity>::tryExpandCapacity): Deleted.
(WTF::minCapacity>::resize): Deleted.
(WTF::minCapacity>::resizeToFit): Deleted.
(WTF::minCapacity>::shrink): Deleted.
(WTF::minCapacity>::grow): Deleted.
(WTF::minCapacity>::asanSetInitialBufferSizeTo): Deleted.
(WTF::minCapacity>::asanSetBufferSizeToFullCapacity): Deleted.
(WTF::minCapacity>::asanBufferSizeWillChangeTo): Deleted.
(WTF::minCapacity>::reserveCapacity): Deleted.
(WTF::minCapacity>::tryReserveCapacity): Deleted.
(WTF::minCapacity>::reserveInitialCapacity): Deleted.
(WTF::minCapacity>::shrinkCapacity): Deleted.
(WTF::minCapacity>::append): Deleted.
(WTF::minCapacity>::tryAppend): Deleted.
(WTF::minCapacity>::constructAndAppend): Deleted.
(WTF::minCapacity>::tryConstructAndAppend): Deleted.
(WTF::minCapacity>::appendSlowCase): Deleted.
(WTF::minCapacity>::constructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::tryConstructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::uncheckedAppend): Deleted.
(WTF::minCapacity>::uncheckedConstructAndAppend): Deleted.
(WTF::minCapacity>::appendVector): Deleted.
(WTF::minCapacity>::insert): Deleted.
(WTF::minCapacity>::insertVector): Deleted.
(WTF::minCapacity>::remove): Deleted.
(WTF::minCapacity>::removeFirst): Deleted.
(WTF::minCapacity>::removeFirstMatching): Deleted.
(WTF::minCapacity>::removeAll): Deleted.
(WTF::minCapacity>::removeAllMatching): Deleted.
(WTF::minCapacity>::reverse): Deleted.
(WTF::minCapacity>::map const): Deleted.
(WTF::minCapacity>::releaseBuffer): Deleted.
(WTF::minCapacity>::checkConsistency): Deleted.
(WTF::minCapacity>::isolatedCopy const): Deleted.
* wtf/text/CString.cpp:
(WTF::CStringBuffer::createUninitialized):
* wtf/text/CString.h:
* wtf/text/StringBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/text/StringBuffer.h:
(WTF::StringBuffer::StringBuffer):
(WTF::StringBuffer::~StringBuffer):
(WTF::StringBuffer::resize):
(WTF::StringBuffer::release):
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::~StringImpl):
(WTF::StringImpl::destroy):
(WTF::StringImpl::createUninitializedInternalNonEmpty):
(WTF::StringImpl::reallocateInternal):
* wtf/text/StringImpl.h:
(WTF::StringImpl::StringImpl):
(WTF::StringImpl::createSubstringSharingImpl):
(WTF::StringImpl::tryCreateUninitialized):
(WTF::StringImpl::adopt):
* wtf/text/cf/StringImplCF.cpp:
(WTF::StringWrapperCFAllocator::allocate):
(WTF::StringWrapperCFAllocator::reallocate):
(WTF::StringWrapperCFAllocator::deallocate):
Canonical link: https://commits.webkit.org/218863@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253987 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-01-03 02:36:43 +00:00
|
|
|
heap/GCSegmentedArray.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/GigacageAlignedMemoryAllocator.cpp
|
|
|
|
heap/HandleSet.cpp
|
|
|
|
heap/Heap.cpp
|
|
|
|
heap/HeapCell.cpp
|
2017-11-30 04:39:50 +00:00
|
|
|
heap/HeapCellType.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/HeapFinalizerCallback.cpp
|
|
|
|
heap/HeapHelperPool.cpp
|
|
|
|
heap/HeapProfiler.cpp
|
|
|
|
heap/HeapSnapshot.cpp
|
|
|
|
heap/HeapSnapshotBuilder.cpp
|
|
|
|
heap/IncrementalSweeper.cpp
|
2017-11-30 04:39:50 +00:00
|
|
|
heap/IsoAlignedMemoryAllocator.cpp
|
It should be possible to flag a cell for unconditional finalization
https://bugs.webkit.org/show_bug.cgi?id=180636
Reviewed by Saam Barati.
Source/JavaScriptCore:
UnconditionalFinalizers were annoying - you had to allocate them and you had to manage a
global linked list - but they had some nice properties:
- You only did the hardest work (creating the UnconditionalFinalizer) on first GC where you
survived and needed it.
-> Just needing it wasn't enough.
-> Just surviving wasn't enough.
The new API based on IsoSubspaces meant that just surviving was enough to cause unconditional
finalizer logic to be invoked. I think that's not great. InferredType got around this by
making InferredStructure a cell, but this was a gross hack. For one, it meant that
InferredStructure would survive during the GC in which its finalizer obviated the need for its
existence. It's not really an idiom I want us to repeat because it sounds like the sort of
thing that turns out to be subtly broken.
We really need to have a way of indicating when you have entered into the state that requires
your unconditional finalizer to be invoked. Basically, we want to be able to track the set of
objects that need unconditional finalizers. Only the subset of that set that overlaps with the
set of marked objects needs to be accurate. The easiest way to do this is a hierarchy of
bitvectors: one to say which MarkedBlocks have objects that have unconditional finalizers, and
another level to say which atoms within a MarkedBlock have unconditional finalizers.
This change introduces IsoCellSet, which couples itself to the MarkedAllocator of some
IsoSubspace to allow maintaining a set of objects (well, cells - you could do this with
auxiliaries) that belong to that IsoSubspace. It'll have undefined behavior if you try to
add/remove/contains an object that isn't in that IsoSubspace. For objects in that subspace,
you can add/remove/contains and forEachMarkedCell. The cost of each IsoCellSet is at worst
about 0.8% increase in size to every object in the subspace that the set is attached to. So,
it makes sense to have a handful per subspace max. This change only needs one per subspace,
but you could imagine more if we do this for WeakReferenceHarvester.
To absolutely minimize the possibility that this incurs costs, the add/remove/contains
functions can be used from any thread so long as forEachMarkedCell isn't running. This means
that InferredType only needs to add itself to the set during visitChildren. Thus, it needs to
both survive and need it for the hardest work to take place. The work of adding does involve
a gnarly load chain that ends in a CAS: load block handle from block, load index, load
segment, load bitvector, load bit -> if not set, then CAS. That's five dependent loads!
However, it's perfect for running in parallel since the only write operations are to widely
dispersed cache lines that contain the bits underlying the set.
The best part is how forEachMarkedCell works. That skips blocks that don't have any objects
that need unconditional finalizers, and only touches the memory of marked objects that have
the unconditional finalizer bit set. It will walk those objects in roughly address order. I
previously found that this speeds up walking over a lot of objects when I made similar changes
for DOM GC (calling visitAdditionalChildren via forEachMarkedCell rather than by walking a
HashSet).
This change makes InferredStructure be a malloc object again, but now it's in an IsoHeap.
My expectation for this change is that it's perf-neutral. Long-term, it gives us a path
forward for eliminating UnconditionalFinalizer and WeakReferenceHarvester while using
IsoSubspace in more places.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* heap/AtomIndices.h: Added.
(JSC::AtomIndices::AtomIndices):
* heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):
* heap/Heap.h:
* heap/IsoCellSet.cpp: Added.
(JSC::IsoCellSet::IsoCellSet):
(JSC::IsoCellSet::~IsoCellSet):
(JSC::IsoCellSet::addSlow):
(JSC::IsoCellSet::didResizeBits):
(JSC::IsoCellSet::didRemoveBlock):
(JSC::IsoCellSet::sweepToFreeList):
* heap/IsoCellSet.h: Added.
* heap/IsoCellSetInlines.h: Added.
(JSC::IsoCellSet::add):
(JSC::IsoCellSet::remove):
(JSC::IsoCellSet::contains const):
(JSC::IsoCellSet::forEachMarkedCell):
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::didResizeBits):
(JSC::IsoSubspace::didRemoveBlock):
(JSC::IsoSubspace::didBeginSweepingToFreeList):
* heap/IsoSubspace.h:
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::addBlock):
(JSC::MarkedAllocator::removeBlock):
* heap/MarkedAllocator.h:
* heap/MarkedAllocatorInlines.h:
* heap/MarkedBlock.cpp:
(JSC::MarkedBlock::Handle::sweep):
(JSC::MarkedBlock::Handle::isEmpty): Deleted.
* heap/MarkedBlock.h:
(JSC::MarkedBlock::marks const):
(JSC::MarkedBlock::Handle::newlyAllocated const):
* heap/MarkedBlockInlines.h:
(JSC::MarkedBlock::Handle::isAllocated):
(JSC::MarkedBlock::Handle::isEmpty):
(JSC::MarkedBlock::Handle::emptyMode):
(JSC::MarkedBlock::Handle::forEachMarkedCell):
* heap/Subspace.cpp:
(JSC::Subspace::didResizeBits):
(JSC::Subspace::didRemoveBlock):
(JSC::Subspace::didBeginSweepingToFreeList):
* heap/Subspace.h:
* heap/SubspaceInlines.h:
(JSC::Subspace::forEachMarkedCell):
* runtime/InferredStructure.cpp:
(JSC::InferredStructure::InferredStructure):
(JSC::InferredStructure::create): Deleted.
(JSC::InferredStructure::destroy): Deleted.
(JSC::InferredStructure::createStructure): Deleted.
(JSC::InferredStructure::visitChildren): Deleted.
(JSC::InferredStructure::finalizeUnconditionally): Deleted.
(JSC::InferredStructure::finishCreation): Deleted.
* runtime/InferredStructure.h:
* runtime/InferredStructureWatchpoint.cpp:
(JSC::InferredStructureWatchpoint::fireInternal):
* runtime/InferredType.cpp:
(JSC::InferredType::visitChildren):
(JSC::InferredType::willStoreValueSlow):
(JSC::InferredType::makeTopSlow):
(JSC::InferredType::set):
(JSC::InferredType::removeStructure):
(JSC::InferredType::finalizeUnconditionally):
* runtime/InferredType.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Source/WTF:
This adds ConcurrentVector, which is like SegmentedVector, but wastes some space to allow
resizing to proceed concurrently to access. It's not possible to resize concurrently to
resizing, concurrent read/writes aren't protected from racing if they access the same element,
and who knows what you'll get if you iterate up to size() while someone else append()s. The
key insight is to stash all prior copies of the spine, so that nobody crashes trying to access
a stale spine.
I'm going to want to do the same thing for FastBitVector, by creating a segmented WordOwner
class. That would require repeating the dance of having a spine that can resize while stashing
old versions. So, the spine resizing logic is abstracted behind ConcurrentBuffer. You could
use that as a kind of "concurrent vector" for immutable data. That's how ConcurrentVector uses
it: it's an immutable array of segment pointers.
* WTF.xcodeproj/project.pbxproj:
* wtf/ConcurrentBuffer.h: Added.
(WTF::ConcurrentBuffer::ConcurrentBuffer):
(WTF::ConcurrentBuffer::~ConcurrentBuffer):
(WTF::ConcurrentBuffer::growExact):
(WTF::ConcurrentBuffer::grow):
(WTF::ConcurrentBuffer::array const):
(WTF::ConcurrentBuffer::operator[]):
(WTF::ConcurrentBuffer::operator[] const):
(WTF::ConcurrentBuffer::createArray):
* wtf/ConcurrentVector.h: Added.
(WTF::ConcurrentVectorIterator::~ConcurrentVectorIterator):
(WTF::ConcurrentVectorIterator::operator* const):
(WTF::ConcurrentVectorIterator::operator-> const):
(WTF::ConcurrentVectorIterator::operator++):
(WTF::ConcurrentVectorIterator::operator== const):
(WTF::ConcurrentVectorIterator::operator!= const):
(WTF::ConcurrentVectorIterator::operator=):
(WTF::ConcurrentVectorIterator::ConcurrentVectorIterator):
(WTF::ConcurrentVector::~ConcurrentVector):
(WTF::ConcurrentVector::size const):
(WTF::ConcurrentVector::isEmpty const):
(WTF::ConcurrentVector::at):
(WTF::ConcurrentVector::at const):
(WTF::ConcurrentVector::operator[]):
(WTF::ConcurrentVector::operator[] const):
(WTF::ConcurrentVector::first):
(WTF::ConcurrentVector::first const):
(WTF::ConcurrentVector::last):
(WTF::ConcurrentVector::last const):
(WTF::ConcurrentVector::takeLast):
(WTF::ConcurrentVector::append):
(WTF::ConcurrentVector::alloc):
(WTF::ConcurrentVector::removeLast):
(WTF::ConcurrentVector::grow):
(WTF::ConcurrentVector::begin):
(WTF::ConcurrentVector::end):
(WTF::ConcurrentVector::segmentExistsFor):
(WTF::ConcurrentVector::segmentFor):
(WTF::ConcurrentVector::subscriptFor):
(WTF::ConcurrentVector::ensureSegmentsFor):
(WTF::ConcurrentVector::ensureSegment):
(WTF::ConcurrentVector::allocateSegment):
Canonical link: https://commits.webkit.org/196644@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225831 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-12-13 02:35:54 +00:00
|
|
|
heap/IsoCellSet.cpp
|
[JSC] IsoHeapCellType should have destroy function member instead of specializing template function
https://bugs.webkit.org/show_bug.cgi?id=205152
Reviewed by Saam Barati.
We were specializing MarkedBlock::Handle::specializedSweep in 5 different ways for each IsoSubspace-ed cell.
This bloats binary. Instead of specializing it with CellType, we specialize it with one functor, which invokes
function pointer held by IsoHeapCellType. This requires one indirect function call per cell. But this is OK since,
1. We were using JSDestructibleObject's cell->classInfo->methodTable.destroy function call to dispatch destruction,
before IsoSubspace replaces them with IsoHeapCellType-based destruction. Compared to that, the new one is still
saving one pointer chasing basically (classInfo dereference, we assume cell deference is no cost since it will
be done anyway).
2. We still keep JSString's destroy function inlining by using IsoInlinedHeapCellType. This is important since
it is critical to performance and we had JSStringHeapCellType before we replaced it with IsoHeapCellType.
But IsoInlinedHeapCellType specialization is for only one class so generated binary size is the same to the
old code using JSStringHeapCellType.
This saves 480KB binary-size in JavaScriptCore. And more importantly, after this patch, adding IsoSubspace
will not bloat code, so we can simply put things into IsoSubspace.
This patch also removes `using namespace JSC;` in global code in JavaScriptCore except for API codes, since
it starts causing build failure due to unified builds: API defines JSType enum in a global scope, which is
different from our JSC::JSType. If we do `using namespace JSC;` in a global scope, it can lead to ambiguity of
looking up.
* API/JSHeapFinalizerPrivate.cpp:
(JSContextGroupAddHeapFinalizer):
(JSContextGroupRemoveHeapFinalizer):
* API/JSHeapFinalizerPrivate.h:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/AbstractMacroAssembler.cpp:
* bindings/ScriptFunctionCall.cpp:
* bindings/ScriptObject.cpp:
* bindings/ScriptValue.cpp:
* heap/IsoHeapCellType.cpp: Copied from Source/JavaScriptCore/assembler/AbstractMacroAssembler.cpp.
(JSC::IsoHeapCellType::finishSweep):
(JSC::IsoHeapCellType::destroy):
* heap/IsoHeapCellType.h:
* heap/IsoInlinedHeapCellType.h: Copied from Source/JavaScriptCore/heap/IsoHeapCellType.h.
* heap/MutatorState.cpp:
* heap/Synchronousness.cpp:
* inspector/InjectedScriptHost.cpp:
* inspector/InjectedScriptManager.cpp:
* inspector/JSGlobalObjectConsoleClient.cpp:
* inspector/JSGlobalObjectInspectorController.cpp:
* inspector/JSGlobalObjectScriptDebugServer.cpp:
* inspector/JSInjectedScriptHost.cpp:
* inspector/JSInjectedScriptHostPrototype.cpp:
* inspector/JSJavaScriptCallFrame.cpp:
* inspector/JSJavaScriptCallFramePrototype.cpp:
* inspector/JavaScriptCallFrame.cpp:
* inspector/PerGlobalObjectWrapperWorld.cpp:
* inspector/ScriptCallStackFactory.cpp:
* inspector/ScriptDebugServer.cpp:
* inspector/agents/InspectorHeapAgent.cpp:
* inspector/agents/InspectorScriptProfilerAgent.cpp:
* inspector/agents/JSGlobalObjectAuditAgent.cpp:
* inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
* inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Canonical link: https://commits.webkit.org/218351@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253423 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-12-12 09:36:13 +00:00
|
|
|
heap/IsoHeapCellType.cpp
|
2017-11-30 04:39:50 +00:00
|
|
|
heap/IsoSubspace.cpp
|
2018-04-19 19:33:03 +00:00
|
|
|
heap/IsoSubspacePerVM.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/JITStubRoutineSet.cpp
|
2019-11-09 03:45:18 +00:00
|
|
|
heap/PreciseAllocation.cpp
|
JSC GC should support TLCs (thread local caches)
https://bugs.webkit.org/show_bug.cgi?id=181559
Reviewed by Mark Lam and Saam Barati.
Source/JavaScriptCore:
This is a big step towards object distancing by site origin. This patch implements TLCs, or
thread-local caches, which allow each thread to allocate from its own free lists. It also
means that any given thread can context-switch TLCs. This will allow us to do separate
allocation for separate site origins. Eventually, once we reshape how MarkedBlock looks, this
will allow us to have a hard distancing constraint between objects from different origins.
In this new design, every "size class" is represented as a BlockDirectory (formerly known as
MarkedAllocator, prior to r226822). This contains a bag of blocks allocated using some
aligned memory allocator (which roughly represents which cage you came out of), and anyone
using the same allocator can share those blocks - but so long as they are in that
BlockDirectory, they will have the size and type of that directory. Previously, each
BlockDirectory had exactly one FreeList. Now, each BlockDirectory has a double-linked-list of
LocalAllocators, each of which has a FreeList.
To decide which LocalAllocator to allocate out of, we need a ThreadLocalCache and a
BlockDirectory. The directory gives us an offset-within-the-ThreadLocalCache, which we simply
call the Allocator (which is just a POD type that contains a 32-bit offset). Each allocation
starts by figuring out what Allocator it wants (often we have this information at JIT time).
Then the allocation loads its ThreadLocalCache::Data from a fast TLS slot. Then we add the
Allocator offset to the ThreadLocalCache::Data to get the LocalAllocator. Note that we use
offsets as opposed to indices to make it easy to do the math on each allocation (if
LocalAllocator had a weird size then every allocation would have to do an imul).
This is a definite slow-down on GC-heavy benchmarks, but by a small margin, and only on
unusually heavy tests. For example, boyer and splay are both 3% regressed, but the Octane
geomean is just fine. The JetStream score regressed by 0.5% with p = 0.08 (so maybe there is
something there, but it's not significant according to our threshold).
Relanding after fixing ARM64 bug in AssemblyHelpers::emitAllocateWithNonNullAllocator(). That
function needs to be careful to avoid using the scratch register because the FTL will call it
in disallow-scratch-register mode.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* b3/B3LowerToAir.cpp:
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::admitsStack):
* b3/B3StackmapSpecial.cpp:
(JSC::B3::StackmapSpecial::forEachArgImpl):
(JSC::B3::StackmapSpecial::isArgValidForRep):
* b3/B3StackmapValue.cpp:
(JSC::B3::StackmapValue::appendSomeRegisterWithClobber):
* b3/B3StackmapValue.h:
* b3/B3Validate.cpp:
* b3/B3ValueRep.cpp:
(JSC::B3::ValueRep::addUsedRegistersTo const):
(JSC::B3::ValueRep::dump const):
(WTF::printInternal):
* b3/B3ValueRep.h:
(JSC::B3::ValueRep::ValueRep):
* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfile::ObjectAllocationProfile):
(JSC::ObjectAllocationProfile::clear):
* bytecode/ObjectAllocationProfileInlines.h:
(JSC::ObjectAllocationProfile::initializeProfile):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
(JSC::DFG::SpeculativeJIT::compileMakeRope):
(JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
(JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
(JSC::DFG::SpeculativeJIT::compileCreateThis):
(JSC::DFG::SpeculativeJIT::compileNewObject):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMakeRope):
(JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
(JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl):
(JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell):
(JSC::FTL::DFG::LowerDFGToB3::allocateObject):
(JSC::FTL::DFG::LowerDFGToB3::allocatorForSize):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
* heap/Allocator.cpp: Added.
(JSC::Allocator::cellSize const):
* heap/Allocator.h: Added.
(JSC::Allocator::Allocator):
(JSC::Allocator::offset const):
(JSC::Allocator::operator== const):
(JSC::Allocator::operator!= const):
(JSC::Allocator::operator bool const):
* heap/AllocatorInlines.h: Added.
(JSC::Allocator::allocate const):
(JSC::Allocator::tryAllocate const):
* heap/BlockDirectory.cpp:
(JSC::BlockDirectory::BlockDirectory):
(JSC::BlockDirectory::findBlockForAllocation):
(JSC::BlockDirectory::stopAllocating):
(JSC::BlockDirectory::prepareForAllocation):
(JSC::BlockDirectory::stopAllocatingForGood):
(JSC::BlockDirectory::resumeAllocating):
(JSC::BlockDirectory::endMarking):
(JSC::BlockDirectory::isFreeListedCell):
(JSC::BlockDirectory::didConsumeFreeList): Deleted.
(JSC::BlockDirectory::tryAllocateWithoutCollecting): Deleted.
(JSC::BlockDirectory::allocateIn): Deleted.
(JSC::BlockDirectory::tryAllocateIn): Deleted.
(JSC::BlockDirectory::doTestCollectionsIfNeeded): Deleted.
(JSC::BlockDirectory::allocateSlowCase): Deleted.
* heap/BlockDirectory.h:
(JSC::BlockDirectory::cellKind const):
(JSC::BlockDirectory::allocator const):
(JSC::BlockDirectory::freeList const): Deleted.
(JSC::BlockDirectory::offsetOfFreeList): Deleted.
(JSC::BlockDirectory::offsetOfCellSize): Deleted.
* heap/BlockDirectoryInlines.h:
(JSC::BlockDirectory::isFreeListedCell const): Deleted.
(JSC::BlockDirectory::allocate): Deleted.
* heap/CompleteSubspace.cpp:
(JSC::CompleteSubspace::CompleteSubspace):
(JSC::CompleteSubspace::allocatorFor):
(JSC::CompleteSubspace::allocate):
(JSC::CompleteSubspace::allocateNonVirtual):
(JSC::CompleteSubspace::allocatorForSlow):
(JSC::CompleteSubspace::allocateSlow):
(JSC::CompleteSubspace::tryAllocateSlow):
* heap/CompleteSubspace.h:
(JSC::CompleteSubspace::allocatorForSizeStep):
(JSC::CompleteSubspace::allocatorForNonVirtual):
* heap/FreeList.h:
* heap/GCDeferralContext.h:
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::lastChanceToFinalize):
* heap/Heap.h:
(JSC::Heap::threadLocalCacheLayout):
* heap/IsoCellSet.h:
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
(JSC::IsoSubspace::allocatorFor):
(JSC::IsoSubspace::allocate):
(JSC::IsoSubspace::allocateNonVirtual):
* heap/IsoSubspace.h:
(JSC::IsoSubspace::allocatorForNonVirtual):
* heap/LocalAllocator.cpp: Added.
(JSC::LocalAllocator::LocalAllocator):
(JSC::LocalAllocator::reset):
(JSC::LocalAllocator::~LocalAllocator):
(JSC::LocalAllocator::stopAllocating):
(JSC::LocalAllocator::resumeAllocating):
(JSC::LocalAllocator::prepareForAllocation):
(JSC::LocalAllocator::stopAllocatingForGood):
(JSC::LocalAllocator::allocateSlowCase):
(JSC::LocalAllocator::didConsumeFreeList):
(JSC::LocalAllocator::tryAllocateWithoutCollecting):
(JSC::LocalAllocator::allocateIn):
(JSC::LocalAllocator::tryAllocateIn):
(JSC::LocalAllocator::doTestCollectionsIfNeeded):
(JSC::LocalAllocator::isFreeListedCell const):
* heap/LocalAllocator.h: Added.
(JSC::LocalAllocator::offsetOfFreeList):
(JSC::LocalAllocator::offsetOfCellSize):
* heap/LocalAllocatorInlines.h: Added.
(JSC::LocalAllocator::allocate):
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::stopAllocatingForGood):
* heap/MarkedSpace.h:
* heap/SlotVisitor.cpp:
* heap/SlotVisitor.h:
* heap/Subspace.h:
* heap/ThreadLocalCache.cpp: Added.
(JSC::ThreadLocalCache::create):
(JSC::ThreadLocalCache::ThreadLocalCache):
(JSC::ThreadLocalCache::~ThreadLocalCache):
(JSC::ThreadLocalCache::allocateData):
(JSC::ThreadLocalCache::destroyData):
(JSC::ThreadLocalCache::installSlow):
(JSC::ThreadLocalCache::installData):
(JSC::ThreadLocalCache::allocatorSlow):
(JSC::ThreadLocalCache::destructor):
* heap/ThreadLocalCache.h: Added.
(JSC::ThreadLocalCache::offsetOfSize):
(JSC::ThreadLocalCache::offsetOfFirstAllocator):
* heap/ThreadLocalCacheInlines.h: Added.
(JSC::ThreadLocalCache::getImpl):
(JSC::ThreadLocalCache::get):
(JSC::ThreadLocalCache::install):
(JSC::ThreadLocalCache::allocator):
(JSC::ThreadLocalCache::tryGetAllocator):
* heap/ThreadLocalCacheLayout.cpp: Added.
(JSC::ThreadLocalCacheLayout::ThreadLocalCacheLayout):
(JSC::ThreadLocalCacheLayout::~ThreadLocalCacheLayout):
(JSC::ThreadLocalCacheLayout::allocateOffset):
(JSC::ThreadLocalCacheLayout::snapshot):
(JSC::ThreadLocalCacheLayout::directory):
* heap/ThreadLocalCacheLayout.h: Added.
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator):
(JSC::AssemblyHelpers::emitAllocate):
(JSC::AssemblyHelpers::emitAllocateVariableSized):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::vm):
(JSC::AssemblyHelpers::emitAllocateJSCell):
(JSC::AssemblyHelpers::emitAllocateJSObject):
(JSC::AssemblyHelpers::emitAllocateJSObjectWithKnownSize):
(JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator): Deleted.
(JSC::AssemblyHelpers::emitAllocate): Deleted.
(JSC::AssemblyHelpers::emitAllocateVariableSized): Deleted.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_new_object):
(JSC::JIT::emit_op_create_this):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_new_object):
(JSC::JIT::emit_op_create_this):
* runtime/ButterflyInlines.h:
(JSC::Butterfly::createUninitialized):
(JSC::Butterfly::tryCreate):
(JSC::Butterfly::growArrayRight):
* runtime/DirectArguments.cpp:
(JSC::DirectArguments::overrideThings):
* runtime/GenericArgumentsInlines.h:
(JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor):
* runtime/HashMapImpl.h:
(JSC::HashMapBuffer::create):
* runtime/JSArray.cpp:
(JSC::JSArray::tryCreateUninitializedRestricted):
(JSC::JSArray::unshiftCountSlowCase):
* runtime/JSArray.h:
(JSC::JSArray::tryCreate):
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
* runtime/JSCellInlines.h:
(JSC::tryAllocateCellHelper):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::threadLocalCache const):
* runtime/JSLock.cpp:
(JSC::JSLock::didAcquireLock):
* runtime/Options.h:
* runtime/RegExpMatchesArray.h:
(JSC::tryCreateUninitializedRegExpMatchesArray):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* runtime/VMEntryScope.cpp:
(JSC::VMEntryScope::VMEntryScope):
Source/WTF:
* wtf/Bitmap.h: Just fixing a compile error.
Canonical link: https://commits.webkit.org/197951@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227617 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-01-25 19:32:00 +00:00
|
|
|
heap/LocalAllocator.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/MachineStackMarker.cpp
|
|
|
|
heap/MarkStack.cpp
|
GC constraint solving should be parallel
https://bugs.webkit.org/show_bug.cgi?id=179934
Reviewed by JF Bastien.
PerformanceTests:
Added a version of splay that measures latency in a way that run-jsc-benchmarks groks.
* Octane/splay.js: Added.
(this.Setup.setup.setup):
(this.TearDown.tearDown.tearDown):
(Benchmark):
(BenchmarkResult):
(BenchmarkResult.prototype.valueOf):
(BenchmarkSuite):
(alert):
(Math.random):
(BenchmarkSuite.ResetRNG):
(RunStep):
(BenchmarkSuite.RunSuites):
(BenchmarkSuite.CountBenchmarks):
(BenchmarkSuite.GeometricMean):
(BenchmarkSuite.GeometricMeanTime):
(BenchmarkSuite.AverageAbovePercentile):
(BenchmarkSuite.GeometricMeanLatency):
(BenchmarkSuite.FormatScore):
(BenchmarkSuite.prototype.NotifyStep):
(BenchmarkSuite.prototype.NotifyResult):
(BenchmarkSuite.prototype.NotifyError):
(BenchmarkSuite.prototype.RunSingleBenchmark):
(RunNextSetup):
(RunNextBenchmark):
(RunNextTearDown):
(BenchmarkSuite.prototype.RunStep):
(GeneratePayloadTree):
(GenerateKey):
(SplayUpdateStats):
(InsertNewNode):
(SplaySetup):
(SplayTearDown):
(SplayRun):
(SplayTree):
(SplayTree.prototype.isEmpty):
(SplayTree.prototype.insert):
(SplayTree.prototype.remove):
(SplayTree.prototype.find):
(SplayTree.prototype.findMax):
(SplayTree.prototype.findGreatestLessThan):
(SplayTree.prototype.exportKeys):
(SplayTree.prototype.splay_):
(SplayTree.Node):
(SplayTree.Node.prototype.traverse_):
(report):
(start):
Source/JavaScriptCore:
This makes it possible to do constraint solving in parallel. This looks like a 1% Speedometer
speed-up. It's more than 1% on trunk-Speedometer.
The constraint solver supports running constraints in parallel in two different ways:
- Run multiple constraints in parallel to each other. This only works for constraints that can
tolerate other constraints running concurrently to them (constraint.concurrency() ==
ConstraintConcurrency::Concurrent). This is the most basic kind of parallelism that the
constraint solver supports. All constraints except the JSC SPI constraints are concurrent. We
could probably make them concurrent, but I'm playing it safe for now.
- A constraint can create parallel work for itself, which the constraint solver will interleave
with other stuff. A constraint can report that it has parallel work by returning
ConstraintParallelism::Parallel from its executeImpl() function. Then the solver will allow that
constraint's doParallelWorkImpl() function to run on as many GC marker threads as are available,
for as long as that function wants to run.
It's not possible to have a non-concurrent constraint that creates parallel work.
The parallelism is implemented in terms of the existing GC marker threads. This turns out to be
most natural for two reasons:
- No need to start any other threads.
- The constraints all want to be passed a SlotVisitor. Running on the marker threads means having
access to those threads' SlotVisitors. Also, it means less load balancing. The solver will
create work on each marking thread's SlotVisitor. When the solver is done "stealing" a marker
thread, that thread will have work it can start doing immediately. Before this change, we had to
contribute the work found by the constraint solver to the global worklist so that it could be
distributed to the marker threads by load balancing. This change probably helps to avoid that
load balancing step.
A lot of this change is about making it easy to iterate GC data structures in parallel. This
change makes almost all constraints parallel-enabled, but only the DOM's output constraint uses
the parallel work API. That constraint iterates the marked cells in two subspaces. This change
makes it very easy to compose parallel iterators over subspaces, allocators, blocks, and cells.
The marked cell parallel iterator is composed out of parallel iterators for the others. A parallel
iterator is just an iterator that can do an atomic next() very quickly. We abstract them using
RefPtr<SharedTask<...()>>, where ... is the type returned from the iterator. We know it's done
when it returns a falsish version of ... (in the current code, that's always a pointer type, so
done is indicated by null).
* API/JSMarkingConstraintPrivate.cpp:
(JSContextGroupAddMarkingConstraint):
* API/JSVirtualMachine.mm:
(scanExternalObjectGraph):
(scanExternalRememberedSet):
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::propagateTransitions const):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitWeakly):
(JSC::CodeBlock::shouldJettisonDueToOldAge):
(JSC::shouldMarkTransition):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
* dfg/DFGWorklist.cpp:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* heap/ConstraintParallelism.h: Added.
(WTF::printInternal):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::addToRememberedSet):
(JSC::Heap::runFixpointPhase):
(JSC::Heap::stopThePeriphery):
(JSC::Heap::resumeThePeriphery):
(JSC::Heap::addCoreConstraints):
(JSC::Heap::setBonusVisitorTask):
(JSC::Heap::runTaskInParallel):
(JSC::Heap::forEachSlotVisitor): Deleted.
* heap/Heap.h:
(JSC::Heap::worldIsRunning const):
(JSC::Heap::runFunctionInParallel):
* heap/HeapInlines.h:
(JSC::Heap::worldIsStopped const):
(JSC::Heap::isMarked):
(JSC::Heap::incrementDeferralDepth):
(JSC::Heap::decrementDeferralDepth):
(JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
(JSC::Heap::forEachSlotVisitor):
(JSC::Heap::collectorBelievesThatTheWorldIsStopped const): Deleted.
(JSC::Heap::isMarkedConcurrently): Deleted.
* heap/HeapSnapshotBuilder.cpp:
(JSC::HeapSnapshotBuilder::appendNode):
* heap/LargeAllocation.h:
(JSC::LargeAllocation::isMarked):
(JSC::LargeAllocation::isMarkedConcurrently): Deleted.
* heap/LockDuringMarking.h:
(JSC::lockDuringMarking):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::parallelNotEmptyBlockSource):
* heap/MarkedAllocator.h:
* heap/MarkedBlock.h:
(JSC::MarkedBlock::aboutToMark):
(JSC::MarkedBlock::isMarked):
(JSC::MarkedBlock::areMarksStaleWithDependency): Deleted.
(JSC::MarkedBlock::isMarkedConcurrently): Deleted.
* heap/MarkedSpace.h:
(JSC::MarkedSpace::activeWeakSetsBegin):
(JSC::MarkedSpace::activeWeakSetsEnd):
(JSC::MarkedSpace::newActiveWeakSetsBegin):
(JSC::MarkedSpace::newActiveWeakSetsEnd):
* heap/MarkingConstraint.cpp:
(JSC::MarkingConstraint::MarkingConstraint):
(JSC::MarkingConstraint::execute):
(JSC::MarkingConstraint::quickWorkEstimate):
(JSC::MarkingConstraint::workEstimate):
(JSC::MarkingConstraint::doParallelWork):
(JSC::MarkingConstraint::finishParallelWork):
(JSC::MarkingConstraint::doParallelWorkImpl):
(JSC::MarkingConstraint::finishParallelWorkImpl):
* heap/MarkingConstraint.h:
(JSC::MarkingConstraint::lastExecuteParallelism const):
(JSC::MarkingConstraint::parallelism const):
(JSC::MarkingConstraint::quickWorkEstimate): Deleted.
(JSC::MarkingConstraint::workEstimate): Deleted.
* heap/MarkingConstraintSet.cpp:
(JSC::MarkingConstraintSet::MarkingConstraintSet):
(JSC::MarkingConstraintSet::add):
(JSC::MarkingConstraintSet::executeConvergence):
(JSC::MarkingConstraintSet::executeConvergenceImpl):
(JSC::MarkingConstraintSet::executeAll):
(JSC::MarkingConstraintSet::ExecutionContext::ExecutionContext): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didVisitSomething const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::shouldTimeOut const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::drain): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didExecute const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::execute): Deleted.
(): Deleted.
* heap/MarkingConstraintSet.h:
* heap/MarkingConstraintSolver.cpp: Added.
(JSC::MarkingConstraintSolver::MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::~MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::didVisitSomething const):
(JSC::MarkingConstraintSolver::execute):
(JSC::MarkingConstraintSolver::drain):
(JSC::MarkingConstraintSolver::converge):
(JSC::MarkingConstraintSolver::runExecutionThread):
(JSC::MarkingConstraintSolver::didExecute):
* heap/MarkingConstraintSolver.h: Added.
* heap/OpaqueRootSet.h: Removed.
* heap/ParallelSourceAdapter.h: Added.
(JSC::ParallelSourceAdapter::ParallelSourceAdapter):
(JSC::createParallelSourceAdapter):
* heap/SimpleMarkingConstraint.cpp: Added.
(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::~SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::quickWorkEstimate):
(JSC::SimpleMarkingConstraint::executeImpl):
* heap/SimpleMarkingConstraint.h: Added.
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::didStartMarking):
(JSC::SlotVisitor::reset):
(JSC::SlotVisitor::appendToMarkStack):
(JSC::SlotVisitor::visitChildren):
(JSC::SlotVisitor::updateMutatorIsStopped):
(JSC::SlotVisitor::mutatorIsStoppedIsUpToDate const):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::performIncrementOfDraining):
(JSC::SlotVisitor::didReachTermination):
(JSC::SlotVisitor::hasWork):
(JSC::SlotVisitor::drainFromShared):
(JSC::SlotVisitor::drainInParallelPassively):
(JSC::SlotVisitor::waitForTermination):
(JSC::SlotVisitor::addOpaqueRoot): Deleted.
(JSC::SlotVisitor::containsOpaqueRoot const): Deleted.
(JSC::SlotVisitor::containsOpaqueRootTriState const): Deleted.
(JSC::SlotVisitor::mergeIfNecessary): Deleted.
(JSC::SlotVisitor::mergeOpaqueRootsIfProfitable): Deleted.
(JSC::SlotVisitor::mergeOpaqueRoots): Deleted.
* heap/SlotVisitor.h:
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::addOpaqueRoot):
(JSC::SlotVisitor::containsOpaqueRoot const):
(JSC::SlotVisitor::vm):
(JSC::SlotVisitor::vm const):
* heap/Subspace.cpp:
(JSC::Subspace::parallelAllocatorSource):
(JSC::Subspace::parallelNotEmptyMarkedBlockSource):
* heap/Subspace.h:
* heap/SubspaceInlines.h:
(JSC::Subspace::forEachMarkedCellInParallel):
* heap/VisitCounter.h: Added.
(JSC::VisitCounter::VisitCounter):
(JSC::VisitCounter::visitCount const):
* heap/VisitingTimeout.h: Removed.
* heap/WeakBlock.cpp:
(JSC::WeakBlock::specializedVisit):
* runtime/Structure.cpp:
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::markIfCheap):
Source/WebCore:
No new tests because no change in behavior. This change is best tested using DOM-GC-intensive
benchmarks like Speedometer and Dromaeo.
This parallelizes the DOM's output constraint, and makes some small changes to make this more
scalable.
* ForwardingHeaders/heap/SimpleMarkingConstraint.h: Added.
* ForwardingHeaders/heap/VisitingTimeout.h: Removed.
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/DOMGCOutputConstraint.cpp: Added.
(WebCore::DOMGCOutputConstraint::DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::~DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::executeImpl):
(WebCore::DOMGCOutputConstraint::doParallelWorkImpl):
(WebCore::DOMGCOutputConstraint::finishParallelWorkImpl):
* bindings/js/DOMGCOutputConstraint.h: Added.
* bindings/js/WebCoreJSClientData.cpp:
(WebCore::JSVMClientData::initNormalWorld):
* dom/Node.cpp:
(WebCore::Node::eventTargetDataConcurrently):
(WebCore::Node::ensureEventTargetData):
(WebCore::Node::clearEventTargetData):
Source/WTF:
This does some changes to make it easier to do parallel constraint solving:
- I finally removed dependencyWith. This was a silly construct whose only purpose is to confuse
people about what it means to have a dependency chain. I took that as an opportunity to grealy
simplify the GC's use of dependency chaining.
- Added more logic to Deque<>, since I use it for part of the load balancer.
- Made it possible to profile lock contention. See
https://bugs.webkit.org/show_bug.cgi?id=180250#c0 for some preliminary measurements.
- Introduced holdLockIf, which makes it easy to perform predicated lock acquisition. We use that
to pick a lock in WebCore.
- Introduced CountingLock. It's like WTF::Lock except it also enables optimistic read transactions
sorta like Java's StampedLock.
* WTF.xcodeproj/project.pbxproj:
* wtf/Atomics.h:
(WTF::dependency):
(WTF::DependencyWith::DependencyWith): Deleted.
(WTF::dependencyWith): Deleted.
* wtf/BitVector.h:
(WTF::BitVector::iterator::operator++):
* wtf/CMakeLists.txt:
* wtf/ConcurrentPtrHashSet.cpp: Added.
(WTF::ConcurrentPtrHashSet::ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::~ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::deleteOldTables):
(WTF::ConcurrentPtrHashSet::clear):
(WTF::ConcurrentPtrHashSet::initialize):
(WTF::ConcurrentPtrHashSet::addSlow):
(WTF::ConcurrentPtrHashSet::resizeIfNecessary):
(WTF::ConcurrentPtrHashSet::resizeAndAdd):
(WTF::ConcurrentPtrHashSet::Table::create):
* wtf/ConcurrentPtrHashSet.h: Added.
(WTF::ConcurrentPtrHashSet::contains):
(WTF::ConcurrentPtrHashSet::add):
(WTF::ConcurrentPtrHashSet::size const):
(WTF::ConcurrentPtrHashSet::Table::maxLoad const):
(WTF::ConcurrentPtrHashSet::hash):
(WTF::ConcurrentPtrHashSet::cast):
(WTF::ConcurrentPtrHashSet::containsImpl const):
(WTF::ConcurrentPtrHashSet::addImpl):
* wtf/Deque.h:
(WTF::inlineCapacity>::takeFirst):
* wtf/FastMalloc.h:
* wtf/Lock.cpp:
(WTF::LockBase::lockSlow):
* wtf/Locker.h:
(WTF::holdLockIf):
* wtf/ScopedLambda.h:
* wtf/SharedTask.h:
(WTF::SharedTask<PassedResultType):
(WTF::SharedTask<ResultType): Deleted.
* wtf/StackShot.h: Added.
(WTF::StackShot::StackShot):
(WTF::StackShot::operator=):
(WTF::StackShot::array const):
(WTF::StackShot::size const):
(WTF::StackShot::operator bool const):
(WTF::StackShot::operator== const):
(WTF::StackShot::hash const):
(WTF::StackShot::isHashTableDeletedValue const):
(WTF::StackShot::operator> const):
(WTF::StackShot::deletedValueArray):
(WTF::StackShotHash::hash):
(WTF::StackShotHash::equal):
* wtf/StackShotProfiler.h: Added.
(WTF::StackShotProfiler::StackShotProfiler):
(WTF::StackShotProfiler::profile):
(WTF::StackShotProfiler::run):
Tools:
* Scripts/run-jsc-benchmarks: Add splay-latency test, since this change needed to be carefully validated with that benchmark.
* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/ConcurrentPtrHashSet.cpp: Added. This has unit tests of the new concurrent data structure. The tests focus on correctness under serial execution, which appears to be enough for now (it's so easy to catch a concurrency bug by just running the GC).
(TestWebKitAPI::TEST):
Canonical link: https://commits.webkit.org/196360@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225524 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-12-05 17:53:57 +00:00
|
|
|
heap/MarkStackMergingConstraint.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/MarkedBlock.cpp
|
|
|
|
heap/MarkedSpace.cpp
|
|
|
|
heap/MarkingConstraint.cpp
|
|
|
|
heap/MarkingConstraintSet.cpp
|
GC constraint solving should be parallel
https://bugs.webkit.org/show_bug.cgi?id=179934
Reviewed by JF Bastien.
PerformanceTests:
Added a version of splay that measures latency in a way that run-jsc-benchmarks groks.
* Octane/splay.js: Added.
(this.Setup.setup.setup):
(this.TearDown.tearDown.tearDown):
(Benchmark):
(BenchmarkResult):
(BenchmarkResult.prototype.valueOf):
(BenchmarkSuite):
(alert):
(Math.random):
(BenchmarkSuite.ResetRNG):
(RunStep):
(BenchmarkSuite.RunSuites):
(BenchmarkSuite.CountBenchmarks):
(BenchmarkSuite.GeometricMean):
(BenchmarkSuite.GeometricMeanTime):
(BenchmarkSuite.AverageAbovePercentile):
(BenchmarkSuite.GeometricMeanLatency):
(BenchmarkSuite.FormatScore):
(BenchmarkSuite.prototype.NotifyStep):
(BenchmarkSuite.prototype.NotifyResult):
(BenchmarkSuite.prototype.NotifyError):
(BenchmarkSuite.prototype.RunSingleBenchmark):
(RunNextSetup):
(RunNextBenchmark):
(RunNextTearDown):
(BenchmarkSuite.prototype.RunStep):
(GeneratePayloadTree):
(GenerateKey):
(SplayUpdateStats):
(InsertNewNode):
(SplaySetup):
(SplayTearDown):
(SplayRun):
(SplayTree):
(SplayTree.prototype.isEmpty):
(SplayTree.prototype.insert):
(SplayTree.prototype.remove):
(SplayTree.prototype.find):
(SplayTree.prototype.findMax):
(SplayTree.prototype.findGreatestLessThan):
(SplayTree.prototype.exportKeys):
(SplayTree.prototype.splay_):
(SplayTree.Node):
(SplayTree.Node.prototype.traverse_):
(report):
(start):
Source/JavaScriptCore:
This makes it possible to do constraint solving in parallel. This looks like a 1% Speedometer
speed-up. It's more than 1% on trunk-Speedometer.
The constraint solver supports running constraints in parallel in two different ways:
- Run multiple constraints in parallel to each other. This only works for constraints that can
tolerate other constraints running concurrently to them (constraint.concurrency() ==
ConstraintConcurrency::Concurrent). This is the most basic kind of parallelism that the
constraint solver supports. All constraints except the JSC SPI constraints are concurrent. We
could probably make them concurrent, but I'm playing it safe for now.
- A constraint can create parallel work for itself, which the constraint solver will interleave
with other stuff. A constraint can report that it has parallel work by returning
ConstraintParallelism::Parallel from its executeImpl() function. Then the solver will allow that
constraint's doParallelWorkImpl() function to run on as many GC marker threads as are available,
for as long as that function wants to run.
It's not possible to have a non-concurrent constraint that creates parallel work.
The parallelism is implemented in terms of the existing GC marker threads. This turns out to be
most natural for two reasons:
- No need to start any other threads.
- The constraints all want to be passed a SlotVisitor. Running on the marker threads means having
access to those threads' SlotVisitors. Also, it means less load balancing. The solver will
create work on each marking thread's SlotVisitor. When the solver is done "stealing" a marker
thread, that thread will have work it can start doing immediately. Before this change, we had to
contribute the work found by the constraint solver to the global worklist so that it could be
distributed to the marker threads by load balancing. This change probably helps to avoid that
load balancing step.
A lot of this change is about making it easy to iterate GC data structures in parallel. This
change makes almost all constraints parallel-enabled, but only the DOM's output constraint uses
the parallel work API. That constraint iterates the marked cells in two subspaces. This change
makes it very easy to compose parallel iterators over subspaces, allocators, blocks, and cells.
The marked cell parallel iterator is composed out of parallel iterators for the others. A parallel
iterator is just an iterator that can do an atomic next() very quickly. We abstract them using
RefPtr<SharedTask<...()>>, where ... is the type returned from the iterator. We know it's done
when it returns a falsish version of ... (in the current code, that's always a pointer type, so
done is indicated by null).
* API/JSMarkingConstraintPrivate.cpp:
(JSContextGroupAddMarkingConstraint):
* API/JSVirtualMachine.mm:
(scanExternalObjectGraph):
(scanExternalRememberedSet):
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::propagateTransitions const):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitWeakly):
(JSC::CodeBlock::shouldJettisonDueToOldAge):
(JSC::shouldMarkTransition):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
* dfg/DFGWorklist.cpp:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* heap/ConstraintParallelism.h: Added.
(WTF::printInternal):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::addToRememberedSet):
(JSC::Heap::runFixpointPhase):
(JSC::Heap::stopThePeriphery):
(JSC::Heap::resumeThePeriphery):
(JSC::Heap::addCoreConstraints):
(JSC::Heap::setBonusVisitorTask):
(JSC::Heap::runTaskInParallel):
(JSC::Heap::forEachSlotVisitor): Deleted.
* heap/Heap.h:
(JSC::Heap::worldIsRunning const):
(JSC::Heap::runFunctionInParallel):
* heap/HeapInlines.h:
(JSC::Heap::worldIsStopped const):
(JSC::Heap::isMarked):
(JSC::Heap::incrementDeferralDepth):
(JSC::Heap::decrementDeferralDepth):
(JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
(JSC::Heap::forEachSlotVisitor):
(JSC::Heap::collectorBelievesThatTheWorldIsStopped const): Deleted.
(JSC::Heap::isMarkedConcurrently): Deleted.
* heap/HeapSnapshotBuilder.cpp:
(JSC::HeapSnapshotBuilder::appendNode):
* heap/LargeAllocation.h:
(JSC::LargeAllocation::isMarked):
(JSC::LargeAllocation::isMarkedConcurrently): Deleted.
* heap/LockDuringMarking.h:
(JSC::lockDuringMarking):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::parallelNotEmptyBlockSource):
* heap/MarkedAllocator.h:
* heap/MarkedBlock.h:
(JSC::MarkedBlock::aboutToMark):
(JSC::MarkedBlock::isMarked):
(JSC::MarkedBlock::areMarksStaleWithDependency): Deleted.
(JSC::MarkedBlock::isMarkedConcurrently): Deleted.
* heap/MarkedSpace.h:
(JSC::MarkedSpace::activeWeakSetsBegin):
(JSC::MarkedSpace::activeWeakSetsEnd):
(JSC::MarkedSpace::newActiveWeakSetsBegin):
(JSC::MarkedSpace::newActiveWeakSetsEnd):
* heap/MarkingConstraint.cpp:
(JSC::MarkingConstraint::MarkingConstraint):
(JSC::MarkingConstraint::execute):
(JSC::MarkingConstraint::quickWorkEstimate):
(JSC::MarkingConstraint::workEstimate):
(JSC::MarkingConstraint::doParallelWork):
(JSC::MarkingConstraint::finishParallelWork):
(JSC::MarkingConstraint::doParallelWorkImpl):
(JSC::MarkingConstraint::finishParallelWorkImpl):
* heap/MarkingConstraint.h:
(JSC::MarkingConstraint::lastExecuteParallelism const):
(JSC::MarkingConstraint::parallelism const):
(JSC::MarkingConstraint::quickWorkEstimate): Deleted.
(JSC::MarkingConstraint::workEstimate): Deleted.
* heap/MarkingConstraintSet.cpp:
(JSC::MarkingConstraintSet::MarkingConstraintSet):
(JSC::MarkingConstraintSet::add):
(JSC::MarkingConstraintSet::executeConvergence):
(JSC::MarkingConstraintSet::executeConvergenceImpl):
(JSC::MarkingConstraintSet::executeAll):
(JSC::MarkingConstraintSet::ExecutionContext::ExecutionContext): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didVisitSomething const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::shouldTimeOut const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::drain): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didExecute const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::execute): Deleted.
(): Deleted.
* heap/MarkingConstraintSet.h:
* heap/MarkingConstraintSolver.cpp: Added.
(JSC::MarkingConstraintSolver::MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::~MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::didVisitSomething const):
(JSC::MarkingConstraintSolver::execute):
(JSC::MarkingConstraintSolver::drain):
(JSC::MarkingConstraintSolver::converge):
(JSC::MarkingConstraintSolver::runExecutionThread):
(JSC::MarkingConstraintSolver::didExecute):
* heap/MarkingConstraintSolver.h: Added.
* heap/OpaqueRootSet.h: Removed.
* heap/ParallelSourceAdapter.h: Added.
(JSC::ParallelSourceAdapter::ParallelSourceAdapter):
(JSC::createParallelSourceAdapter):
* heap/SimpleMarkingConstraint.cpp: Added.
(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::~SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::quickWorkEstimate):
(JSC::SimpleMarkingConstraint::executeImpl):
* heap/SimpleMarkingConstraint.h: Added.
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::didStartMarking):
(JSC::SlotVisitor::reset):
(JSC::SlotVisitor::appendToMarkStack):
(JSC::SlotVisitor::visitChildren):
(JSC::SlotVisitor::updateMutatorIsStopped):
(JSC::SlotVisitor::mutatorIsStoppedIsUpToDate const):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::performIncrementOfDraining):
(JSC::SlotVisitor::didReachTermination):
(JSC::SlotVisitor::hasWork):
(JSC::SlotVisitor::drainFromShared):
(JSC::SlotVisitor::drainInParallelPassively):
(JSC::SlotVisitor::waitForTermination):
(JSC::SlotVisitor::addOpaqueRoot): Deleted.
(JSC::SlotVisitor::containsOpaqueRoot const): Deleted.
(JSC::SlotVisitor::containsOpaqueRootTriState const): Deleted.
(JSC::SlotVisitor::mergeIfNecessary): Deleted.
(JSC::SlotVisitor::mergeOpaqueRootsIfProfitable): Deleted.
(JSC::SlotVisitor::mergeOpaqueRoots): Deleted.
* heap/SlotVisitor.h:
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::addOpaqueRoot):
(JSC::SlotVisitor::containsOpaqueRoot const):
(JSC::SlotVisitor::vm):
(JSC::SlotVisitor::vm const):
* heap/Subspace.cpp:
(JSC::Subspace::parallelAllocatorSource):
(JSC::Subspace::parallelNotEmptyMarkedBlockSource):
* heap/Subspace.h:
* heap/SubspaceInlines.h:
(JSC::Subspace::forEachMarkedCellInParallel):
* heap/VisitCounter.h: Added.
(JSC::VisitCounter::VisitCounter):
(JSC::VisitCounter::visitCount const):
* heap/VisitingTimeout.h: Removed.
* heap/WeakBlock.cpp:
(JSC::WeakBlock::specializedVisit):
* runtime/Structure.cpp:
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::markIfCheap):
Source/WebCore:
No new tests because no change in behavior. This change is best tested using DOM-GC-intensive
benchmarks like Speedometer and Dromaeo.
This parallelizes the DOM's output constraint, and makes some small changes to make this more
scalable.
* ForwardingHeaders/heap/SimpleMarkingConstraint.h: Added.
* ForwardingHeaders/heap/VisitingTimeout.h: Removed.
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/DOMGCOutputConstraint.cpp: Added.
(WebCore::DOMGCOutputConstraint::DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::~DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::executeImpl):
(WebCore::DOMGCOutputConstraint::doParallelWorkImpl):
(WebCore::DOMGCOutputConstraint::finishParallelWorkImpl):
* bindings/js/DOMGCOutputConstraint.h: Added.
* bindings/js/WebCoreJSClientData.cpp:
(WebCore::JSVMClientData::initNormalWorld):
* dom/Node.cpp:
(WebCore::Node::eventTargetDataConcurrently):
(WebCore::Node::ensureEventTargetData):
(WebCore::Node::clearEventTargetData):
Source/WTF:
This does some changes to make it easier to do parallel constraint solving:
- I finally removed dependencyWith. This was a silly construct whose only purpose is to confuse
people about what it means to have a dependency chain. I took that as an opportunity to grealy
simplify the GC's use of dependency chaining.
- Added more logic to Deque<>, since I use it for part of the load balancer.
- Made it possible to profile lock contention. See
https://bugs.webkit.org/show_bug.cgi?id=180250#c0 for some preliminary measurements.
- Introduced holdLockIf, which makes it easy to perform predicated lock acquisition. We use that
to pick a lock in WebCore.
- Introduced CountingLock. It's like WTF::Lock except it also enables optimistic read transactions
sorta like Java's StampedLock.
* WTF.xcodeproj/project.pbxproj:
* wtf/Atomics.h:
(WTF::dependency):
(WTF::DependencyWith::DependencyWith): Deleted.
(WTF::dependencyWith): Deleted.
* wtf/BitVector.h:
(WTF::BitVector::iterator::operator++):
* wtf/CMakeLists.txt:
* wtf/ConcurrentPtrHashSet.cpp: Added.
(WTF::ConcurrentPtrHashSet::ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::~ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::deleteOldTables):
(WTF::ConcurrentPtrHashSet::clear):
(WTF::ConcurrentPtrHashSet::initialize):
(WTF::ConcurrentPtrHashSet::addSlow):
(WTF::ConcurrentPtrHashSet::resizeIfNecessary):
(WTF::ConcurrentPtrHashSet::resizeAndAdd):
(WTF::ConcurrentPtrHashSet::Table::create):
* wtf/ConcurrentPtrHashSet.h: Added.
(WTF::ConcurrentPtrHashSet::contains):
(WTF::ConcurrentPtrHashSet::add):
(WTF::ConcurrentPtrHashSet::size const):
(WTF::ConcurrentPtrHashSet::Table::maxLoad const):
(WTF::ConcurrentPtrHashSet::hash):
(WTF::ConcurrentPtrHashSet::cast):
(WTF::ConcurrentPtrHashSet::containsImpl const):
(WTF::ConcurrentPtrHashSet::addImpl):
* wtf/Deque.h:
(WTF::inlineCapacity>::takeFirst):
* wtf/FastMalloc.h:
* wtf/Lock.cpp:
(WTF::LockBase::lockSlow):
* wtf/Locker.h:
(WTF::holdLockIf):
* wtf/ScopedLambda.h:
* wtf/SharedTask.h:
(WTF::SharedTask<PassedResultType):
(WTF::SharedTask<ResultType): Deleted.
* wtf/StackShot.h: Added.
(WTF::StackShot::StackShot):
(WTF::StackShot::operator=):
(WTF::StackShot::array const):
(WTF::StackShot::size const):
(WTF::StackShot::operator bool const):
(WTF::StackShot::operator== const):
(WTF::StackShot::hash const):
(WTF::StackShot::isHashTableDeletedValue const):
(WTF::StackShot::operator> const):
(WTF::StackShot::deletedValueArray):
(WTF::StackShotHash::hash):
(WTF::StackShotHash::equal):
* wtf/StackShotProfiler.h: Added.
(WTF::StackShotProfiler::StackShotProfiler):
(WTF::StackShotProfiler::profile):
(WTF::StackShotProfiler::run):
Tools:
* Scripts/run-jsc-benchmarks: Add splay-latency test, since this change needed to be carefully validated with that benchmark.
* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/ConcurrentPtrHashSet.cpp: Added. This has unit tests of the new concurrent data structure. The tests focus on correctness under serial execution, which appears to be enough for now (it's so easy to catch a concurrency bug by just running the GC).
(TestWebKitAPI::TEST):
Canonical link: https://commits.webkit.org/196360@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225524 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-12-05 17:53:57 +00:00
|
|
|
heap/MarkingConstraintSolver.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/MutatorScheduler.cpp
|
|
|
|
heap/MutatorState.cpp
|
2021-03-16 21:58:54 +00:00
|
|
|
heap/RootMarkReason.cpp
|
GC constraint solving should be parallel
https://bugs.webkit.org/show_bug.cgi?id=179934
Reviewed by JF Bastien.
PerformanceTests:
Added a version of splay that measures latency in a way that run-jsc-benchmarks groks.
* Octane/splay.js: Added.
(this.Setup.setup.setup):
(this.TearDown.tearDown.tearDown):
(Benchmark):
(BenchmarkResult):
(BenchmarkResult.prototype.valueOf):
(BenchmarkSuite):
(alert):
(Math.random):
(BenchmarkSuite.ResetRNG):
(RunStep):
(BenchmarkSuite.RunSuites):
(BenchmarkSuite.CountBenchmarks):
(BenchmarkSuite.GeometricMean):
(BenchmarkSuite.GeometricMeanTime):
(BenchmarkSuite.AverageAbovePercentile):
(BenchmarkSuite.GeometricMeanLatency):
(BenchmarkSuite.FormatScore):
(BenchmarkSuite.prototype.NotifyStep):
(BenchmarkSuite.prototype.NotifyResult):
(BenchmarkSuite.prototype.NotifyError):
(BenchmarkSuite.prototype.RunSingleBenchmark):
(RunNextSetup):
(RunNextBenchmark):
(RunNextTearDown):
(BenchmarkSuite.prototype.RunStep):
(GeneratePayloadTree):
(GenerateKey):
(SplayUpdateStats):
(InsertNewNode):
(SplaySetup):
(SplayTearDown):
(SplayRun):
(SplayTree):
(SplayTree.prototype.isEmpty):
(SplayTree.prototype.insert):
(SplayTree.prototype.remove):
(SplayTree.prototype.find):
(SplayTree.prototype.findMax):
(SplayTree.prototype.findGreatestLessThan):
(SplayTree.prototype.exportKeys):
(SplayTree.prototype.splay_):
(SplayTree.Node):
(SplayTree.Node.prototype.traverse_):
(report):
(start):
Source/JavaScriptCore:
This makes it possible to do constraint solving in parallel. This looks like a 1% Speedometer
speed-up. It's more than 1% on trunk-Speedometer.
The constraint solver supports running constraints in parallel in two different ways:
- Run multiple constraints in parallel to each other. This only works for constraints that can
tolerate other constraints running concurrently to them (constraint.concurrency() ==
ConstraintConcurrency::Concurrent). This is the most basic kind of parallelism that the
constraint solver supports. All constraints except the JSC SPI constraints are concurrent. We
could probably make them concurrent, but I'm playing it safe for now.
- A constraint can create parallel work for itself, which the constraint solver will interleave
with other stuff. A constraint can report that it has parallel work by returning
ConstraintParallelism::Parallel from its executeImpl() function. Then the solver will allow that
constraint's doParallelWorkImpl() function to run on as many GC marker threads as are available,
for as long as that function wants to run.
It's not possible to have a non-concurrent constraint that creates parallel work.
The parallelism is implemented in terms of the existing GC marker threads. This turns out to be
most natural for two reasons:
- No need to start any other threads.
- The constraints all want to be passed a SlotVisitor. Running on the marker threads means having
access to those threads' SlotVisitors. Also, it means less load balancing. The solver will
create work on each marking thread's SlotVisitor. When the solver is done "stealing" a marker
thread, that thread will have work it can start doing immediately. Before this change, we had to
contribute the work found by the constraint solver to the global worklist so that it could be
distributed to the marker threads by load balancing. This change probably helps to avoid that
load balancing step.
A lot of this change is about making it easy to iterate GC data structures in parallel. This
change makes almost all constraints parallel-enabled, but only the DOM's output constraint uses
the parallel work API. That constraint iterates the marked cells in two subspaces. This change
makes it very easy to compose parallel iterators over subspaces, allocators, blocks, and cells.
The marked cell parallel iterator is composed out of parallel iterators for the others. A parallel
iterator is just an iterator that can do an atomic next() very quickly. We abstract them using
RefPtr<SharedTask<...()>>, where ... is the type returned from the iterator. We know it's done
when it returns a falsish version of ... (in the current code, that's always a pointer type, so
done is indicated by null).
* API/JSMarkingConstraintPrivate.cpp:
(JSContextGroupAddMarkingConstraint):
* API/JSVirtualMachine.mm:
(scanExternalObjectGraph):
(scanExternalRememberedSet):
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::propagateTransitions const):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitWeakly):
(JSC::CodeBlock::shouldJettisonDueToOldAge):
(JSC::shouldMarkTransition):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
* dfg/DFGWorklist.cpp:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* heap/ConstraintParallelism.h: Added.
(WTF::printInternal):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::addToRememberedSet):
(JSC::Heap::runFixpointPhase):
(JSC::Heap::stopThePeriphery):
(JSC::Heap::resumeThePeriphery):
(JSC::Heap::addCoreConstraints):
(JSC::Heap::setBonusVisitorTask):
(JSC::Heap::runTaskInParallel):
(JSC::Heap::forEachSlotVisitor): Deleted.
* heap/Heap.h:
(JSC::Heap::worldIsRunning const):
(JSC::Heap::runFunctionInParallel):
* heap/HeapInlines.h:
(JSC::Heap::worldIsStopped const):
(JSC::Heap::isMarked):
(JSC::Heap::incrementDeferralDepth):
(JSC::Heap::decrementDeferralDepth):
(JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
(JSC::Heap::forEachSlotVisitor):
(JSC::Heap::collectorBelievesThatTheWorldIsStopped const): Deleted.
(JSC::Heap::isMarkedConcurrently): Deleted.
* heap/HeapSnapshotBuilder.cpp:
(JSC::HeapSnapshotBuilder::appendNode):
* heap/LargeAllocation.h:
(JSC::LargeAllocation::isMarked):
(JSC::LargeAllocation::isMarkedConcurrently): Deleted.
* heap/LockDuringMarking.h:
(JSC::lockDuringMarking):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::parallelNotEmptyBlockSource):
* heap/MarkedAllocator.h:
* heap/MarkedBlock.h:
(JSC::MarkedBlock::aboutToMark):
(JSC::MarkedBlock::isMarked):
(JSC::MarkedBlock::areMarksStaleWithDependency): Deleted.
(JSC::MarkedBlock::isMarkedConcurrently): Deleted.
* heap/MarkedSpace.h:
(JSC::MarkedSpace::activeWeakSetsBegin):
(JSC::MarkedSpace::activeWeakSetsEnd):
(JSC::MarkedSpace::newActiveWeakSetsBegin):
(JSC::MarkedSpace::newActiveWeakSetsEnd):
* heap/MarkingConstraint.cpp:
(JSC::MarkingConstraint::MarkingConstraint):
(JSC::MarkingConstraint::execute):
(JSC::MarkingConstraint::quickWorkEstimate):
(JSC::MarkingConstraint::workEstimate):
(JSC::MarkingConstraint::doParallelWork):
(JSC::MarkingConstraint::finishParallelWork):
(JSC::MarkingConstraint::doParallelWorkImpl):
(JSC::MarkingConstraint::finishParallelWorkImpl):
* heap/MarkingConstraint.h:
(JSC::MarkingConstraint::lastExecuteParallelism const):
(JSC::MarkingConstraint::parallelism const):
(JSC::MarkingConstraint::quickWorkEstimate): Deleted.
(JSC::MarkingConstraint::workEstimate): Deleted.
* heap/MarkingConstraintSet.cpp:
(JSC::MarkingConstraintSet::MarkingConstraintSet):
(JSC::MarkingConstraintSet::add):
(JSC::MarkingConstraintSet::executeConvergence):
(JSC::MarkingConstraintSet::executeConvergenceImpl):
(JSC::MarkingConstraintSet::executeAll):
(JSC::MarkingConstraintSet::ExecutionContext::ExecutionContext): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didVisitSomething const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::shouldTimeOut const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::drain): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::didExecute const): Deleted.
(JSC::MarkingConstraintSet::ExecutionContext::execute): Deleted.
(): Deleted.
* heap/MarkingConstraintSet.h:
* heap/MarkingConstraintSolver.cpp: Added.
(JSC::MarkingConstraintSolver::MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::~MarkingConstraintSolver):
(JSC::MarkingConstraintSolver::didVisitSomething const):
(JSC::MarkingConstraintSolver::execute):
(JSC::MarkingConstraintSolver::drain):
(JSC::MarkingConstraintSolver::converge):
(JSC::MarkingConstraintSolver::runExecutionThread):
(JSC::MarkingConstraintSolver::didExecute):
* heap/MarkingConstraintSolver.h: Added.
* heap/OpaqueRootSet.h: Removed.
* heap/ParallelSourceAdapter.h: Added.
(JSC::ParallelSourceAdapter::ParallelSourceAdapter):
(JSC::createParallelSourceAdapter):
* heap/SimpleMarkingConstraint.cpp: Added.
(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::~SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::quickWorkEstimate):
(JSC::SimpleMarkingConstraint::executeImpl):
* heap/SimpleMarkingConstraint.h: Added.
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::didStartMarking):
(JSC::SlotVisitor::reset):
(JSC::SlotVisitor::appendToMarkStack):
(JSC::SlotVisitor::visitChildren):
(JSC::SlotVisitor::updateMutatorIsStopped):
(JSC::SlotVisitor::mutatorIsStoppedIsUpToDate const):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::performIncrementOfDraining):
(JSC::SlotVisitor::didReachTermination):
(JSC::SlotVisitor::hasWork):
(JSC::SlotVisitor::drainFromShared):
(JSC::SlotVisitor::drainInParallelPassively):
(JSC::SlotVisitor::waitForTermination):
(JSC::SlotVisitor::addOpaqueRoot): Deleted.
(JSC::SlotVisitor::containsOpaqueRoot const): Deleted.
(JSC::SlotVisitor::containsOpaqueRootTriState const): Deleted.
(JSC::SlotVisitor::mergeIfNecessary): Deleted.
(JSC::SlotVisitor::mergeOpaqueRootsIfProfitable): Deleted.
(JSC::SlotVisitor::mergeOpaqueRoots): Deleted.
* heap/SlotVisitor.h:
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::addOpaqueRoot):
(JSC::SlotVisitor::containsOpaqueRoot const):
(JSC::SlotVisitor::vm):
(JSC::SlotVisitor::vm const):
* heap/Subspace.cpp:
(JSC::Subspace::parallelAllocatorSource):
(JSC::Subspace::parallelNotEmptyMarkedBlockSource):
* heap/Subspace.h:
* heap/SubspaceInlines.h:
(JSC::Subspace::forEachMarkedCellInParallel):
* heap/VisitCounter.h: Added.
(JSC::VisitCounter::VisitCounter):
(JSC::VisitCounter::visitCount const):
* heap/VisitingTimeout.h: Removed.
* heap/WeakBlock.cpp:
(JSC::WeakBlock::specializedVisit):
* runtime/Structure.cpp:
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::markIfCheap):
Source/WebCore:
No new tests because no change in behavior. This change is best tested using DOM-GC-intensive
benchmarks like Speedometer and Dromaeo.
This parallelizes the DOM's output constraint, and makes some small changes to make this more
scalable.
* ForwardingHeaders/heap/SimpleMarkingConstraint.h: Added.
* ForwardingHeaders/heap/VisitingTimeout.h: Removed.
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/DOMGCOutputConstraint.cpp: Added.
(WebCore::DOMGCOutputConstraint::DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::~DOMGCOutputConstraint):
(WebCore::DOMGCOutputConstraint::executeImpl):
(WebCore::DOMGCOutputConstraint::doParallelWorkImpl):
(WebCore::DOMGCOutputConstraint::finishParallelWorkImpl):
* bindings/js/DOMGCOutputConstraint.h: Added.
* bindings/js/WebCoreJSClientData.cpp:
(WebCore::JSVMClientData::initNormalWorld):
* dom/Node.cpp:
(WebCore::Node::eventTargetDataConcurrently):
(WebCore::Node::ensureEventTargetData):
(WebCore::Node::clearEventTargetData):
Source/WTF:
This does some changes to make it easier to do parallel constraint solving:
- I finally removed dependencyWith. This was a silly construct whose only purpose is to confuse
people about what it means to have a dependency chain. I took that as an opportunity to grealy
simplify the GC's use of dependency chaining.
- Added more logic to Deque<>, since I use it for part of the load balancer.
- Made it possible to profile lock contention. See
https://bugs.webkit.org/show_bug.cgi?id=180250#c0 for some preliminary measurements.
- Introduced holdLockIf, which makes it easy to perform predicated lock acquisition. We use that
to pick a lock in WebCore.
- Introduced CountingLock. It's like WTF::Lock except it also enables optimistic read transactions
sorta like Java's StampedLock.
* WTF.xcodeproj/project.pbxproj:
* wtf/Atomics.h:
(WTF::dependency):
(WTF::DependencyWith::DependencyWith): Deleted.
(WTF::dependencyWith): Deleted.
* wtf/BitVector.h:
(WTF::BitVector::iterator::operator++):
* wtf/CMakeLists.txt:
* wtf/ConcurrentPtrHashSet.cpp: Added.
(WTF::ConcurrentPtrHashSet::ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::~ConcurrentPtrHashSet):
(WTF::ConcurrentPtrHashSet::deleteOldTables):
(WTF::ConcurrentPtrHashSet::clear):
(WTF::ConcurrentPtrHashSet::initialize):
(WTF::ConcurrentPtrHashSet::addSlow):
(WTF::ConcurrentPtrHashSet::resizeIfNecessary):
(WTF::ConcurrentPtrHashSet::resizeAndAdd):
(WTF::ConcurrentPtrHashSet::Table::create):
* wtf/ConcurrentPtrHashSet.h: Added.
(WTF::ConcurrentPtrHashSet::contains):
(WTF::ConcurrentPtrHashSet::add):
(WTF::ConcurrentPtrHashSet::size const):
(WTF::ConcurrentPtrHashSet::Table::maxLoad const):
(WTF::ConcurrentPtrHashSet::hash):
(WTF::ConcurrentPtrHashSet::cast):
(WTF::ConcurrentPtrHashSet::containsImpl const):
(WTF::ConcurrentPtrHashSet::addImpl):
* wtf/Deque.h:
(WTF::inlineCapacity>::takeFirst):
* wtf/FastMalloc.h:
* wtf/Lock.cpp:
(WTF::LockBase::lockSlow):
* wtf/Locker.h:
(WTF::holdLockIf):
* wtf/ScopedLambda.h:
* wtf/SharedTask.h:
(WTF::SharedTask<PassedResultType):
(WTF::SharedTask<ResultType): Deleted.
* wtf/StackShot.h: Added.
(WTF::StackShot::StackShot):
(WTF::StackShot::operator=):
(WTF::StackShot::array const):
(WTF::StackShot::size const):
(WTF::StackShot::operator bool const):
(WTF::StackShot::operator== const):
(WTF::StackShot::hash const):
(WTF::StackShot::isHashTableDeletedValue const):
(WTF::StackShot::operator> const):
(WTF::StackShot::deletedValueArray):
(WTF::StackShotHash::hash):
(WTF::StackShotHash::equal):
* wtf/StackShotProfiler.h: Added.
(WTF::StackShotProfiler::StackShotProfiler):
(WTF::StackShotProfiler::profile):
(WTF::StackShotProfiler::run):
Tools:
* Scripts/run-jsc-benchmarks: Add splay-latency test, since this change needed to be carefully validated with that benchmark.
* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/ConcurrentPtrHashSet.cpp: Added. This has unit tests of the new concurrent data structure. The tests focus on correctness under serial execution, which appears to be enough for now (it's so easy to catch a concurrency bug by just running the GC).
(TestWebKitAPI::TEST):
Canonical link: https://commits.webkit.org/196360@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225524 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-12-05 17:53:57 +00:00
|
|
|
heap/SimpleMarkingConstraint.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/SlotVisitor.cpp
|
|
|
|
heap/SpaceTimeMutatorScheduler.cpp
|
|
|
|
heap/StochasticSpaceTimeMutatorScheduler.cpp
|
|
|
|
heap/StopIfNecessaryTimer.cpp
|
|
|
|
heap/Subspace.cpp
|
|
|
|
heap/SynchronousStopTheWorldMutatorScheduler.cpp
|
|
|
|
heap/Synchronousness.cpp
|
Implement a GC verifier.
https://bugs.webkit.org/show_bug.cgi?id=217274
rdar://56255683
Reviewed by Filip Pizlo and Saam Barati.
Source/JavaScriptCore:
The idea behind the GC verifier is that in the GC End phase before we finalize
and sweep, we'll do a simple stop the world synchronous full GC with the
VerifierSlotVisitor. The VerifierSlotVisitor will collect it's own information
on whether a JS cell should be marked or not. After this verifier GC pass, we'll
compare the mark results.
If the verifier GC says a cell should be marked, then the real GC should have
marked the cell. The reverse is not true: if the verifier does not mark a cell,
it is still OK for the real GC to mark it. For example, in an eden GC, all old
generation cells would be considered mark by the real GC though the verifier would
know better if they are already dead.
Implementation details:
1. SlotVisitor (only used by the real GC) now inherits from a new abstract class,
AbstractSlotVisitor.
VerifierSlotVisitor (only used by the verifier GC) also inherits from
AbstractSlotVisitor.
2. AbstractSlotVisitor declares many virtual methods.
SlotVisitor implements some of these virtual methods as inline and final.
If the client is invoking one these methods and knows that it will be operating
on a SlotVisitor, the method being final allows it to be inlined into the client
instead of going through the virtual dispatch.
For the VerifierSlotVisitor, these methods will always be invoked by virtual
dispatch via the AbstractSlotVisitor abstraction.
3. Almost all methods that takes a SlotVisitor previously (with a few exceptions)
will now be templatized, and specialized to either take a SlotVisitor or an
AbstractSlotVisitor.
The cell MethodTable will now have 2 versions of visitChildren and visitOutputConstraints:
one for SlotVisitor, and one for AbstractSlotVisitor.
The reason we don't wire the 2nd version to VerifierSlotVisitor (instead of
AbstractSlotVisitor) is because we don't need the GC verifier to run at top
speed (though we don't want it to be too slow). Also, having hooks for using
an AbstractSlotVisitor gives us more utility for implementing other types of
GC checkers / analyzers in the future as subclasses of AbstractSlotVisitor.
4. Some minority of methods that used to take a SlotVisitor but are not critical
to performance, will now just take an AbstractSlotVisitor instead. For example,
see TypeProfilerLog::visit().
5. isReachableFromOpaqueRoots() methods will also only take an AbstractSlotVisitor.
The reason this is OK is because isReachableFromOpaqueRoots() only uses the
visitor's addOpaqueRoot() and containsOpaqueRoot() methods, which are implemented
in the AbstractSlotVisitor itself.
For SlotVisitor, the m_opaqueRoot field will reference Heap::m_opaqueRoots.
For VerifierSlotVisitor, the m_opaqueRoot field will reference its own
opaque roots storage.
This implementation of addOpaqueRoot() is perf neutral for SlotVisitor because
where it would previously invoke m_heap.m_opaqueRoots.add(), it will now
invoke m_opaqueRoot.add() instead where m_opaqueRoot points to m_heap.m_opaqueRoots.
Ditto for AbstractSlotVisitor::containsOpaqueRoot().
6. When reifying a templatized visit method, we do it in 2 ways:
a. Implement the template method as an ALWAYS_INLINE Impl method, and have
2 visit methods (taking a SlotVisitor and an AbstractSlotVisitor respectively)
inline the Impl method. For example, see JSObject::visitChildrenImpl().
b. Just templatize the visit method, and explicitly instantiate it with a SlotVisitor
and an AbstractSlotVisitor. For example, see DesiredTransition::visitChildren().
The reason we need form (a) is if:
i. we need to export the visit methods.
For example, see JSObject:visitChildren().
Note: A Clang engineer told me that "there's no way to export an explicit
instantiation that will make it a strong symbol." This is because "C++ does not
provide any standard way to guarantee that an explicit instantiation is unique,
and Clang hasn't added any extension to do so."
ii. the visit method is an override of a virtual method.
For example, see DFG::Scannable::visitChildren() and DFG::Graph::visitChildren().
Otherwise, we'll prefer form (b) as it is natural C++.
7. Because templatizing all the visit methods requires a lot of boiler plate code,
we introduce some macros in SlotVisitorMacros.h to reduce some of the boiler
plate burden.
We especially try to do this for methods of form (a) (see (6) above) which
require more boiler plate.
8. The driver of the real GC is MarkingConstraintSet::executeConvergence() which
runs with the MarkingConstraintSolver.
The driver of the verifier GC is Heap::verifyGC(), which has a loop to drain
marked objects and execute contraints.
9. The GC verifier is built in by default but disabled. The relevant options are:
JSC_verifyGC and JSC_verboseVerifyGC.
JSC_verifyGC will enable the GC verifier.
If JSC_verifyGC is true and the verifier finds a cell that is
erroneously not marked by the real GC, it will dump an error message and then
crash with a RELEASE_ASSERT.
JSC_verboseVerifyGC will enable the GC verifier along with some more heavy
weight record keeping (i.e. tracking the parent / owner cell that marked a
cell, and capturing the call stack when the marked cell is appended to the mark
stack).
If JSC_verboseVerifyGC is true and the verifier finds a cell that is
erroneously not marked by the real GC, it will dump the parent cell and
captured stack along with an error message before crashing. This extra
information provides the starting point for debugging GC bugs found by the
verifier.
Enabling JSC_verboseVerifyGC will automatically enable JSC_verifyGC.
10. Non-determinism in the real GC.
The GC verifier's algorithm relies on the real GC being deterministic. However,
there are a few places where this is not true:
a. Marking conservative roots on the mutator stacks.
By the time the verifier GC runs (in the GC End phase), the mutator stacks
will look completely different than what the real GC saw. To work around
this, if the verifier is enabled, then every conservative root captured by
the real GC will also be added to the verifier's mark stack.
When running verifyGC() in the End phase, the conservative root scans will be
treated as no-ops.
b. CodeBlock::shouldJettisonDueToOldAge() may return a different value.
This is possible because the codeBlock may be in mid compilation while the
real GC is in progress.
CodeBlock::shouldVisitStrongly() calls shouldJettisonDueToOldAge(), and may
see an old LLInt codeBlock whose timeToLive has expired. As a result,
shouldJettisonDueToOldAge() returns true and shouldVisitStrongly() will
return false for the real GC, leading to it not marking the codeBlock.
However, before the verifier GC gets to run, baseline compilation on the
codeBlock may finish. As a baseline codeBlock now, it gets a longer time
to live.
As a result, when the verifier GC runs, shouldJettisonDueToOldAge() will
return false, and shouldVisitStrongly() in turn returns true. This results
in the verifier GC marking the codeBlock (and its children) when the real
GC did not, which leads to a false error. This is not a real error because
if the real GC did not mark the code block, it will simply get jettisoned,
and can be reinstantiated when needed later. There's no GC bug here.
However, we do need to work around this to prevent the false error for the
GC verifier.
The work around is to introduce a CodeBlock::m_visitChildrenSkippedDueToOldAge
flag that records what the real GC decided in shouldJettisonDueToOldAge().
This allows the verifier GC to replay the same decision and get a consistent
result.
c. CodeBlock::propagateTransitions() will only do a best effort at visiting
cells in ICs, etc. If a cell is not already strongly marked by the time
CodeBlock::propagateTransitions() checks it, propagateTransitions() will
not mark other cells that are reachable from it.
Since the real GC does marking on concurrent threads, marking order is not
deterministic. CodeBlock::propagateTransitions() may or may not see a cell
as already marked by the time it runs.
The verifier GC may mark some of these cells in a different order than the
real GC. As a result, in the verifier GC, CodeBlock::propagateTransitions()
may see a cell as marked (and therefore, visit its children) when it did
not for the real GC.
To work around this, we currently add a SuppressGCVerifierScope to
CodeBlock::propagateTransitions() to pessimize the verifier, and assume that
propagateTransitions() will mark nothing.
SuppressGCVerifierScope is a blunt hammer that stops the verifier GC from
analyzing all cells potentially reachable via CodeBlock::propagateTransitions().
In the future, it may be possible to refine this and track which cells were
actually skipped over (like we did for shouldJettisonDueToOldAge()).
However, this decision tracking needs to be done in the real GC, and can be
very expensive in terms of performance. The shouldJettisonDueToOldAge()
case is rare, and as such lends itself to this more fine grain tracking
without hurting performance. The decisions made in CodeBlock::propagateTransitions()
are not as rare, and hence, it would hurt performance if we did fine grain
decision tracking there (at least or now).
11. Marking in the verifier GC.
The real GC tracks cell marks using a Bitmap in the MarkedBlocks. The verifier
GC keeps tracks of MarkedBlock cell marks using a Bitmap on the side, stashed
away in a HashMap.
To improve the verifier marking performance, we reserve a void* m_verifierMemo
pointer in the MarkedBlock, which the verifier will employ to cache its
MarkedBlockData for that MarkedBlock. This allows the verifier to get to its
side Bitmap without having to do a HashMap look up for every cell.
Size-wise, in the current 16K MarkBlocks, there is previously room for 1005.5
atoms after reserving space for the MarkedBlock::Footer. Since we can never
allocate half an atom anyway, that .5 atom gives us the 8 bytes we need for
the m_verifierMemo pointer, which we'll put in the MarkedBlock::Footer. With
this patch, each MarkedBlock will now have exactly 1005 atoms available for
allocation.
I ran JetStream2 and Speedometer2 locally on a MacBookAir10,1, MacBookPro16,1,
and a 12.9” 4th Gen iPad Pro. The benchmark results for these were all neutral.
The design of the GC verifier is such that it incurs almost no additional runtime
memory overhead if not in use. Code size does increase significantly because
there are now 2 variants of most of the methods that take a SlotVisitor.
When in use, the additional runtime memory is encapsulated in the
VerifierSlotVisitor, which is instantiated and destructed every GC cycle. Hence,
it can affect peak memory usage during GCs, but the cost is transient. It does
not persist past the GC End phase.
* API/JSAPIWrapperObject.h:
* API/JSAPIWrapperObject.mm:
(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
(JSC::JSAPIWrapperObject::visitChildrenImpl):
(JSC::JSAPIWrapperObject::visitChildren): Deleted.
* API/JSCallbackObject.cpp:
* API/JSCallbackObject.h:
(JSC::JSCallbackObjectData::visitChildren):
(JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren):
(JSC::JSCallbackObject<Parent>::visitChildrenImpl):
* API/JSManagedValue.mm:
(JSManagedValueHandleOwner::isReachableFromOpaqueRoots):
* API/JSMarkingConstraintPrivate.cpp:
(JSC::isMarked):
(JSContextGroupAddMarkingConstraint):
* API/JSVirtualMachine.mm:
(scanExternalObjectGraph):
(scanExternalRememberedSet):
* API/JSVirtualMachineInternal.h:
* API/MarkedJSValueRefArray.cpp:
(JSC::MarkedJSValueRefArray::visitAggregate):
* API/MarkedJSValueRefArray.h:
* API/glib/JSAPIWrapperGlobalObject.cpp:
(JSC::JSAPIWrapperGlobalObject::visitChildren): Deleted.
* API/glib/JSAPIWrapperGlobalObject.h:
* API/glib/JSAPIWrapperObjectGLib.cpp:
(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
(JSC::JSAPIWrapperObject::visitChildrenImpl):
(JSC::JSAPIWrapperObject::visitChildren): Deleted.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Scripts/wkbuiltins/builtins_generate_internals_wrapper_header.py:
(BuiltinsInternalsWrapperHeaderGenerator):
* Scripts/wkbuiltins/builtins_generate_internals_wrapper_implementation.py:
(BuiltinsInternalsWrapperImplementationGenerator.generate_visit_method):
* Scripts/wkbuiltins/builtins_templates.py:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::propagateTransitions const):
(JSC::AccessCase::visitAggregateImpl const):
(JSC::AccessCase::visitAggregate const): Deleted.
* bytecode/AccessCase.h:
* bytecode/ByValInfo.cpp:
(JSC::ByValInfo::visitAggregateImpl):
(JSC::ByValInfo::visitAggregate): Deleted.
* bytecode/ByValInfo.h:
* bytecode/CheckPrivateBrandStatus.cpp:
(JSC::CheckPrivateBrandStatus::visitAggregateImpl):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::visitAggregate): Deleted.
* bytecode/CheckPrivateBrandStatus.h:
* bytecode/CheckPrivateBrandVariant.cpp:
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::visitAggregateImpl):
(JSC::CheckPrivateBrandVariant::visitAggregate): Deleted.
* bytecode/CheckPrivateBrandVariant.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::visitChildrenImpl):
(JSC::CodeBlock::visitChildren):
(JSC::CodeBlock::shouldVisitStrongly):
(JSC::CodeBlock::shouldJettisonDueToOldAge):
(JSC::shouldMarkTransition):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::visitOSRExitTargets):
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC::CodeBlock::stronglyVisitWeakReferences):
* bytecode/CodeBlock.h:
* bytecode/DeleteByIdVariant.cpp:
(JSC::DeleteByIdVariant::visitAggregateImpl):
(JSC::DeleteByIdVariant::markIfCheap):
(JSC::DeleteByIdVariant::visitAggregate): Deleted.
* bytecode/DeleteByIdVariant.h:
* bytecode/DeleteByStatus.cpp:
(JSC::DeleteByStatus::visitAggregateImpl):
(JSC::DeleteByStatus::markIfCheap):
(JSC::DeleteByStatus::visitAggregate): Deleted.
* bytecode/DeleteByStatus.h:
* bytecode/DirectEvalCodeCache.cpp:
(JSC::DirectEvalCodeCache::visitAggregateImpl):
(JSC::DirectEvalCodeCache::visitAggregate): Deleted.
* bytecode/DirectEvalCodeCache.h:
* bytecode/ExecutableToCodeBlockEdge.cpp:
(JSC::ExecutableToCodeBlockEdge::visitChildrenImpl):
(JSC::ExecutableToCodeBlockEdge::visitOutputConstraintsImpl):
(JSC::ExecutableToCodeBlockEdge::runConstraint):
(JSC::ExecutableToCodeBlockEdge::visitChildren): Deleted.
(JSC::ExecutableToCodeBlockEdge::visitOutputConstraints): Deleted.
* bytecode/ExecutableToCodeBlockEdge.h:
* bytecode/GetByIdVariant.cpp:
(JSC::GetByIdVariant::visitAggregateImpl):
(JSC::GetByIdVariant::markIfCheap):
(JSC::GetByIdVariant::visitAggregate): Deleted.
* bytecode/GetByIdVariant.h:
* bytecode/GetByStatus.cpp:
(JSC::GetByStatus::visitAggregateImpl):
(JSC::GetByStatus::markIfCheap):
(JSC::GetByStatus::visitAggregate): Deleted.
* bytecode/GetByStatus.h:
* bytecode/InByIdStatus.cpp:
(JSC::InByIdStatus::markIfCheap):
* bytecode/InByIdStatus.h:
* bytecode/InByIdVariant.cpp:
(JSC::InByIdVariant::markIfCheap):
* bytecode/InByIdVariant.h:
* bytecode/InternalFunctionAllocationProfile.h:
(JSC::InternalFunctionAllocationProfile::visitAggregate):
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfileBase::visitAggregate):
(JSC::ObjectAllocationProfileWithPrototype::visitAggregate):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::propagateTransitions const):
(JSC::PolymorphicAccess::visitAggregateImpl):
(JSC::PolymorphicAccess::visitAggregate): Deleted.
* bytecode/PolymorphicAccess.h:
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::markIfCheap):
* bytecode/PutByIdStatus.h:
* bytecode/PutByIdVariant.cpp:
(JSC::PutByIdVariant::markIfCheap):
* bytecode/PutByIdVariant.h:
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::visitAggregateImpl):
(JSC::RecordedStatuses::markIfCheap):
(JSC::RecordedStatuses::visitAggregate): Deleted.
* bytecode/RecordedStatuses.h:
* bytecode/SetPrivateBrandStatus.cpp:
(JSC::SetPrivateBrandStatus::visitAggregateImpl):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::visitAggregate): Deleted.
* bytecode/SetPrivateBrandStatus.h:
* bytecode/SetPrivateBrandVariant.cpp:
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::visitAggregateImpl):
(JSC::SetPrivateBrandVariant::visitAggregate): Deleted.
* bytecode/SetPrivateBrandVariant.h:
* bytecode/StructureSet.cpp:
(JSC::StructureSet::markIfCheap const):
* bytecode/StructureSet.h:
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::visitAggregateImpl):
(JSC::StructureStubInfo::propagateTransitions):
(JSC::StructureStubInfo::visitAggregate): Deleted.
* bytecode/StructureStubInfo.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::visitChildrenImpl):
(JSC::UnlinkedCodeBlock::visitChildren): Deleted.
* bytecode/UnlinkedCodeBlock.h:
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::UnlinkedFunctionExecutable::visitChildrenImpl):
(JSC::UnlinkedFunctionExecutable::visitChildren): Deleted.
* bytecode/UnlinkedFunctionExecutable.h:
* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::visitChildrenImpl):
(JSC::DebuggerScope::visitChildren): Deleted.
* debugger/DebuggerScope.h:
* dfg/DFGDesiredTransitions.cpp:
(JSC::DFG::DesiredTransition::visitChildren):
(JSC::DFG::DesiredTransitions::visitChildren):
* dfg/DFGDesiredTransitions.h:
* dfg/DFGDesiredWeakReferences.cpp:
(JSC::DFG::DesiredWeakReferences::visitChildren):
* dfg/DFGDesiredWeakReferences.h:
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::visitChildrenImpl):
(JSC::DFG::Graph::visitChildren):
* dfg/DFGGraph.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
(JSC::DFG::Plan::isKnownToBeLiveDuringGC):
(JSC::DFG::Plan::isKnownToBeLiveAfterGC):
* dfg/DFGPlan.h:
* dfg/DFGPlanInlines.h:
(JSC::DFG::Plan::iterateCodeBlocksForGC):
* dfg/DFGSafepoint.cpp:
(JSC::DFG::Safepoint::checkLivenessAndVisitChildren):
(JSC::DFG::Safepoint::isKnownToBeLiveDuringGC):
(JSC::DFG::Safepoint::isKnownToBeLiveAfterGC):
* dfg/DFGSafepoint.h:
* dfg/DFGScannable.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::visitWeakReferences):
(JSC::DFG::Worklist::removeDeadPlans):
* dfg/DFGWorklist.h:
* dfg/DFGWorklistInlines.h:
(JSC::DFG::iterateCodeBlocksForGC):
(JSC::DFG::Worklist::iterateCodeBlocksForGC):
* heap/AbstractSlotVisitor.h: Added.
(JSC::AbstractSlotVisitor::Context::cell const):
(JSC::AbstractSlotVisitor::SuppressGCVerifierScope::SuppressGCVerifierScope):
(JSC::AbstractSlotVisitor::SuppressGCVerifierScope::~SuppressGCVerifierScope):
(JSC::AbstractSlotVisitor::DefaultMarkingViolationAssertionScope::DefaultMarkingViolationAssertionScope):
(JSC::AbstractSlotVisitor::collectorMarkStack):
(JSC::AbstractSlotVisitor::mutatorMarkStack):
(JSC::AbstractSlotVisitor::collectorMarkStack const):
(JSC::AbstractSlotVisitor::mutatorMarkStack const):
(JSC::AbstractSlotVisitor::isEmpty):
(JSC::AbstractSlotVisitor::setIgnoreNewOpaqueRoots):
(JSC::AbstractSlotVisitor::visitCount const):
(JSC::AbstractSlotVisitor::addToVisitCount):
(JSC::AbstractSlotVisitor::rootMarkReason const):
(JSC::AbstractSlotVisitor::setRootMarkReason):
(JSC::AbstractSlotVisitor::didRace):
(JSC::AbstractSlotVisitor::codeName const):
(JSC::SetRootMarkReasonScope::SetRootMarkReasonScope):
(JSC::SetRootMarkReasonScope::~SetRootMarkReasonScope):
* heap/AbstractSlotVisitorInlines.h: Added.
(JSC::AbstractSlotVisitor::Context::Context):
(JSC::AbstractSlotVisitor::Context::~Context):
(JSC::AbstractSlotVisitor::AbstractSlotVisitor):
(JSC::AbstractSlotVisitor::heap const):
(JSC::AbstractSlotVisitor::vm):
(JSC::AbstractSlotVisitor::vm const):
(JSC::AbstractSlotVisitor::addOpaqueRoot):
(JSC::AbstractSlotVisitor::containsOpaqueRoot const):
(JSC::AbstractSlotVisitor::append):
(JSC::AbstractSlotVisitor::appendHidden):
(JSC::AbstractSlotVisitor::appendHiddenUnbarriered):
(JSC::AbstractSlotVisitor::appendValues):
(JSC::AbstractSlotVisitor::appendValuesHidden):
(JSC::AbstractSlotVisitor::appendUnbarriered):
(JSC::AbstractSlotVisitor::parentCell const):
(JSC::AbstractSlotVisitor::reset):
* heap/HandleSet.cpp:
(JSC::HandleSet::visitStrongHandles):
* heap/HandleSet.h:
* heap/Heap.cpp:
(JSC::Heap::iterateExecutingAndCompilingCodeBlocks):
(JSC::Heap::iterateExecutingAndCompilingCodeBlocksWithoutHoldingLocks):
(JSC::Heap::runEndPhase):
(JSC::Heap::willStartCollection):
(JSC::scanExternalRememberedSet):
(JSC::serviceSamplingProfiler):
(JSC::Heap::addCoreConstraints):
(JSC::Heap::verifyGC):
(JSC::Heap::isAnalyzingHeap const): Deleted.
* heap/Heap.h:
(JSC::Heap::isMarkingForGCVerifier const):
(JSC::Heap::numOpaqueRoots const): Deleted.
* heap/HeapInlines.h:
(JSC::Heap::isMarked):
* heap/HeapProfiler.cpp:
(JSC::HeapProfiler::setActiveHeapAnalyzer):
* heap/IsoCellSet.h:
* heap/IsoCellSetInlines.h:
(JSC::IsoCellSet::forEachMarkedCellInParallel):
* heap/JITStubRoutineSet.cpp:
(JSC::JITStubRoutineSet::traceMarkedStubRoutines):
* heap/JITStubRoutineSet.h:
(JSC::JITStubRoutineSet::traceMarkedStubRoutines):
* heap/MarkStackMergingConstraint.cpp:
(JSC::MarkStackMergingConstraint::prepareToExecuteImpl):
(JSC::MarkStackMergingConstraint::executeImplImpl):
(JSC::MarkStackMergingConstraint::executeImpl):
* heap/MarkStackMergingConstraint.h:
* heap/MarkedBlock.h:
(JSC::MarkedBlock::Handle::atomAt const):
(JSC::MarkedBlock::setVerifierMemo):
(JSC::MarkedBlock::verifierMemo const):
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::visitWeakSets):
* heap/MarkedSpace.h:
* heap/MarkingConstraint.cpp:
(JSC::MarkingConstraint::execute):
(JSC::MarkingConstraint::executeSynchronously):
(JSC::MarkingConstraint::prepareToExecute):
(JSC::MarkingConstraint::doParallelWork):
(JSC::MarkingConstraint::prepareToExecuteImpl):
* heap/MarkingConstraint.h:
* heap/MarkingConstraintExecutorPair.h: Added.
(JSC::MarkingConstraintExecutorPair::MarkingConstraintExecutorPair):
(JSC::MarkingConstraintExecutorPair::execute):
* heap/MarkingConstraintSet.cpp:
(JSC::MarkingConstraintSet::add):
(JSC::MarkingConstraintSet::executeAllSynchronously):
(JSC::MarkingConstraintSet::executeAll): Deleted.
* heap/MarkingConstraintSet.h:
(JSC::MarkingConstraintSet::add):
* heap/MarkingConstraintSolver.cpp:
* heap/MarkingConstraintSolver.h:
* heap/SimpleMarkingConstraint.cpp:
(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::executeImplImpl):
(JSC::SimpleMarkingConstraint::executeImpl):
* heap/SimpleMarkingConstraint.h:
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::SlotVisitor):
(JSC::SlotVisitor::reset):
(JSC::SlotVisitor::appendSlow):
(JSC::SlotVisitor::addParallelConstraintTask):
* heap/SlotVisitor.h:
(JSC::SlotVisitor::collectorMarkStack): Deleted.
(JSC::SlotVisitor::mutatorMarkStack): Deleted.
(JSC::SlotVisitor::collectorMarkStack const): Deleted.
(JSC::SlotVisitor::mutatorMarkStack const): Deleted.
(JSC::SlotVisitor::isEmpty): Deleted.
(JSC::SlotVisitor::isFirstVisit const): Deleted.
(JSC::SlotVisitor::bytesVisited const): Deleted.
(JSC::SlotVisitor::visitCount const): Deleted.
(JSC::SlotVisitor::addToVisitCount): Deleted.
(JSC::SlotVisitor::isAnalyzingHeap const): Deleted.
(JSC::SlotVisitor::heapAnalyzer const): Deleted.
(JSC::SlotVisitor::rootMarkReason const): Deleted.
(JSC::SlotVisitor::setRootMarkReason): Deleted.
(JSC::SlotVisitor::markingVersion const): Deleted.
(JSC::SlotVisitor::mutatorIsStopped const): Deleted.
(JSC::SlotVisitor::rightToRun): Deleted.
(JSC::SlotVisitor::didRace): Deleted.
(JSC::SlotVisitor::setIgnoreNewOpaqueRoots): Deleted.
(JSC::SlotVisitor::codeName const): Deleted.
(JSC::SetRootMarkReasonScope::SetRootMarkReasonScope): Deleted.
(JSC::SetRootMarkReasonScope::~SetRootMarkReasonScope): Deleted.
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::isMarked const):
(JSC::SlotVisitor::addOpaqueRoot): Deleted.
(JSC::SlotVisitor::containsOpaqueRoot const): Deleted.
(JSC::SlotVisitor::heap const): Deleted.
(JSC::SlotVisitor::vm): Deleted.
(JSC::SlotVisitor::vm const): Deleted.
* heap/SlotVisitorMacros.h: Added.
* heap/Subspace.h:
* heap/SubspaceInlines.h:
(JSC::Subspace::forEachMarkedCellInParallel):
* heap/VerifierSlotVisitor.cpp: Added.
(JSC::MarkerData::MarkerData):
(JSC::VerifierSlotVisitor::MarkedBlockData::MarkedBlockData):
(JSC::VerifierSlotVisitor::MarkedBlockData::addMarkerData):
(JSC::VerifierSlotVisitor::MarkedBlockData::markerData const):
(JSC::VerifierSlotVisitor::PreciseAllocationData::PreciseAllocationData):
(JSC::VerifierSlotVisitor::PreciseAllocationData::markerData const):
(JSC::VerifierSlotVisitor::PreciseAllocationData::addMarkerData):
(JSC::VerifierSlotVisitor::VerifierSlotVisitor):
(JSC::VerifierSlotVisitor::~VerifierSlotVisitor):
(JSC::VerifierSlotVisitor::addParallelConstraintTask):
(JSC::VerifierSlotVisitor::executeConstraintTasks):
(JSC::VerifierSlotVisitor::append):
(JSC::VerifierSlotVisitor::appendToMarkStack):
(JSC::VerifierSlotVisitor::appendUnbarriered):
(JSC::VerifierSlotVisitor::appendHiddenUnbarriered):
(JSC::VerifierSlotVisitor::drain):
(JSC::VerifierSlotVisitor::dumpMarkerData):
(JSC::VerifierSlotVisitor::isFirstVisit const):
(JSC::VerifierSlotVisitor::isMarked const):
(JSC::VerifierSlotVisitor::markAuxiliary):
(JSC::VerifierSlotVisitor::mutatorIsStopped const):
(JSC::VerifierSlotVisitor::testAndSetMarked):
(JSC::VerifierSlotVisitor::setMarkedAndAppendToMarkStack):
(JSC::VerifierSlotVisitor::visitAsConstraint):
(JSC::VerifierSlotVisitor::visitChildren):
* heap/VerifierSlotVisitor.h: Added.
(JSC::VerifierSlotVisitor::MarkedBlockData::block const):
(JSC::VerifierSlotVisitor::MarkedBlockData::atoms const):
(JSC::VerifierSlotVisitor::MarkedBlockData::isMarked):
(JSC::VerifierSlotVisitor::MarkedBlockData::testAndSetMarked):
(JSC::VerifierSlotVisitor::PreciseAllocationData::allocation const):
(JSC::VerifierSlotVisitor::appendSlow):
* heap/VerifierSlotVisitorInlines.h: Added.
(JSC::VerifierSlotVisitor::forEachLiveCell):
(JSC::VerifierSlotVisitor::forEachLivePreciseAllocation):
(JSC::VerifierSlotVisitor::forEachLiveMarkedBlockCell):
* heap/VisitCounter.h:
(JSC::VisitCounter::VisitCounter):
(JSC::VisitCounter::visitor const):
* heap/WeakBlock.cpp:
(JSC::WeakBlock::specializedVisit):
(JSC::WeakBlock::visitImpl):
(JSC::WeakBlock::visit):
* heap/WeakBlock.h:
* heap/WeakHandleOwner.cpp:
(JSC::WeakHandleOwner::isReachableFromOpaqueRoots):
* heap/WeakHandleOwner.h:
* heap/WeakSet.cpp:
* heap/WeakSet.h:
(JSC::WeakSet::visit):
* interpreter/ShadowChicken.cpp:
(JSC::ShadowChicken::visitChildren):
* interpreter/ShadowChicken.h:
* jit/GCAwareJITStubRoutine.cpp:
(JSC::MarkingGCAwareJITStubRoutine::markRequiredObjectsInternalImpl):
(JSC::MarkingGCAwareJITStubRoutine::markRequiredObjectsInternal):
(JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal): Deleted.
* jit/GCAwareJITStubRoutine.h:
(JSC::GCAwareJITStubRoutine::markRequiredObjects):
(JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal):
* jit/JITWorklist.cpp:
* jit/PolymorphicCallStubRoutine.cpp:
(JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternalImpl):
(JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal):
* jit/PolymorphicCallStubRoutine.h:
* runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::visitChildrenImpl):
(JSC::AbstractModuleRecord::visitChildren): Deleted.
* runtime/AbstractModuleRecord.h:
* runtime/ArgList.cpp:
(JSC::MarkedArgumentBuffer::markLists):
* runtime/ArgList.h:
* runtime/CacheableIdentifier.h:
* runtime/CacheableIdentifierInlines.h:
(JSC::CacheableIdentifier::visitAggregate const):
* runtime/ClassInfo.h:
(JSC::MethodTable::visitChildren const):
(JSC::MethodTable::visitOutputConstraints const):
* runtime/ClonedArguments.cpp:
(JSC::ClonedArguments::visitChildrenImpl):
(JSC::ClonedArguments::visitChildren): Deleted.
* runtime/ClonedArguments.h:
* runtime/DirectArguments.cpp:
(JSC::DirectArguments::visitChildrenImpl):
(JSC::DirectArguments::visitChildren): Deleted.
* runtime/DirectArguments.h:
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::visitChildrenImpl):
(JSC::EvalExecutable::visitChildren): Deleted.
* runtime/EvalExecutable.h:
* runtime/Exception.cpp:
(JSC::Exception::visitChildrenImpl):
(JSC::Exception::visitChildren): Deleted.
* runtime/Exception.h:
* runtime/FunctionExecutable.cpp:
(JSC::FunctionExecutable::visitChildrenImpl):
(JSC::FunctionExecutable::visitChildren): Deleted.
* runtime/FunctionExecutable.h:
* runtime/FunctionRareData.cpp:
(JSC::FunctionRareData::visitChildrenImpl):
(JSC::FunctionRareData::visitChildren): Deleted.
* runtime/FunctionRareData.h:
* runtime/GenericArguments.h:
* runtime/GenericArgumentsInlines.h:
(JSC::GenericArguments<Type>::visitChildrenImpl):
(JSC::GenericArguments<Type>::visitChildren): Deleted.
* runtime/GetterSetter.cpp:
(JSC::GetterSetter::visitChildrenImpl):
(JSC::GetterSetter::visitChildren): Deleted.
* runtime/GetterSetter.h:
* runtime/HashMapImpl.cpp:
(JSC::HashMapBucket<Data>::visitChildrenImpl):
(JSC::HashMapImpl<HashMapBucket>::visitChildrenImpl):
(JSC::HashMapBucket<Data>::visitChildren): Deleted.
(JSC::HashMapImpl<HashMapBucket>::visitChildren): Deleted.
* runtime/HashMapImpl.h:
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::visitChildrenImpl):
(JSC::InternalFunction::visitChildren): Deleted.
* runtime/InternalFunction.h:
* runtime/IntlCollator.cpp:
(JSC::IntlCollator::visitChildrenImpl):
(JSC::IntlCollator::visitChildren): Deleted.
* runtime/IntlCollator.h:
* runtime/IntlDateTimeFormat.cpp:
(JSC::IntlDateTimeFormat::visitChildrenImpl):
(JSC::IntlDateTimeFormat::visitChildren): Deleted.
* runtime/IntlDateTimeFormat.h:
* runtime/IntlLocale.cpp:
(JSC::IntlLocale::visitChildrenImpl):
(JSC::IntlLocale::visitChildren): Deleted.
* runtime/IntlLocale.h:
* runtime/IntlNumberFormat.cpp:
(JSC::IntlNumberFormat::visitChildrenImpl):
(JSC::IntlNumberFormat::visitChildren): Deleted.
* runtime/IntlNumberFormat.h:
* runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::visitChildrenImpl):
(JSC::IntlPluralRules::visitChildren): Deleted.
* runtime/IntlPluralRules.h:
* runtime/IntlRelativeTimeFormat.cpp:
(JSC::IntlRelativeTimeFormat::visitChildrenImpl):
(JSC::IntlRelativeTimeFormat::visitChildren): Deleted.
* runtime/IntlRelativeTimeFormat.h:
* runtime/IntlSegmentIterator.cpp:
(JSC::IntlSegmentIterator::visitChildrenImpl):
(JSC::IntlSegmentIterator::visitChildren): Deleted.
* runtime/IntlSegmentIterator.h:
* runtime/IntlSegments.cpp:
(JSC::IntlSegments::visitChildrenImpl):
(JSC::IntlSegments::visitChildren): Deleted.
* runtime/IntlSegments.h:
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::visitChildrenImpl):
(JSC::JSArrayBufferView::visitChildren): Deleted.
* runtime/JSArrayBufferView.h:
* runtime/JSArrayIterator.cpp:
(JSC::JSArrayIterator::visitChildrenImpl):
(JSC::JSArrayIterator::visitChildren): Deleted.
* runtime/JSArrayIterator.h:
* runtime/JSAsyncGenerator.cpp:
(JSC::JSAsyncGenerator::visitChildrenImpl):
(JSC::JSAsyncGenerator::visitChildren): Deleted.
* runtime/JSAsyncGenerator.h:
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::visitChildrenImpl):
(JSC::JSBigInt::visitChildren): Deleted.
* runtime/JSBigInt.h:
* runtime/JSBoundFunction.cpp:
(JSC::JSBoundFunction::visitChildrenImpl):
(JSC::JSBoundFunction::visitChildren): Deleted.
* runtime/JSBoundFunction.h:
* runtime/JSCallee.cpp:
(JSC::JSCallee::visitChildrenImpl):
(JSC::JSCallee::visitChildren): Deleted.
* runtime/JSCallee.h:
* runtime/JSCell.h:
* runtime/JSCellInlines.h:
(JSC::JSCell::visitChildrenImpl):
(JSC::JSCell::visitOutputConstraintsImpl):
(JSC::JSCell::visitChildren): Deleted.
(JSC::JSCell::visitOutputConstraints): Deleted.
* runtime/JSFinalizationRegistry.cpp:
(JSC::JSFinalizationRegistry::visitChildrenImpl):
(JSC::JSFinalizationRegistry::visitChildren): Deleted.
* runtime/JSFinalizationRegistry.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::visitChildrenImpl):
(JSC::JSFunction::visitChildren): Deleted.
* runtime/JSFunction.h:
* runtime/JSGenerator.cpp:
(JSC::JSGenerator::visitChildrenImpl):
(JSC::JSGenerator::visitChildren): Deleted.
* runtime/JSGenerator.h:
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::visitChildrenImpl):
(JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): Deleted.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::visitChildrenImpl):
(JSC::JSGlobalObject::visitChildren): Deleted.
* runtime/JSGlobalObject.h:
* runtime/JSImmutableButterfly.cpp:
(JSC::JSImmutableButterfly::visitChildrenImpl):
(JSC::JSImmutableButterfly::visitChildren): Deleted.
* runtime/JSImmutableButterfly.h:
* runtime/JSInternalFieldObjectImpl.h:
* runtime/JSInternalFieldObjectImplInlines.h:
(JSC::JSInternalFieldObjectImpl<passedNumberOfInternalFields>::visitChildrenImpl):
(JSC::JSInternalFieldObjectImpl<passedNumberOfInternalFields>::visitChildren): Deleted.
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::visitChildrenImpl):
(JSC::JSLexicalEnvironment::visitChildren): Deleted.
* runtime/JSLexicalEnvironment.h:
* runtime/JSMapIterator.cpp:
(JSC::JSMapIterator::visitChildrenImpl):
(JSC::JSMapIterator::visitChildren): Deleted.
* runtime/JSMapIterator.h:
* runtime/JSModuleEnvironment.cpp:
(JSC::JSModuleEnvironment::visitChildrenImpl):
(JSC::JSModuleEnvironment::visitChildren): Deleted.
* runtime/JSModuleEnvironment.h:
* runtime/JSModuleNamespaceObject.cpp:
(JSC::JSModuleNamespaceObject::visitChildrenImpl):
(JSC::JSModuleNamespaceObject::visitChildren): Deleted.
* runtime/JSModuleNamespaceObject.h:
* runtime/JSModuleRecord.cpp:
(JSC::JSModuleRecord::visitChildrenImpl):
(JSC::JSModuleRecord::visitChildren): Deleted.
* runtime/JSModuleRecord.h:
* runtime/JSNativeStdFunction.cpp:
(JSC::JSNativeStdFunction::visitChildrenImpl):
(JSC::JSNativeStdFunction::visitChildren): Deleted.
* runtime/JSNativeStdFunction.h:
* runtime/JSObject.cpp:
(JSC::JSObject::markAuxiliaryAndVisitOutOfLineProperties):
(JSC::JSObject::visitButterfly):
(JSC::JSObject::visitButterflyImpl):
(JSC::JSObject::visitChildrenImpl):
(JSC::JSFinalObject::visitChildrenImpl):
(JSC::JSObject::visitChildren): Deleted.
(JSC::JSFinalObject::visitChildren): Deleted.
* runtime/JSObject.h:
* runtime/JSPromise.cpp:
(JSC::JSPromise::visitChildrenImpl):
(JSC::JSPromise::visitChildren): Deleted.
* runtime/JSPromise.h:
* runtime/JSPropertyNameEnumerator.cpp:
(JSC::JSPropertyNameEnumerator::visitChildrenImpl):
(JSC::JSPropertyNameEnumerator::visitChildren): Deleted.
* runtime/JSPropertyNameEnumerator.h:
* runtime/JSProxy.cpp:
(JSC::JSProxy::visitChildrenImpl):
(JSC::JSProxy::visitChildren): Deleted.
* runtime/JSProxy.h:
* runtime/JSScope.cpp:
(JSC::JSScope::visitChildrenImpl):
(JSC::JSScope::visitChildren): Deleted.
* runtime/JSScope.h:
* runtime/JSSegmentedVariableObject.cpp:
(JSC::JSSegmentedVariableObject::visitChildrenImpl):
(JSC::JSSegmentedVariableObject::visitChildren): Deleted.
* runtime/JSSegmentedVariableObject.h:
* runtime/JSSetIterator.cpp:
(JSC::JSSetIterator::visitChildrenImpl):
(JSC::JSSetIterator::visitChildren): Deleted.
* runtime/JSSetIterator.h:
* runtime/JSString.cpp:
(JSC::JSString::visitChildrenImpl):
(JSC::JSString::visitChildren): Deleted.
* runtime/JSString.h:
* runtime/JSStringIterator.cpp:
(JSC::JSStringIterator::visitChildrenImpl):
(JSC::JSStringIterator::visitChildren): Deleted.
* runtime/JSStringIterator.h:
* runtime/JSSymbolTableObject.cpp:
(JSC::JSSymbolTableObject::visitChildrenImpl):
(JSC::JSSymbolTableObject::visitChildren): Deleted.
* runtime/JSSymbolTableObject.h:
* runtime/JSWeakObjectRef.cpp:
(JSC::JSWeakObjectRef::visitChildrenImpl):
(JSC::JSWeakObjectRef::visitChildren): Deleted.
* runtime/JSWeakObjectRef.h:
* runtime/JSWithScope.cpp:
(JSC::JSWithScope::visitChildrenImpl):
(JSC::JSWithScope::visitChildren): Deleted.
* runtime/JSWithScope.h:
* runtime/JSWrapperObject.cpp:
(JSC::JSWrapperObject::visitChildrenImpl):
(JSC::JSWrapperObject::visitChildren): Deleted.
* runtime/JSWrapperObject.h:
* runtime/LazyClassStructure.cpp:
(JSC::LazyClassStructure::visit):
* runtime/LazyClassStructure.h:
* runtime/LazyProperty.h:
* runtime/LazyPropertyInlines.h:
(JSC::ElementType>::visit):
* runtime/ModuleProgramExecutable.cpp:
(JSC::ModuleProgramExecutable::visitChildrenImpl):
(JSC::ModuleProgramExecutable::visitChildren): Deleted.
* runtime/ModuleProgramExecutable.h:
* runtime/Options.cpp:
(JSC::Options::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::visitChildrenImpl):
(JSC::ProgramExecutable::visitChildren): Deleted.
* runtime/ProgramExecutable.h:
* runtime/PropertyMapHashTable.h:
* runtime/PropertyTable.cpp:
(JSC::PropertyTable::visitChildrenImpl):
(JSC::PropertyTable::visitChildren): Deleted.
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::visitChildrenImpl):
(JSC::ProxyObject::visitChildren): Deleted.
* runtime/ProxyObject.h:
* runtime/ProxyRevoke.cpp:
(JSC::ProxyRevoke::visitChildrenImpl):
(JSC::ProxyRevoke::visitChildren): Deleted.
* runtime/ProxyRevoke.h:
* runtime/RegExpCachedResult.cpp:
(JSC::RegExpCachedResult::visitAggregateImpl):
(JSC::RegExpCachedResult::visitAggregate): Deleted.
* runtime/RegExpCachedResult.h:
* runtime/RegExpGlobalData.cpp:
(JSC::RegExpGlobalData::visitAggregateImpl):
(JSC::RegExpGlobalData::visitAggregate): Deleted.
* runtime/RegExpGlobalData.h:
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::visitChildrenImpl):
(JSC::RegExpObject::visitChildren): Deleted.
* runtime/RegExpObject.h:
* runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::visit):
* runtime/SamplingProfiler.h:
* runtime/ScopedArguments.cpp:
(JSC::ScopedArguments::visitChildrenImpl):
(JSC::ScopedArguments::visitChildren): Deleted.
* runtime/ScopedArguments.h:
* runtime/SimpleTypedArrayController.cpp:
(JSC::SimpleTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):
* runtime/SimpleTypedArrayController.h:
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::visitStrongReferences):
* runtime/SmallStrings.h:
* runtime/SparseArrayValueMap.cpp:
(JSC::SparseArrayValueMap::visitChildrenImpl):
(JSC::SparseArrayValueMap::visitChildren): Deleted.
* runtime/SparseArrayValueMap.h:
* runtime/StackFrame.cpp:
(JSC::StackFrame::visitChildren): Deleted.
* runtime/StackFrame.h:
(JSC::StackFrame::visitChildren):
* runtime/Structure.cpp:
(JSC::Structure::visitChildrenImpl):
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::markIfCheap):
(JSC::Structure::visitChildren): Deleted.
* runtime/Structure.h:
* runtime/StructureChain.cpp:
(JSC::StructureChain::visitChildrenImpl):
(JSC::StructureChain::visitChildren): Deleted.
* runtime/StructureChain.h:
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::visitChildrenImpl):
(JSC::StructureRareData::visitChildren): Deleted.
* runtime/StructureRareData.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::visitChildrenImpl):
(JSC::SymbolTable::visitChildren): Deleted.
* runtime/SymbolTable.h:
* runtime/TypeProfilerLog.cpp:
(JSC::TypeProfilerLog::visit):
* runtime/TypeProfilerLog.h:
* runtime/VM.h:
(JSC::VM::isAnalyzingHeap const):
(JSC::VM::activeHeapAnalyzer const):
(JSC::VM::setActiveHeapAnalyzer):
* runtime/WeakMapImpl.cpp:
(JSC::WeakMapImpl<WeakMapBucket>::visitChildrenImpl):
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKey>>::visitOutputConstraints):
(JSC::WeakMapImpl<BucketType>::visitOutputConstraints):
(JSC::WeakMapImpl<WeakMapBucket>::visitChildren): Deleted.
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitOutputConstraints): Deleted.
* runtime/WeakMapImpl.h:
(JSC::WeakMapBucket::visitAggregate):
* tools/JSDollarVM.cpp:
(JSC::JSDollarVM::visitChildrenImpl):
(JSC::JSDollarVM::visitChildren): Deleted.
* tools/JSDollarVM.h:
* wasm/WasmGlobal.cpp:
(JSC::Wasm::Global::visitAggregateImpl):
(JSC::Wasm::Global::visitAggregate): Deleted.
* wasm/WasmGlobal.h:
* wasm/WasmTable.cpp:
(JSC::Wasm::Table::visitAggregateImpl):
(JSC::Wasm::Table::visitAggregate): Deleted.
* wasm/WasmTable.h:
* wasm/js/JSToWasmICCallee.cpp:
(JSC::JSToWasmICCallee::visitChildrenImpl):
(JSC::JSToWasmICCallee::visitChildren): Deleted.
* wasm/js/JSToWasmICCallee.h:
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::visitChildrenImpl):
(JSC::JSWebAssemblyCodeBlock::visitChildren): Deleted.
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyGlobal.cpp:
(JSC::JSWebAssemblyGlobal::visitChildrenImpl):
(JSC::JSWebAssemblyGlobal::visitChildren): Deleted.
* wasm/js/JSWebAssemblyGlobal.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::visitChildrenImpl):
(JSC::JSWebAssemblyInstance::visitChildren): Deleted.
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::visitChildrenImpl):
(JSC::JSWebAssemblyMemory::visitChildren): Deleted.
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::visitChildrenImpl):
(JSC::JSWebAssemblyModule::visitChildren): Deleted.
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::visitChildrenImpl):
(JSC::JSWebAssemblyTable::visitChildren): Deleted.
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::visitChildrenImpl):
(JSC::WebAssemblyFunction::visitChildren): Deleted.
* wasm/js/WebAssemblyFunction.h:
* wasm/js/WebAssemblyFunctionBase.cpp:
(JSC::WebAssemblyFunctionBase::visitChildrenImpl):
(JSC::WebAssemblyFunctionBase::visitChildren): Deleted.
* wasm/js/WebAssemblyFunctionBase.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::visitChildrenImpl):
(JSC::WebAssemblyModuleRecord::visitChildren): Deleted.
* wasm/js/WebAssemblyModuleRecord.h:
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::visitChildrenImpl):
(JSC::WebAssemblyWrapperFunction::visitChildren): Deleted.
* wasm/js/WebAssemblyWrapperFunction.h:
Source/WebCore:
1. Added support for the GC verifier.
2. Also removed NodeFilterCondition::visitAggregate() because it is not used.
3. Rebased bindings test results.
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::visitReferencedIndexes const):
* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::visitReferencedObjectStores const):
* Modules/indexeddb/IDBTransaction.h:
* Modules/webaudio/AudioBuffer.cpp:
(WebCore::AudioBuffer::visitChannelWrappers):
* Modules/webaudio/AudioBuffer.h:
* bindings/js/DOMGCOutputConstraint.cpp:
(WebCore::DOMGCOutputConstraint::executeImplImpl):
(WebCore::DOMGCOutputConstraint::executeImpl):
* bindings/js/DOMGCOutputConstraint.h:
* bindings/js/JSAbortControllerCustom.cpp:
(WebCore::JSAbortController::visitAdditionalChildren):
* bindings/js/JSAbortSignalCustom.cpp:
(WebCore::JSAbortSignalOwner::isReachableFromOpaqueRoots):
* bindings/js/JSAttrCustom.cpp:
(WebCore::JSAttr::visitAdditionalChildren):
* bindings/js/JSAudioBufferCustom.cpp:
(WebCore::JSAudioBuffer::visitAdditionalChildren):
* bindings/js/JSAudioTrackCustom.cpp:
(WebCore::JSAudioTrack::visitAdditionalChildren):
* bindings/js/JSAudioTrackListCustom.cpp:
(WebCore::JSAudioTrackList::visitAdditionalChildren):
* bindings/js/JSAudioWorkletProcessorCustom.cpp:
(WebCore::JSAudioWorkletProcessor::visitAdditionalChildren):
* bindings/js/JSCSSRuleCustom.cpp:
(WebCore::JSCSSRule::visitAdditionalChildren):
* bindings/js/JSCSSRuleListCustom.cpp:
(WebCore::JSCSSRuleListOwner::isReachableFromOpaqueRoots):
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(WebCore::JSCSSStyleDeclaration::visitAdditionalChildren):
* bindings/js/JSCallbackData.cpp:
(WebCore::JSCallbackDataWeak::visitJSFunction):
(WebCore::JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots):
* bindings/js/JSCallbackData.h:
* bindings/js/JSCanvasRenderingContext2DCustom.cpp:
(WebCore::JSCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):
(WebCore::JSCanvasRenderingContext2D::visitAdditionalChildren):
* bindings/js/JSCustomEventCustom.cpp:
(WebCore::JSCustomEvent::visitAdditionalChildren):
* bindings/js/JSDOMBuiltinConstructorBase.cpp:
(WebCore::JSDOMBuiltinConstructorBase::visitChildrenImpl):
(WebCore::JSDOMBuiltinConstructorBase::visitChildren): Deleted.
* bindings/js/JSDOMBuiltinConstructorBase.h:
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::visitChildrenImpl):
(WebCore::JSDOMGlobalObject::visitChildren): Deleted.
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMGuardedObject.h:
* bindings/js/JSDOMQuadCustom.cpp:
(WebCore::JSDOMQuad::visitAdditionalChildren):
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::visitAdditionalChildren):
* bindings/js/JSDeprecatedCSSOMValueCustom.cpp:
(WebCore::JSDeprecatedCSSOMValueOwner::isReachableFromOpaqueRoots):
* bindings/js/JSDocumentCustom.cpp:
(WebCore::JSDocument::visitAdditionalChildren):
* bindings/js/JSErrorEventCustom.cpp:
(WebCore::JSErrorEvent::visitAdditionalChildren):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::visitJSFunctionImpl):
(WebCore::JSEventListener::visitJSFunction):
* bindings/js/JSEventListener.h:
* bindings/js/JSEventTargetCustom.cpp:
(WebCore::JSEventTarget::visitAdditionalChildren):
* bindings/js/JSFetchEventCustom.cpp:
(WebCore::JSFetchEvent::visitAdditionalChildren):
* bindings/js/JSHTMLCanvasElementCustom.cpp:
(WebCore::JSHTMLCanvasElement::visitAdditionalChildren):
* bindings/js/JSHTMLTemplateElementCustom.cpp:
(WebCore::JSHTMLTemplateElement::visitAdditionalChildren):
* bindings/js/JSHistoryCustom.cpp:
(WebCore::JSHistory::visitAdditionalChildren):
* bindings/js/JSIDBCursorCustom.cpp:
(WebCore::JSIDBCursor::visitAdditionalChildren):
* bindings/js/JSIDBCursorWithValueCustom.cpp:
(WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
* bindings/js/JSIDBIndexCustom.cpp:
(WebCore::JSIDBIndex::visitAdditionalChildren):
* bindings/js/JSIDBObjectStoreCustom.cpp:
(WebCore::JSIDBObjectStore::visitAdditionalChildren):
* bindings/js/JSIDBRequestCustom.cpp:
(WebCore::JSIDBRequest::visitAdditionalChildren):
* bindings/js/JSIDBTransactionCustom.cpp:
(WebCore::JSIDBTransaction::visitAdditionalChildren):
* bindings/js/JSIntersectionObserverCustom.cpp:
(WebCore::JSIntersectionObserver::visitAdditionalChildren):
* bindings/js/JSIntersectionObserverEntryCustom.cpp:
(WebCore::JSIntersectionObserverEntry::visitAdditionalChildren):
* bindings/js/JSMessageChannelCustom.cpp:
(WebCore::JSMessageChannel::visitAdditionalChildren):
* bindings/js/JSMessageEventCustom.cpp:
(WebCore::JSMessageEvent::visitAdditionalChildren):
* bindings/js/JSMessagePortCustom.cpp:
(WebCore::JSMessagePort::visitAdditionalChildren):
* bindings/js/JSMutationObserverCustom.cpp:
(WebCore::JSMutationObserver::visitAdditionalChildren):
(WebCore::JSMutationObserverOwner::isReachableFromOpaqueRoots):
* bindings/js/JSMutationRecordCustom.cpp:
(WebCore::JSMutationRecord::visitAdditionalChildren):
* bindings/js/JSNavigatorCustom.cpp:
(WebCore::JSNavigator::visitAdditionalChildren):
* bindings/js/JSNodeCustom.cpp:
(WebCore::isReachableFromDOM):
(WebCore::JSNodeOwner::isReachableFromOpaqueRoots):
(WebCore::JSNode::visitAdditionalChildren):
* bindings/js/JSNodeIteratorCustom.cpp:
(WebCore::JSNodeIterator::visitAdditionalChildren):
* bindings/js/JSNodeListCustom.cpp:
(WebCore::JSNodeListOwner::isReachableFromOpaqueRoots):
* bindings/js/JSOffscreenCanvasRenderingContext2DCustom.cpp:
(WebCore::JSOffscreenCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):
(WebCore::JSOffscreenCanvasRenderingContext2D::visitAdditionalChildren):
* bindings/js/JSPaintRenderingContext2DCustom.cpp:
(WebCore::JSPaintRenderingContext2DOwner::isReachableFromOpaqueRoots):
(WebCore::JSPaintRenderingContext2D::visitAdditionalChildren):
* bindings/js/JSPaintWorkletGlobalScopeCustom.cpp:
(WebCore::JSPaintWorkletGlobalScope::visitAdditionalChildren):
* bindings/js/JSPaymentMethodChangeEventCustom.cpp:
(WebCore::JSPaymentMethodChangeEvent::visitAdditionalChildren):
* bindings/js/JSPaymentResponseCustom.cpp:
(WebCore::JSPaymentResponse::visitAdditionalChildren):
* bindings/js/JSPerformanceObserverCustom.cpp:
(WebCore::JSPerformanceObserver::visitAdditionalChildren):
(WebCore::JSPerformanceObserverOwner::isReachableFromOpaqueRoots):
* bindings/js/JSPopStateEventCustom.cpp:
(WebCore::JSPopStateEvent::visitAdditionalChildren):
* bindings/js/JSPromiseRejectionEventCustom.cpp:
(WebCore::JSPromiseRejectionEvent::visitAdditionalChildren):
* bindings/js/JSResizeObserverCustom.cpp:
(WebCore::JSResizeObserver::visitAdditionalChildren):
* bindings/js/JSResizeObserverEntryCustom.cpp:
(WebCore::JSResizeObserverEntry::visitAdditionalChildren):
* bindings/js/JSSVGViewSpecCustom.cpp:
(WebCore::JSSVGViewSpec::visitAdditionalChildren):
* bindings/js/JSServiceWorkerGlobalScopeCustom.cpp:
(WebCore::JSServiceWorkerGlobalScope::visitAdditionalChildren):
* bindings/js/JSStaticRangeCustom.cpp:
(WebCore::JSStaticRange::visitAdditionalChildren):
* bindings/js/JSStyleSheetCustom.cpp:
(WebCore::JSStyleSheet::visitAdditionalChildren):
* bindings/js/JSTextTrackCueCustom.cpp:
(WebCore::JSTextTrackCueOwner::isReachableFromOpaqueRoots):
(WebCore::JSTextTrackCue::visitAdditionalChildren):
* bindings/js/JSTextTrackCustom.cpp:
(WebCore::JSTextTrack::visitAdditionalChildren):
* bindings/js/JSTextTrackListCustom.cpp:
(WebCore::JSTextTrackList::visitAdditionalChildren):
* bindings/js/JSTreeWalkerCustom.cpp:
(WebCore::JSTreeWalker::visitAdditionalChildren):
* bindings/js/JSUndoItemCustom.cpp:
(WebCore::JSUndoItem::visitAdditionalChildren):
(WebCore::JSUndoItemOwner::isReachableFromOpaqueRoots):
* bindings/js/JSValueInWrappedObject.h:
(WebCore::JSValueInWrappedObject::visit const):
* bindings/js/JSVideoTrackCustom.cpp:
(WebCore::JSVideoTrack::visitAdditionalChildren):
* bindings/js/JSVideoTrackListCustom.cpp:
(WebCore::JSVideoTrackList::visitAdditionalChildren):
* bindings/js/JSWebGL2RenderingContextCustom.cpp:
(WebCore::JSWebGL2RenderingContext::visitAdditionalChildren):
* bindings/js/JSWebGLRenderingContextCustom.cpp:
(WebCore::JSWebGLRenderingContext::visitAdditionalChildren):
* bindings/js/JSWorkerGlobalScopeBase.cpp:
(WebCore::JSWorkerGlobalScopeBase::visitChildrenImpl):
(WebCore::JSWorkerGlobalScopeBase::visitChildren): Deleted.
* bindings/js/JSWorkerGlobalScopeBase.h:
* bindings/js/JSWorkerGlobalScopeCustom.cpp:
(WebCore::JSWorkerGlobalScope::visitAdditionalChildren):
* bindings/js/JSWorkerNavigatorCustom.cpp:
(WebCore::JSWorkerNavigator::visitAdditionalChildren):
* bindings/js/JSWorkletGlobalScopeBase.cpp:
(WebCore::JSWorkletGlobalScopeBase::visitChildrenImpl):
(WebCore::JSWorkletGlobalScopeBase::visitChildren): Deleted.
* bindings/js/JSWorkletGlobalScopeBase.h:
* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::visitAdditionalChildren):
* bindings/js/JSXPathResultCustom.cpp:
(WebCore::JSXPathResult::visitAdditionalChildren):
* bindings/js/WebCoreTypedArrayController.cpp:
(WebCore::WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):
* bindings/js/WebCoreTypedArrayController.h:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateImplementation):
(GenerateCallbackHeaderContent):
(GenerateCallbackImplementationContent):
(GenerateIterableDefinition):
* bindings/scripts/test/JS/JSDOMWindow.cpp:
(WebCore::JSDOMWindow::subspaceForImpl):
* bindings/scripts/test/JS/JSDedicatedWorkerGlobalScope.cpp:
(WebCore::JSDedicatedWorkerGlobalScope::subspaceForImpl):
* bindings/scripts/test/JS/JSExposedToWorkerAndWindow.cpp:
(WebCore::JSExposedToWorkerAndWindow::subspaceForImpl):
(WebCore::JSExposedToWorkerAndWindowOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSExposedToWorkerAndWindow.h:
* bindings/scripts/test/JS/JSPaintWorkletGlobalScope.cpp:
(WebCore::JSPaintWorkletGlobalScope::subspaceForImpl):
* bindings/scripts/test/JS/JSServiceWorkerGlobalScope.cpp:
(WebCore::JSServiceWorkerGlobalScope::subspaceForImpl):
* bindings/scripts/test/JS/JSTestCEReactions.cpp:
(WebCore::JSTestCEReactions::subspaceForImpl):
(WebCore::JSTestCEReactionsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestCEReactions.h:
* bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp:
(WebCore::JSTestCEReactionsStringifier::subspaceForImpl):
(WebCore::JSTestCEReactionsStringifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestCEReactionsStringifier.h:
* bindings/scripts/test/JS/JSTestCallTracer.cpp:
(WebCore::JSTestCallTracer::subspaceForImpl):
(WebCore::JSTestCallTracerOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestCallTracer.h:
* bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp:
(WebCore::JSTestClassWithJSBuiltinConstructor::subspaceForImpl):
(WebCore::JSTestClassWithJSBuiltinConstructorOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.h:
* bindings/scripts/test/JS/JSTestConditionalIncludes.cpp:
(WebCore::JSTestConditionalIncludes::subspaceForImpl):
(WebCore::JSTestConditionalIncludesOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestConditionalIncludes.h:
* bindings/scripts/test/JS/JSTestConditionallyReadWrite.cpp:
(WebCore::JSTestConditionallyReadWrite::subspaceForImpl):
(WebCore::JSTestConditionallyReadWriteOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestConditionallyReadWrite.h:
* bindings/scripts/test/JS/JSTestDOMJIT.cpp:
(WebCore::JSTestDOMJIT::subspaceForImpl):
* bindings/scripts/test/JS/JSTestDefaultToJSON.cpp:
(WebCore::JSTestDefaultToJSON::subspaceForImpl):
(WebCore::JSTestDefaultToJSONOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestDefaultToJSON.h:
* bindings/scripts/test/JS/JSTestDefaultToJSONFilteredByExposed.cpp:
(WebCore::JSTestDefaultToJSONFilteredByExposed::subspaceForImpl):
(WebCore::JSTestDefaultToJSONFilteredByExposedOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestDefaultToJSONFilteredByExposed.h:
* bindings/scripts/test/JS/JSTestDefaultToJSONIndirectInheritance.cpp:
(WebCore::JSTestDefaultToJSONIndirectInheritance::subspaceForImpl):
* bindings/scripts/test/JS/JSTestDefaultToJSONInherit.cpp:
(WebCore::JSTestDefaultToJSONInherit::subspaceForImpl):
* bindings/scripts/test/JS/JSTestDefaultToJSONInheritFinal.cpp:
(WebCore::JSTestDefaultToJSONInheritFinal::subspaceForImpl):
* bindings/scripts/test/JS/JSTestDomainSecurity.cpp:
(WebCore::JSTestDomainSecurity::subspaceForImpl):
(WebCore::JSTestDomainSecurityOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestDomainSecurity.h:
* bindings/scripts/test/JS/JSTestEnabledBySetting.cpp:
(WebCore::JSTestEnabledBySetting::subspaceForImpl):
(WebCore::JSTestEnabledBySettingOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestEnabledBySetting.h:
* bindings/scripts/test/JS/JSTestEnabledForContext.cpp:
(WebCore::JSTestEnabledForContext::subspaceForImpl):
(WebCore::JSTestEnabledForContextOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestEnabledForContext.h:
* bindings/scripts/test/JS/JSTestEventConstructor.cpp:
(WebCore::JSTestEventConstructor::subspaceForImpl):
* bindings/scripts/test/JS/JSTestEventTarget.cpp:
(WebCore::JSTestEventTarget::subspaceForImpl):
* bindings/scripts/test/JS/JSTestException.cpp:
(WebCore::JSTestException::subspaceForImpl):
(WebCore::JSTestExceptionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestException.h:
* bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:
(WebCore::JSTestGenerateIsReachable::subspaceForImpl):
(WebCore::JSTestGenerateIsReachableOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestGenerateIsReachable.h:
* bindings/scripts/test/JS/JSTestGlobalObject.cpp:
(WebCore::JSTestGlobalObject::subspaceForImpl):
(WebCore::JSTestGlobalObjectOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestGlobalObject.h:
* bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp:
(WebCore::JSTestIndexedSetterNoIdentifier::subspaceForImpl):
(WebCore::JSTestIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.h:
* bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp:
(WebCore::JSTestIndexedSetterThrowingException::subspaceForImpl):
(WebCore::JSTestIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.h:
* bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp:
(WebCore::JSTestIndexedSetterWithIdentifier::subspaceForImpl):
(WebCore::JSTestIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.h:
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::jsTestInterfacePrototypeFunction_entriesCaller):
(WebCore::JSTestInterface::subspaceForImpl):
(WebCore::JSTestInterfaceOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestInterface.h:
* bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp:
(WebCore::JSTestInterfaceLeadingUnderscore::subspaceForImpl):
(WebCore::JSTestInterfaceLeadingUnderscoreOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.h:
* bindings/scripts/test/JS/JSTestIterable.cpp:
(WebCore::jsTestIterablePrototypeFunction_entriesCaller):
(WebCore::JSTestIterable::subspaceForImpl):
(WebCore::JSTestIterableOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestIterable.h:
* bindings/scripts/test/JS/JSTestJSBuiltinConstructor.cpp:
(WebCore::JSTestJSBuiltinConstructor::subspaceForImpl):
* bindings/scripts/test/JS/JSTestLegacyFactoryFunction.cpp:
(WebCore::JSTestLegacyFactoryFunction::subspaceForImpl):
(WebCore::JSTestLegacyFactoryFunctionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestLegacyFactoryFunction.h:
* bindings/scripts/test/JS/JSTestLegacyNoInterfaceObject.cpp:
(WebCore::JSTestLegacyNoInterfaceObject::subspaceForImpl):
(WebCore::JSTestLegacyNoInterfaceObjectOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestLegacyNoInterfaceObject.h:
* bindings/scripts/test/JS/JSTestLegacyOverrideBuiltIns.cpp:
(WebCore::JSTestLegacyOverrideBuiltIns::subspaceForImpl):
(WebCore::JSTestLegacyOverrideBuiltInsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestLegacyOverrideBuiltIns.h:
* bindings/scripts/test/JS/JSTestMapLike.cpp:
(WebCore::JSTestMapLike::subspaceForImpl):
(WebCore::JSTestMapLikeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestMapLike.h:
* bindings/scripts/test/JS/JSTestMapLikeWithOverriddenOperations.cpp:
(WebCore::JSTestMapLikeWithOverriddenOperations::subspaceForImpl):
(WebCore::JSTestMapLikeWithOverriddenOperationsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestMapLikeWithOverriddenOperations.h:
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:
(WebCore::JSTestNamedAndIndexedSetterNoIdentifier::subspaceForImpl):
(WebCore::JSTestNamedAndIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:
(WebCore::JSTestNamedAndIndexedSetterThrowingException::subspaceForImpl):
(WebCore::JSTestNamedAndIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.h:
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:
(WebCore::JSTestNamedAndIndexedSetterWithIdentifier::subspaceForImpl):
(WebCore::JSTestNamedAndIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp:
(WebCore::JSTestNamedDeleterNoIdentifier::subspaceForImpl):
(WebCore::JSTestNamedDeleterNoIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp:
(WebCore::JSTestNamedDeleterThrowingException::subspaceForImpl):
(WebCore::JSTestNamedDeleterThrowingExceptionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.h:
* bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp:
(WebCore::JSTestNamedDeleterWithIdentifier::subspaceForImpl):
(WebCore::JSTestNamedDeleterWithIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp:
(WebCore::JSTestNamedDeleterWithIndexedGetter::subspaceForImpl):
(WebCore::JSTestNamedDeleterWithIndexedGetterOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.h:
* bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp:
(WebCore::JSTestNamedGetterCallWith::subspaceForImpl):
(WebCore::JSTestNamedGetterCallWithOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedGetterCallWith.h:
* bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp:
(WebCore::JSTestNamedGetterNoIdentifier::subspaceForImpl):
(WebCore::JSTestNamedGetterNoIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp:
(WebCore::JSTestNamedGetterWithIdentifier::subspaceForImpl):
(WebCore::JSTestNamedGetterWithIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:
(WebCore::JSTestNamedSetterNoIdentifier::subspaceForImpl):
(WebCore::JSTestNamedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:
(WebCore::JSTestNamedSetterThrowingException::subspaceForImpl):
(WebCore::JSTestNamedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterThrowingException.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:
(WebCore::JSTestNamedSetterWithIdentifier::subspaceForImpl):
(WebCore::JSTestNamedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:
(WebCore::JSTestNamedSetterWithIndexedGetter::subspaceForImpl):
(WebCore::JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:
(WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::subspaceForImpl):
(WebCore::JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyOverrideBuiltIns.cpp:
(WebCore::JSTestNamedSetterWithLegacyOverrideBuiltIns::subspaceForImpl):
(WebCore::JSTestNamedSetterWithLegacyOverrideBuiltInsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyOverrideBuiltIns.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeableProperties.cpp:
(WebCore::JSTestNamedSetterWithLegacyUnforgeableProperties::subspaceForImpl):
(WebCore::JSTestNamedSetterWithLegacyUnforgeablePropertiesOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeableProperties.h:
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeablePropertiesAndLegacyOverrideBuiltIns.cpp:
(WebCore::JSTestNamedSetterWithLegacyUnforgeablePropertiesAndLegacyOverrideBuiltIns::subspaceForImpl):
(WebCore::JSTestNamedSetterWithLegacyUnforgeablePropertiesAndLegacyOverrideBuiltInsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeablePropertiesAndLegacyOverrideBuiltIns.h:
* bindings/scripts/test/JS/JSTestNode.cpp:
(WebCore::jsTestNodePrototypeFunction_entriesCaller):
(WebCore::JSTestNode::subspaceForImpl):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObj::subspaceForImpl):
(WebCore::JSTestObj::visitChildrenImpl):
(WebCore::JSTestObjOwner::isReachableFromOpaqueRoots):
(WebCore::JSTestObj::visitChildren): Deleted.
* bindings/scripts/test/JS/JSTestObj.h:
* bindings/scripts/test/JS/JSTestOperationConditional.cpp:
(WebCore::JSTestOperationConditional::subspaceForImpl):
(WebCore::JSTestOperationConditionalOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestOperationConditional.h:
* bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
(WebCore::JSTestOverloadedConstructors::subspaceForImpl):
(WebCore::JSTestOverloadedConstructorsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestOverloadedConstructors.h:
* bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp:
(WebCore::JSTestOverloadedConstructorsWithSequence::subspaceForImpl):
(WebCore::JSTestOverloadedConstructorsWithSequenceOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.h:
* bindings/scripts/test/JS/JSTestPluginInterface.cpp:
(WebCore::JSTestPluginInterface::subspaceForImpl):
(WebCore::JSTestPluginInterfaceOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestPluginInterface.h:
* bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp:
(WebCore::JSTestPromiseRejectionEvent::subspaceForImpl):
* bindings/scripts/test/JS/JSTestReadOnlyMapLike.cpp:
(WebCore::JSTestReadOnlyMapLike::subspaceForImpl):
(WebCore::JSTestReadOnlyMapLikeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestReadOnlyMapLike.h:
* bindings/scripts/test/JS/JSTestReadOnlySetLike.cpp:
(WebCore::JSTestReadOnlySetLike::subspaceForImpl):
(WebCore::JSTestReadOnlySetLikeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestReadOnlySetLike.h:
* bindings/scripts/test/JS/JSTestReportExtraMemoryCost.cpp:
(WebCore::JSTestReportExtraMemoryCost::subspaceForImpl):
(WebCore::JSTestReportExtraMemoryCost::visitChildrenImpl):
(WebCore::JSTestReportExtraMemoryCostOwner::isReachableFromOpaqueRoots):
(WebCore::JSTestReportExtraMemoryCost::visitChildren): Deleted.
* bindings/scripts/test/JS/JSTestReportExtraMemoryCost.h:
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::JSTestSerializedScriptValueInterface::subspaceForImpl):
(WebCore::JSTestSerializedScriptValueInterface::visitChildrenImpl):
(WebCore::JSTestSerializedScriptValueInterfaceOwner::isReachableFromOpaqueRoots):
(WebCore::JSTestSerializedScriptValueInterface::visitChildren): Deleted.
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h:
* bindings/scripts/test/JS/JSTestSetLike.cpp:
(WebCore::JSTestSetLike::subspaceForImpl):
(WebCore::JSTestSetLikeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestSetLike.h:
* bindings/scripts/test/JS/JSTestSetLikeWithOverriddenOperations.cpp:
(WebCore::JSTestSetLikeWithOverriddenOperations::subspaceForImpl):
(WebCore::JSTestSetLikeWithOverriddenOperationsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestSetLikeWithOverriddenOperations.h:
* bindings/scripts/test/JS/JSTestStringifier.cpp:
(WebCore::JSTestStringifier::subspaceForImpl):
(WebCore::JSTestStringifierOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifier.h:
* bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp:
(WebCore::JSTestStringifierAnonymousOperation::subspaceForImpl):
(WebCore::JSTestStringifierAnonymousOperationOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.h:
* bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp:
(WebCore::JSTestStringifierNamedOperation::subspaceForImpl):
(WebCore::JSTestStringifierNamedOperationOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierNamedOperation.h:
* bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp:
(WebCore::JSTestStringifierOperationImplementedAs::subspaceForImpl):
(WebCore::JSTestStringifierOperationImplementedAsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.h:
* bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp:
(WebCore::JSTestStringifierOperationNamedToString::subspaceForImpl):
(WebCore::JSTestStringifierOperationNamedToStringOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.h:
* bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp:
(WebCore::JSTestStringifierReadOnlyAttribute::subspaceForImpl):
(WebCore::JSTestStringifierReadOnlyAttributeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.h:
* bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp:
(WebCore::JSTestStringifierReadWriteAttribute::subspaceForImpl):
(WebCore::JSTestStringifierReadWriteAttributeOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.h:
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
(WebCore::JSTestTypedefs::subspaceForImpl):
(WebCore::JSTestTypedefsOwner::isReachableFromOpaqueRoots):
* bindings/scripts/test/JS/JSTestTypedefs.h:
* bindings/scripts/test/JS/JSWorkerGlobalScope.cpp:
(WebCore::JSWorkerGlobalScope::subspaceForImpl):
* bindings/scripts/test/JS/JSWorkletGlobalScope.cpp:
(WebCore::JSWorkletGlobalScope::subspaceForImpl):
* dom/ActiveDOMCallback.h:
(WebCore::ActiveDOMCallback::visitJSFunction):
* dom/EventListener.h:
(WebCore::EventListener::visitJSFunction):
* dom/EventTarget.cpp:
(WebCore::EventTarget::visitJSEventListeners):
* dom/EventTarget.h:
* dom/MutationRecord.cpp:
* dom/MutationRecord.h:
* dom/NodeFilterCondition.h:
(WebCore::NodeFilterCondition::visitAggregate): Deleted.
* dom/StaticRange.cpp:
(WebCore::StaticRange::visitNodesConcurrently const):
* dom/StaticRange.h:
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::addMembersToOpaqueRoots):
* html/canvas/WebGL2RenderingContext.h:
* html/canvas/WebGLFramebuffer.cpp:
(WebCore::WebGLFramebuffer::addMembersToOpaqueRoots):
* html/canvas/WebGLFramebuffer.h:
* html/canvas/WebGLProgram.cpp:
(WebCore::WebGLProgram::addMembersToOpaqueRoots):
* html/canvas/WebGLProgram.h:
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::addMembersToOpaqueRoots):
* html/canvas/WebGLRenderingContextBase.h:
* html/canvas/WebGLTransformFeedback.cpp:
(WebCore::WebGLTransformFeedback::addMembersToOpaqueRoots):
* html/canvas/WebGLTransformFeedback.h:
* html/canvas/WebGLVertexArrayObjectBase.cpp:
(WebCore::WebGLVertexArrayObjectBase::addMembersToOpaqueRoots):
* html/canvas/WebGLVertexArrayObjectBase.h:
Canonical link: https://commits.webkit.org/234335@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@273138 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-19 15:51:15 +00:00
|
|
|
heap/VerifierSlotVisitor.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
heap/VisitRaceKey.cpp
|
|
|
|
heap/Weak.cpp
|
|
|
|
heap/WeakBlock.cpp
|
|
|
|
heap/WeakHandleOwner.cpp
|
|
|
|
heap/WeakSet.cpp
|
|
|
|
heap/WriteBarrierSupport.cpp
|
|
|
|
|
|
|
|
inspector/AsyncStackTrace.cpp
|
|
|
|
inspector/ConsoleMessage.cpp
|
|
|
|
inspector/ContentSearchUtilities.cpp
|
|
|
|
inspector/IdentifiersFactory.cpp
|
|
|
|
inspector/InjectedScript.cpp
|
|
|
|
inspector/InjectedScriptBase.cpp
|
|
|
|
inspector/InjectedScriptHost.cpp
|
|
|
|
inspector/InjectedScriptManager.cpp
|
|
|
|
inspector/InjectedScriptModule.cpp
|
|
|
|
inspector/InspectorAgentRegistry.cpp
|
|
|
|
inspector/InspectorFrontendRouter.cpp
|
|
|
|
inspector/InspectorBackendDispatcher.cpp
|
2019-12-04 08:24:13 +00:00
|
|
|
inspector/InspectorTarget.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
inspector/JSGlobalObjectConsoleClient.cpp
|
2020-08-24 18:40:30 +00:00
|
|
|
inspector/JSGlobalObjectDebugger.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
inspector/JSGlobalObjectInspectorController.cpp
|
|
|
|
inspector/JSInjectedScriptHost.cpp
|
|
|
|
inspector/JSInjectedScriptHostPrototype.cpp
|
|
|
|
inspector/JSJavaScriptCallFrame.cpp
|
|
|
|
inspector/JSJavaScriptCallFramePrototype.cpp
|
|
|
|
inspector/JavaScriptCallFrame.cpp
|
|
|
|
inspector/PerGlobalObjectWrapperWorld.cpp
|
|
|
|
inspector/ScriptArguments.cpp
|
|
|
|
inspector/ScriptCallFrame.cpp
|
|
|
|
inspector/ScriptCallStack.cpp
|
|
|
|
inspector/ScriptCallStackFactory.cpp
|
|
|
|
|
2017-10-18 19:14:51 +00:00
|
|
|
// Derived Sources
|
2017-09-26 15:34:19 +00:00
|
|
|
inspector/InspectorBackendDispatchers.cpp
|
|
|
|
inspector/InspectorFrontendDispatchers.cpp
|
|
|
|
inspector/InspectorProtocolObjects.cpp
|
|
|
|
|
2017-09-20 23:08:50 +00:00
|
|
|
inspector/agents/InspectorAgent.cpp
|
2019-01-15 08:25:33 +00:00
|
|
|
inspector/agents/InspectorAuditAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
inspector/agents/InspectorConsoleAgent.cpp
|
|
|
|
inspector/agents/InspectorDebuggerAgent.cpp
|
|
|
|
inspector/agents/InspectorHeapAgent.cpp
|
|
|
|
inspector/agents/InspectorRuntimeAgent.cpp
|
|
|
|
inspector/agents/InspectorScriptProfilerAgent.cpp
|
Web Inspector: Keep Web Inspector window alive across process swaps (PSON) (Remote Inspector)
https://bugs.webkit.org/show_bug.cgi?id=191494
<rdar://problem/45469854>
Reviewed by Devin Rousso.
Source/JavaScriptCore:
* CMakeLists.txt:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
New domain and resources.
* inspector/protocol/Target.json: Added.
New protocol domain, modeled after Worker.json, to allow for
multiplexing between different targets.
* inspector/InspectorTarget.h:
Each target will instantiate an InspectorTarget and must
provide an identifier, type, and means of connecting/disconnecting
to a frontend channel.
* inspector/agents/InspectorTargetAgent.cpp: Added.
(Inspector::InspectorTargetAgent::InspectorTargetAgent):
(Inspector::InspectorTargetAgent::didCreateFrontendAndBackend):
(Inspector::InspectorTargetAgent::willDestroyFrontendAndBackend):
(Inspector::InspectorTargetAgent::exists):
(Inspector::InspectorTargetAgent::initialized):
(Inspector::InspectorTargetAgent::sendMessageToTarget):
(Inspector::InspectorTargetAgent::sendMessageFromTargetToFrontend):
(Inspector::targetTypeToProtocolType):
(Inspector::buildTargetInfoObject):
(Inspector::InspectorTargetAgent::targetCreated):
(Inspector::InspectorTargetAgent::targetTerminated):
(Inspector::InspectorTargetAgent::connectToTargets):
(Inspector::InspectorTargetAgent::disconnectFromTargets):
* inspector/agents/InspectorTargetAgent.h: Added.
TargetAgent holds a list of targets, and connects/disconnects to each
of the targets when a frontend connects/disconnects.
* inspector/scripts/codegen/generator.py:
Better enum casing of ServiceWorker.
Source/WebCore:
* inspector/InspectorClient.h:
(WebCore::InspectorClient::allowRemoteInspectionToPageDirectly const):
Provide a hook so that a client may wish to allow direct remote inspection of the Page.
This is used by WebKitLegacy only.
* page/Page.cpp:
(Page::Page):
Only enable the PageDebuggable if the client wishes remote inspection of the Page directly.
This is used by WebKitLegacy only.
* inspector/InspectorController.cpp:
(WebCore::InspectorController::connectFrontend):
* inspector/InspectorController.h:
* page/PageDebuggable.cpp:
(WebCore::PageDebuggable::connect):
(WebCore::PageDebuggable::disconnect):
* page/PageDebuggable.h:
When a frontend connects, always enable the developer extras for the Page.
This is pretty much only for the remote path, which allows inspection if developer
extras were not already enabled (iOS). This simplifies the logic, and toggling
developer extras after it was already enabled is not really important.
Source/WebInspectorUI:
This starts introducing multi-target support into the Web Inspector frontend.
Specifically a backend connection that is persistent, but has the ability to
connect to and transition between Page targets received through that backend
connection.
This patch introduces the concept of a "Backend Target" which is the single
connection that the frontend contains to a backend. The old way of connecting
directly to a target is still supported. In that case the frontend constructs
a DirectBackendTarget for the debuggable type the frontend was spawns for.
However, if the frontend opens and has a TargetAgent, then it is likely
connected to a multi-target supporting backend and instead constructs a
MultiplexingBackendTarget, and will receive further information about
sub-targets to connect to. The only sub-target at the moment is a Page
sub-target.
As part of bringing up multi-target support this adds a few measures to
handle situations where the frontend is playing fast and loose with agents.
When the frontend does `FooAgent.method` it intends that to be performed
on the "main" target being debugged. Likewise when the frontend loops
over targets it expects them to be the debuggable targets. This patch
profiles a new implementation of `WI.mainTarget` and `WI.targets` to
match the assumptions being made by the frontend.
- In a direct-target world, there is a single target which
should be used for global agents and in WI.targets.
- In a multi-target world, the page target is the one that
should be used for global agents and WI.targets is the list
of sub-targets (excluding the MultiplexingBackendTarget).
In a multi-target world, there are now commonly two Targets. The
MultiplexingBackendTarget and a PageTarget sub-target. In the future
this may include more targets, such as ServiceWorkers, DedicatedWorkers,
and perhaps even frames.
In a multi-target world, the frontend is immediately told about targets
as soon as it opens (via Target.targetCreated). In order to support
this, frontend initialization happens without a main target being available.
So this makes a few small changes to frontend initialization to perform
a bit of work once we know what the main target is.
During a page transition the frontend is told to destroy existing targets
and is soon after told about any new page targets (via Target.targetDestroyed
and Target.targetCreated). The frontend special cases this page transition.
It expects only one Page target to be alive at any time, accessible through
WI.pageTarget. When a page transition happens the WI.pageTarget changes, and
the frontend performs a bit of work to prepare the UI to handle the transition:
`<Manager>.transitionPageTarget` / WI.Notification.TransitionPageTarget.
For the most part the UI behaves fine as long once there are main frame
change and main resource change events, but those other events allow
the frontend to respond to the specific page transition cases.
* UserInterface/Base/Main.js:
(WI.loaded):
(WI.initializeBackendTarget):
(WI.initializePageTarget):
(WI.transitionPageTarget):
(WI.terminatePageTarget):
(WI.resetMainExecutionContext):
(WI.redirectGlobalAgentsToConnection):
(WI.contentLoaded):
New global functions for target initialization
and page transitioning.
* UserInterface/Test/Test.js:
(WI.loaded):
(WI.initializeBackendTarget):
(WI.initializePageTarget):
(WI.transitionPageTarget):
(WI.terminatePageTarget):
(WI.resetMainExecutionContext):
(WI.redirectGlobalAgentsToConnection):
New global functions for target initialization.
Tests continue to be a direct connection to the Page.
* UserInterface/Protocol/TargetObserver.js:
(WI.TargetObserver.prototype.targetCreated):
(WI.TargetObserver.prototype.targetDestroyed):
(WI.TargetObserver.prototype.dispatchMessageFromTarget):
New observer goes to the manager.
* UserInterface/Controllers/TargetManager.js:
(WI.TargetManager):
(WI.TargetManager.prototype.get targets):
(WI.TargetManager.prototype.get allTargets):
(WI.TargetManager.prototype.targetForIdentifier):
(WI.TargetManager.prototype.targetCreated):
(WI.TargetManager.prototype.targetDestroyed):
(WI.TargetManager.prototype.dispatchMessageFromTarget):
(WI.TargetManager.prototype.createMultiplexingBackendTarget):
(WI.TargetManager.prototype.createDirectBackendTarget):
(WI.TargetManager.prototype._addTarget):
(WI.TargetManager.prototype._removeTarget):
(WI.TargetManager.prototype._createTarget):
(WI.TargetManager.prototype._checkAndHandlePageTargetTransition):
(WI.TargetManager.prototype._checkAndHandlePageTargetTermination):
(WI.TargetManager.prototype.addTarget): Deleted.
(WI.TargetManager.prototype.removeTarget): Deleted.
(WI.TargetManager.prototype.initializeMainTarget): Deleted.
TargetManager is where we handle creating and destroying targets
and their connections. In order to simplify things a bit we make
`WI.targets`, which goes through `get targets()` an array instead
of a Set. And this includes only the sub-targets.
* UserInterface/Controllers/WorkerManager.js:
(WI.WorkerManager.prototype.workerCreated):
(WI.WorkerManager.prototype.workerTerminated):
Workers are still special-target-like things that multiplex through
WorkerAgent instead of TargetAgent. We'd like to promote these to
be full targets in the future.
* UserInterface/Protocol/DirectBackendTarget.js: Renamed from Source/WebInspectorUI/UserInterface/Protocol/MainTarget.js.
(WI.DirectBackendTarget):
(WI.DirectBackendTarget.connectionInfoForDebuggable):
(WI.DirectBackendTarget.prototype.get mainResource):
(WI.DirectBackendTarget.prototype.set mainResource):
This is the only "MainTarget" class. It is the backend target for a direct connection.
* UserInterface/Protocol/MultiplexingBackendTarget.js:
(WI.MultiplexingBackendTarget):
(WI.MultiplexingBackendTarget.prototype.initialize):
(WI.MultiplexingBackendTarget.prototype.get name):
(WI.MultiplexingBackendTarget.prototype.get executionContext):
(WI.MultiplexingBackendTarget.prototype.get mainResource):
This is the new backend target for a multi-target connection.
We don't expect it to be treated like other targets, so we don't
expect anyone to ask it for resources/executionContext/name info.
* UserInterface/Controllers/RuntimeManager.js:
(WI.TargetManager.prototype.evaluateInInspectedWindow):
This can be triggered by watch expressions before any target, and
therefore execution context, is available. Just return null, when
an execution context is available those clients will try again.
* UserInterface/Debug/Bootstrap.js:
Provide an WI.isEngineeringBuild boolean that can be used for various
debugging features.
* UserInterface/Main.html:
* UserInterface/Test.html:
New resources.
* UserInterface/Protocol/InspectorBackend.js:
(InspectorBackendClass.prototype.dispatch):
(InspectorBackendClass.prototype.runAfterPendingDispatches):
(InspectorBackend.Agent):
`InspectorBackend.mainConnection` was renamed `InspectorBackend.backendConnection`.
* UserInterface/Protocol/Connection.js:
(InspectorBackend.Connection):
(InspectorBackend.Connection.prototype._dispatchResponse):
(InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback):
(InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise):
(InspectorBackend.BackendConnection):
(InspectorBackend.BackendConnection.prototype.sendMessageToBackend):
(InspectorBackend.WorkerConnection):
(InspectorBackend.TargetConnection):
(InspectorBackend.TargetConnection.sendMessageToBackend):
Use a global sequence id to make filtering a bit easier in protocol tracing.
TargetConnection is identical to WorkerConnection except it uses TargetAgent
instead of WorkerAgent to perform multiplexing.
* UserInterface/Protocol/JavaScriptContextTarget.js:
(WI.JavaScriptContextTarget):
* UserInterface/Protocol/PageTarget.js:
(WI.PageTarget):
(WI.PageTarget.prototype.get displayName):
Specialized target types.
* UserInterface/Views/DebuggerSidebarPanel.js:
(WI.DebuggerSidebarPanel):
(WI.DebuggerSidebarPanel.prototype._targetAdded):
(WI.DebuggerSidebarPanel.prototype._targetRemoved):
(WI.DebuggerSidebarPanel.prototype._updateCallStackTreeOutline):
* UserInterface/Views/SourceCodeTextEditor.js:
(WI.SourceCodeTextEditor.prototype._targetAdded):
(WI.SourceCodeTextEditor.prototype._targetRemoved):
(WI.SourceCodeTextEditor.prototype._callFramesDidChange):
(WI.SourceCodeTextEditor.prototype._updateThreadIndicatorWidget):
(WI.SourceCodeTextEditor.prototype._reinsertAllThreadIndicators):
* UserInterface/Views/QuickConsole.js:
(WI.QuickConsole.prototype.initializeMainExecutionContextPathComponent):
(WI.QuickConsole.prototype._targetAdded):
(WI.QuickConsole.prototype._targetRemoved):
We make target added get called with all targets, including the
MultiplexingBackendTarget and PageTargets, both of which would
not have happened before. Before it was only WorkerTargets. Make
these sites a little more robust for the type of target they expect
to be able to handle.
* UserInterface/Base/Object.js:
* UserInterface/Controllers/DOMManager.js:
(WI.DOMManager):
(WI.DOMManager.prototype.transitionPageTarget):
(WI.DOMManager.prototype.requestDocument):
(WI.DOMManager.prototype._setDocument):
* UserInterface/Controllers/NetworkManager.js:
(WI.NetworkManager):
(WI.NetworkManager.prototype.transitionPageTarget):
(WI.NetworkManager.prototype.executionContextCreated):
(WI.NetworkManager.prototype._processMainFrameResourceTreePayload):
* UserInterface/Models/DefaultDashboard.js:
(WI.DefaultDashboard):
(WI.DefaultDashboard.prototype._mainResourceDidChange):
(WI.DefaultDashboard.prototype._transitionPageTarget):
* UserInterface/Views/NetworkTableContentView.js:
(WI.NetworkTableContentView):
(WI.NetworkTableContentView.prototype._mainResourceDidChange):
(WI.NetworkTableContentView.prototype._transitionPageTarget):
Special case handling when performing a page transition.
* UserInterface/Views/SettingsTabContentView.js:
* UserInterface/Debug/UncaughtExceptionReporter.js:
Document reloads are not supported right now.
Source/WebKit:
To support process swapping a slim Web Inspector backend lives in the UIProcess.
The Web Inspector frontend connects to it and is told about sub-targets, namely
pages, that it can further connect to. When performing a process swap the backend
tells the frontend to destroy existing targets and create new targets.
In the UIProcess the WebPageProxy has a WebPageInspectorController, with a single
TargetAgent holding InspectorTargetProxies to targets it knows about. Inspector
protocol messages go through this inspector controller and are routed to the
WebPage and its WebCore::Page's InspectorController. The WebPageProxy decides
when to close and expose new page targets during process swap, or basically
any time it reconnects to a WebProcess. So this patch also makes Web Inspector
stay alive and reconnect to a page when the inspected page crashes!
In the WebContentProcess the WebPage has a WebPageInspectorTarget. It also
has a WebPageInspectorTargetController in anticipation of further sub-targets
within the page (workers, frames) but none exist at the moment. The WebPage
relies on the WebPageProxy to know when to expose this target as a debuggable.
* Sources.txt:
* WebKit.xcodeproj/project.pbxproj:
New files.
* Shared/WebPageCreationParameters.cpp:
(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):
* Shared/WebPageCreationParameters.h:
Remote inspector state can now stay in the UIProcess and does not need to
be passed down to the WebContentProcess.
* UIProcess/WebPageDebuggable.cpp: Copied from Source/WebCore/page/PageDebuggable.cpp.
(WebKit::WebPageDebuggable::WebPageDebuggable):
(WebKit::WebPageDebuggable::name const):
(WebKit::WebPageDebuggable::url const):
(WebKit::WebPageDebuggable::hasLocalDebugger const):
(WebKit::WebPageDebuggable::connect):
(WebKit::WebPageDebuggable::disconnect):
(WebKit::WebPageDebuggable::dispatchMessageFromRemote):
(WebKit::WebPageDebuggable::setIndicating):
(WebKit::WebPageDebuggable::setNameOverride):
* UIProcess/WebPageDebuggable.h: Copied from Source/WebCore/page/PageDebuggable.h.
Remote debuggable entry point into the UIProcess for a page.
This is pretty much identical to the PageDebuggable in WebCore.
* Scripts/webkit/messages.py:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/WebPageProxy.cpp:
(WebKit::m_resetRecentCrashCountTimer):
(WebKit::WebPageProxy::finishAttachingToWebProcess):
(WebKit::WebPageProxy::close):
(WebKit::WebPageProxy::createInspectorTarget):
(WebKit::WebPageProxy::destroyInspectorTarget):
(WebKit::WebPageProxy::sendMessageToInspectorFrontend):
(WebKit::WebPageProxy::setIndicating):
(WebKit::WebPageProxy::allowsRemoteInspection const):
(WebKit::WebPageProxy::setAllowsRemoteInspection):
(WebKit::WebPageProxy::remoteInspectionNameOverride const):
(WebKit::WebPageProxy::setRemoteInspectionNameOverride):
(WebKit::WebPageProxy::remoteInspectorInformationDidChange):
(WebKit::WebPageProxy::clearInspectorTargets):
(WebKit::WebPageProxy::createInspectorTargets):
(WebKit::WebPageProxy::didCommitLoadForFrame):
(WebKit::WebPageProxy::didReceiveTitleForFrame):
(WebKit::WebPageProxy::creationParameters):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::inspectorController):
(WebKit::WebPageProxy::allowsRemoteInspection const): Deleted.
(WebKit::WebPageProxy::remoteInspectionNameOverride const): Deleted.
Own more inspector state in the UIProcess including a debuggable and inspector controller.
* UIProcess/WebPageInspectorController.h: Added.
* UIProcess/WebPageInspectorController.cpp: Added.
(WebKit::WebPageInspectorController::WebPageInspectorController):
(WebKit::WebPageInspectorController::pageClosed):
(WebKit::WebPageInspectorController::hasLocalFrontend const):
(WebKit::WebPageInspectorController::hasRemoteFrontend const):
(WebKit::WebPageInspectorController::connectFrontend):
(WebKit::WebPageInspectorController::disconnectFrontend):
(WebKit::WebPageInspectorController::disconnectAllFrontends):
(WebKit::WebPageInspectorController::dispatchMessageFromFrontend):
(WebKit::WebPageInspectorController::setIndicating):
(WebKit::WebPageInspectorController::clearTargets):
(WebKit::WebPageInspectorController::createInspectorTarget):
(WebKit::WebPageInspectorController::destroyInspectorTarget):
(WebKit::WebPageInspectorController::sendMessageToInspectorFrontend):
InspectorController with a single TargetAgent in the UIProcess.
* UIProcess/WebPageInspectorTargetAgent.h:
* UIProcess/WebPageInspectorTargetAgent.cpp:
(WebKit::WebPageInspectorTargetAgent::WebPageInspectorTargetAgent):
(WebKit::WebPageInspectorTargetAgent::frontendChannel):
Target agent implementation.
* UIProcess/InspectorTargetProxy.cpp:
(WebKit::InspectorTargetProxy::create):
(WebKit::InspectorTargetProxy::InspectorTargetProxy):
(WebKit::InspectorTargetProxy::connect):
(WebKit::InspectorTargetProxy::disconnect):
(WebKit::InspectorTargetProxy::sendMessageToTargetBackend):
* UIProcess/InspectorTargetProxy.h:
UIProcess proxy for an InspectorTarget in the WebContentProcess.
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::processForNavigationInternal):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::m_shouldAttachDrawingAreaOnPageTransition):
(WebKit::WebPage::connectInspector):
(WebKit::WebPage::disconnectInspector):
(WebKit::WebPage::sendMessageToTargetBackend):
(WebKit::WebPage::setIndicating):
(WebKit::WebPage::setAllowsRemoteInspection): Deleted.
(WebKit::WebPage::setRemoteInspectionNameOverride): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/WebPageInspectorTarget.h:
* WebProcess/WebPage/WebPageInspectorTarget.cpp:
(WebKit::WebPageInspectorTarget::WebPageInspectorTarget):
(WebKit::WebPageInspectorTarget::identifier const):
(WebKit::WebPageInspectorTarget::connect):
(WebKit::WebPageInspectorTarget::disconnect):
(WebKit::WebPageInspectorTarget::sendMessageToTargetBackend):
InspectorTarget for this WebPage.
* WebProcess/WebPage/WebPageInspectorTargetController.cpp: Added.
(WebKit::WebPageInspectorTargetController::WebPageInspectorTargetController):
(WebKit::WebPageInspectorTargetController::~WebPageInspectorTargetController):
(WebKit::WebPageInspectorTargetController::addTarget):
(WebKit::WebPageInspectorTargetController::removeTarget):
(WebKit::WebPageInspectorTargetController::connectInspector):
(WebKit::WebPageInspectorTargetController::disconnectInspector):
(WebKit::WebPageInspectorTargetController::sendMessageToTargetBackend):
(WebKit::WebPageInspectorTargetController::sendMessageToTargetFrontend):
* WebProcess/WebPage/WebPageInspectorTargetController.h:
* WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.h:
* WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.cpp:
(WebKit::WebPageInspectorTargetFrontendChannel::create):
(WebKit::WebPageInspectorTargetFrontendChannel::WebPageInspectorTargetFrontendChannel):
(WebKit::WebPageInspectorTargetFrontendChannel::sendMessageToFrontend):
Preparation for more target managment in the WebContentProcess.
Source/WebKitLegacy/mac:
* WebCoreSupport/WebInspectorClient.h:
WebKitLegacy will still have remote inspection of the Page directly.
LayoutTests:
* inspector/unit-tests/target-manager.html:
WI.targets has switched to being an array instead of a set.
Canonical link: https://commits.webkit.org/206396@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238192 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-14 21:03:49 +00:00
|
|
|
inspector/agents/InspectorTargetAgent.cpp
|
2019-01-15 08:25:33 +00:00
|
|
|
inspector/agents/JSGlobalObjectAuditAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
inspector/agents/JSGlobalObjectDebuggerAgent.cpp
|
|
|
|
inspector/agents/JSGlobalObjectRuntimeAgent.cpp
|
|
|
|
|
|
|
|
interpreter/AbstractPC.cpp
|
|
|
|
interpreter/CLoopStack.cpp
|
|
|
|
interpreter/CallFrame.cpp
|
|
|
|
interpreter/Interpreter.cpp
|
|
|
|
interpreter/ShadowChicken.cpp
|
|
|
|
interpreter/StackVisitor.cpp
|
|
|
|
|
|
|
|
jit/AssemblyHelpers.cpp
|
2021-05-26 15:15:22 +00:00
|
|
|
jit/BaselineJITPlan.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/BinarySwitch.cpp
|
|
|
|
jit/CCallHelpers.cpp
|
|
|
|
jit/CachedRecovery.cpp
|
|
|
|
jit/CallFrameShuffleData.cpp
|
|
|
|
jit/CallFrameShuffler.cpp
|
|
|
|
jit/CallFrameShuffler32_64.cpp
|
|
|
|
jit/CallFrameShuffler64.cpp
|
|
|
|
jit/ExecutableAllocationFuzz.cpp
|
|
|
|
jit/ExecutableAllocator.cpp
|
|
|
|
jit/GCAwareJITStubRoutine.cpp
|
|
|
|
jit/GPRInfo.cpp
|
|
|
|
jit/ICStats.cpp
|
|
|
|
jit/IntrinsicEmitter.cpp
|
|
|
|
jit/JIT.cpp
|
|
|
|
jit/JITAddGenerator.cpp
|
|
|
|
jit/JITArithmetic.cpp
|
|
|
|
jit/JITArithmetic32_64.cpp
|
|
|
|
jit/JITBitAndGenerator.cpp
|
|
|
|
jit/JITBitOrGenerator.cpp
|
|
|
|
jit/JITBitXorGenerator.cpp
|
|
|
|
jit/JITCall.cpp
|
|
|
|
jit/JITCall32_64.cpp
|
|
|
|
jit/JITCode.cpp
|
2021-01-19 00:24:52 +00:00
|
|
|
jit/JITCompilation.cpp
|
2021-05-26 15:15:22 +00:00
|
|
|
jit/JITCompilationKey.cpp
|
|
|
|
jit/JITCompilationMode.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/JITDisassembler.cpp
|
|
|
|
jit/JITDivGenerator.cpp
|
|
|
|
jit/JITExceptions.cpp
|
|
|
|
jit/JITInlineCacheGenerator.cpp
|
|
|
|
jit/JITLeftShiftGenerator.cpp
|
|
|
|
jit/JITMulGenerator.cpp
|
|
|
|
jit/JITNegGenerator.cpp
|
2021-01-19 00:24:52 +00:00
|
|
|
jit/JITOpaqueByproducts.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/JITOpcodes.cpp
|
|
|
|
jit/JITOpcodes32_64.cpp
|
|
|
|
jit/JITOperations.cpp
|
2021-05-26 15:15:22 +00:00
|
|
|
jit/JITPlan.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/JITPropertyAccess.cpp
|
|
|
|
jit/JITPropertyAccess32_64.cpp
|
|
|
|
jit/JITRightShiftGenerator.cpp
|
2021-05-26 15:15:22 +00:00
|
|
|
jit/JITSafepoint.cpp
|
2021-05-28 18:36:44 +00:00
|
|
|
jit/JITSizeStatistics.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/JITStubRoutine.cpp
|
|
|
|
jit/JITSubGenerator.cpp
|
|
|
|
jit/JITThunks.cpp
|
|
|
|
jit/JITToDFGDeferredCompilationCallback.cpp
|
|
|
|
jit/JITWorklist.cpp
|
2021-05-26 15:15:22 +00:00
|
|
|
jit/JITWorklistThread.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/PCToCodeOriginMap.cpp
|
|
|
|
jit/PolymorphicCallStubRoutine.cpp
|
|
|
|
jit/Reg.cpp
|
|
|
|
jit/RegisterAtOffset.cpp
|
|
|
|
jit/RegisterAtOffsetList.cpp
|
|
|
|
jit/RegisterSet.cpp
|
|
|
|
jit/Repatch.cpp
|
|
|
|
jit/ScratchRegisterAllocator.cpp
|
|
|
|
jit/SetupVarargsFrame.cpp
|
Implement some common Baseline JIT slow paths using JIT thunks.
https://bugs.webkit.org/show_bug.cgi?id=225682
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
This patch implements the following changes:
1. Implement exception handling thunks:
a. handleExceptionGenerator, which calls operationLookupExceptionHandler().
b. handleExceptionWithCallFrameRollbackGenerator, which calls
operationLookupExceptionHandlerFromCallerFrame().
All the JIT tiers were emitting their own copy of these routines to call these
operation, one per CodeBlock. We now emit 2 thunks for these and have all the
tiers just jump to them.
PolymorphicAccess also now uses the handleExceptionGenerator thunk.
DFG::JITCompiler::compileExceptionHandlers() has one small behavior difference
before it calls operationLookupExceptionHandlerFromCallerFrame(): it first
re-sets the top of stack for the function where we are about to throw a
StackOverflowError from. This re-setting of top of stack is useless because
we're imminently unwinding out of at least this frame for the StackOverflowError.
Hence, it is ok to use the handleExceptionWithCallFrameRollbackGenerator thunk
here as well. Note that no other tiers does this re-setting of top of stack.
FTLLowerDFGToB3 has one case using operationLookupExceptionHandlerFromCallerFrame()
which cannot be refactored to use these thunks because it does additional
work to throw a StackOverflowError. A different thunk will be needed. I left
it alone for now.
2. Introduce JITThunks::existingCTIStub(ThunkGenerator, NoLockingNecessaryTag) so
that a thunk can get a pointer to another thunk without locking the JITThunks
lock. Otherwise, deadlock ensues.
3. Change SlowPathCall to emit and use thunks instead of emitting a blob of code
to call a slow path function for every bytecode in a CodeBlock.
4. Introduce JITThunks::ctiSlowPathFunctionStub() to manage these SlowPathFunction
thunks.
5. Introduce JITThunks::preinitializeAggressiveCTIThunks() to initialize these
thunks at VM initialization time. Pre-initializing them has multiple benefits:
a. the thunks are not scattered through out JIT memory, thereby reducing
fragmentation.
b. we don't spend time at runtime compiling them when the user is interacting
with the VM. Conceptually, these thunks can be VM independent and can be
shared by VMs process-wide. However, it will require some additional work.
For now, the thunks remain bound to a specific VM instance.
These changes are only enabled when ENABLE(EXTRA_CTI_THUNKS), which is currently
only available for ARM64 and non-Windows x86_64.
This patch has passed JSC tests on AS Mac.
With this patch, --dumpLinkBufferStats shows the following changes in emitted
JIT code size (using a single run of the CLI version of JetStream2 on AS Mac):
Base New Diff
BaselineJIT: 89089964 (84.962811 MB) 84624776 (80.704475 MB) 0.95x (reduction)
DFG: 39117360 (37.305222 MB) 36415264 (34.728302 MB) 0.93x (reduction)
Thunk: 23230968 (22.154778 MB) 23130336 (22.058807 MB) 1.00x
InlineCache: 22027416 (21.006981 MB) 21969728 (20.951965 MB) 1.00x
FTL: 6575772 (6.271145 MB) 6097336 (5.814873 MB) 0.93x (reduction)
Wasm: 2302724 (2.196049 MB) 2301956 (2.195316 MB) 1.00x
YarrJIT: 1538956 (1.467663 MB) 1522488 (1.451958 MB) 0.99x
CSSJIT: 0 0
Uncategorized: 0 0
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/CodeBlock.h:
(JSC::CodeBlock::offsetOfInstructionsRawPointer):
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* jit/JIT.cpp:
(JSC::JIT::link):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JIT.h:
* jit/JITThunks.cpp:
(JSC::JITThunks::existingCTIStub):
(JSC::JITThunks::ctiSlowPathFunctionStub):
(JSC::JITThunks::preinitializeExtraCTIThunks):
* jit/JITThunks.h:
* jit/SlowPathCall.cpp: Added.
(JSC::JITSlowPathCall::call):
(JSC::JITSlowPathCall::generateThunk):
* jit/SlowPathCall.h:
* jit/ThunkGenerators.cpp:
(JSC::handleExceptionGenerator):
(JSC::handleExceptionWithCallFrameRollbackGenerator):
(JSC::popThunkStackPreservesAndHandleExceptionGenerator):
* jit/ThunkGenerators.h:
* runtime/CommonSlowPaths.h:
* runtime/SlowPathFunction.h: Added.
* runtime/VM.cpp:
(JSC::VM::VM):
Source/WTF:
Introduce ENABLE(EXTRA_CTI_THUNKS) flag to guard the use of these new thunks.
Currently, the thunks are 64-bit only, and only supported for ARM64 and non-Windows
X86_64. The reason it is not supported for Windows as well is because Windows
only has 4 argument registers. In this patch, the thunks do not use that many
registers yet, but there will be more thunks coming that will require the use
of up to 6 argument registers.
* wtf/PlatformEnable.h:
Canonical link: https://commits.webkit.org/237639@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277383 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-12 19:11:25 +00:00
|
|
|
jit/SlowPathCall.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
jit/TagRegistersMode.cpp
|
|
|
|
jit/TempRegisterSet.cpp
|
|
|
|
jit/ThunkGenerators.cpp
|
|
|
|
|
|
|
|
llint/LLIntCLoop.cpp
|
|
|
|
llint/LLIntData.cpp
|
|
|
|
llint/LLIntEntrypoint.cpp
|
|
|
|
llint/LLIntExceptions.cpp
|
|
|
|
llint/LLIntSlowPaths.cpp
|
|
|
|
llint/LLIntThunks.cpp
|
|
|
|
|
|
|
|
parser/Lexer.cpp
|
|
|
|
parser/ModuleAnalyzer.cpp
|
|
|
|
parser/Nodes.cpp
|
|
|
|
parser/NodesAnalyzeModule.cpp
|
|
|
|
parser/Parser.cpp
|
|
|
|
parser/ParserArena.cpp
|
|
|
|
parser/SourceProvider.cpp
|
|
|
|
parser/SourceProviderCache.cpp
|
|
|
|
parser/UnlinkedSourceCode.cpp
|
|
|
|
parser/VariableEnvironment.cpp
|
|
|
|
|
|
|
|
profiler/ProfilerBytecode.cpp
|
|
|
|
profiler/ProfilerBytecodeSequence.cpp
|
|
|
|
profiler/ProfilerBytecodes.cpp
|
|
|
|
profiler/ProfilerCompilation.cpp
|
|
|
|
profiler/ProfilerCompilationKind.cpp
|
|
|
|
profiler/ProfilerCompiledBytecode.cpp
|
|
|
|
profiler/ProfilerDatabase.cpp
|
|
|
|
profiler/ProfilerEvent.cpp
|
|
|
|
profiler/ProfilerJettisonReason.cpp
|
|
|
|
profiler/ProfilerOSRExit.cpp
|
|
|
|
profiler/ProfilerOSRExitSite.cpp
|
|
|
|
profiler/ProfilerOrigin.cpp
|
|
|
|
profiler/ProfilerOriginStack.cpp
|
|
|
|
profiler/ProfilerProfiledBytecodes.cpp
|
|
|
|
profiler/ProfilerUID.cpp
|
|
|
|
|
|
|
|
runtime/AbstractModuleRecord.cpp
|
2020-04-17 19:31:08 +00:00
|
|
|
runtime/AggregateError.cpp
|
|
|
|
runtime/AggregateErrorConstructor.cpp
|
|
|
|
runtime/AggregateErrorPrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/ArgList.cpp
|
|
|
|
runtime/ArrayBuffer.cpp
|
|
|
|
runtime/ArrayBufferView.cpp
|
|
|
|
runtime/ArrayConstructor.cpp
|
|
|
|
runtime/ArrayConventions.cpp
|
|
|
|
runtime/ArrayIteratorPrototype.cpp
|
|
|
|
runtime/ArrayPrototype.cpp
|
|
|
|
runtime/AsyncFromSyncIteratorPrototype.cpp
|
|
|
|
runtime/AsyncGeneratorFunctionConstructor.cpp
|
|
|
|
runtime/AsyncGeneratorFunctionPrototype.cpp
|
|
|
|
runtime/AsyncGeneratorPrototype.cpp
|
|
|
|
runtime/AsyncIteratorPrototype.cpp
|
|
|
|
runtime/AtomicsObject.cpp
|
|
|
|
runtime/AsyncFunctionConstructor.cpp
|
|
|
|
runtime/AsyncFunctionPrototype.cpp
|
|
|
|
runtime/BasicBlockLocation.cpp
|
2018-01-02 23:38:36 +00:00
|
|
|
runtime/BigIntConstructor.cpp
|
|
|
|
runtime/BigIntObject.cpp
|
|
|
|
runtime/BigIntPrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/BooleanConstructor.cpp
|
|
|
|
runtime/BooleanObject.cpp
|
|
|
|
runtime/BooleanPrototype.cpp
|
[ESNext] Implement private methods
https://bugs.webkit.org/show_bug.cgi?id=194434
Reviewed by Filip Pizlo.
JSTests:
* stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
* stress/private-brand-installed-after-super-call-from-eval.js: Added.
* stress/private-method-brand-check.js: Added.
* stress/private-method-change-attribute-from-branded-structure.js: Added.
* stress/private-method-change-prototype-from-branded-structure.js: Added.
* stress/private-method-check-private-brand-ic.js: Added.
* stress/private-method-check-structure-miss.js: Added.
* stress/private-method-comparison.js: Added.
* stress/private-method-delete-property-from-branded-structure.js: Added.
* stress/private-method-extends-brand-check.js: Added.
* stress/private-method-get-and-call.js: Added.
* stress/private-method-invalid-multiple-brand-installation.js: Added.
* stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
* stress/private-method-nested-class.js: Added.
* stress/private-method-on-sealed-objects.js: Added.
* stress/private-method-on-uncacheable-dictionary.js: Added.
* stress/private-method-polymorphic-with-constant-symbol.js: Added.
* stress/private-method-set-brand-should-have-write-barrier.js: Added.
* stress/private-method-untyped-use.js: Added.
* stress/private-method-with-uncacheable-dictionary-transition.js: Added.
* stress/private-methods-inline-cache.js: Added.
* stress/private-methods-megamorphic-ic.js: Added.
* stress/private-methods-on-proxy.js: Added.
* stress/private-methods-poly-ic-multiple-classes.js: Added.
* stress/private-methods-poly-ic-single-class.js: Added.
* stress/private-names-available-on-direct-eval.js: Added.
* test262/config.yaml:
Source/JavaScriptCore:
This patch is adding support to private methods following the
specification on https://tc39.es/proposal-private-methods/.
This is introducing a new way to declare private methods on
class syntax. Private methods are only accessible within
classes they were declared, and only can be called from
objects that are instance of these classes.
To guarantee such rules, the proposal presents the concept of
Brand Check. During class evaluation, if a private method is present,
a `brand` is installed in this class. Every instance of such class
then gets this brand installed during `[[Construct]]` operation. It
means that an object can have multiple brands (e.g when there is also
private methods declared on super class). Before accessing a private
method, there is a check to validate if the target of the call has the
brand of callee method.
The brand check mechanism is implemented using a `@privateBrand`
stored on class scope. Here is a representation of how this mechanism
works:
```
class C {
#m() { return 3; }
method() { return this.#m(); }
}
let c = new C();
console.log(c.method()); // prints 3
```
Generated bytecode for the following representation:
```
{ // class lexical scope
const @privateBrand = @createPrivateSymbol();
const #m = function () { return 3; }
C.prototype.method = function() {
@check_private_brand(this, @privateBrand);
return #m.call(this);
}
C = function() {
@set_private_brand(this, @privateBrand);
}
}
let c = new C();
console.log(c.method()); // prints 3
```
# Resolving correct brand to check
In the case of shadowing or nested scope, we need to emit brand
checks to the right private brand. See code below:
```
class C {
#m() { return 3; }
method() { return this.#m();}
A = class {
#m2() { return 3; }
foo(o) { return o.#m(); }
}
}
```
The call of "#m" in `foo` refers to "C::#m". In such case, we need to
check C's private brand, instead of A's private brand.
To perform the proper check, we first resolve scope of "#m" and then
check the private brand of this scope (the scope where the private
method and brand are stored is the same).
So the bytecode to lookup the right brand is:
```
mov loc9, arg1
resolve_scope loc10, "#m"
get_from_scope loc11, loc10, "@privateBrand"
check_private_brand loc9, loc11
get_from_scope loc11, loc10, "#m"
// setup call frame
call loc11, ...
// ...
```
# Brand check mechanism
We are introducing in this patch 2 new bytecodes to allow brand check
of objects: `op_set_brand` and `op_check_brand`.
`op_set_brand` sets a new brand in an object, so we can perform the brand
check later when accessing private methods. This operations throws when
trying to add the same brand twice in an Object.
`op_check_brand` checks if the given object contains the brand we are
looking for. It traverses the brand chain to verify if the brand is
present, and throws `TypeError` otherwise.
We are also introducing a subclass for Structure called BrandedStructure.
It is used to store brands and to allow brand check mechanism. BrandedStructure
stores a brand and a parent pointer to another BrandedStructure that allow
us traverse the brand chain. With `BrandedStructure`, we can then
infer that a given object has the brand we are looking for just
checking its structureId. This is a very good optimization, since we can
reduce most of brand checks to structure checks.
We created a new kind of transition called `SetBrand` that happens when
`op_set_brand` is executed. This allow us to cache such kind of
trasitions on trasition table using the key `<brand->uid, 0,
TransitionKind::SetBrand>`. During this transition, we take previous
structure and apply one of the following rules:
1. If it's a BrandedStructure, we then set it to `m_parentBrand`,
to allow proper brand chain check.
2. If it's not a BrandedStructure, we set `m_parentBrand` to `nullptr`,
meaning that this is the first brand being added to the object
with this structure.
For now, we are using the flag `isBrandedStructure` to identify that a
given Structure is a BrandedStructure. This is done to avoid changes
on places where we are checking for `vm.structureStructure()`.
However, if we ever need space on Structure, this flag is a good
candidate to be deleted and we can move to a solution that uses
`vm.brandedStructureStructure()`;
# JIT Support
This patch also includes initial JIT support for `set_private_brand`
and `check_private_brand`. On Baseline JIT, we are using
`JITPravateBrandAccessGenerator` to support IC for both operands.
On `DFGByteCodeParser` we are trying to inline brand access whenever
possible, and fallbacking to `SetPrivateBrand` and
`CheckPrivateBrand` otherwise. Those nodes are not being optimized at
their full potential, but the code generated by them is also relying on
`JITPrivateBrandAccessGenerator` to have IC support for both DFG and
FTL. During DFG parsing, we try to reduce those access to `CheckIsConstant`
and `CheckStructure` (with `PutStructure` for `set_private_brand` cases)
based on available profiled data. This is meant to make brand checks
almost free on DFG/FTL tiers when we have a single evaluation of a
class, since the `CheckIsConstant` can be eliminated by the constant-folded
scope load, and the `CheckStructure` is very likely to be redundant
to any other `CheckStructure` that can be performed on receiver
when we have a finite structure set.
For instance, when we have a brand check on a path-of-no-return to
a `GetByOffset` sequence on the same receiver, the `CheckStructure`
for the brand check will enable CSE of the `CheckStructure` that
would happen for that `GetByOffset`. Such design is possible because brand
checks supports polymorphic access very similr to what we have for
`GetByOffset` sequences.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):
* builtins/BuiltinExecutables.h:
We are adding a new parameter `PrivateBrandRequirement` to propagate
when a default constructor needs to emit code to setup private brand
on instances.
* builtins/BuiltinNames.h:
Adding `@privateBrand` that we use to store private brand on
class's scope.
* bytecode/AccessCase.cpp:
(JSC::AccessCase::createCheckPrivateBrand):
(JSC::AccessCase::createSetPrivateBrand):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::structure const):
(JSC::AccessCase::newStructure const):
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CheckPrivateBrandStatus.cpp: Added.
(JSC::CheckPrivateBrandStatus::appendVariant):
(JSC::CheckPrivateBrandStatus::computeForBaseline):
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
(JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::CheckPrivateBrandStatus::computeFor):
(JSC::CheckPrivateBrandStatus::slowVersion const):
(JSC::CheckPrivateBrandStatus::merge):
(JSC::CheckPrivateBrandStatus::filter):
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
(JSC::CheckPrivateBrandStatus::visitAggregate):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::finalize):
(JSC::CheckPrivateBrandStatus::dump const):
* bytecode/CheckPrivateBrandStatus.h: Added.
* bytecode/CheckPrivateBrandVariant.cpp: Added.
(JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::attemptToMerge):
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::finalize):
(JSC::CheckPrivateBrandVariant::visitAggregate):
(JSC::CheckPrivateBrandVariant::dump const):
(JSC::CheckPrivateBrandVariant::dumpInContext const):
* bytecode/CheckPrivateBrandVariant.h: Added.
(JSC::CheckPrivateBrandVariant::structureSet const):
(JSC::CheckPrivateBrandVariant::structureSet):
(JSC::CheckPrivateBrandVariant::identifier const):
(JSC::CheckPrivateBrandVariant::overlaps):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::privateBrandRequirement const):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addCheckPrivateBrandStatus):
(JSC::RecordedStatuses::addSetPrivateBrandStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):
* bytecode/RecordedStatuses.h:
(JSC::RecordedStatuses::forEachVector):
* bytecode/SetPrivateBrandStatus.cpp: Added.
(JSC::SetPrivateBrandStatus::appendVariant):
(JSC::SetPrivateBrandStatus::computeForBaseline):
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
(JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::SetPrivateBrandStatus::computeFor):
(JSC::SetPrivateBrandStatus::slowVersion const):
(JSC::SetPrivateBrandStatus::merge):
(JSC::SetPrivateBrandStatus::filter):
(JSC::SetPrivateBrandStatus::singleIdentifier const):
(JSC::SetPrivateBrandStatus::visitAggregate):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::finalize):
(JSC::SetPrivateBrandStatus::dump const):
* bytecode/SetPrivateBrandStatus.h: Added.
* bytecode/SetPrivateBrandVariant.cpp: Added.
(JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::attemptToMerge):
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::finalize):
(JSC::SetPrivateBrandVariant::visitAggregate):
(JSC::SetPrivateBrandVariant::dump const):
(JSC::SetPrivateBrandVariant::dumpInContext const):
* bytecode/SetPrivateBrandVariant.h: Added.
(JSC::SetPrivateBrandVariant::oldStructure const):
(JSC::SetPrivateBrandVariant::newStructure const):
(JSC::SetPrivateBrandVariant::identifier const):
(JSC::SetPrivateBrandVariant::overlaps):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::privateBrandRequirement const):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
We changed BytecodeGenerator for FunctionNode and EvalNode to
propagate parentScope PrivateNameEnvironment. These environments stores
private name entries that are visible into the scope of the
function/eval.
This is required to identify the kind of access a private name is
referring to, since it can be a private field or a private method.
(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::emitGetPrivateName):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):
The process to create a private brand is as follows:
1. Create a PrivateSymbol using `@createPrivateSymbol`.
2. Store this symbol into a given scope (i.e class lexical scope)
on `@privateBrand` variable.
(JSC::BytecodeGenerator::emitInstallPrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):
We added `m_privateNamesStack` to BytecodeGenerator to represent the
scope chain of available private names while generating bytecode.
(JSC::BytecodeGenerator::emitCheckPrivateBrand):
(JSC::BytecodeGenerator::isPrivateMethod):
(JSC::BytecodeGenerator::pushPrivateAccessNames):
(JSC::BytecodeGenerator::popPrivateAccessNames):
(JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
(JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::privateBrandRequirement const):
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):
This change is required to properly propagate PrivateBrandRequirement
to arrow functions that can potentially call `super()`.
* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitDeclarePrivateFieldNames):
(JSC::PropertyListNode::emitBytecode):
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BaseDotNode::emitGetPropertyValue):
Adding support to properly access private method. Since we store
private methods on class lexical scope, we need a different set of
instructions to access a private method.
(JSC::BaseDotNode::emitPutProperty):
In the case of we trying to write in a private method, we need to
throw a TypeError according to specification
(https://tc39.es/proposal-private-methods/#sec-privatefieldset).
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::ClassExprNode::emitBytecode):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addPrivateBrandAccess):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCheckPrivateBrandStatus):
(JSC::DFG::Node::checkPrivateBrandStatus):
(JSC::DFG::Node::hasSetPrivateBrandStatus):
(JSC::DFG::Node::setPrivateBrandStatus):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
(JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
(JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):
* interpreter/Interpreter.cpp:
(JSC::eval):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::generateFastPath):
(JSC::JITPrivateBrandAccessGenerator::finalize):
* jit/JITInlineCacheGenerator.h:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::slowPathJump const):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::getPrivateName):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/Repatch.cpp:
(JSC::tryCacheCheckPrivateBrand):
(JSC::repatchCheckPrivateBrand):
(JSC::tryCacheSetPrivateBrand):
(JSC::repatchSetPrivateBrand):
(JSC::resetCheckPrivateBrand):
(JSC::resetSetPrivateBrand):
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
(JSC::Scope::declarePrivateMethod):
(JSC::Scope::declarePrivateField):
(JSC::Parser<LexerType>::parse):
(JSC::parse):
(JSC::Scope::declarePrivateName): Deleted.
* parser/ParserModes.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createDotAccess):
* parser/VariableEnvironment.cpp:
(JSC::VariableEnvironment::declarePrivateMethod):
* parser/VariableEnvironment.h:
(JSC::VariableEnvironmentEntry::isPrivateField const):
(JSC::VariableEnvironmentEntry::isPrivateMethod const):
(JSC::VariableEnvironmentEntry::setIsPrivateField):
(JSC::VariableEnvironmentEntry::setIsPrivateMethod):
(JSC::PrivateNameEntry::isMethod const):
(JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
(JSC::VariableEnvironment::addPrivateName):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::privateNameEnvironment const):
(JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
(JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
(JSC::VariableEnvironment::declarePrivateName): Deleted.
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
(JSC::CachedFunctionExecutable::privateBrandRequirement const):
(JSC::CachedCodeBlock::derivedContextType const):
(JSC::CachedFunctionExecutable::encode):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.
* runtime/CodeCache.cpp:
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):
(JSC::generateUnlinkedCodeBlockForDirectEval):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
* runtime/CodeCache.h:
* runtime/DirectEvalExecutable.cpp:
(JSC::DirectEvalExecutable::create):
(JSC::DirectEvalExecutable::DirectEvalExecutable):
* runtime/DirectEvalExecutable.h:
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::EvalExecutable):
* runtime/EvalExecutable.h:
(JSC::EvalExecutable::executableInfo const):
(JSC::EvalExecutable::privateBrandRequirement const):
* runtime/ExceptionHelpers.cpp:
(JSC::createInvalidPrivateNameError):
* runtime/IndirectEvalExecutable.cpp:
(JSC::IndirectEvalExecutable::IndirectEvalExecutable):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::checkPrivateBrand):
(JSC::JSObject::setPrivateBrand):
* runtime/JSScope.cpp:
(JSC::JSScope::collectClosureVariablesUnderTDZ):
* runtime/JSScope.h:
* runtime/ModuleProgramExecutable.h:
* runtime/Options.cpp:
(JSC::Options::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/ProgramExecutable.h:
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyTable):
(JSC::BrandedStructure::BrandedStructure):
(JSC::BrandedStructure::create):
(JSC::BrandedStructure::checkBrand):
(JSC::Structure::setBrandTransitionFromExistingStructureImpl):
(JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
(JSC::Structure::setBrandTransition):
* runtime/Structure.h:
(JSC::Structure::finishCreation):
* runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::forEachPropertyConcurrently):
* runtime/StructureTransitionTable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::cloneScopePart):
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Canonical link: https://commits.webkit.org/233852@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 16:30:24 +00:00
|
|
|
runtime/BrandedStructure.cpp
|
2019-06-04 11:14:10 +00:00
|
|
|
runtime/BytecodeCacheError.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/CallData.cpp
|
2019-04-10 19:18:20 +00:00
|
|
|
runtime/CachePayload.cpp
|
|
|
|
runtime/CacheUpdate.cpp
|
Replace uses of Box<Identifier> with a new CacheableIdentifier class.
https://bugs.webkit.org/show_bug.cgi?id=205544
<rdar://problem/58041800>
Reviewed by Saam Barati.
JSTests:
* stress/racy-gc-cleanup-of-identifier-after-mutator-stops-running.js: Added.
Source/JavaScriptCore:
The introduction of the use of Box<Identifier> was to get around having to
ref/deref the underlying UniqedStringImpl in Identifiers from the compiler
and GC threads. However, it proves to be difficult to control when these
Box<Identifier>s get destructed, and requires that we find all the places in
the compier and GC threads where this can happen, and apply keep alive tactics
there to defer destruction of the Box<Identifier> to the mutator thread.
This patch fixes this by replacing uses of Box<Identifier> with
CacheableIdentifier, which is effectively a tagged union of a JSCell* or a
UniquedStringImpl*. The JSCell*, in this case, can be either a Symbol* or a
JSString* that is backed by an atom string. The VM runtime ensures that we'll
never try to cache an identifier from a JSCell that is not one of these. This
CacheableIdentifier can be destructed from the compiler or GC thread. Since it
doesn't hold a ref of the underlying UniquedStringImpl, it won't try to deref
it on destruction.
Instead, we'll need to visit CacheableIdentifiers during GC scans to keep the
JSCell in it alive, and that JSCell will, in turn, keep the underlying
UniquedStringImpl alive.
This patch also does the following:
1. Add a visitAggregate() method to StructureStubInfo, PolymorphicAccess, and
AccessCase to visit the CacheableIdentifier's JSCell identifier. This
visitAggregate() is called from CodeBlock::stronglyVisitStrongReferences().
When we write barrier a CodeBlock, it guarantees that its visitAggregate()
methods is called. However, it does not guarantee that its propagateTransitions()
method will be called. Since the CacheableIdentifier's reference to a cell
should be a strong reference, visiting it via a StructureStubInfo::visitAggregate()
method is the right thing to do.
See https://bugs.webkit.org/show_bug.cgi?id=205544#c7 for an example of why
propagateTransitions() doesn't always do the job.
StructureStubInfo::visitWeakReferences() is also inappropriate for this
because it is only called after all marking is done. It is also not meant
to keep cells alive but merely for clearing weak references to dead cells.
2. Also add to visitAggregate() for ModuleNamespaceData's m_identifier in
GetByStatus::markIfCheap().
3. Remove previously applied keep alive tactics to work around Box<Identifier>
destruction. This also retores the allowance to destruct DFG::Plans on a
compiler thread.
4. Added a JSString:getValueImpl() helper.
5. Added a write barrier in DFG and FTL JITFinalizer's finalizeCommon() to ensure
that frozen values are scanned by the GC.
During compilation, the frozen values were previously protected by the Plan.
After finalization, they should be protected by the CodeBlock. Hence, we
should barrier the CodeBlock since the last GC scan of the CodeBlock may have
happened before the frozen values were registered with the CodeBlock.
GC considerations:
==================
The following also addresses Yusuke's concerns in https://bugs.webkit.org/show_bug.cgi?id=205544#c10.
CacheableIdentifier is only stored as fields in 4 classes/structs:
1. AccessCase::m_identifier
2. GetByIdVariant::m_identifier
3. ModuleNamespaceData::m_identifier
4. StructureStubInfo::m_getByIdSelfIdentifier
AccessCase::m_identifier
========================
While the access case is being created and added in tryCacheGetBy(), the
CacheableIdentifier is still on the stack and protected from the GC. At the
bottom of tryCacheGetBy(), StructureStubInfo::addAccessCase() is called to add
the access case.
StructureStubInfo::addAccessCase() will barrier the owner CodeBlock at its end,
and CodeBlock::stronglyVisitStrongReferences() will visit the StructureStubInfo,
which in turn visits the AccessCase. StructureStubInfo::visitAggregate() has
been added for this purpose.
GetByIdVariant::m_identifier
============================
GetByIdVariant is only stored in GetByStatus. Both GetByIdVariant and GetByStatus
are only created and handled in the DFG/FTL compiler threads. While the compiler
thread is working with them, they are safe from the GC because the GC won't collect
objects until the compiler thread is at a SafePoint.
At compiler SafePoints, any GetByStatus that needs to be persisted is stored in
DFG::Plan::m_recordedStatuses. The Plan will visit the m_recordedStatuses in
Plan::checkLivenessAndVisitChildren().
At the end of compilation, Plan::m_recordedStatuses is transferred over to the owner
CodeBlock's DFG::CommonData in Plan::finalizeWithoutNotifyingCallback().
Plan::finalizeWithoutNotifyingCallback() will also barrier the owner CodeBlock at
its end.
Thereafter, CodeBlock::stronglyVisitStrongReferences() will visit the recordedStatuses.
ModuleNamespaceData::m_identifier
=================================
ModuleNamespaceData is only stored in a GetByStatus, and is therefore protected
similarly as the GetByIdVariant::m_identifier case above.
StructureStubInfo::m_getByIdSelfIdentifier
==========================================
StructureStubInfo::initGetByIdSelf() is called from inside tryCacheGetBy().
StructureStubInfo::initGetByIdSelf() will barrier the owner CodeBlock. The
CacheableIdentifier here is protected in the same way as the AccessCase::m_identifier
case above.
DesiredIdentifiers
==================
The compiler thread may also stash a CacheableIdentifier's uid in its
DesiredIdentifiers. Normally, the identifiers stashed in DesiredIdentifiers are
from identifiers that the CodeBlock already knows abut and manages (e.g. from
GetByIds). For uids from a cell-based CacheableIdentifier variable is passed to
a GetByVal, we need kep the cell alive in order to keep the uid alive. This is
achieved by freezing the cell with freezeStrong() in the op_get_by_val case in
the DFG BytecodeParser.
Reseting a StructureStubInfo while its IC code is still executing on the stack
==============================================================================
The concern is that IC code may call slow path / getter functions that may in turn:
1. reset the IC, and
2. run the GC.
This can be a problem if:
1. there is a scenario where we return from the slow path / getter function
and run IC code that uses the cell / uid from the CacheableIdentifier.
This is because the StructureStubInfo is what visits the that cell, which
in turn its uid alive. Once the StructureStubInfo is reset, it will no
longer be associated with any AccessCase or the m_getByIdSelfIdentifier.
As such they will not be visited, and the CacheableIdentifier may be collected
by the GC.
In practice, the generated IC code never uses the cell / uid after it calls
any slow path / getter function. I've verified this by auditing the code
generation in InlineAccess::generateSelfInAccess() and PolymorphicAccess::regenerate().
Hence, there's no issue with using a collected cell / uid.
2. there is a scenario where a slow path / getter function makes use of the cell / uid
from the CacheableIdentifier but does not protect it.
The only 2 slow path functions:
operationGetByValGeneric()
operationGetByValOptimize()
operationGetByValGeneric() does not use any CacheableIdentifier from the StructureStubInfo.
operationGetByValOptimize() modifies the StructureStubInfo in tryCacheGetBy()
under the protection of a GCSafeConcurrentJSLocker, and can reset the
StructureStubInfo. However, it does not use any CacheableIdentifier after
that.
Hence, there's also no GC issue here.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::create):
(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::commit):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::visitAggregate const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::uid const):
(JSC::AccessCase::identifier const):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::stronglyVisitStrongReferences):
* bytecode/GetByIdVariant.cpp:
(JSC::GetByIdVariant::GetByIdVariant):
(JSC::GetByIdVariant::attemptToMerge):
(JSC::GetByIdVariant::visitAggregate):
(JSC::GetByIdVariant::dumpInContext const):
* bytecode/GetByIdVariant.h:
(JSC::GetByIdVariant::identifier const):
(JSC::GetByIdVariant::overlaps):
* bytecode/GetByStatus.cpp:
(JSC::GetByStatus::computeFromLLInt):
(JSC::GetByStatus::computeFor):
(JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByStatus::visitAggregate):
(JSC::GetByStatus::singleIdentifier const):
* bytecode/GetByStatus.h:
* bytecode/GetterSetterAccessCase.cpp:
(JSC::GetterSetterAccessCase::GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::create):
* bytecode/GetterSetterAccessCase.h:
* bytecode/InstanceOfAccessCase.cpp:
(JSC::InstanceOfAccessCase::InstanceOfAccessCase):
* bytecode/IntrinsicGetterAccessCase.cpp:
(JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
(JSC::IntrinsicGetterAccessCase::create):
* bytecode/IntrinsicGetterAccessCase.h:
* bytecode/ModuleNamespaceAccessCase.cpp:
(JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
(JSC::ModuleNamespaceAccessCase::create):
* bytecode/ModuleNamespaceAccessCase.h:
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::visitAggregate):
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
* bytecode/ProxyableAccessCase.cpp:
(JSC::ProxyableAccessCase::ProxyableAccessCase):
(JSC::ProxyableAccessCase::create):
* bytecode/ProxyableAccessCase.h:
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::visitAggregate):
* bytecode/RecordedStatuses.h:
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::initGetByIdSelf):
(JSC::StructureStubInfo::addAccessCase):
(JSC::StructureStubInfo::visitAggregate):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::getByIdSelfIdentifier):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDesiredIdentifiers.cpp:
(JSC::DFG::DesiredIdentifiers::ensure):
(JSC::DFG::DesiredIdentifiers::at const):
(JSC::DFG::DesiredIdentifiers::reallyAdd):
(JSC::DFG::DesiredIdentifiers::processCodeBlockIdentifiersIfNeeded): Deleted.
* dfg/DFGDesiredIdentifiers.h:
* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalizeCommon):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::~Plan):
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
(JSC::DFG::Plan::cancel):
* dfg/DFGPlan.h:
(JSC::DFG::Plan::keepAliveIdentifier): Deleted.
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::removeAllReadyPlansForVM):
(JSC::DFG::Worklist::removeDeadPlans):
(JSC::DFG::Worklist::removeNonCompilingPlansForVM):
(JSC::DFG::Worklist::deleteCancelledPlansForVM): Deleted.
* dfg/DFGWorklist.h:
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeCommon):
* jit/JITOperations.cpp:
* jit/Repatch.cpp:
(JSC::tryCacheGetBy):
(JSC::repatchGetBy):
(JSC::tryCacheArrayGetByVal):
(JSC::tryCacheInstanceOf):
* jit/Repatch.h:
* runtime/CacheableIdentifier.cpp: Added.
(JSC::CacheableIdentifier::dump const):
* runtime/CacheableIdentifier.h: Added.
(JSC::CacheableIdentifier::CacheableIdentifier):
(JSC::CacheableIdentifier::isUid const):
(JSC::CacheableIdentifier::isCell const):
(JSC::CacheableIdentifier::isSymbol const):
(JSC::CacheableIdentifier::operator bool const):
* runtime/CacheableIdentifierInlines.h: Added.
(JSC::CacheableIdentifier::CacheableIdentifier):
(JSC::CacheableIdentifier::cell const):
(JSC::CacheableIdentifier::uid const):
(JSC::CacheableIdentifier::isCacheableIdentifierCell):
(JSC::CacheableIdentifier::isSymbolCell const):
(JSC::CacheableIdentifier::isStringCell const):
(JSC::CacheableIdentifier::setCellBits):
(JSC::CacheableIdentifier::setUidBits):
(JSC::CacheableIdentifier::visitAggregate const):
(JSC::CacheableIdentifier::operator== const):
(JSC::CacheableIdentifier::operator!= const):
* runtime/ExceptionHelpers.cpp:
(JSC::functionCallBase):
* runtime/JSString.h:
(JSC::JSString::getValueImpl const):
* runtime/VM.cpp:
(JSC::VM::ensureWatchpointSetForImpureProperty):
(JSC::VM::addImpureProperty):
(JSC::VM::registerWatchpointForImpureProperty): Deleted.
* runtime/VM.h:
Source/WebCore:
* bindings/js/CommonVM.cpp:
(WebCore::addImpureProperty):
Canonical link: https://commits.webkit.org/219286@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254464 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-01-13 23:55:57 +00:00
|
|
|
runtime/CacheableIdentifier.cpp
|
2019-04-10 19:18:20 +00:00
|
|
|
runtime/CachedBytecode.cpp
|
2020-09-04 01:03:33 +00:00
|
|
|
runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp
|
2019-01-22 18:00:14 +00:00
|
|
|
runtime/CachedTypes.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/CatchScope.cpp
|
|
|
|
runtime/ClassInfo.cpp
|
|
|
|
runtime/ClonedArguments.cpp
|
|
|
|
runtime/CodeCache.cpp
|
|
|
|
runtime/CodeSpecializationKind.cpp
|
|
|
|
runtime/CommonIdentifiers.cpp
|
|
|
|
runtime/CommonSlowPaths.cpp
|
|
|
|
runtime/CompilationResult.cpp
|
|
|
|
runtime/Completion.cpp
|
|
|
|
runtime/ConfigFile.cpp
|
|
|
|
runtime/ConsoleClient.cpp
|
|
|
|
runtime/ConsoleObject.cpp
|
|
|
|
runtime/ConstantMode.cpp
|
|
|
|
runtime/ConstructData.cpp
|
|
|
|
runtime/ControlFlowProfiler.cpp
|
|
|
|
runtime/CustomGetterSetter.cpp
|
|
|
|
runtime/DOMAttributeGetterSetter.cpp
|
|
|
|
runtime/DataView.cpp
|
|
|
|
runtime/DateConstructor.cpp
|
|
|
|
runtime/DateConversion.cpp
|
|
|
|
runtime/DateInstance.cpp
|
|
|
|
runtime/DatePrototype.cpp
|
|
|
|
runtime/DirectArguments.cpp
|
|
|
|
runtime/DirectArgumentsOffset.cpp
|
|
|
|
runtime/DirectEvalExecutable.cpp
|
2019-04-05 04:17:44 +00:00
|
|
|
runtime/DoublePredictionFuzzerAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/DumpContext.cpp
|
2020-04-07 22:32:21 +00:00
|
|
|
runtime/ECMAMode.cpp
|
2020-04-05 08:34:43 +00:00
|
|
|
runtime/EnsureStillAliveHere.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/Error.cpp
|
|
|
|
runtime/ErrorConstructor.cpp
|
|
|
|
runtime/ErrorHandlingScope.cpp
|
|
|
|
runtime/ErrorInstance.cpp
|
|
|
|
runtime/ErrorPrototype.cpp
|
2019-01-26 09:07:25 +00:00
|
|
|
runtime/ErrorType.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/EvalExecutable.cpp
|
|
|
|
runtime/Exception.cpp
|
|
|
|
runtime/ExceptionEventLocation.cpp
|
|
|
|
runtime/ExceptionFuzz.cpp
|
|
|
|
runtime/ExceptionHelpers.cpp
|
|
|
|
runtime/ExceptionScope.cpp
|
|
|
|
runtime/ExecutableBase.cpp
|
2019-12-02 06:44:16 +00:00
|
|
|
runtime/FileBasedFuzzerAgent.cpp
|
|
|
|
runtime/FileBasedFuzzerAgentBase.cpp
|
2020-07-20 21:03:16 +00:00
|
|
|
runtime/FinalizationRegistryConstructor.cpp
|
|
|
|
runtime/FinalizationRegistryPrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/FunctionConstructor.cpp
|
|
|
|
runtime/FunctionExecutable.cpp
|
|
|
|
runtime/FunctionExecutableDump.cpp
|
|
|
|
runtime/FunctionHasExecutedCache.cpp
|
|
|
|
runtime/FunctionPrototype.cpp
|
|
|
|
runtime/FunctionRareData.cpp
|
2019-04-03 22:24:47 +00:00
|
|
|
runtime/FuzzerAgent.cpp
|
2019-12-02 06:44:16 +00:00
|
|
|
runtime/FuzzerPredictions.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/GeneratorFunctionConstructor.cpp
|
|
|
|
runtime/GeneratorFunctionPrototype.cpp
|
|
|
|
runtime/GeneratorPrototype.cpp
|
2018-10-29 13:16:03 +00:00
|
|
|
runtime/GetPutInfo.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/GetterSetter.cpp
|
2019-03-22 07:14:43 +00:00
|
|
|
runtime/GlobalExecutable.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/HashMapImpl.cpp
|
|
|
|
runtime/Identifier.cpp
|
|
|
|
runtime/IndexingType.cpp
|
|
|
|
runtime/IndirectEvalExecutable.cpp
|
|
|
|
runtime/InitializeThreading.cpp
|
|
|
|
runtime/InternalFunction.cpp
|
|
|
|
runtime/Intrinsic.cpp
|
2020-09-16 04:23:41 +00:00
|
|
|
runtime/IntlCache.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/IntlCollator.cpp
|
|
|
|
runtime/IntlCollatorConstructor.cpp
|
|
|
|
runtime/IntlCollatorPrototype.cpp
|
[JSC] Implement Intl.DateTimeFormat.formatRangeToParts
https://bugs.webkit.org/show_bug.cgi?id=213822
<rdar://problem/69328711>
Reviewed by Ross Kirsling.
JSTests:
* stress/intl-datetimeformat-formatrange-relevant-extensions.js:
* stress/intl-datetimeformat-formatrange-should-not-handle-gregorian-change-date.js: Added.
(shouldBe):
(vm.icuHeaderVersion):
* stress/intl-datetimeformat-formatrange.js:
(shouldThrow):
(test):
* stress/intl-datetimeformat-formatrangetoparts-relevant-extensions-ja.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt1.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt2.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt3.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt4.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt5.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.vm.icuVersion):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt6.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt7.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt8.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt9.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt10.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt11.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt12.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt13.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt14.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt15.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt16.formatRangeToParts):
* stress/intl-datetimeformat-formatrangetoparts-relevant-extensions.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
* stress/intl-datetimeformat-formatrangetoparts-should-not-handle-gregorian-change-date.js: Added.
(shouldBe):
(compareParts):
(vm.icuHeaderVersion):
* stress/intl-datetimeformat-formatrangetoparts.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
* test262/config.yaml:
* test262/expectations.yaml: This failure is because of CLDR data inside ICU. ICU 67 will fix them.
Source/JavaScriptCore:
This patch implements Intl.DateTimeFormat.formatRangeToParts. It is already stage-4 (included in the spec).
The inputs are date interval, and this function generates array of parts of formatted string of date interval.
Currently, required ICU APIs are draft status. So, for now, we track ABI changes, and use APIs with careful version checks.
However, currently, OpenSource macOS WebKit is built with specific ICU header (ICU 62 headers). So for now, we disable it
in OpenSource macOS WebKit build. But we enable it for Apple Internal SDK WebKit build. We can enable it if we include
multiple ICU header sets and select appropriate one against the linked ICU version. In the other platforms, they are using
corresponding ICU headers so that we can just enable it.
There are two interesting implementation topics.
1. From ICU 67, the signature of udtitvfmt_formatToResult is changed. We need to switch the implementation with fine grained ICU version checks.
2. udtitvfmt_formatToResult does not have an ability to configure gregorian calendar change date: before that date, the calendar is julian.
In ECMAScript spec, we need to ignore this gregorian calendar change date, and we should handle all gregorian calendar dates as is even if
the dates are older than gregorian calendar change date. However, since udtitvfmt_formatToResult does not offer the above ability,
ICU automatically switches the calendar between gregorian and julian. To fix this issue, ICU 67 introduced udtitvfmt_formatCalendarToResult,
which can take an explicit calendar for each input date so that we configure gregorian calendar change date. But this only exists after ICU 67.
In the implementations using ICU 64-66, we just use udtitvfmt_formatToResult.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/IntlDateTimeFormat.cpp:
(JSC::UDateIntervalFormatDeleter::operator()):
(JSC::IntlDateTimeFormat::formatToParts const):
(JSC::definitelyAfterGregorianCalendarChangeDate):
(JSC::formattedValueFromDateRange):
(JSC::IntlDateTimeFormat::formatRange):
(JSC::IntlDateTimeFormat::formatRangeToParts):
* runtime/IntlDateTimeFormat.h:
* runtime/IntlDateTimeFormatPrototype.cpp:
(JSC::IntlDateTimeFormatPrototype::create):
(JSC::IntlDateTimeFormatPrototype::finishCreation):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/IntlDateTimeFormatPrototype.h:
* runtime/OptionsList.h:
Canonical link: https://commits.webkit.org/231485@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269706 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-11-12 00:25:17 +00:00
|
|
|
runtime/IntlDateTimeFormat.cpp @no-unify // Confine U_HIDE_DRAFT_API's effect to this file.
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/IntlDateTimeFormatConstructor.cpp
|
|
|
|
runtime/IntlDateTimeFormatPrototype.cpp
|
2020-07-21 00:04:06 +00:00
|
|
|
runtime/IntlDisplayNames.cpp
|
|
|
|
runtime/IntlDisplayNamesConstructor.cpp
|
|
|
|
runtime/IntlDisplayNamesPrototype.cpp
|
[JSC] Implement Intl.DateTimeFormat.formatRangeToParts
https://bugs.webkit.org/show_bug.cgi?id=213822
<rdar://problem/69328711>
Reviewed by Ross Kirsling.
JSTests:
* stress/intl-datetimeformat-formatrange-relevant-extensions.js:
* stress/intl-datetimeformat-formatrange-should-not-handle-gregorian-change-date.js: Added.
(shouldBe):
(vm.icuHeaderVersion):
* stress/intl-datetimeformat-formatrange.js:
(shouldThrow):
(test):
* stress/intl-datetimeformat-formatrangetoparts-relevant-extensions-ja.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt1.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt2.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt3.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt4.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt5.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.vm.icuVersion):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt6.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt7.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt8.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt9.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt10.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt11.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt12.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt13.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt14.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt15.formatRangeToParts):
(Intl.DateTimeFormat.formatRangeToParts.compareParts.fmt16.formatRangeToParts):
* stress/intl-datetimeformat-formatrangetoparts-relevant-extensions.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
* stress/intl-datetimeformat-formatrangetoparts-should-not-handle-gregorian-change-date.js: Added.
(shouldBe):
(compareParts):
(vm.icuHeaderVersion):
* stress/intl-datetimeformat-formatrangetoparts.js: Added.
(shouldBe):
(compareParts):
(shouldThrow):
* test262/config.yaml:
* test262/expectations.yaml: This failure is because of CLDR data inside ICU. ICU 67 will fix them.
Source/JavaScriptCore:
This patch implements Intl.DateTimeFormat.formatRangeToParts. It is already stage-4 (included in the spec).
The inputs are date interval, and this function generates array of parts of formatted string of date interval.
Currently, required ICU APIs are draft status. So, for now, we track ABI changes, and use APIs with careful version checks.
However, currently, OpenSource macOS WebKit is built with specific ICU header (ICU 62 headers). So for now, we disable it
in OpenSource macOS WebKit build. But we enable it for Apple Internal SDK WebKit build. We can enable it if we include
multiple ICU header sets and select appropriate one against the linked ICU version. In the other platforms, they are using
corresponding ICU headers so that we can just enable it.
There are two interesting implementation topics.
1. From ICU 67, the signature of udtitvfmt_formatToResult is changed. We need to switch the implementation with fine grained ICU version checks.
2. udtitvfmt_formatToResult does not have an ability to configure gregorian calendar change date: before that date, the calendar is julian.
In ECMAScript spec, we need to ignore this gregorian calendar change date, and we should handle all gregorian calendar dates as is even if
the dates are older than gregorian calendar change date. However, since udtitvfmt_formatToResult does not offer the above ability,
ICU automatically switches the calendar between gregorian and julian. To fix this issue, ICU 67 introduced udtitvfmt_formatCalendarToResult,
which can take an explicit calendar for each input date so that we configure gregorian calendar change date. But this only exists after ICU 67.
In the implementations using ICU 64-66, we just use udtitvfmt_formatToResult.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/IntlDateTimeFormat.cpp:
(JSC::UDateIntervalFormatDeleter::operator()):
(JSC::IntlDateTimeFormat::formatToParts const):
(JSC::definitelyAfterGregorianCalendarChangeDate):
(JSC::formattedValueFromDateRange):
(JSC::IntlDateTimeFormat::formatRange):
(JSC::IntlDateTimeFormat::formatRangeToParts):
* runtime/IntlDateTimeFormat.h:
* runtime/IntlDateTimeFormatPrototype.cpp:
(JSC::IntlDateTimeFormatPrototype::create):
(JSC::IntlDateTimeFormatPrototype::finishCreation):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/IntlDateTimeFormatPrototype.h:
* runtime/OptionsList.h:
Canonical link: https://commits.webkit.org/231485@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269706 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-11-12 00:25:17 +00:00
|
|
|
runtime/IntlListFormat.cpp @no-unify // Confine U_HIDE_DRAFT_API's effect in this file.
|
2020-10-25 06:20:47 +00:00
|
|
|
runtime/IntlListFormatConstructor.cpp
|
|
|
|
runtime/IntlListFormatPrototype.cpp
|
2020-05-06 06:01:07 +00:00
|
|
|
runtime/IntlLocale.cpp
|
|
|
|
runtime/IntlLocaleConstructor.cpp
|
|
|
|
runtime/IntlLocalePrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/IntlNumberFormat.cpp
|
|
|
|
runtime/IntlNumberFormatConstructor.cpp
|
|
|
|
runtime/IntlNumberFormatPrototype.cpp
|
|
|
|
runtime/IntlObject.cpp
|
2018-04-26 16:37:26 +00:00
|
|
|
runtime/IntlPluralRules.cpp
|
|
|
|
runtime/IntlPluralRulesConstructor.cpp
|
|
|
|
runtime/IntlPluralRulesPrototype.cpp
|
[ECMA-402] Intl.RelativeTimeFormat missing in WebKit
https://bugs.webkit.org/show_bug.cgi?id=209770
Reviewed by Darin Adler.
JSTests:
* stress/intl-relativetimeformat.js: Added.
* test262/config.yaml:
Enable Intl.RelativeTimeFormat feature with flag.
* test262/expectations.yaml:
Mark known failures.
Test for locale validation is not specific to RelativeTimeFormat and should be investigated separately.
Tests for Polish appear to be wrong and should be corrected in test262.
Source/JavaScriptCore:
This patch implements the recent ECMA-402 feature Intl.RelativeTimeFormat.
RelativeTimeFormat has format / formatToParts functions like NumberFormat / DateTimeFormat
and is used to turn a number and unit into a formatted relative time string, e.g.:
new Intl.RelativeTimeFormat('en').format(10, 'day')
> 'in 10 days'
new Intl.RelativeTimeFormat('en', { numeric: 'auto' }).format(0, 'day')
> 'today'
Implementation of RelativeTimeFormat#formatToParts makes direct use of NumberFormat#formatToParts,
as the relative time string consists of at most one formatted number with optional literal text on either side.
This feature is runtime-guarded by the `useIntlRelativeTimeFormat` option.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/CommonIdentifiers.h:
* runtime/IntlRelativeTimeFormat.cpp: Added.
* runtime/IntlRelativeTimeFormat.h: Added.
* runtime/IntlRelativeTimeFormatConstructor.cpp: Added.
* runtime/IntlRelativeTimeFormatConstructor.h: Added.
* runtime/IntlRelativeTimeFormatPrototype.cpp: Added.
* runtime/IntlRelativeTimeFormatPrototype.h: Added.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::relativeTimeFormatStructure):
* runtime/OptionsList.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Add feature and runtime option.
* runtime/IntlDateTimeFormat.cpp:
(JSC::IntlDateTimeFormat::formatToParts):
* runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::initializePluralRules):
(JSC::IntlPluralRules::resolvedOptions):
Make "type" a property name.
* runtime/IntlNumberFormat.cpp:
(JSC::IntlNumberFormat::initializeNumberFormat):
(JSC::IntlNumberFormat::resolvedOptions):
(JSC::IntlNumberFormat::formatToPartsInternal):
(JSC::IntlNumberFormat::formatToParts):
* runtime/IntlNumberFormat.h:
Factor out formatToPartsInternal so that RelativeTimeFormat can use it with its own UNumberFormat.
(This logic is too complicated to duplicate; it's because ICU won't split, e.g., "10,000" into parts for us.)
* runtime/IntlObject.cpp:
(JSC::IntlObject::IntlObject):
(JSC::IntlObject::create):
(JSC::IntlObject::finishCreation):
(JSC::intlAvailableLocales):
(JSC::intlCollatorAvailableLocales):
(JSC::isUnicodeLocaleIdentifierType):
(JSC::supportedLocales):
(JSC::intlDateTimeFormatAvailableLocales): Deleted.
(JSC::intlNumberFormatAvailableLocales): Deleted.
* runtime/IntlObject.h:
(JSC::intlDateTimeFormatAvailableLocales):
(JSC::intlNumberFormatAvailableLocales):
(JSC::intlPluralRulesAvailableLocales):
(JSC::intlRelativeTimeFormatAvailableLocales):
Perform three corrections for Intl classes:
1. Collator should be the only class with unique "available locales".
[unum|udat]_getAvailable exist but they've deferred to uloc_getAvailable for 20 years.
2. isUnicodeLocaleIdentifierType isn't just `alphanum{3,8}` but rather `alphanum{3,8} (sep alphanum{3,8})*`.
This is my own mistake from r239941.
3. supportedLocalesOf entries should not be frozen.
Changed in https://github.com/tc39/ecma402/pull/278.
* tools/JSDollarVM.cpp:
(JSC::functionICUVersion):
(JSC::JSDollarVM::finishCreation):
Add $vm.icuVersion so that we can add per-line skips to stress tests.
Tools:
* Scripts/run-jsc-stress-tests:
Add runIntlRelativeTimeFormatEnabled.
Canonical link: https://commits.webkit.org/223609@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260349 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-20 05:15:35 +00:00
|
|
|
runtime/IntlRelativeTimeFormat.cpp
|
|
|
|
runtime/IntlRelativeTimeFormatConstructor.cpp
|
|
|
|
runtime/IntlRelativeTimeFormatPrototype.cpp
|
2020-08-22 19:22:24 +00:00
|
|
|
runtime/IntlSegmentIterator.cpp
|
|
|
|
runtime/IntlSegmentIteratorPrototype.cpp
|
|
|
|
runtime/IntlSegmenter.cpp
|
|
|
|
runtime/IntlSegmenterConstructor.cpp
|
|
|
|
runtime/IntlSegmenterPrototype.cpp
|
|
|
|
runtime/IntlSegments.cpp
|
|
|
|
runtime/IntlSegmentsPrototype.cpp
|
2021-04-13 02:04:15 +00:00
|
|
|
runtime/IntlWorkaround.cpp @no-unify // Confine U_HIDE_DRAFT_API's effect to this file.
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/IteratorOperations.cpp
|
|
|
|
runtime/IteratorPrototype.cpp
|
|
|
|
runtime/JSArray.cpp
|
|
|
|
runtime/JSArrayBuffer.cpp
|
|
|
|
runtime/JSArrayBufferConstructor.cpp
|
|
|
|
runtime/JSArrayBufferPrototype.cpp
|
|
|
|
runtime/JSArrayBufferView.cpp
|
|
|
|
runtime/JSAsyncFunction.cpp
|
2019-10-02 21:23:09 +00:00
|
|
|
runtime/JSAsyncGenerator.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSAsyncGeneratorFunction.cpp
|
2020-01-09 06:07:29 +00:00
|
|
|
runtime/JSArrayIterator.cpp
|
2017-12-12 21:01:57 +00:00
|
|
|
runtime/JSBigInt.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSBoundFunction.cpp
|
2019-09-12 15:04:29 +00:00
|
|
|
runtime/JSCConfig.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSCJSValue.cpp
|
2019-03-20 23:32:26 +00:00
|
|
|
runtime/JSCPtrTag.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSCallee.cpp
|
|
|
|
runtime/JSCell.cpp
|
2021-02-15 23:08:52 +00:00
|
|
|
runtime/JSCustomGetterFunction.cpp
|
|
|
|
runtime/JSCustomSetterFunction.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSDataView.cpp
|
|
|
|
runtime/JSDataViewPrototype.cpp
|
2020-12-15 21:38:51 +00:00
|
|
|
runtime/JSDateMath.cpp @no-unify // Confine U_SHOW_CPLUSPLUS_API's effect to this file.
|
2017-11-30 04:39:50 +00:00
|
|
|
runtime/JSDestructibleObjectHeapCellType.cpp
|
2020-07-20 21:03:16 +00:00
|
|
|
runtime/JSFinalizationRegistry.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSFunction.cpp
|
[JSC] Generator should have internal fields
https://bugs.webkit.org/show_bug.cgi?id=201159
Reviewed by Keith Miller.
JSTests:
* stress/create-generator.js: Added.
(shouldBe):
(test.generator):
(test):
* stress/generator-construct-failure.js: Added.
(shouldThrow):
(TypeError):
* stress/generator-prototype-change.js: Added.
(shouldBe):
(gen):
* stress/generator-prototype-closure.js: Added.
(shouldBe):
(test.gen):
(test):
* stress/object-assign-fast-path.js:
Source/JavaScriptCore:
This patch makes generator's internal states InternalField instead of private properties.
Each generator function produces a generator with different [[Prototype]], which makes generators have different Structures.
As a result, Generator.prototype.next etc.'s implementation becomes megamorphic even if it is not necessary.
If we make these structures adaptively poly-proto, some generators get poly-proto structures while others are not, resulting
in megamorphic lookup in Generator.prototype.next. If we make all the generator's structure poly-proto, it makes Generator.prototype.next
lookup suboptimal for now.
In this patch, we start with a relatively simple solution. This patch introduces JSGenerator class, and it has internal fields for generator's internal
states. We extend promise-internal-field access bytecodes to access to these fields from bytecode so that Generator.prototype.next can access
these fields without using megamorphic get_by_id_direct.
And we attach JSGeneratorType to JSGenerator so that we can efficiently implement `@isGenerator()` check in bytecode.
We reserve the offset = 0 slot for the future poly-proto extension for JSGenerator. By reserving this slot, non-poly-proto JSGenerator and poly-proto
JSGenerator still can offer the way to access to the same Generator internal fields with the same offset while poly-proto JSGenerator can get offset = 0
inline-storage slot for PolyProto implementation.
This patch adds op_create_generator since it is distinct from op_create_promise once we add PolyProto support.
In the future when we introduce some kind of op_create_async_generator we will probably share only one bytecode for both generator and async generator.
This patch offers around 10% improvement in JetStream2/Basic. And this patch is the basis of optimization of JetStream2/async-fs which leverages async generators significantly.
This patch includes several design decisions.
1. We add a new JSGenerator instead of leveraging JSFinalObject. The main reason is that we would like to have JSGeneratorType to quickly query `@isGenerator`.
2. This patch currently does not include object-allocation-sinking support for JSGenerator, but it is trivial, and will be added. And this patch also does not include poly-proto
support for JSGenerator. The main reason is simply because this patch is already large enough, and I do not want to make this patch larger and larger.
3. We can support arbitrary sized inline-storage: Reserving 0-5 offsets for internal fields, and start putting all the other things to the subsequent internal fields. But for now,
we are not taking this approach just because I'm not sure this is necessary. If we found such a pattern, we can easily extend the current one but for now, I would like to keep
this patch simple.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/AsyncFunctionPrototype.js:
(globalPrivate.asyncFunctionResume):
* builtins/GeneratorPrototype.js:
(globalPrivate.generatorResume):
(next):
(return):
(throw):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::run):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/SpeculatedType.cpp:
(JSC::speculationFromJSType):
* bytecode/SpeculatedType.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitPutGeneratorFields):
(JSC::BytecodeGenerator::emitCreateGenerator):
(JSC::BytecodeGenerator::emitNewGenerator):
(JSC::BytecodeGenerator::emitYield):
(JSC::BytecodeGenerator::emitDelegateYield):
(JSC::BytecodeGenerator::emitGeneratorStateChange):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitIsGenerator):
(JSC::BytecodeGenerator::generatorStateRegister):
(JSC::BytecodeGenerator::generatorValueRegister):
(JSC::BytecodeGenerator::generatorResumeModeRegister):
(JSC::BytecodeGenerator::generatorFrameRegister):
* bytecompiler/NodesCodegen.cpp:
(JSC::generatorInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_putGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isGenerator):
(JSC::FunctionNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupIsCellWithType):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToNewGenerator):
(JSC::DFG::Node::speculatedTypeForQuery):
(JSC::DFG::Node::hasStructure):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCreatePromise):
(JSC::DFG::SpeculativeJIT::compileCreateGenerator):
(JSC::DFG::SpeculativeJIT::compileNewGenerator):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileNewGenerator):
(JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateGenerator):
(JSC::FTL::DFG::LowerDFGToB3::isCellWithType):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_internal_field):
(JSC::JIT::emit_op_put_internal_field):
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::createSubclassStructureSlow):
* runtime/InternalFunction.h:
(JSC::InternalFunction::createSubclassStructure):
* runtime/JSGenerator.cpp: Added.
(JSC::JSGenerator::create):
(JSC::JSGenerator::createStructure):
(JSC::JSGenerator::JSGenerator):
(JSC::JSGenerator::finishCreation):
(JSC::JSGenerator::visitChildren):
* runtime/JSGenerator.h: Copied from Source/JavaScriptCore/runtime/JSGeneratorFunction.h.
* runtime/JSGeneratorFunction.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::generatorStructure const):
* runtime/JSType.cpp:
(WTF::printInternal):
* runtime/JSType.h:
Canonical link: https://commits.webkit.org/215550@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250025 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-18 05:02:45 +00:00
|
|
|
runtime/JSGenerator.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSGeneratorFunction.cpp
|
|
|
|
runtime/JSGlobalLexicalEnvironment.cpp
|
|
|
|
runtime/JSGlobalObject.cpp
|
|
|
|
runtime/JSGlobalObjectDebuggable.cpp
|
|
|
|
runtime/JSGlobalObjectFunctions.cpp
|
2018-05-22 18:04:31 +00:00
|
|
|
runtime/JSImmutableButterfly.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSInternalPromise.cpp
|
|
|
|
runtime/JSInternalPromiseConstructor.cpp
|
|
|
|
runtime/JSInternalPromisePrototype.cpp
|
|
|
|
runtime/JSLexicalEnvironment.cpp
|
|
|
|
runtime/JSLock.cpp
|
|
|
|
runtime/JSMap.cpp
|
|
|
|
runtime/JSMapIterator.cpp
|
2018-08-02 03:55:47 +00:00
|
|
|
runtime/JSMicrotask.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSModuleEnvironment.cpp
|
|
|
|
runtime/JSModuleLoader.cpp
|
|
|
|
runtime/JSModuleNamespaceObject.cpp
|
|
|
|
runtime/JSModuleRecord.cpp
|
|
|
|
runtime/JSNativeStdFunction.cpp
|
|
|
|
runtime/JSONObject.cpp
|
|
|
|
runtime/JSObject.cpp
|
|
|
|
runtime/JSPromise.cpp
|
|
|
|
runtime/JSPromiseConstructor.cpp
|
|
|
|
runtime/JSPromisePrototype.cpp
|
|
|
|
runtime/JSPropertyNameEnumerator.cpp
|
|
|
|
runtime/JSProxy.cpp
|
|
|
|
runtime/JSRunLoopTimer.cpp
|
|
|
|
runtime/JSScope.cpp
|
|
|
|
runtime/JSScriptFetcher.cpp
|
Support integrity="" on module scripts
https://bugs.webkit.org/show_bug.cgi?id=177959
Reviewed by Sam Weinig.
Source/JavaScriptCore:
This patch adds Subresource Integrity check for module scripts. Currently,
only top-level module can be verified with integrity parameter since there
is no way to perform integrity check onto the imported modules.
In JSC side, we add `parameters` to the entry point of the module loader
pipeline. This is fetching parameters and used when fetching modules.
We separately pass this parameters to the pipeline along with the script fetcher.
The script fetcher is only one for module graph since this is the initiator of
this module graph loading. On the other hand, this parameters is for each
module fetching. While setting "integrity" parameters to this script fetcher is
sufficient to pass parameters to top-level-module's fetching, it is not enough
for the future extension.
In the future, we will investigate a way to pass parameters to each non-top-level
module. At that time, this `parameters` should be per-module. This is because
"integrity" value should be different for each module. For example, we will accept
some form of syntax to add parameters to `import`. Some proposed syntax is like
https://discourse.wicg.io/t/specifying-nonce-or-integrity-when-importing-modules/1861
import "./xxx.js" integrity "xxxxxxx"
In this case, this `parameters` will be passed to "./xxx.js" module fetching. This
`parameters` should be different from the one of top-level-module's one. That's why
we need per-module `parameters` and why this patch adds `parameters` to the module pipeline.
On the other hand, we also want to keep script fetcher. This `per-module-graph` thing
is important to offer module-graph-wide information. For example, import.meta would
have `import.meta.scriptElement`, which is the script element fetching the module graph
including this. So, we keep the both, script fetcher and parameters.
https://github.com/tc39/proposal-import-meta
This parameters will be finally used by pipeline's fetch hook, and WebCore side
can use this parameters to fetch modules.
We also further clean up the module pipeline by dropping unnecessary features.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/ModuleLoaderPrototype.js:
(requestFetch):
(requestInstantiate):
(requestSatisfy):
(loadModule):
(loadAndEvaluateModule):
This loadAndEvaluateModule should be implemented by just calling loadModule and
linkAndEvaluateModule. We can drop requestReady and requestLink.
(requestLink): Deleted.
(requestImportModule): Deleted.
* jsc.cpp:
(GlobalObject::moduleLoaderImportModule):
(GlobalObject::moduleLoaderFetch):
import and fetch hook takes parameters. Currently, we always pass `undefined` for
import hook. When dynamic `import()` is extended to accept additional parameters
like integrity, this parameters will be replaced with the actual value.
(functionLoadModule):
(runWithOptions):
* runtime/Completion.cpp:
(JSC::loadAndEvaluateModule):
(JSC::loadModule):
(JSC::importModule):
* runtime/Completion.h:
* runtime/JSGlobalObject.h:
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncImportModule):
* runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::loadAndEvaluateModule):
(JSC::JSModuleLoader::loadModule):
(JSC::JSModuleLoader::requestImportModule):
(JSC::JSModuleLoader::importModule):
(JSC::JSModuleLoader::fetch):
* runtime/JSModuleLoader.h:
* runtime/JSScriptFetchParameters.cpp: Added.
(JSC::JSScriptFetchParameters::destroy):
* runtime/JSScriptFetchParameters.h: Added.
(JSC::JSScriptFetchParameters::createStructure):
(JSC::JSScriptFetchParameters::create):
(JSC::JSScriptFetchParameters::parameters const):
(JSC::JSScriptFetchParameters::JSScriptFetchParameters):
Add ScriptFetchParameters' JSCell wrapper, JSScriptFetchParameters.
It is used in the module pipeline.
* runtime/JSType.h:
* runtime/ModuleLoaderPrototype.cpp:
(JSC::moduleLoaderPrototypeFetch):
* runtime/ScriptFetchParameters.h: Added.
(JSC::ScriptFetchParameters::~ScriptFetchParameters):
Add ScriptFetchParameters. We can define our own custom ScriptFetchParameters
by inheriting this class. WebCore creates ModuleFetchParameters by inheriting
this.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Source/WebCore:
This patch extends module hooks to accept fetching parameters.
When starting fetching modules, WebCore creates ModuleFetchParameters.
And this parameters is propagated to the fetch hook. Then, fetch
hook can use this parameters to fetch modules.
This parameters only contains `integrity` field. This "integrity" is
used to perform subresource integrity check in module loader pipeline.
And this error is just proparaged as errors in module pipeline, which
is the same to the other types of errors in module pipeline.
Test: http/tests/subresource-integrity/sri-module.html
* ForwardingHeaders/runtime/JSScriptFetchParameters.h: Added.
* ForwardingHeaders/runtime/ScriptFetchParameters.h: Added.
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/CachedModuleScriptLoader.cpp:
(WebCore::CachedModuleScriptLoader::create):
(WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader):
Take parameters, which includes "integrity".
* bindings/js/CachedModuleScriptLoader.h:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::moduleLoaderFetch):
(WebCore::JSDOMWindowBase::moduleLoaderImportModule):
import and fetch hooks take parameters.
* bindings/js/JSDOMWindowBase.h:
* bindings/js/JSMainThreadExecState.h:
(WebCore::JSMainThreadExecState::loadModule):
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::loadModuleScriptInWorld):
(WebCore::ScriptController::loadModuleScript):
Pass parameters to the entry point of the module pipeline.
* bindings/js/ScriptController.h:
* bindings/js/ScriptModuleLoader.cpp:
(WebCore::ScriptModuleLoader::fetch):
If parameters are passed, we set them to CachedModuleScriptLoader.
(WebCore::ScriptModuleLoader::importModule):
Pass parameters to the entry point of dynamic import.
(WebCore::ScriptModuleLoader::notifyFinished):
If script loader has parameters, we perform subresource integrity check here.
* bindings/js/ScriptModuleLoader.h:
* dom/LoadableModuleScript.cpp:
(WebCore::LoadableModuleScript::create):
(WebCore::LoadableModuleScript::LoadableModuleScript):
(WebCore::LoadableModuleScript::load):
Create ModuleFetchParameters with "integrity" value.
* dom/LoadableModuleScript.h:
* dom/ModuleFetchParameters.h: Copied from Source/WebCore/bindings/js/CachedModuleScriptLoader.h.
(WebCore::ModuleFetchParameters::create):
(WebCore::ModuleFetchParameters::integrity const):
(WebCore::ModuleFetchParameters::ModuleFetchParameters):
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::requestModuleScript):
Pass "integrity" value to the module script.
LayoutTests:
* http/tests/subresource-integrity/resources/crossorigin-anon-script-module.js: Added.
* http/tests/subresource-integrity/resources/crossorigin-creds-script-module.js: Added.
* http/tests/subresource-integrity/resources/crossorigin-ineligible-script-module.js: Added.
* http/tests/subresource-integrity/resources/matching-digest-module.js: Added.
* http/tests/subresource-integrity/resources/non-matching-digest-module.js: Added.
* http/tests/subresource-integrity/resources/sri-utilities.js:
(add_result_callback):
(SRIModuleTest):
(SRIModuleTest.prototype.execute):
* http/tests/subresource-integrity/sri-module-expected.txt: Added.
* http/tests/subresource-integrity/sri-module.html: Added.
* js/dom/modules/module-inline-ignore-integrity-expected.txt: Added.
* js/dom/modules/module-inline-ignore-integrity.html: Added.
* js/dom/modules/module-integrity-non-top-level-expected.txt: Added.
* js/dom/modules/module-integrity-non-top-level.html: Added.
* js/dom/modules/script-tests/module-integrity-non-top-level-2.js: Added.
* js/dom/modules/script-tests/module-integrity-non-top-level.js: Added.
Canonical link: https://commits.webkit.org/194461@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223237 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-12 13:12:48 +00:00
|
|
|
runtime/JSScriptFetchParameters.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSSegmentedVariableObject.cpp
|
|
|
|
runtime/JSSet.cpp
|
|
|
|
runtime/JSSetIterator.cpp
|
|
|
|
runtime/JSSourceCode.cpp
|
|
|
|
runtime/JSString.cpp
|
|
|
|
runtime/JSStringIterator.cpp
|
|
|
|
runtime/JSStringJoiner.cpp
|
|
|
|
runtime/JSSymbolTableObject.cpp
|
2018-02-13 18:10:30 +00:00
|
|
|
runtime/JSTemplateObjectDescriptor.cpp
|
2018-10-29 13:16:03 +00:00
|
|
|
runtime/JSType.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSTypedArrayConstructors.cpp
|
|
|
|
runtime/JSTypedArrayPrototypes.cpp
|
|
|
|
runtime/JSTypedArrayViewConstructor.cpp
|
|
|
|
runtime/JSTypedArrayViewPrototype.cpp
|
|
|
|
runtime/JSTypedArrays.cpp
|
|
|
|
runtime/JSWeakMap.cpp
|
2019-06-18 21:02:19 +00:00
|
|
|
runtime/JSWeakObjectRef.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/JSWeakSet.cpp
|
|
|
|
runtime/JSWithScope.cpp
|
|
|
|
runtime/JSWrapperObject.cpp
|
|
|
|
runtime/LazyClassStructure.cpp
|
2019-04-10 19:18:20 +00:00
|
|
|
runtime/LeafExecutable.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/LiteralParser.cpp
|
|
|
|
runtime/Lookup.cpp
|
|
|
|
runtime/MapConstructor.cpp
|
|
|
|
runtime/MapIteratorPrototype.cpp
|
|
|
|
runtime/MapPrototype.cpp
|
|
|
|
runtime/MatchResult.cpp
|
|
|
|
runtime/MathCommon.cpp
|
|
|
|
runtime/MathObject.cpp
|
|
|
|
runtime/MemoryStatistics.cpp
|
|
|
|
runtime/ModuleProgramExecutable.cpp
|
2020-01-08 23:41:30 +00:00
|
|
|
runtime/NarrowingNumberPredictionFuzzerAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/NativeErrorConstructor.cpp
|
|
|
|
runtime/NativeErrorPrototype.cpp
|
|
|
|
runtime/NativeExecutable.cpp
|
|
|
|
runtime/NullGetterFunction.cpp
|
|
|
|
runtime/NullSetterFunction.cpp
|
|
|
|
runtime/NumberConstructor.cpp
|
|
|
|
runtime/NumberObject.cpp
|
2020-01-08 23:41:30 +00:00
|
|
|
runtime/NumberPredictionFuzzerAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/NumberPrototype.cpp
|
|
|
|
runtime/ObjectConstructor.cpp
|
|
|
|
runtime/ObjectInitializationScope.cpp
|
|
|
|
runtime/ObjectPrototype.cpp
|
|
|
|
runtime/Operations.cpp
|
2019-10-22 00:17:50 +00:00
|
|
|
runtime/Options.cpp
|
2019-12-02 06:44:16 +00:00
|
|
|
runtime/PredictionFileCreatingFuzzerAgent.cpp
|
2020-09-23 17:19:38 +00:00
|
|
|
runtime/PrivateFieldPutKind.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/ProgramExecutable.cpp
|
2020-07-20 21:03:16 +00:00
|
|
|
runtime/DeferredWorkTimer.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/PropertyDescriptor.cpp
|
|
|
|
runtime/PropertySlot.cpp
|
|
|
|
runtime/PropertyTable.cpp
|
|
|
|
runtime/ProxyConstructor.cpp
|
|
|
|
runtime/ProxyObject.cpp
|
|
|
|
runtime/ProxyRevoke.cpp
|
2019-04-03 22:24:47 +00:00
|
|
|
runtime/RandomizingFuzzerAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/ReflectObject.cpp
|
|
|
|
runtime/RegExp.cpp
|
|
|
|
runtime/RegExpCache.cpp
|
|
|
|
runtime/RegExpCachedResult.cpp
|
|
|
|
runtime/RegExpConstructor.cpp
|
2019-01-28 19:52:17 +00:00
|
|
|
runtime/RegExpGlobalData.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/RegExpMatchesArray.cpp
|
|
|
|
runtime/RegExpObject.cpp
|
|
|
|
runtime/RegExpPrototype.cpp
|
2019-06-18 21:21:48 +00:00
|
|
|
runtime/RegExpStringIteratorPrototype.cpp
|
2021-03-30 22:46:57 +00:00
|
|
|
runtime/ResourceExhaustion.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/RuntimeType.cpp
|
|
|
|
runtime/SamplingCounter.cpp
|
|
|
|
runtime/SamplingProfiler.cpp
|
|
|
|
runtime/ScopeOffset.cpp
|
|
|
|
runtime/ScopedArguments.cpp
|
|
|
|
runtime/ScopedArgumentsTable.cpp
|
|
|
|
runtime/ScriptExecutable.cpp
|
|
|
|
runtime/SetConstructor.cpp
|
|
|
|
runtime/SetIteratorPrototype.cpp
|
|
|
|
runtime/SetPrototype.cpp
|
|
|
|
runtime/SimpleTypedArrayController.cpp
|
|
|
|
runtime/SmallStrings.cpp
|
|
|
|
runtime/SparseArrayValueMap.cpp
|
|
|
|
runtime/StackFrame.cpp
|
|
|
|
runtime/StrictEvalActivation.cpp
|
|
|
|
runtime/StringConstructor.cpp
|
|
|
|
runtime/StringIteratorPrototype.cpp
|
|
|
|
runtime/StringObject.cpp
|
|
|
|
runtime/StringPrototype.cpp
|
|
|
|
runtime/StringRecursionChecker.cpp
|
|
|
|
runtime/Structure.cpp
|
2017-10-10 07:58:27 +00:00
|
|
|
runtime/StructureCache.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/StructureChain.cpp
|
|
|
|
runtime/StructureIDTable.cpp
|
|
|
|
runtime/StructureRareData.cpp
|
|
|
|
runtime/Symbol.cpp
|
|
|
|
runtime/SymbolConstructor.cpp
|
|
|
|
runtime/SymbolObject.cpp
|
|
|
|
runtime/SymbolPrototype.cpp
|
|
|
|
runtime/SymbolTable.cpp
|
2018-02-13 18:10:30 +00:00
|
|
|
runtime/TemplateObjectDescriptor.cpp
|
2021-07-07 00:48:50 +00:00
|
|
|
runtime/TemporalNow.cpp
|
|
|
|
runtime/TemporalObject.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/TestRunnerUtils.cpp
|
|
|
|
runtime/ThrowScope.cpp
|
|
|
|
runtime/TypeLocationCache.cpp
|
|
|
|
runtime/TypeProfiler.cpp
|
|
|
|
runtime/TypeProfilerLog.cpp
|
|
|
|
runtime/TypeSet.cpp
|
|
|
|
runtime/TypedArrayController.cpp
|
|
|
|
runtime/TypedArrayType.cpp
|
|
|
|
runtime/TypeofType.cpp
|
|
|
|
runtime/VM.cpp
|
|
|
|
runtime/VMEntryScope.cpp
|
|
|
|
runtime/VMTraps.cpp
|
|
|
|
runtime/VarOffset.cpp
|
|
|
|
runtime/Watchdog.cpp
|
|
|
|
runtime/WeakMapConstructor.cpp
|
[JSC] Implement optimized WeakMap and WeakSet
https://bugs.webkit.org/show_bug.cgi?id=179929
Reviewed by Saam Barati.
JSTests:
* microbenchmarks/weak-map-key.js:
* microbenchmarks/weak-set-key.js: Copied from JSTests/microbenchmarks/weak-map-key.js.
(assert):
(objectKey):
(let.start.Date.now):
* stress/basic-weakmap.js: Added.
(shouldBe):
(test):
* stress/basic-weakset.js: Added.
(shouldBe):
(test.set new):
* stress/weakmap-cse-set-break.js: Added.
(shouldBe):
(test):
* stress/weakmap-cse.js: Added.
(shouldBe):
(test):
* stress/weakmap-gc.js: Added.
(test):
* stress/weakset-cse-add-break.js: Added.
(shouldBe):
(test.set new):
* stress/weakset-cse.js: Added.
(shouldBe):
(test.set new):
* stress/weakset-gc.js: Added.
(test.set add):
(test.set new):
(test):
Source/JavaScriptCore:
This patch introduces WeakMapImpl to optimize WeakMap and WeakSet.
This is similar to HashMapImpl. But,
1. WeakMapImpl's bucket is not allocated in GC heap since WeakMap
do not need to have iterators.
2. WeakMapImpl's buffer is allocated in JSValue Gigacage instead
of auxiliary buffer. This is because we would like to allocate buffer
when finalizing GC. At that time, WeakMapImpl prunes dead entries and
shrink it if necessary. However, allocating from the GC heap during
finalization is not allowed.
In particular, (2) is important since it ensures any WeakMap operations
do not cause GC. Since GC may collect dead keys in WeakMap, rehash WeakMap,
and reallocate/change WeakMap's buffer, ensuring that any WeakMap operations
do not cause GC makes our implementation simple. To ensure this, we place
DisallowGC for each WeakMap's interface.
In DFG, we introduce WeakMapGet and ExtractValueFromWeakMapGet nodes.
WeakMapGet looks up entry in WeakMapImpl and returns value. If it is
WeakMap, it returns value. And it returns key if it is WeakSet. If it
does not find a corresponding entry, it returns JSEmpty.
ExtractValueFromWeakMapGet converts JSEmpty to JSUndefined.
This patch improves WeakMap and WeakSet operations.
baseline patched
weak-set-key 240.6932+-10.4923 ^ 148.7606+-6.1784 ^ definitely 1.6180x faster
weak-map-key 174.3176+-8.2680 ^ 151.7053+-6.8723 ^ definitely 1.1491x faster
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* dfg/DFGAbstractHeap.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileExtractValueFromWeakMapGet):
(JSC::DFG::SpeculativeJIT::compileWeakMapGet):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileExtractValueFromWeakMapGet):
(JSC::FTL::DFG::LowerDFGToB3::compileWeakMapGet):
* inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::weakMapEntries):
(Inspector::JSInjectedScriptHost::weakSetEntries):
Existing code is incorrect. They can run GC and break WeakMap's iterator.
We introduce takeSnapshot function to WeakMapImpl, which retrieves live
entries without causing any GC.
* runtime/HashMapImpl.h:
(JSC::shouldShrink):
(JSC::shouldRehashAfterAdd):
(JSC::nextCapacity):
(JSC::HashMapImpl::shouldRehashAfterAdd const):
(JSC::HashMapImpl::shouldShrink const):
(JSC::HashMapImpl::rehash):
(JSC::WeakMapHash::hash): Deleted.
(JSC::WeakMapHash::equal): Deleted.
* runtime/Intrinsic.cpp:
(JSC::intrinsicName):
* runtime/Intrinsic.h:
* runtime/JSWeakMap.cpp:
* runtime/JSWeakMap.h:
* runtime/JSWeakSet.cpp:
* runtime/JSWeakSet.h:
* runtime/VM.cpp:
* runtime/WeakGCMap.h:
(JSC::WeakGCMap::forEach): Deleted.
* runtime/WeakMapBase.cpp: Removed.
* runtime/WeakMapBase.h: Removed.
* runtime/WeakMapConstructor.cpp:
(JSC::constructWeakMap):
* runtime/WeakMapImpl.cpp: Added.
(JSC::WeakMapImpl<WeakMapBucket>::destroy):
(JSC::WeakMapImpl<WeakMapBucket>::visitChildren):
(JSC::WeakMapImpl<WeakMapBucket>::estimatedSize):
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKey>>::visitWeakReferences):
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitWeakReferences):
(JSC::WeakMapImpl<WeakMapBucket>::finalizeUnconditionally):
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKey>>::takeSnapshot):
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::takeSnapshot):
* runtime/WeakMapImpl.h: Added.
(JSC::jsWeakMapHash):
(JSC::nextCapacityAfterRemoveBatching):
(JSC::WeakMapBucket::setKey):
(JSC::WeakMapBucket::setValue):
(JSC::WeakMapBucket::key const):
(JSC::WeakMapBucket::value const):
(JSC::WeakMapBucket::copyFrom):
(JSC::WeakMapBucket::offsetOfKey):
(JSC::WeakMapBucket::offsetOfValue):
(JSC::WeakMapBucket::extractValue):
(JSC::WeakMapBucket::isEmpty):
(JSC::WeakMapBucket::deletedKey):
(JSC::WeakMapBucket::isDeleted):
(JSC::WeakMapBucket::makeDeleted):
(JSC::WeakMapBucket::visitAggregate):
(JSC::WeakMapBucket::clearValue):
(JSC::WeakMapBuffer::allocationSize):
(JSC::WeakMapBuffer::buffer const):
(JSC::WeakMapBuffer::create):
(JSC::WeakMapBuffer::reset):
(JSC::WeakMapImpl::WeakMapImpl):
(JSC::WeakMapImpl::finishCreation):
(JSC::WeakMapImpl::get):
(JSC::WeakMapImpl::has):
(JSC::WeakMapImpl::add):
(JSC::WeakMapImpl::remove):
(JSC::WeakMapImpl::size const):
(JSC::WeakMapImpl::offsetOfBuffer):
(JSC::WeakMapImpl::offsetOfCapacity):
(JSC::WeakMapImpl::findBucket):
(JSC::WeakMapImpl::buffer const):
(JSC::WeakMapImpl::forEach):
(JSC::WeakMapImpl::shouldRehashAfterAdd const):
(JSC::WeakMapImpl::shouldShrink const):
(JSC::WeakMapImpl::canUseBucket):
(JSC::WeakMapImpl::addInternal):
(JSC::WeakMapImpl::findBucketAlreadyHashed):
(JSC::WeakMapImpl::rehash):
(JSC::WeakMapImpl::checkConsistency const):
(JSC::WeakMapImpl::makeAndSetNewBuffer):
(JSC::WeakMapImpl::assertBufferIsEmpty const):
(JSC::WeakMapImpl::DeadKeyCleaner::target):
* runtime/WeakMapPrototype.cpp:
(JSC::WeakMapPrototype::finishCreation):
(JSC::protoFuncWeakMapGet):
(JSC::protoFuncWeakMapHas):
* runtime/WeakSetConstructor.cpp:
(JSC::constructWeakSet):
* runtime/WeakSetPrototype.cpp:
(JSC::WeakSetPrototype::finishCreation):
(JSC::protoFuncWeakSetHas):
(JSC::protoFuncWeakSetAdd):
Source/WTF:
We introduce JSValueMalloc, which is specialized malloc scheme with Gigacage::JSValue.
This is used for WeakMapImpl's buffer.
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/JSValueMalloc.cpp: Added.
(WTF::tryJSValueMalloc):
(WTF::jsValueMalloc):
(WTF::jsValueRealloc):
(WTF::jsValueFree):
* wtf/JSValueMalloc.h: Added.
(WTF::JSValueMalloc::malloc):
(WTF::JSValueMalloc::tryMalloc):
(WTF::JSValueMalloc::realloc):
(WTF::JSValueMalloc::free):
* wtf/MallocPtr.h:
(WTF::MallocPtr::~MallocPtr):
(WTF::MallocPtr::malloc):
(WTF::MallocPtr::tryMalloc):
(WTF::MallocPtr::realloc):
We extend MallocPtr to adopt malloc scheme as its template parameter.
Canonical link: https://commits.webkit.org/196645@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225832 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-12-13 02:49:00 +00:00
|
|
|
runtime/WeakMapImpl.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/WeakMapPrototype.cpp
|
2019-06-18 21:02:19 +00:00
|
|
|
runtime/WeakObjectRefConstructor.cpp
|
|
|
|
runtime/WeakObjectRefPrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
runtime/WeakSetConstructor.cpp
|
|
|
|
runtime/WeakSetPrototype.cpp
|
2020-01-08 23:41:30 +00:00
|
|
|
runtime/WideningNumberPredictionFuzzerAgent.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
|
2017-10-18 19:14:51 +00:00
|
|
|
// Derived Sources
|
|
|
|
// FIXME: We should move this to runtime but it kept breaking the Windows build in weird ways... https://bugs.webkit.org/show_bug.cgi?id=177486
|
2017-09-26 15:34:19 +00:00
|
|
|
JSCBuiltins.cpp
|
|
|
|
|
2017-09-20 23:08:50 +00:00
|
|
|
tools/CellList.cpp
|
2019-09-12 15:04:29 +00:00
|
|
|
tools/CompilerTimingScope.cpp
|
2020-06-11 22:47:21 +00:00
|
|
|
tools/FunctionAllowlist.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
tools/FunctionOverrides.cpp
|
|
|
|
tools/HeapVerifier.cpp
|
Introducing Integrity audit functions.
https://bugs.webkit.org/show_bug.cgi?id=202085
Reviewed by Saam Barati.
This patch's main goal is to introduce the Integrity audit functions. They can
be used wherever we want to audit a cell to probabilistically ensure it is not
corrupted. However, to keep this patch small, we will only introduce the audit
tool here with one example use in SlotVisitor. We'll follow up later with more
patches to deploy this tool throughout the VM.
1. Introduced Integrity audit functions that can be configured at several
AuditLevels:
None - don't do any audits.
Minimal - do a minimal quick audit (minimize perf impact).
Full - do a full audit of the many aspects of a cell.
Random - randomly do a full audit with a probability dictated by
Options::randomIntegrityAuditRate() between 0.0 (never audit) and
1.0 (audit at every chance).
The default AuditLevel for Debug builds is Random.
The default AuditLevel for Release builds is None.
The default Options::randomIntegrityAuditRate() is 0.05.
How full audits work?
====================
The full audit uses the VMInspector::verifyCell() template function to do its
job. The reason for keeping this separate is to allow the template function
to be used later for debug checks that want to take some custom action on
verification failure instead of crashing with a RELEASE_ASSERT.
Full audit of a cell pointer includes:
a. Verify that a cell designated as a LargeAllocation is in the heap's
set of LargeAllocations.
b. Verify that a cell not designated as a LargeAllocation is actually in its
MarkedBlock's bounds.
c. Verify that the cell's container (LargeAllocation / MarkedBlock) actually
belongs to the current VM.
d. Verify that a cell in a MarkedBlock is properly aligned on the block's
allocation unit size.
e. If the cell is not an ImmutableButterfly, verify that it is not located in
the Gigacage.
f. Verify that the cell's JSType matches its StructureBlob's JSType.
g. Verify that the cell size as dictated by the cell ClassInfo does not exceed
the size of the allocation unit size (as expected by the container
MarkedBlock or LargeAllocation).
Some cells are dynamically size (see isDynamicallySizedType()). For these
cells, we compute their sizes and verify that the size does not exceed the
allocation unit size. Their sizes should also be greater or equal to the
static cell size as dictated by their ClassInfo.
h. If a cell has a butterfly, verify that the butterfly is in its the JSValue
Gigacage.
We can add more verifications later, or make some these more robust, but this
is a start for now.
How random audits work?
======================
Random audits are triggered by the m_triggerBits bits in VM::m_integrityRandom.
m_triggerBits is a 64-bit bitfield.
If Options::randomIntegrityAuditRate() is 0, m_triggerBits will always be 0,
and no audits will be done.
If Options::randomIntegrityAuditRate() is non-zero, m_triggerBits will be
initialized as follows:
| 1 reload bit | ... 63 trigger bits ... |
The reload bit is always set (more details below).
Each of the 63 trigger bits are randomly set depending if the following is true
for the bit:
VM::random() <= Options::randomIntegrityAuditRate() * UINT_MAX
When Integrity::auditCell() is called, we take the bottom bit as the trigger
bit for the current cell, and shifts the rest down by 1.
If m_triggerBits is non-null after the shift, the taken trigger bit will dictate
whether we do a full audit on the current cell or not.
Once the reload bit reaches the bottom, we call a reload function to
re-initialize m_triggerBits. The reload function also returns a bool
indicating whether to trigger a full audit of the current cell.
With this scheme, we only need to call the reload function once every 64 calls
to Integrity::auditCell(), and can efficiently determine whether to trigger
the audit the other 63 times with the probability specified in
Options::randomIntegrityAuditRate().
2. Embedded the C++ class size of JSCells into their ClassInfo. This is used in
the full audits to verify cell sizes.
3. Added isDynamicallySizedType() to check if a JSType has a dynamic size allocation
i.e. the size of instances of this type is not determined by the static C++
size of its class, but rather, depends on some runtime variable.
4. Made the VMInspector a friend of several classes so that it can access their
private methods and fields.
5. Moved the inline function JSBigInt::allocationSize() from BigInt.cpp to its
header file so that we can use it in VMInspector::verifyCellSize().
6. Gave the JSModuleNamespaceObject() its own JSType so that we can identify it
as a dynamically sized object.
7. Increased the randomness of VM::random() (which is implemented with WeakRandom)
by re-seeding it with a cryptographically random number each GC.
8. Called Integrity::auditCell() on SlotVisitor::appendJSCellOrAuxiliary()'s cell
as an example use of auditCell(). More uses will be added in later patches to
follow.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* heap/Heap.cpp:
(JSC::Heap::runBeginPhase):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::appendJSCellOrAuxiliary):
* runtime/ClassInfo.h:
* runtime/DirectArguments.h:
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::allocationSize): Deleted.
* runtime/JSBigInt.h:
(JSC::JSBigInt::allocationSize):
* runtime/JSModuleNamespaceObject.h:
* runtime/JSType.cpp:
(WTF::printInternal):
* runtime/JSType.h:
(JSC::isDynamicallySizedType):
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/Structure.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
(JSC::VM::random):
(JSC::VM::integrityRandom):
* tools/Integrity.cpp: Added.
(JSC::Integrity::Random::Random):
(JSC::Integrity::Random::reloadAndCheckShouldAuditSlow):
(JSC::Integrity::auditCellFully):
(JSC::Integrity::auditCellMinimallySlow):
* tools/Integrity.h: Added.
(JSC::Integrity::auditCell):
* tools/IntegrityInlines.h: Added.
(JSC::Integrity::Random::shouldAudit):
(JSC::Integrity::auditCellMinimally):
(JSC::Integrity::auditCellRandomly):
* tools/VMInspector.h:
(JSC::VMInspector::unusedVerifier):
(JSC::VMInspector::verifyCellSize):
* tools/VMInspectorInlines.h: Added.
(JSC::VMInspector::verifyCellSize):
(JSC::VMInspector::verifyCell):
Canonical link: https://commits.webkit.org/215737@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-24 06:02:30 +00:00
|
|
|
tools/Integrity.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
tools/JSDollarVM.cpp
|
|
|
|
tools/SigillCrashAnalyzer.cpp
|
|
|
|
tools/VMInspector.cpp
|
|
|
|
|
2019-01-31 02:49:36 +00:00
|
|
|
wasm/WasmAirIRGenerator.cpp @no-unify
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmB3IRGenerator.cpp
|
|
|
|
wasm/WasmBBQPlan.cpp
|
|
|
|
wasm/WasmBinding.cpp
|
|
|
|
wasm/WasmCallee.cpp
|
2019-08-02 22:58:09 +00:00
|
|
|
wasm/WasmCalleeRegistry.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmCallingConvention.cpp
|
|
|
|
wasm/WasmCodeBlock.cpp
|
2019-08-02 22:58:09 +00:00
|
|
|
wasm/WasmCompilationMode.cpp
|
[JSC] OSR entry to Wasm OMG
https://bugs.webkit.org/show_bug.cgi?id=200362
Reviewed by Michael Saboff.
JSTests:
* wasm/stress/osr-entry-basic.js: Added.
(instance.exports.loop):
* wasm/stress/osr-entry-many-locals-f32.js: Added.
* wasm/stress/osr-entry-many-locals-f64.js: Added.
* wasm/stress/osr-entry-many-locals-i32.js: Added.
* wasm/stress/osr-entry-many-locals-i64.js: Added.
* wasm/stress/osr-entry-many-stacks-f32.js: Added.
* wasm/stress/osr-entry-many-stacks-f64.js: Added.
* wasm/stress/osr-entry-many-stacks-i32.js: Added.
* wasm/stress/osr-entry-many-stacks-i64.js: Added.
Source/JavaScriptCore:
This patch implements Wasm OSR entry mechanism from BBQ tier to OMG tier.
We found that one of JetStream2 test heavily relies on OSR entry feature. gcc-loops-wasm consumes
most of time in BBQ tier since one of the function takes significantly long time. And since we did
not have OSR entry feature, we cannot use OMG function until that BBQ function finishes.
To implement Wasm OSR feature, we first capture all locals and stacks in the patchpoint to generate
the stackmap. Once the threshold is crossed, the patchpoint calls `MacroAssembler::probe` feature to
capture whole register context, and C++ runtime function reads stackmap and Probe::Context to perform
OSR entry. This patch intentionally makes OSR entry written in C++ runtime side as much as possible
to make it easily reusable for the other tiers. For example, we are planning to introduce Wasm interpreter,
and it can easily use this tier-up function. Because of this simplicity, this generic implementation can
cover both BBQ Air and BBQ B3 tier-up features. So, in the feature, it is possible that we revive BBQ B3,
and construct the wasm pipeline like, interpreter->BBQ B3->OMG B3.
To generate OMG code for OSR entry, we add a new mode OMGForOSREntry, which mimics the FTLForOSREntry.
In FTLForOSREntry, we cut unrelated blocks including the usual entry point in DFG tier and later convert
graph to SSA. This is possible because DFG is not SSA. On the other hand, B3 is SSA and we cannot take the
same thing without a hack.
This patch introduce a hack: making all wasm locals and stack values B3::Variable for OMGForOSREntry mode.
Then, we can cut blocks easily and we can generate the B3 graph without doing reachability analysis from the
OSR entry point. B3 will remove unreachable blocks later.
Tier-up function mimics DFG->FTL OSR entry heuristics and threshold as much as possible. And this patch adjusts
the tier-up count threshold to make it close to DFG->FTL ones. Wasm tier-up is now using ExecutionCounter, which
is inherited from Wasm::TierUpCount. Since wasm can execute concurrently, the tier-up counter can be racily updated.
But this is OK in practice. Even if we see some more tier-up function calls or tier-up function calls are delayed,
the critical part is guarded by a lock in tier-up function.
In iMac Pro, it shows ~4x runtime improvement for gcc-loops-wasm. On iOS device (iPhone XR), we saw ~2x improvement.
ToT:
HashSet-wasm:Score: 24.6pt stdev=4.6%
:Time:Geometric: 204ms stdev=4.4%
Runtime:Time: 689ms stdev=1.0%
Startup:Time: 60.3ms stdev=8.4%
gcc-loops-wasm:Score: 8.41pt stdev=6.7%
:Time:Geometric: 597ms stdev=6.5%
Runtime:Time: 8.509s stdev=0.7%
Startup:Time: 42ms stdev=12.4%
quicksort-wasm:Score: 347pt stdev=20.9%
:Time:Geometric: 15ms stdev=18.6%
Runtime:Time: 28.2ms stdev=7.9%
Startup:Time: 8.2ms stdev=35.0%
richards-wasm:Score: 77.6pt stdev=4.5%
:Time:Geometric: 64.6ms stdev=4.4%
Runtime:Time: 544ms stdev=3.3%
Startup:Time: 7.67ms stdev=6.7%
tsf-wasm:Score: 47.9pt stdev=4.5%
:Time:Geometric: 104ms stdev=4.8%
Runtime:Time: 259ms stdev=4.4%
Startup:Time: 42.2ms stdev=8.5%
Patched:
HashSet-wasm:Score: 24.1pt stdev=4.1%
:Time:Geometric: 208ms stdev=4.1%
Runtime:Time: 684ms stdev=1.1%
Startup:Time: 63.2ms stdev=8.1%
gcc-loops-wasm:Score: 15.7pt stdev=5.1%
:Time:Geometric: 319ms stdev=5.3%
Runtime:Time: 2.491s stdev=0.7%
Startup:Time: 41ms stdev=11.0%
quicksort-wasm:Score: 353pt stdev=13.7%
:Time:Geometric: 14ms stdev=12.7%
Runtime:Time: 26.2ms stdev=2.9%
Startup:Time: 8.0ms stdev=23.7%
richards-wasm:Score: 77.4pt stdev=5.3%
:Time:Geometric: 64.7ms stdev=5.3%
Runtime:Time: 536ms stdev=1.5%
Startup:Time: 7.83ms stdev=9.6%
tsf-wasm:Score: 47.3pt stdev=5.7%
:Time:Geometric: 106ms stdev=6.1%
Runtime:Time: 250ms stdev=3.5%
Startup:Time: 45ms stdev=13.8%
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchAdd32):
* b3/B3ValueRep.h:
* bytecode/CodeBlock.h:
* bytecode/ExecutionCounter.cpp:
(JSC::applyMemoryUsageHeuristics):
(JSC::ExecutionCounter<countingVariant>::setThreshold):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGJITCode.h:
* dfg/DFGOperations.cpp:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::prologueStackPointerDelta):
* runtime/Options.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::createStack):
(JSC::Wasm::AirIRGenerator::emitPatchpoint):
(JSC::Wasm::AirIRGenerator::outerLoopIndex const):
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::AirIRGenerator::addLoop):
(JSC::Wasm::AirIRGenerator::addElse):
(JSC::Wasm::AirIRGenerator::addBranch):
(JSC::Wasm::AirIRGenerator::addSwitch):
(JSC::Wasm::AirIRGenerator::endBlock):
(JSC::Wasm::AirIRGenerator::addEndToUnreachable):
(JSC::Wasm::AirIRGenerator::unifyValuesWithBlock):
(JSC::Wasm::AirIRGenerator::dump):
(JSC::Wasm::AirIRGenerator::emitTierUpCheck): Deleted.
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::Stack::Stack):
(JSC::Wasm::B3IRGenerator::Stack::append):
(JSC::Wasm::B3IRGenerator::Stack::takeLast):
(JSC::Wasm::B3IRGenerator::Stack::last):
(JSC::Wasm::B3IRGenerator::Stack::size const):
(JSC::Wasm::B3IRGenerator::Stack::isEmpty const):
(JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList):
(JSC::Wasm::B3IRGenerator::Stack::at const):
(JSC::Wasm::B3IRGenerator::Stack::variableAt const):
(JSC::Wasm::B3IRGenerator::Stack::shrink):
(JSC::Wasm::B3IRGenerator::Stack::swap):
(JSC::Wasm::B3IRGenerator::Stack::dump const):
(JSC::Wasm::B3IRGenerator::createStack):
(JSC::Wasm::B3IRGenerator::outerLoopIndex const):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addElse):
(JSC::Wasm::B3IRGenerator::addBranch):
(JSC::Wasm::B3IRGenerator::addSwitch):
(JSC::Wasm::B3IRGenerator::endBlock):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
(JSC::Wasm::B3IRGenerator::unifyValuesWithBlock):
(JSC::Wasm::B3IRGenerator::dump):
(JSC::Wasm::parseAndCompile):
(JSC::Wasm::B3IRGenerator::emitTierUpCheck): Deleted.
(JSC::Wasm::dumpExpressionStack): Deleted.
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::compileFunctions):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::entrypointLoadLocationFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::tierUpCount): Deleted.
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmContext.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::Context::scratchBufferForSize):
* wasm/WasmContext.h:
* wasm/WasmContextInlines.h:
(JSC::Wasm::Context::tryLoadInstanceFromTLS):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
(JSC::Wasm::FunctionParser<Context>::parseBody):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
* wasm/WasmOMGForOSREntryPlan.cpp: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.cpp.
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.h.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
(JSC::Wasm::OMGPlan::runForIndex): Deleted.
* wasm/WasmOMGPlan.h:
* wasm/WasmOSREntryData.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
(JSC::Wasm::OSREntryValue::OSREntryValue):
(JSC::Wasm::OSREntryValue::type const):
(JSC::Wasm::OSREntryData::OSREntryData):
(JSC::Wasm::OSREntryData::functionIndex const):
(JSC::Wasm::OSREntryData::loopIndex const):
(JSC::Wasm::OSREntryData::values):
* wasm/WasmOperations.cpp: Added.
(JSC::Wasm::shouldTriggerOMGCompile):
(JSC::Wasm::triggerOMGReplacementCompile):
(JSC::Wasm::doOSREntry):
(JSC::Wasm::triggerOSREntryNow):
(JSC::Wasm::triggerTierUpNow):
* wasm/WasmOperations.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmThunks.cpp:
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator): Deleted.
* wasm/WasmThunks.h:
* wasm/WasmTierUpCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::TierUpCount::TierUpCount):
(JSC::Wasm::TierUpCount::addOSREntryData):
* wasm/WasmTierUpCount.h:
(JSC::Wasm::TierUpCount::loopIncrement):
(JSC::Wasm::TierUpCount::functionEntryIncrement):
(JSC::Wasm::TierUpCount::osrEntryTriggers):
(JSC::Wasm::TierUpCount::outerLoops):
(JSC::Wasm::TierUpCount::getLock):
(JSC::Wasm::TierUpCount::optimizeAfterWarmUp):
(JSC::Wasm::TierUpCount::checkIfOptimizationThresholdReached):
(JSC::Wasm::TierUpCount::dontOptimizeAnytimeSoon):
(JSC::Wasm::TierUpCount::optimizeNextInvocation):
(JSC::Wasm::TierUpCount::optimizeSoon):
(JSC::Wasm::TierUpCount::setOptimizationThresholdBasedOnCompilationResult):
(JSC::Wasm::TierUpCount::TierUpCount): Deleted.
(JSC::Wasm::TierUpCount::loopDecrement): Deleted.
(JSC::Wasm::TierUpCount::functionEntryDecrement): Deleted.
(JSC::Wasm::TierUpCount::shouldStartTierUp): Deleted.
(JSC::Wasm::TierUpCount::count): Deleted.
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::createStack):
(JSC::Wasm::Validate::addLoop):
(JSC::Wasm::Validate::addElse):
(JSC::Wasm::Validate::checkBranchTarget):
(JSC::Wasm::Validate::addBranch):
(JSC::Wasm::Validate::addSwitch):
(JSC::Wasm::Validate::endBlock):
(JSC::Wasm::Validate::unify):
(JSC::Wasm::dumpExpressionStack):
(JSC::Wasm::Validate::dump):
Tools:
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/214633@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-20 00:21:29 +00:00
|
|
|
wasm/WasmContext.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/WasmEmbedder.h
|
[WebAssembly] Create a Wasm interpreter
https://bugs.webkit.org/show_bug.cgi?id=194257
<rdar://problem/44186794>
Reviewed by Saam Barati.
Source/JavaScriptCore:
Add an interpreter tier to WebAssembly which reuses the LLInt infrastructure. The interpreter
currently tiers up straight to OMG and can OSR enter at the prologue and from loops. The initial
implementation of the interpreter is very naive, but despite the lack of optimizations it still
shows a 2x improvement on the WebAssembly subtests in JetStream2 and 2x improvement on the
PSPDFKit benchmark. It reduces "compilation" times by ~3x and it's neutral on throughput.
The interpreter follows the same calling conventions as the BBQ/OMG, this means that:
- We have to allocate locals for all argument registers and write all arguments registers to the
stack in the prologue.
- Calls have to allocate space for at least as many arguments as the number of argument registers.
Before each call, all argument registers must be loaded from the stack, and after we return from
the call, all registers must be stored back to the stack, in case they contain return values. We
carefully layout the stack so that the arguments that would already have to be passed in the stack
end up in the right place. The stack layout for calls is:
[ gprs ][ fprs ][ optional stack arguments ][ callee frame ]
^ sp
- The return opcode has to load all registers from the stack, since they might need to contain
results of the function.
- The calling convention requires that the callee should store itself in the callee slot of the call
frame, which is impossible in the interpreter, since the code we execute is the same for all callees.
In order to work around that, we generate an entry thunk to the wasm interpreter for each function.
All this thunk does is store the callee in the call frame and tail call the interpreter.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::constantName const):
(JSC::BytecodeDumper<Block>::dumpValue):
(JSC::BytecodeDumper<Block>::dumpBytecode):
(JSC::CodeBlockBytecodeDumper<Block>::vm const):
(JSC::CodeBlockBytecodeDumper<Block>::identifier const):
(JSC::CodeBlockBytecodeDumper<Block>::dumpIdentifiers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpConstants):
(JSC::CodeBlockBytecodeDumper<Block>::dumpExceptionHandlers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
* bytecode/BytecodeDumper.h:
(JSC::BytecodeDumper::dumpValue):
(JSC::BytecodeDumper::BytecodeDumper):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::performGeneratorification):
* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Fits.h:
* bytecode/Instruction.h:
(JSC::BaseInstruction::BaseInstruction):
(JSC::BaseInstruction::Impl::opcodeID const):
(JSC::BaseInstruction::opcodeID const):
(JSC::BaseInstruction::name const):
(JSC::BaseInstruction::isWide16 const):
(JSC::BaseInstruction::isWide32 const):
(JSC::BaseInstruction::hasMetadata const):
(JSC::BaseInstruction::sizeShiftAmount const):
(JSC::BaseInstruction::size const):
(JSC::BaseInstruction::is const):
(JSC::BaseInstruction::as const):
(JSC::BaseInstruction::cast):
(JSC::BaseInstruction::cast const):
(JSC::BaseInstruction::wide16 const):
(JSC::BaseInstruction::wide32 const):
* bytecode/InstructionStream.h:
(JSC::InstructionStream::iterator::operator+=):
(JSC::InstructionStream::iterator::operator++):
(JSC::InstructionStreamWriter::iterator::operator+=):
(JSC::InstructionStreamWriter::iterator::operator++):
* bytecode/Opcode.cpp:
* bytecode/Opcode.h:
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecode/VirtualRegister.cpp:
(JSC::VirtualRegister::VirtualRegister):
* bytecode/VirtualRegister.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::GenericLabel<JSGeneratorTraits>::setLocation):
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/BytecodeGeneratorBase.h: Added.
* bytecompiler/BytecodeGeneratorBaseInlines.h: Added.
(JSC::shrinkToFit):
(JSC::BytecodeGeneratorBase<Traits>::BytecodeGeneratorBase):
(JSC::BytecodeGeneratorBase<Traits>::newLabel):
(JSC::BytecodeGeneratorBase<Traits>::newEmittedLabel):
(JSC::BytecodeGeneratorBase<Traits>::reclaimFreeRegisters):
(JSC::BytecodeGeneratorBase<Traits>::emitLabel):
(JSC::BytecodeGeneratorBase<Traits>::recordOpcode):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode16):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode32):
(JSC::BytecodeGeneratorBase<Traits>::write):
(JSC::BytecodeGeneratorBase<Traits>::newRegister):
(JSC::BytecodeGeneratorBase<Traits>::newTemporary):
(JSC::BytecodeGeneratorBase<Traits>::addVar):
(JSC::BytecodeGeneratorBase<Traits>::allocateCalleeSaveSpace):
* bytecompiler/Label.h:
(JSC::GenericBoundLabel::GenericBoundLabel):
(JSC::GenericBoundLabel::target):
(JSC::GenericBoundLabel::saveTarget):
(JSC::GenericBoundLabel::commitTarget):
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOperations.cpp:
* generator/Argument.rb:
* generator/DSL.rb:
* generator/GeneratedFile.rb:
* generator/Opcode.rb:
* generator/Options.rb:
* generator/Section.rb:
* generator/Wasm.rb: Added.
* interpreter/Register.h:
* interpreter/RegisterInlines.h:
(JSC::Register::operator=):
* jit/JITArithmetic.cpp:
* jit/JITOpcodes.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC::LLInt::wasmExceptionInstructions):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::wasmFunctionEntryThunk):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* llint/WebAssembly.asm: Added.
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/parser.rb:
* offlineasm/registers.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:
* parser/Nodes.h:
* runtime/Error.cpp:
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator() const):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* runtime/Options.cpp:
(JSC::overrideDefaults):
* runtime/OptionsList.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::recordJITFrame):
(JSC::FrameWalker::resetAtMachineFrame):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::isControlTypeIf):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::isControlTypeIf):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::prepareImpl):
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):
(JSC::Wasm::BBQPlan::didCompleteCompilation):
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h: Removed.
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
(JSC::Wasm::Callee::dump const):
(JSC::Wasm::JITCallee::JITCallee):
(JSC::Wasm::LLIntCallee::setEntrypoint):
(JSC::Wasm::LLIntCallee::entrypoint const):
(JSC::Wasm::LLIntCallee::calleeSaveRegisters):
(JSC::Wasm:: const):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::setOSREntryCallee):
(JSC::Wasm::JITCallee::wasmToWasmCallsites):
(JSC::Wasm::JITCallee:: const):
* wasm/WasmCallingConvention.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmToWasmExitStub):
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmEmbedder.h:
* wasm/WasmEntryPlan.cpp: Added.
(JSC::Wasm::EntryPlan::EntryPlan):
(JSC::Wasm::EntryPlan::stateString):
(JSC::Wasm::EntryPlan::moveToState):
(JSC::Wasm::EntryPlan::didReceiveFunctionData):
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::prepare):
(JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder):
(JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder):
(JSC::Wasm::EntryPlan::complete):
(JSC::Wasm::EntryPlan::compileFunctions):
(JSC::Wasm::EntryPlan::work):
* wasm/WasmEntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmBBQPlan.h.
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::exports const):
(JSC::Wasm::EntryPlan::internalFunctionCount const):
(JSC::Wasm::EntryPlan::takeModuleInformation):
(JSC::Wasm::EntryPlan::takeWasmToWasmExitStubs):
(JSC::Wasm::EntryPlan::takeWasmToWasmCallsites):
(JSC::Wasm::EntryPlan::hasBeenPrepared const):
(JSC::Wasm::EntryPlan::tryReserveCapacity):
* wasm/WasmFunctionCodeBlock.cpp: Added.
(JSC::Wasm::FunctionCodeBlock::setInstructions):
(JSC::Wasm::FunctionCodeBlock::dumpBytecode):
(JSC::Wasm::FunctionCodeBlock::addOutOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::addSignature):
(JSC::Wasm::FunctionCodeBlock::signature const):
(JSC::Wasm::FunctionCodeBlock::addJumpTable):
(JSC::Wasm::FunctionCodeBlock::jumpTable const const):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTables const):
* wasm/WasmFunctionCodeBlock.h: Added.
(JSC::Wasm::FunctionCodeBlock::FunctionCodeBlock):
(JSC::Wasm::FunctionCodeBlock::getConstant const):
(JSC::Wasm::FunctionCodeBlock::functionIndex const):
(JSC::Wasm::FunctionCodeBlock::addJumpTarget):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTargets):
(JSC::Wasm::FunctionCodeBlock::lastJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::bytecodeOffset):
(JSC::Wasm::FunctionCodeBlock::tierUpCounter):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmInstance.h:
* wasm/WasmLLIntGenerator.cpp: Added.
(JSC::Wasm::LLIntGenerator::ControlType::ControlType):
(JSC::Wasm::LLIntGenerator::ControlType::loop):
(JSC::Wasm::LLIntGenerator::ControlType::topLevel):
(JSC::Wasm::LLIntGenerator::ControlType::block):
(JSC::Wasm::LLIntGenerator::ControlType::if_):
(JSC::Wasm::LLIntGenerator::ControlType::targetLabelForBranch const):
(JSC::Wasm::LLIntGenerator::fail const):
(JSC::Wasm::LLIntGenerator::unifyValuesWithBlock):
(JSC::Wasm::LLIntGenerator::emptyExpression):
(JSC::Wasm::LLIntGenerator::createStack):
(JSC::Wasm::LLIntGenerator::isControlTypeIf):
(JSC::Wasm::LLIntGenerator::addEndToUnreachable):
(JSC::Wasm::LLIntGenerator::setParser):
(JSC::Wasm::LLIntGenerator::dump):
(JSC::Wasm::LLIntGenerator::virtualRegisterForLocal):
(JSC::Wasm::LLIntGenerator::tmpsForSignature):
(JSC::Wasm::LLIntGenerator::jsNullConstant):
(JSC::Wasm::LLIntGenerator::isConstant):
(JSC::Wasm::parseAndCompileBytecode):
(JSC::Wasm::LLIntGenerator::LLIntGenerator):
(JSC::Wasm::LLIntGenerator::finalize):
(JSC::Wasm::LLIntGenerator::callInformationFor):
(JSC::Wasm::LLIntGenerator::addArguments):
(JSC::Wasm::LLIntGenerator::addLocal):
(JSC::Wasm::LLIntGenerator::addConstant):
(JSC::Wasm::LLIntGenerator::getLocal):
(JSC::Wasm::LLIntGenerator::setLocal):
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
(JSC::Wasm::LLIntGenerator::addLoop):
(JSC::Wasm::LLIntGenerator::addTopLevel):
(JSC::Wasm::LLIntGenerator::addBlock):
(JSC::Wasm::LLIntGenerator::addIf):
(JSC::Wasm::LLIntGenerator::addElse):
(JSC::Wasm::LLIntGenerator::addElseToUnreachable):
(JSC::Wasm::LLIntGenerator::addReturn):
(JSC::Wasm::LLIntGenerator::addBranch):
(JSC::Wasm::LLIntGenerator::addSwitch):
(JSC::Wasm::LLIntGenerator::endBlock):
(JSC::Wasm::LLIntGenerator::addCall):
(JSC::Wasm::LLIntGenerator::addCallIndirect):
(JSC::Wasm::LLIntGenerator::addRefIsNull):
(JSC::Wasm::LLIntGenerator::addRefFunc):
(JSC::Wasm::LLIntGenerator::addTableGet):
(JSC::Wasm::LLIntGenerator::addTableSet):
(JSC::Wasm::LLIntGenerator::addTableSize):
(JSC::Wasm::LLIntGenerator::addTableGrow):
(JSC::Wasm::LLIntGenerator::addTableFill):
(JSC::Wasm::LLIntGenerator::addUnreachable):
(JSC::Wasm::LLIntGenerator::addCurrentMemory):
(JSC::Wasm::LLIntGenerator::addGrowMemory):
(JSC::Wasm::LLIntGenerator::addSelect):
(JSC::Wasm::LLIntGenerator::load):
(JSC::Wasm::LLIntGenerator::store):
(JSC::GenericLabel<Wasm::GeneratorTraits>::setLocation):
* wasm/WasmLLIntGenerator.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmLLIntPlan.cpp: Added.
(JSC::Wasm::LLIntPlan::prepareImpl):
(JSC::Wasm::LLIntPlan::compileFunction):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::initializeCallees):
* wasm/WasmLLIntPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
* wasm/WasmLLIntTierUpCounter.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::LLIntTierUpCounter::addOSREntryDataForLoop):
(JSC::Wasm::LLIntTierUpCounter::osrEntryDataForLoop const const):
* wasm/WasmLLIntTierUpCounter.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
(JSC::Wasm::LLIntTierUpCounter::LLIntTierUpCounter):
(JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
(JSC::Wasm::LLIntTierUpCounter::checkIfOptimizationThresholdReached):
(JSC::Wasm::LLIntTierUpCounter::optimizeSoon):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationResult):
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmOMGForOSREntryPlan.cpp:
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h:
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmSlowPaths.cpp: Added.
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
(JSC::LLInt::doWasmCall):
(JSC::LLInt::doWasmCallIndirect):
(JSC::LLInt::slow_path_wasm_throw_exception):
(JSC::LLInt::slow_path_wasm_popcount):
(JSC::LLInt::slow_path_wasm_popcountll):
* wasm/WasmSlowPaths.h: Added.
* wasm/WasmTable.cpp:
(JSC::Wasm::FuncRefTable::function const):
(JSC::Wasm::FuncRefTable::instance const):
* wasm/WasmTable.h:
* wasm/WasmTierUpCount.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::isControlTypeIf):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::calleeSaves const):
Tools:
Add a mode that runs WebAssembly tests without the LLInt (i.e. only Air)
and update the no-air mode to also disable the LLInt tier.
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/217068@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251886 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-31 22:32:52 +00:00
|
|
|
wasm/WasmEntryPlan.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmFaultSignalHandler.cpp
|
|
|
|
wasm/WasmFormat.cpp
|
[WebAssembly] Create a Wasm interpreter
https://bugs.webkit.org/show_bug.cgi?id=194257
<rdar://problem/44186794>
Reviewed by Saam Barati.
Source/JavaScriptCore:
Add an interpreter tier to WebAssembly which reuses the LLInt infrastructure. The interpreter
currently tiers up straight to OMG and can OSR enter at the prologue and from loops. The initial
implementation of the interpreter is very naive, but despite the lack of optimizations it still
shows a 2x improvement on the WebAssembly subtests in JetStream2 and 2x improvement on the
PSPDFKit benchmark. It reduces "compilation" times by ~3x and it's neutral on throughput.
The interpreter follows the same calling conventions as the BBQ/OMG, this means that:
- We have to allocate locals for all argument registers and write all arguments registers to the
stack in the prologue.
- Calls have to allocate space for at least as many arguments as the number of argument registers.
Before each call, all argument registers must be loaded from the stack, and after we return from
the call, all registers must be stored back to the stack, in case they contain return values. We
carefully layout the stack so that the arguments that would already have to be passed in the stack
end up in the right place. The stack layout for calls is:
[ gprs ][ fprs ][ optional stack arguments ][ callee frame ]
^ sp
- The return opcode has to load all registers from the stack, since they might need to contain
results of the function.
- The calling convention requires that the callee should store itself in the callee slot of the call
frame, which is impossible in the interpreter, since the code we execute is the same for all callees.
In order to work around that, we generate an entry thunk to the wasm interpreter for each function.
All this thunk does is store the callee in the call frame and tail call the interpreter.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::constantName const):
(JSC::BytecodeDumper<Block>::dumpValue):
(JSC::BytecodeDumper<Block>::dumpBytecode):
(JSC::CodeBlockBytecodeDumper<Block>::vm const):
(JSC::CodeBlockBytecodeDumper<Block>::identifier const):
(JSC::CodeBlockBytecodeDumper<Block>::dumpIdentifiers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpConstants):
(JSC::CodeBlockBytecodeDumper<Block>::dumpExceptionHandlers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
* bytecode/BytecodeDumper.h:
(JSC::BytecodeDumper::dumpValue):
(JSC::BytecodeDumper::BytecodeDumper):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::performGeneratorification):
* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Fits.h:
* bytecode/Instruction.h:
(JSC::BaseInstruction::BaseInstruction):
(JSC::BaseInstruction::Impl::opcodeID const):
(JSC::BaseInstruction::opcodeID const):
(JSC::BaseInstruction::name const):
(JSC::BaseInstruction::isWide16 const):
(JSC::BaseInstruction::isWide32 const):
(JSC::BaseInstruction::hasMetadata const):
(JSC::BaseInstruction::sizeShiftAmount const):
(JSC::BaseInstruction::size const):
(JSC::BaseInstruction::is const):
(JSC::BaseInstruction::as const):
(JSC::BaseInstruction::cast):
(JSC::BaseInstruction::cast const):
(JSC::BaseInstruction::wide16 const):
(JSC::BaseInstruction::wide32 const):
* bytecode/InstructionStream.h:
(JSC::InstructionStream::iterator::operator+=):
(JSC::InstructionStream::iterator::operator++):
(JSC::InstructionStreamWriter::iterator::operator+=):
(JSC::InstructionStreamWriter::iterator::operator++):
* bytecode/Opcode.cpp:
* bytecode/Opcode.h:
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecode/VirtualRegister.cpp:
(JSC::VirtualRegister::VirtualRegister):
* bytecode/VirtualRegister.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::GenericLabel<JSGeneratorTraits>::setLocation):
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/BytecodeGeneratorBase.h: Added.
* bytecompiler/BytecodeGeneratorBaseInlines.h: Added.
(JSC::shrinkToFit):
(JSC::BytecodeGeneratorBase<Traits>::BytecodeGeneratorBase):
(JSC::BytecodeGeneratorBase<Traits>::newLabel):
(JSC::BytecodeGeneratorBase<Traits>::newEmittedLabel):
(JSC::BytecodeGeneratorBase<Traits>::reclaimFreeRegisters):
(JSC::BytecodeGeneratorBase<Traits>::emitLabel):
(JSC::BytecodeGeneratorBase<Traits>::recordOpcode):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode16):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode32):
(JSC::BytecodeGeneratorBase<Traits>::write):
(JSC::BytecodeGeneratorBase<Traits>::newRegister):
(JSC::BytecodeGeneratorBase<Traits>::newTemporary):
(JSC::BytecodeGeneratorBase<Traits>::addVar):
(JSC::BytecodeGeneratorBase<Traits>::allocateCalleeSaveSpace):
* bytecompiler/Label.h:
(JSC::GenericBoundLabel::GenericBoundLabel):
(JSC::GenericBoundLabel::target):
(JSC::GenericBoundLabel::saveTarget):
(JSC::GenericBoundLabel::commitTarget):
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOperations.cpp:
* generator/Argument.rb:
* generator/DSL.rb:
* generator/GeneratedFile.rb:
* generator/Opcode.rb:
* generator/Options.rb:
* generator/Section.rb:
* generator/Wasm.rb: Added.
* interpreter/Register.h:
* interpreter/RegisterInlines.h:
(JSC::Register::operator=):
* jit/JITArithmetic.cpp:
* jit/JITOpcodes.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC::LLInt::wasmExceptionInstructions):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::wasmFunctionEntryThunk):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* llint/WebAssembly.asm: Added.
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/parser.rb:
* offlineasm/registers.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:
* parser/Nodes.h:
* runtime/Error.cpp:
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator() const):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* runtime/Options.cpp:
(JSC::overrideDefaults):
* runtime/OptionsList.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::recordJITFrame):
(JSC::FrameWalker::resetAtMachineFrame):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::isControlTypeIf):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::isControlTypeIf):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::prepareImpl):
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):
(JSC::Wasm::BBQPlan::didCompleteCompilation):
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h: Removed.
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
(JSC::Wasm::Callee::dump const):
(JSC::Wasm::JITCallee::JITCallee):
(JSC::Wasm::LLIntCallee::setEntrypoint):
(JSC::Wasm::LLIntCallee::entrypoint const):
(JSC::Wasm::LLIntCallee::calleeSaveRegisters):
(JSC::Wasm:: const):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::setOSREntryCallee):
(JSC::Wasm::JITCallee::wasmToWasmCallsites):
(JSC::Wasm::JITCallee:: const):
* wasm/WasmCallingConvention.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmToWasmExitStub):
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmEmbedder.h:
* wasm/WasmEntryPlan.cpp: Added.
(JSC::Wasm::EntryPlan::EntryPlan):
(JSC::Wasm::EntryPlan::stateString):
(JSC::Wasm::EntryPlan::moveToState):
(JSC::Wasm::EntryPlan::didReceiveFunctionData):
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::prepare):
(JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder):
(JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder):
(JSC::Wasm::EntryPlan::complete):
(JSC::Wasm::EntryPlan::compileFunctions):
(JSC::Wasm::EntryPlan::work):
* wasm/WasmEntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmBBQPlan.h.
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::exports const):
(JSC::Wasm::EntryPlan::internalFunctionCount const):
(JSC::Wasm::EntryPlan::takeModuleInformation):
(JSC::Wasm::EntryPlan::takeWasmToWasmExitStubs):
(JSC::Wasm::EntryPlan::takeWasmToWasmCallsites):
(JSC::Wasm::EntryPlan::hasBeenPrepared const):
(JSC::Wasm::EntryPlan::tryReserveCapacity):
* wasm/WasmFunctionCodeBlock.cpp: Added.
(JSC::Wasm::FunctionCodeBlock::setInstructions):
(JSC::Wasm::FunctionCodeBlock::dumpBytecode):
(JSC::Wasm::FunctionCodeBlock::addOutOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::addSignature):
(JSC::Wasm::FunctionCodeBlock::signature const):
(JSC::Wasm::FunctionCodeBlock::addJumpTable):
(JSC::Wasm::FunctionCodeBlock::jumpTable const const):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTables const):
* wasm/WasmFunctionCodeBlock.h: Added.
(JSC::Wasm::FunctionCodeBlock::FunctionCodeBlock):
(JSC::Wasm::FunctionCodeBlock::getConstant const):
(JSC::Wasm::FunctionCodeBlock::functionIndex const):
(JSC::Wasm::FunctionCodeBlock::addJumpTarget):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTargets):
(JSC::Wasm::FunctionCodeBlock::lastJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::bytecodeOffset):
(JSC::Wasm::FunctionCodeBlock::tierUpCounter):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmInstance.h:
* wasm/WasmLLIntGenerator.cpp: Added.
(JSC::Wasm::LLIntGenerator::ControlType::ControlType):
(JSC::Wasm::LLIntGenerator::ControlType::loop):
(JSC::Wasm::LLIntGenerator::ControlType::topLevel):
(JSC::Wasm::LLIntGenerator::ControlType::block):
(JSC::Wasm::LLIntGenerator::ControlType::if_):
(JSC::Wasm::LLIntGenerator::ControlType::targetLabelForBranch const):
(JSC::Wasm::LLIntGenerator::fail const):
(JSC::Wasm::LLIntGenerator::unifyValuesWithBlock):
(JSC::Wasm::LLIntGenerator::emptyExpression):
(JSC::Wasm::LLIntGenerator::createStack):
(JSC::Wasm::LLIntGenerator::isControlTypeIf):
(JSC::Wasm::LLIntGenerator::addEndToUnreachable):
(JSC::Wasm::LLIntGenerator::setParser):
(JSC::Wasm::LLIntGenerator::dump):
(JSC::Wasm::LLIntGenerator::virtualRegisterForLocal):
(JSC::Wasm::LLIntGenerator::tmpsForSignature):
(JSC::Wasm::LLIntGenerator::jsNullConstant):
(JSC::Wasm::LLIntGenerator::isConstant):
(JSC::Wasm::parseAndCompileBytecode):
(JSC::Wasm::LLIntGenerator::LLIntGenerator):
(JSC::Wasm::LLIntGenerator::finalize):
(JSC::Wasm::LLIntGenerator::callInformationFor):
(JSC::Wasm::LLIntGenerator::addArguments):
(JSC::Wasm::LLIntGenerator::addLocal):
(JSC::Wasm::LLIntGenerator::addConstant):
(JSC::Wasm::LLIntGenerator::getLocal):
(JSC::Wasm::LLIntGenerator::setLocal):
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
(JSC::Wasm::LLIntGenerator::addLoop):
(JSC::Wasm::LLIntGenerator::addTopLevel):
(JSC::Wasm::LLIntGenerator::addBlock):
(JSC::Wasm::LLIntGenerator::addIf):
(JSC::Wasm::LLIntGenerator::addElse):
(JSC::Wasm::LLIntGenerator::addElseToUnreachable):
(JSC::Wasm::LLIntGenerator::addReturn):
(JSC::Wasm::LLIntGenerator::addBranch):
(JSC::Wasm::LLIntGenerator::addSwitch):
(JSC::Wasm::LLIntGenerator::endBlock):
(JSC::Wasm::LLIntGenerator::addCall):
(JSC::Wasm::LLIntGenerator::addCallIndirect):
(JSC::Wasm::LLIntGenerator::addRefIsNull):
(JSC::Wasm::LLIntGenerator::addRefFunc):
(JSC::Wasm::LLIntGenerator::addTableGet):
(JSC::Wasm::LLIntGenerator::addTableSet):
(JSC::Wasm::LLIntGenerator::addTableSize):
(JSC::Wasm::LLIntGenerator::addTableGrow):
(JSC::Wasm::LLIntGenerator::addTableFill):
(JSC::Wasm::LLIntGenerator::addUnreachable):
(JSC::Wasm::LLIntGenerator::addCurrentMemory):
(JSC::Wasm::LLIntGenerator::addGrowMemory):
(JSC::Wasm::LLIntGenerator::addSelect):
(JSC::Wasm::LLIntGenerator::load):
(JSC::Wasm::LLIntGenerator::store):
(JSC::GenericLabel<Wasm::GeneratorTraits>::setLocation):
* wasm/WasmLLIntGenerator.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmLLIntPlan.cpp: Added.
(JSC::Wasm::LLIntPlan::prepareImpl):
(JSC::Wasm::LLIntPlan::compileFunction):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::initializeCallees):
* wasm/WasmLLIntPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
* wasm/WasmLLIntTierUpCounter.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::LLIntTierUpCounter::addOSREntryDataForLoop):
(JSC::Wasm::LLIntTierUpCounter::osrEntryDataForLoop const const):
* wasm/WasmLLIntTierUpCounter.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
(JSC::Wasm::LLIntTierUpCounter::LLIntTierUpCounter):
(JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
(JSC::Wasm::LLIntTierUpCounter::checkIfOptimizationThresholdReached):
(JSC::Wasm::LLIntTierUpCounter::optimizeSoon):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationResult):
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmOMGForOSREntryPlan.cpp:
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h:
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmSlowPaths.cpp: Added.
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
(JSC::LLInt::doWasmCall):
(JSC::LLInt::doWasmCallIndirect):
(JSC::LLInt::slow_path_wasm_throw_exception):
(JSC::LLInt::slow_path_wasm_popcount):
(JSC::LLInt::slow_path_wasm_popcountll):
* wasm/WasmSlowPaths.h: Added.
* wasm/WasmTable.cpp:
(JSC::Wasm::FuncRefTable::function const):
(JSC::Wasm::FuncRefTable::instance const):
* wasm/WasmTable.h:
* wasm/WasmTierUpCount.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::isControlTypeIf):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::calleeSaves const):
Tools:
Add a mode that runs WebAssembly tests without the LLInt (i.e. only Air)
and update the no-air mode to also disable the LLInt tier.
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/217068@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251886 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-31 22:32:52 +00:00
|
|
|
wasm/WasmFunctionCodeBlock.cpp
|
Adopt the new WebAssembly.Global system
https://bugs.webkit.org/show_bug.cgi?id=186552
Reviewed by Keith Miller.
JSTests:
1. Update spec-harness to accept newer tests. And we update several tests that does not work with the old harness.
2. Add WebAssembly.Global tests.
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(new.WebAssembly.Module):
(assert.throws):
* wasm/js-api/global-external-init-from-import.js:
* wasm/js-api/globals-export.js:
* wasm/modules/js-wasm-global-namespace.js:
(assert.throws):
* wasm/modules/js-wasm-global.js:
(assert.throws):
* wasm/modules/wasm-import-wasm-export-i64-error.js:
* wasm/references/anyref_globals.js:
* wasm/references/func_ref.js:
(assert.eq.instance.exports.fix):
* wasm/spec-harness.js:
(getGlobal):
(let.console.log):
* wasm/spec-harness/sync_index.js: Renamed from JSTests/wasm/spec-harness/index.js.
(reinitializeRegistry.let.handler.get return):
(module):
* wasm/spec-tests/call.wast.js:
* wasm/spec-tests/exports.wast.js:
* wasm/spec-tests/globals.wast.js:
* wasm/spec-tests/if.wast.js:
* wasm/spec-tests/imports.wast.js:
* wasm/spec-tests/linking.wast.js:
* wasm/spec-tests/memory.wast.js:
* wasm/stress/immutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq.instance.exports.getI32):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq):
* wasm/stress/mutable-globals-cross.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance1):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance2):
* wasm/stress/mutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.instance.exports.setI32AsI64):
LayoutTests/imported/w3c:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any.worker-expected.txt:
Source/JavaScriptCore:
This patch adds WebAssembly.Global implementation. It is already included in the Wasm spec (this means, it is not in
staging right now: it was stage-4, and included in the spec). WebAssembly.Global is a wrapper object around
"global" binding. This object can hold "immutable" and "mutable" global binding, and we can access Wasm globals through
this object. Furthermore, we can share mutable global binding through this object across WebAssembly modules.
To implement it efficiently, this patch introduces BindingMode to Wasm globals. If the mode is EmbeddedInInstance,
we continue using the current existing mechanism. If the mode is Portable, we store a pointer to actual value in
Wasm globals array in Wasm::Instance, so that we can access it through one additional dereference.
And we mark all immutable globals as EmbeddedInInstance. If the binding is immutable, internally we do not need to
have one binding. We can just continue using the current mechanism since users cannot observe whether immutable bindings'
storage is shared or not. If the global is mutable, and it is exported outside of the module, we use Portable mode.
So, all the previously used wasm global bindings are EmbeddedInInstance. Only newly added "mutable" "exported" bindings
are Portable and requires one additional dereference.
To access portable bindings efficiently, we add new Wasm bytecodes, `get_global_portable_binding`, `set_global_portable_binding`,
and `set_global_ref_portable_binding`.
This patch improves WPT wasm coverage significantly.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeList.rb:
* heap/HeapCell.cpp:
(JSC::keepAlive):
(JSC::HeapCell::use const): Deleted.
* heap/HeapCell.h:
(JSC::keepAlive):
(JSC::HeapCell::use const):
* llint/WebAssembly.asm:
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::getGlobal):
(JSC::Wasm::AirIRGenerator::setGlobal):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::getGlobal):
(JSC::Wasm::B3IRGenerator::setGlobal):
* wasm/WasmFormat.h:
* wasm/WasmGlobal.cpp: Added.
(JSC::Wasm::Global::get const):
(JSC::Wasm::Global::set):
(JSC::Wasm::Global::visitAggregate):
* wasm/WasmGlobal.h: Added.
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::linkGlobal):
* wasm/WasmInstance.h:
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::globalsToBinding):
(JSC::Wasm::Instance::getGlobalBinding):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
* wasm/WasmModuleInformation.h:
* wasm/WasmOperations.cpp:
(JSC::Wasm::operationWasmWriteBarrierSlowPath):
* wasm/WasmOperations.h:
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
* wasm/WasmSectionParser.h:
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::setGlobal):
* wasm/js/JSWebAssembly.cpp:
* wasm/js/JSWebAssemblyGlobal.cpp: Added.
(JSC::JSWebAssemblyGlobal::create):
(JSC::JSWebAssemblyGlobal::createStructure):
(JSC::JSWebAssemblyGlobal::JSWebAssemblyGlobal):
(JSC::JSWebAssemblyGlobal::finishCreation):
(JSC::JSWebAssemblyGlobal::destroy):
(JSC::JSWebAssemblyGlobal::visitChildren):
* wasm/js/JSWebAssemblyGlobal.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::visitChildren):
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::destroy):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WebAssemblyGlobalConstructor.cpp: Added.
(JSC::constructJSWebAssemblyGlobal):
(JSC::callJSWebAssemblyGlobal):
(JSC::WebAssemblyGlobalConstructor::create):
(JSC::WebAssemblyGlobalConstructor::createStructure):
(JSC::WebAssemblyGlobalConstructor::finishCreation):
(JSC::WebAssemblyGlobalConstructor::WebAssemblyGlobalConstructor):
* wasm/js/WebAssemblyGlobalConstructor.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyGlobalPrototype.cpp: Added.
(JSC::getGlobal):
(JSC::webAssemblyGlobalProtoFuncValueOf):
(JSC::webAssemblyGlobalProtoGetterFuncValue):
(JSC::webAssemblyGlobalProtoSetterFuncValue):
(JSC::WebAssemblyGlobalPrototype::create):
(JSC::WebAssemblyGlobalPrototype::createStructure):
(JSC::WebAssemblyGlobalPrototype::finishCreation):
(JSC::WebAssemblyGlobalPrototype::WebAssemblyGlobalPrototype):
* wasm/js/WebAssemblyGlobalPrototype.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
Canonical link: https://commits.webkit.org/218038@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-12-04 01:36:56 +00:00
|
|
|
wasm/WasmGlobal.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmIndexOrName.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/WasmInstance.cpp
|
|
|
|
wasm/WasmInstance.h
|
[WebAssembly] Create a Wasm interpreter
https://bugs.webkit.org/show_bug.cgi?id=194257
<rdar://problem/44186794>
Reviewed by Saam Barati.
Source/JavaScriptCore:
Add an interpreter tier to WebAssembly which reuses the LLInt infrastructure. The interpreter
currently tiers up straight to OMG and can OSR enter at the prologue and from loops. The initial
implementation of the interpreter is very naive, but despite the lack of optimizations it still
shows a 2x improvement on the WebAssembly subtests in JetStream2 and 2x improvement on the
PSPDFKit benchmark. It reduces "compilation" times by ~3x and it's neutral on throughput.
The interpreter follows the same calling conventions as the BBQ/OMG, this means that:
- We have to allocate locals for all argument registers and write all arguments registers to the
stack in the prologue.
- Calls have to allocate space for at least as many arguments as the number of argument registers.
Before each call, all argument registers must be loaded from the stack, and after we return from
the call, all registers must be stored back to the stack, in case they contain return values. We
carefully layout the stack so that the arguments that would already have to be passed in the stack
end up in the right place. The stack layout for calls is:
[ gprs ][ fprs ][ optional stack arguments ][ callee frame ]
^ sp
- The return opcode has to load all registers from the stack, since they might need to contain
results of the function.
- The calling convention requires that the callee should store itself in the callee slot of the call
frame, which is impossible in the interpreter, since the code we execute is the same for all callees.
In order to work around that, we generate an entry thunk to the wasm interpreter for each function.
All this thunk does is store the callee in the call frame and tail call the interpreter.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::constantName const):
(JSC::BytecodeDumper<Block>::dumpValue):
(JSC::BytecodeDumper<Block>::dumpBytecode):
(JSC::CodeBlockBytecodeDumper<Block>::vm const):
(JSC::CodeBlockBytecodeDumper<Block>::identifier const):
(JSC::CodeBlockBytecodeDumper<Block>::dumpIdentifiers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpConstants):
(JSC::CodeBlockBytecodeDumper<Block>::dumpExceptionHandlers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
* bytecode/BytecodeDumper.h:
(JSC::BytecodeDumper::dumpValue):
(JSC::BytecodeDumper::BytecodeDumper):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::performGeneratorification):
* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Fits.h:
* bytecode/Instruction.h:
(JSC::BaseInstruction::BaseInstruction):
(JSC::BaseInstruction::Impl::opcodeID const):
(JSC::BaseInstruction::opcodeID const):
(JSC::BaseInstruction::name const):
(JSC::BaseInstruction::isWide16 const):
(JSC::BaseInstruction::isWide32 const):
(JSC::BaseInstruction::hasMetadata const):
(JSC::BaseInstruction::sizeShiftAmount const):
(JSC::BaseInstruction::size const):
(JSC::BaseInstruction::is const):
(JSC::BaseInstruction::as const):
(JSC::BaseInstruction::cast):
(JSC::BaseInstruction::cast const):
(JSC::BaseInstruction::wide16 const):
(JSC::BaseInstruction::wide32 const):
* bytecode/InstructionStream.h:
(JSC::InstructionStream::iterator::operator+=):
(JSC::InstructionStream::iterator::operator++):
(JSC::InstructionStreamWriter::iterator::operator+=):
(JSC::InstructionStreamWriter::iterator::operator++):
* bytecode/Opcode.cpp:
* bytecode/Opcode.h:
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecode/VirtualRegister.cpp:
(JSC::VirtualRegister::VirtualRegister):
* bytecode/VirtualRegister.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::GenericLabel<JSGeneratorTraits>::setLocation):
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/BytecodeGeneratorBase.h: Added.
* bytecompiler/BytecodeGeneratorBaseInlines.h: Added.
(JSC::shrinkToFit):
(JSC::BytecodeGeneratorBase<Traits>::BytecodeGeneratorBase):
(JSC::BytecodeGeneratorBase<Traits>::newLabel):
(JSC::BytecodeGeneratorBase<Traits>::newEmittedLabel):
(JSC::BytecodeGeneratorBase<Traits>::reclaimFreeRegisters):
(JSC::BytecodeGeneratorBase<Traits>::emitLabel):
(JSC::BytecodeGeneratorBase<Traits>::recordOpcode):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode16):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode32):
(JSC::BytecodeGeneratorBase<Traits>::write):
(JSC::BytecodeGeneratorBase<Traits>::newRegister):
(JSC::BytecodeGeneratorBase<Traits>::newTemporary):
(JSC::BytecodeGeneratorBase<Traits>::addVar):
(JSC::BytecodeGeneratorBase<Traits>::allocateCalleeSaveSpace):
* bytecompiler/Label.h:
(JSC::GenericBoundLabel::GenericBoundLabel):
(JSC::GenericBoundLabel::target):
(JSC::GenericBoundLabel::saveTarget):
(JSC::GenericBoundLabel::commitTarget):
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOperations.cpp:
* generator/Argument.rb:
* generator/DSL.rb:
* generator/GeneratedFile.rb:
* generator/Opcode.rb:
* generator/Options.rb:
* generator/Section.rb:
* generator/Wasm.rb: Added.
* interpreter/Register.h:
* interpreter/RegisterInlines.h:
(JSC::Register::operator=):
* jit/JITArithmetic.cpp:
* jit/JITOpcodes.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC::LLInt::wasmExceptionInstructions):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::wasmFunctionEntryThunk):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* llint/WebAssembly.asm: Added.
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/parser.rb:
* offlineasm/registers.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:
* parser/Nodes.h:
* runtime/Error.cpp:
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator() const):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* runtime/Options.cpp:
(JSC::overrideDefaults):
* runtime/OptionsList.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::recordJITFrame):
(JSC::FrameWalker::resetAtMachineFrame):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::isControlTypeIf):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::isControlTypeIf):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::prepareImpl):
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):
(JSC::Wasm::BBQPlan::didCompleteCompilation):
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h: Removed.
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
(JSC::Wasm::Callee::dump const):
(JSC::Wasm::JITCallee::JITCallee):
(JSC::Wasm::LLIntCallee::setEntrypoint):
(JSC::Wasm::LLIntCallee::entrypoint const):
(JSC::Wasm::LLIntCallee::calleeSaveRegisters):
(JSC::Wasm:: const):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::setOSREntryCallee):
(JSC::Wasm::JITCallee::wasmToWasmCallsites):
(JSC::Wasm::JITCallee:: const):
* wasm/WasmCallingConvention.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmToWasmExitStub):
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmEmbedder.h:
* wasm/WasmEntryPlan.cpp: Added.
(JSC::Wasm::EntryPlan::EntryPlan):
(JSC::Wasm::EntryPlan::stateString):
(JSC::Wasm::EntryPlan::moveToState):
(JSC::Wasm::EntryPlan::didReceiveFunctionData):
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::prepare):
(JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder):
(JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder):
(JSC::Wasm::EntryPlan::complete):
(JSC::Wasm::EntryPlan::compileFunctions):
(JSC::Wasm::EntryPlan::work):
* wasm/WasmEntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmBBQPlan.h.
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::exports const):
(JSC::Wasm::EntryPlan::internalFunctionCount const):
(JSC::Wasm::EntryPlan::takeModuleInformation):
(JSC::Wasm::EntryPlan::takeWasmToWasmExitStubs):
(JSC::Wasm::EntryPlan::takeWasmToWasmCallsites):
(JSC::Wasm::EntryPlan::hasBeenPrepared const):
(JSC::Wasm::EntryPlan::tryReserveCapacity):
* wasm/WasmFunctionCodeBlock.cpp: Added.
(JSC::Wasm::FunctionCodeBlock::setInstructions):
(JSC::Wasm::FunctionCodeBlock::dumpBytecode):
(JSC::Wasm::FunctionCodeBlock::addOutOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::addSignature):
(JSC::Wasm::FunctionCodeBlock::signature const):
(JSC::Wasm::FunctionCodeBlock::addJumpTable):
(JSC::Wasm::FunctionCodeBlock::jumpTable const const):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTables const):
* wasm/WasmFunctionCodeBlock.h: Added.
(JSC::Wasm::FunctionCodeBlock::FunctionCodeBlock):
(JSC::Wasm::FunctionCodeBlock::getConstant const):
(JSC::Wasm::FunctionCodeBlock::functionIndex const):
(JSC::Wasm::FunctionCodeBlock::addJumpTarget):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTargets):
(JSC::Wasm::FunctionCodeBlock::lastJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::bytecodeOffset):
(JSC::Wasm::FunctionCodeBlock::tierUpCounter):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmInstance.h:
* wasm/WasmLLIntGenerator.cpp: Added.
(JSC::Wasm::LLIntGenerator::ControlType::ControlType):
(JSC::Wasm::LLIntGenerator::ControlType::loop):
(JSC::Wasm::LLIntGenerator::ControlType::topLevel):
(JSC::Wasm::LLIntGenerator::ControlType::block):
(JSC::Wasm::LLIntGenerator::ControlType::if_):
(JSC::Wasm::LLIntGenerator::ControlType::targetLabelForBranch const):
(JSC::Wasm::LLIntGenerator::fail const):
(JSC::Wasm::LLIntGenerator::unifyValuesWithBlock):
(JSC::Wasm::LLIntGenerator::emptyExpression):
(JSC::Wasm::LLIntGenerator::createStack):
(JSC::Wasm::LLIntGenerator::isControlTypeIf):
(JSC::Wasm::LLIntGenerator::addEndToUnreachable):
(JSC::Wasm::LLIntGenerator::setParser):
(JSC::Wasm::LLIntGenerator::dump):
(JSC::Wasm::LLIntGenerator::virtualRegisterForLocal):
(JSC::Wasm::LLIntGenerator::tmpsForSignature):
(JSC::Wasm::LLIntGenerator::jsNullConstant):
(JSC::Wasm::LLIntGenerator::isConstant):
(JSC::Wasm::parseAndCompileBytecode):
(JSC::Wasm::LLIntGenerator::LLIntGenerator):
(JSC::Wasm::LLIntGenerator::finalize):
(JSC::Wasm::LLIntGenerator::callInformationFor):
(JSC::Wasm::LLIntGenerator::addArguments):
(JSC::Wasm::LLIntGenerator::addLocal):
(JSC::Wasm::LLIntGenerator::addConstant):
(JSC::Wasm::LLIntGenerator::getLocal):
(JSC::Wasm::LLIntGenerator::setLocal):
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
(JSC::Wasm::LLIntGenerator::addLoop):
(JSC::Wasm::LLIntGenerator::addTopLevel):
(JSC::Wasm::LLIntGenerator::addBlock):
(JSC::Wasm::LLIntGenerator::addIf):
(JSC::Wasm::LLIntGenerator::addElse):
(JSC::Wasm::LLIntGenerator::addElseToUnreachable):
(JSC::Wasm::LLIntGenerator::addReturn):
(JSC::Wasm::LLIntGenerator::addBranch):
(JSC::Wasm::LLIntGenerator::addSwitch):
(JSC::Wasm::LLIntGenerator::endBlock):
(JSC::Wasm::LLIntGenerator::addCall):
(JSC::Wasm::LLIntGenerator::addCallIndirect):
(JSC::Wasm::LLIntGenerator::addRefIsNull):
(JSC::Wasm::LLIntGenerator::addRefFunc):
(JSC::Wasm::LLIntGenerator::addTableGet):
(JSC::Wasm::LLIntGenerator::addTableSet):
(JSC::Wasm::LLIntGenerator::addTableSize):
(JSC::Wasm::LLIntGenerator::addTableGrow):
(JSC::Wasm::LLIntGenerator::addTableFill):
(JSC::Wasm::LLIntGenerator::addUnreachable):
(JSC::Wasm::LLIntGenerator::addCurrentMemory):
(JSC::Wasm::LLIntGenerator::addGrowMemory):
(JSC::Wasm::LLIntGenerator::addSelect):
(JSC::Wasm::LLIntGenerator::load):
(JSC::Wasm::LLIntGenerator::store):
(JSC::GenericLabel<Wasm::GeneratorTraits>::setLocation):
* wasm/WasmLLIntGenerator.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmLLIntPlan.cpp: Added.
(JSC::Wasm::LLIntPlan::prepareImpl):
(JSC::Wasm::LLIntPlan::compileFunction):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::initializeCallees):
* wasm/WasmLLIntPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
* wasm/WasmLLIntTierUpCounter.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::LLIntTierUpCounter::addOSREntryDataForLoop):
(JSC::Wasm::LLIntTierUpCounter::osrEntryDataForLoop const const):
* wasm/WasmLLIntTierUpCounter.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
(JSC::Wasm::LLIntTierUpCounter::LLIntTierUpCounter):
(JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
(JSC::Wasm::LLIntTierUpCounter::checkIfOptimizationThresholdReached):
(JSC::Wasm::LLIntTierUpCounter::optimizeSoon):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationResult):
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmOMGForOSREntryPlan.cpp:
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h:
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmSlowPaths.cpp: Added.
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
(JSC::LLInt::doWasmCall):
(JSC::LLInt::doWasmCallIndirect):
(JSC::LLInt::slow_path_wasm_throw_exception):
(JSC::LLInt::slow_path_wasm_popcount):
(JSC::LLInt::slow_path_wasm_popcountll):
* wasm/WasmSlowPaths.h: Added.
* wasm/WasmTable.cpp:
(JSC::Wasm::FuncRefTable::function const):
(JSC::Wasm::FuncRefTable::instance const):
* wasm/WasmTable.h:
* wasm/WasmTierUpCount.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::isControlTypeIf):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::calleeSaves const):
Tools:
Add a mode that runs WebAssembly tests without the LLInt (i.e. only Air)
and update the no-air mode to also disable the LLInt tier.
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/217068@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251886 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-31 22:32:52 +00:00
|
|
|
wasm/WasmLLIntGenerator.cpp
|
|
|
|
wasm/WasmLLIntPlan.cpp
|
|
|
|
wasm/WasmLLIntTierUpCounter.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmMachineThreads.cpp
|
|
|
|
wasm/WasmMemory.cpp
|
|
|
|
wasm/WasmMemoryInformation.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/WasmMemoryMode.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmModule.cpp
|
|
|
|
wasm/WasmModuleInformation.cpp
|
|
|
|
wasm/WasmNameSectionParser.cpp
|
[JSC] OSR entry to Wasm OMG
https://bugs.webkit.org/show_bug.cgi?id=200362
Reviewed by Michael Saboff.
JSTests:
* wasm/stress/osr-entry-basic.js: Added.
(instance.exports.loop):
* wasm/stress/osr-entry-many-locals-f32.js: Added.
* wasm/stress/osr-entry-many-locals-f64.js: Added.
* wasm/stress/osr-entry-many-locals-i32.js: Added.
* wasm/stress/osr-entry-many-locals-i64.js: Added.
* wasm/stress/osr-entry-many-stacks-f32.js: Added.
* wasm/stress/osr-entry-many-stacks-f64.js: Added.
* wasm/stress/osr-entry-many-stacks-i32.js: Added.
* wasm/stress/osr-entry-many-stacks-i64.js: Added.
Source/JavaScriptCore:
This patch implements Wasm OSR entry mechanism from BBQ tier to OMG tier.
We found that one of JetStream2 test heavily relies on OSR entry feature. gcc-loops-wasm consumes
most of time in BBQ tier since one of the function takes significantly long time. And since we did
not have OSR entry feature, we cannot use OMG function until that BBQ function finishes.
To implement Wasm OSR feature, we first capture all locals and stacks in the patchpoint to generate
the stackmap. Once the threshold is crossed, the patchpoint calls `MacroAssembler::probe` feature to
capture whole register context, and C++ runtime function reads stackmap and Probe::Context to perform
OSR entry. This patch intentionally makes OSR entry written in C++ runtime side as much as possible
to make it easily reusable for the other tiers. For example, we are planning to introduce Wasm interpreter,
and it can easily use this tier-up function. Because of this simplicity, this generic implementation can
cover both BBQ Air and BBQ B3 tier-up features. So, in the feature, it is possible that we revive BBQ B3,
and construct the wasm pipeline like, interpreter->BBQ B3->OMG B3.
To generate OMG code for OSR entry, we add a new mode OMGForOSREntry, which mimics the FTLForOSREntry.
In FTLForOSREntry, we cut unrelated blocks including the usual entry point in DFG tier and later convert
graph to SSA. This is possible because DFG is not SSA. On the other hand, B3 is SSA and we cannot take the
same thing without a hack.
This patch introduce a hack: making all wasm locals and stack values B3::Variable for OMGForOSREntry mode.
Then, we can cut blocks easily and we can generate the B3 graph without doing reachability analysis from the
OSR entry point. B3 will remove unreachable blocks later.
Tier-up function mimics DFG->FTL OSR entry heuristics and threshold as much as possible. And this patch adjusts
the tier-up count threshold to make it close to DFG->FTL ones. Wasm tier-up is now using ExecutionCounter, which
is inherited from Wasm::TierUpCount. Since wasm can execute concurrently, the tier-up counter can be racily updated.
But this is OK in practice. Even if we see some more tier-up function calls or tier-up function calls are delayed,
the critical part is guarded by a lock in tier-up function.
In iMac Pro, it shows ~4x runtime improvement for gcc-loops-wasm. On iOS device (iPhone XR), we saw ~2x improvement.
ToT:
HashSet-wasm:Score: 24.6pt stdev=4.6%
:Time:Geometric: 204ms stdev=4.4%
Runtime:Time: 689ms stdev=1.0%
Startup:Time: 60.3ms stdev=8.4%
gcc-loops-wasm:Score: 8.41pt stdev=6.7%
:Time:Geometric: 597ms stdev=6.5%
Runtime:Time: 8.509s stdev=0.7%
Startup:Time: 42ms stdev=12.4%
quicksort-wasm:Score: 347pt stdev=20.9%
:Time:Geometric: 15ms stdev=18.6%
Runtime:Time: 28.2ms stdev=7.9%
Startup:Time: 8.2ms stdev=35.0%
richards-wasm:Score: 77.6pt stdev=4.5%
:Time:Geometric: 64.6ms stdev=4.4%
Runtime:Time: 544ms stdev=3.3%
Startup:Time: 7.67ms stdev=6.7%
tsf-wasm:Score: 47.9pt stdev=4.5%
:Time:Geometric: 104ms stdev=4.8%
Runtime:Time: 259ms stdev=4.4%
Startup:Time: 42.2ms stdev=8.5%
Patched:
HashSet-wasm:Score: 24.1pt stdev=4.1%
:Time:Geometric: 208ms stdev=4.1%
Runtime:Time: 684ms stdev=1.1%
Startup:Time: 63.2ms stdev=8.1%
gcc-loops-wasm:Score: 15.7pt stdev=5.1%
:Time:Geometric: 319ms stdev=5.3%
Runtime:Time: 2.491s stdev=0.7%
Startup:Time: 41ms stdev=11.0%
quicksort-wasm:Score: 353pt stdev=13.7%
:Time:Geometric: 14ms stdev=12.7%
Runtime:Time: 26.2ms stdev=2.9%
Startup:Time: 8.0ms stdev=23.7%
richards-wasm:Score: 77.4pt stdev=5.3%
:Time:Geometric: 64.7ms stdev=5.3%
Runtime:Time: 536ms stdev=1.5%
Startup:Time: 7.83ms stdev=9.6%
tsf-wasm:Score: 47.3pt stdev=5.7%
:Time:Geometric: 106ms stdev=6.1%
Runtime:Time: 250ms stdev=3.5%
Startup:Time: 45ms stdev=13.8%
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchAdd32):
* b3/B3ValueRep.h:
* bytecode/CodeBlock.h:
* bytecode/ExecutionCounter.cpp:
(JSC::applyMemoryUsageHeuristics):
(JSC::ExecutionCounter<countingVariant>::setThreshold):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGJITCode.h:
* dfg/DFGOperations.cpp:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::prologueStackPointerDelta):
* runtime/Options.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::createStack):
(JSC::Wasm::AirIRGenerator::emitPatchpoint):
(JSC::Wasm::AirIRGenerator::outerLoopIndex const):
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::AirIRGenerator::addLoop):
(JSC::Wasm::AirIRGenerator::addElse):
(JSC::Wasm::AirIRGenerator::addBranch):
(JSC::Wasm::AirIRGenerator::addSwitch):
(JSC::Wasm::AirIRGenerator::endBlock):
(JSC::Wasm::AirIRGenerator::addEndToUnreachable):
(JSC::Wasm::AirIRGenerator::unifyValuesWithBlock):
(JSC::Wasm::AirIRGenerator::dump):
(JSC::Wasm::AirIRGenerator::emitTierUpCheck): Deleted.
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::Stack::Stack):
(JSC::Wasm::B3IRGenerator::Stack::append):
(JSC::Wasm::B3IRGenerator::Stack::takeLast):
(JSC::Wasm::B3IRGenerator::Stack::last):
(JSC::Wasm::B3IRGenerator::Stack::size const):
(JSC::Wasm::B3IRGenerator::Stack::isEmpty const):
(JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList):
(JSC::Wasm::B3IRGenerator::Stack::at const):
(JSC::Wasm::B3IRGenerator::Stack::variableAt const):
(JSC::Wasm::B3IRGenerator::Stack::shrink):
(JSC::Wasm::B3IRGenerator::Stack::swap):
(JSC::Wasm::B3IRGenerator::Stack::dump const):
(JSC::Wasm::B3IRGenerator::createStack):
(JSC::Wasm::B3IRGenerator::outerLoopIndex const):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addElse):
(JSC::Wasm::B3IRGenerator::addBranch):
(JSC::Wasm::B3IRGenerator::addSwitch):
(JSC::Wasm::B3IRGenerator::endBlock):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
(JSC::Wasm::B3IRGenerator::unifyValuesWithBlock):
(JSC::Wasm::B3IRGenerator::dump):
(JSC::Wasm::parseAndCompile):
(JSC::Wasm::B3IRGenerator::emitTierUpCheck): Deleted.
(JSC::Wasm::dumpExpressionStack): Deleted.
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::compileFunctions):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::entrypointLoadLocationFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::tierUpCount): Deleted.
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmContext.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::Context::scratchBufferForSize):
* wasm/WasmContext.h:
* wasm/WasmContextInlines.h:
(JSC::Wasm::Context::tryLoadInstanceFromTLS):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
(JSC::Wasm::FunctionParser<Context>::parseBody):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
* wasm/WasmOMGForOSREntryPlan.cpp: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.cpp.
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.h.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
(JSC::Wasm::OMGPlan::runForIndex): Deleted.
* wasm/WasmOMGPlan.h:
* wasm/WasmOSREntryData.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
(JSC::Wasm::OSREntryValue::OSREntryValue):
(JSC::Wasm::OSREntryValue::type const):
(JSC::Wasm::OSREntryData::OSREntryData):
(JSC::Wasm::OSREntryData::functionIndex const):
(JSC::Wasm::OSREntryData::loopIndex const):
(JSC::Wasm::OSREntryData::values):
* wasm/WasmOperations.cpp: Added.
(JSC::Wasm::shouldTriggerOMGCompile):
(JSC::Wasm::triggerOMGReplacementCompile):
(JSC::Wasm::doOSREntry):
(JSC::Wasm::triggerOSREntryNow):
(JSC::Wasm::triggerTierUpNow):
* wasm/WasmOperations.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmThunks.cpp:
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator): Deleted.
* wasm/WasmThunks.h:
* wasm/WasmTierUpCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::TierUpCount::TierUpCount):
(JSC::Wasm::TierUpCount::addOSREntryData):
* wasm/WasmTierUpCount.h:
(JSC::Wasm::TierUpCount::loopIncrement):
(JSC::Wasm::TierUpCount::functionEntryIncrement):
(JSC::Wasm::TierUpCount::osrEntryTriggers):
(JSC::Wasm::TierUpCount::outerLoops):
(JSC::Wasm::TierUpCount::getLock):
(JSC::Wasm::TierUpCount::optimizeAfterWarmUp):
(JSC::Wasm::TierUpCount::checkIfOptimizationThresholdReached):
(JSC::Wasm::TierUpCount::dontOptimizeAnytimeSoon):
(JSC::Wasm::TierUpCount::optimizeNextInvocation):
(JSC::Wasm::TierUpCount::optimizeSoon):
(JSC::Wasm::TierUpCount::setOptimizationThresholdBasedOnCompilationResult):
(JSC::Wasm::TierUpCount::TierUpCount): Deleted.
(JSC::Wasm::TierUpCount::loopDecrement): Deleted.
(JSC::Wasm::TierUpCount::functionEntryDecrement): Deleted.
(JSC::Wasm::TierUpCount::shouldStartTierUp): Deleted.
(JSC::Wasm::TierUpCount::count): Deleted.
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::createStack):
(JSC::Wasm::Validate::addLoop):
(JSC::Wasm::Validate::addElse):
(JSC::Wasm::Validate::checkBranchTarget):
(JSC::Wasm::Validate::addBranch):
(JSC::Wasm::Validate::addSwitch):
(JSC::Wasm::Validate::endBlock):
(JSC::Wasm::Validate::unify):
(JSC::Wasm::dumpExpressionStack):
(JSC::Wasm::Validate::dump):
Tools:
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/214633@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-20 00:21:29 +00:00
|
|
|
wasm/WasmOMGForOSREntryPlan.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmOMGPlan.cpp
|
|
|
|
wasm/WasmOpcodeOrigin.cpp
|
[JSC] OSR entry to Wasm OMG
https://bugs.webkit.org/show_bug.cgi?id=200362
Reviewed by Michael Saboff.
JSTests:
* wasm/stress/osr-entry-basic.js: Added.
(instance.exports.loop):
* wasm/stress/osr-entry-many-locals-f32.js: Added.
* wasm/stress/osr-entry-many-locals-f64.js: Added.
* wasm/stress/osr-entry-many-locals-i32.js: Added.
* wasm/stress/osr-entry-many-locals-i64.js: Added.
* wasm/stress/osr-entry-many-stacks-f32.js: Added.
* wasm/stress/osr-entry-many-stacks-f64.js: Added.
* wasm/stress/osr-entry-many-stacks-i32.js: Added.
* wasm/stress/osr-entry-many-stacks-i64.js: Added.
Source/JavaScriptCore:
This patch implements Wasm OSR entry mechanism from BBQ tier to OMG tier.
We found that one of JetStream2 test heavily relies on OSR entry feature. gcc-loops-wasm consumes
most of time in BBQ tier since one of the function takes significantly long time. And since we did
not have OSR entry feature, we cannot use OMG function until that BBQ function finishes.
To implement Wasm OSR feature, we first capture all locals and stacks in the patchpoint to generate
the stackmap. Once the threshold is crossed, the patchpoint calls `MacroAssembler::probe` feature to
capture whole register context, and C++ runtime function reads stackmap and Probe::Context to perform
OSR entry. This patch intentionally makes OSR entry written in C++ runtime side as much as possible
to make it easily reusable for the other tiers. For example, we are planning to introduce Wasm interpreter,
and it can easily use this tier-up function. Because of this simplicity, this generic implementation can
cover both BBQ Air and BBQ B3 tier-up features. So, in the feature, it is possible that we revive BBQ B3,
and construct the wasm pipeline like, interpreter->BBQ B3->OMG B3.
To generate OMG code for OSR entry, we add a new mode OMGForOSREntry, which mimics the FTLForOSREntry.
In FTLForOSREntry, we cut unrelated blocks including the usual entry point in DFG tier and later convert
graph to SSA. This is possible because DFG is not SSA. On the other hand, B3 is SSA and we cannot take the
same thing without a hack.
This patch introduce a hack: making all wasm locals and stack values B3::Variable for OMGForOSREntry mode.
Then, we can cut blocks easily and we can generate the B3 graph without doing reachability analysis from the
OSR entry point. B3 will remove unreachable blocks later.
Tier-up function mimics DFG->FTL OSR entry heuristics and threshold as much as possible. And this patch adjusts
the tier-up count threshold to make it close to DFG->FTL ones. Wasm tier-up is now using ExecutionCounter, which
is inherited from Wasm::TierUpCount. Since wasm can execute concurrently, the tier-up counter can be racily updated.
But this is OK in practice. Even if we see some more tier-up function calls or tier-up function calls are delayed,
the critical part is guarded by a lock in tier-up function.
In iMac Pro, it shows ~4x runtime improvement for gcc-loops-wasm. On iOS device (iPhone XR), we saw ~2x improvement.
ToT:
HashSet-wasm:Score: 24.6pt stdev=4.6%
:Time:Geometric: 204ms stdev=4.4%
Runtime:Time: 689ms stdev=1.0%
Startup:Time: 60.3ms stdev=8.4%
gcc-loops-wasm:Score: 8.41pt stdev=6.7%
:Time:Geometric: 597ms stdev=6.5%
Runtime:Time: 8.509s stdev=0.7%
Startup:Time: 42ms stdev=12.4%
quicksort-wasm:Score: 347pt stdev=20.9%
:Time:Geometric: 15ms stdev=18.6%
Runtime:Time: 28.2ms stdev=7.9%
Startup:Time: 8.2ms stdev=35.0%
richards-wasm:Score: 77.6pt stdev=4.5%
:Time:Geometric: 64.6ms stdev=4.4%
Runtime:Time: 544ms stdev=3.3%
Startup:Time: 7.67ms stdev=6.7%
tsf-wasm:Score: 47.9pt stdev=4.5%
:Time:Geometric: 104ms stdev=4.8%
Runtime:Time: 259ms stdev=4.4%
Startup:Time: 42.2ms stdev=8.5%
Patched:
HashSet-wasm:Score: 24.1pt stdev=4.1%
:Time:Geometric: 208ms stdev=4.1%
Runtime:Time: 684ms stdev=1.1%
Startup:Time: 63.2ms stdev=8.1%
gcc-loops-wasm:Score: 15.7pt stdev=5.1%
:Time:Geometric: 319ms stdev=5.3%
Runtime:Time: 2.491s stdev=0.7%
Startup:Time: 41ms stdev=11.0%
quicksort-wasm:Score: 353pt stdev=13.7%
:Time:Geometric: 14ms stdev=12.7%
Runtime:Time: 26.2ms stdev=2.9%
Startup:Time: 8.0ms stdev=23.7%
richards-wasm:Score: 77.4pt stdev=5.3%
:Time:Geometric: 64.7ms stdev=5.3%
Runtime:Time: 536ms stdev=1.5%
Startup:Time: 7.83ms stdev=9.6%
tsf-wasm:Score: 47.3pt stdev=5.7%
:Time:Geometric: 106ms stdev=6.1%
Runtime:Time: 250ms stdev=3.5%
Startup:Time: 45ms stdev=13.8%
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchAdd32):
* b3/B3ValueRep.h:
* bytecode/CodeBlock.h:
* bytecode/ExecutionCounter.cpp:
(JSC::applyMemoryUsageHeuristics):
(JSC::ExecutionCounter<countingVariant>::setThreshold):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGJITCode.h:
* dfg/DFGOperations.cpp:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::prologueStackPointerDelta):
* runtime/Options.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::createStack):
(JSC::Wasm::AirIRGenerator::emitPatchpoint):
(JSC::Wasm::AirIRGenerator::outerLoopIndex const):
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::AirIRGenerator::addLoop):
(JSC::Wasm::AirIRGenerator::addElse):
(JSC::Wasm::AirIRGenerator::addBranch):
(JSC::Wasm::AirIRGenerator::addSwitch):
(JSC::Wasm::AirIRGenerator::endBlock):
(JSC::Wasm::AirIRGenerator::addEndToUnreachable):
(JSC::Wasm::AirIRGenerator::unifyValuesWithBlock):
(JSC::Wasm::AirIRGenerator::dump):
(JSC::Wasm::AirIRGenerator::emitTierUpCheck): Deleted.
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::Stack::Stack):
(JSC::Wasm::B3IRGenerator::Stack::append):
(JSC::Wasm::B3IRGenerator::Stack::takeLast):
(JSC::Wasm::B3IRGenerator::Stack::last):
(JSC::Wasm::B3IRGenerator::Stack::size const):
(JSC::Wasm::B3IRGenerator::Stack::isEmpty const):
(JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList):
(JSC::Wasm::B3IRGenerator::Stack::at const):
(JSC::Wasm::B3IRGenerator::Stack::variableAt const):
(JSC::Wasm::B3IRGenerator::Stack::shrink):
(JSC::Wasm::B3IRGenerator::Stack::swap):
(JSC::Wasm::B3IRGenerator::Stack::dump const):
(JSC::Wasm::B3IRGenerator::createStack):
(JSC::Wasm::B3IRGenerator::outerLoopIndex const):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addElse):
(JSC::Wasm::B3IRGenerator::addBranch):
(JSC::Wasm::B3IRGenerator::addSwitch):
(JSC::Wasm::B3IRGenerator::endBlock):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
(JSC::Wasm::B3IRGenerator::unifyValuesWithBlock):
(JSC::Wasm::B3IRGenerator::dump):
(JSC::Wasm::parseAndCompile):
(JSC::Wasm::B3IRGenerator::emitTierUpCheck): Deleted.
(JSC::Wasm::dumpExpressionStack): Deleted.
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::compileFunctions):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::entrypointLoadLocationFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::tierUpCount): Deleted.
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmContext.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::Context::scratchBufferForSize):
* wasm/WasmContext.h:
* wasm/WasmContextInlines.h:
(JSC::Wasm::Context::tryLoadInstanceFromTLS):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
(JSC::Wasm::FunctionParser<Context>::parseBody):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
* wasm/WasmOMGForOSREntryPlan.cpp: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.cpp.
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.h.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
(JSC::Wasm::OMGPlan::runForIndex): Deleted.
* wasm/WasmOMGPlan.h:
* wasm/WasmOSREntryData.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
(JSC::Wasm::OSREntryValue::OSREntryValue):
(JSC::Wasm::OSREntryValue::type const):
(JSC::Wasm::OSREntryData::OSREntryData):
(JSC::Wasm::OSREntryData::functionIndex const):
(JSC::Wasm::OSREntryData::loopIndex const):
(JSC::Wasm::OSREntryData::values):
* wasm/WasmOperations.cpp: Added.
(JSC::Wasm::shouldTriggerOMGCompile):
(JSC::Wasm::triggerOMGReplacementCompile):
(JSC::Wasm::doOSREntry):
(JSC::Wasm::triggerOSREntryNow):
(JSC::Wasm::triggerTierUpNow):
* wasm/WasmOperations.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmThunks.cpp:
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator): Deleted.
* wasm/WasmThunks.h:
* wasm/WasmTierUpCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::TierUpCount::TierUpCount):
(JSC::Wasm::TierUpCount::addOSREntryData):
* wasm/WasmTierUpCount.h:
(JSC::Wasm::TierUpCount::loopIncrement):
(JSC::Wasm::TierUpCount::functionEntryIncrement):
(JSC::Wasm::TierUpCount::osrEntryTriggers):
(JSC::Wasm::TierUpCount::outerLoops):
(JSC::Wasm::TierUpCount::getLock):
(JSC::Wasm::TierUpCount::optimizeAfterWarmUp):
(JSC::Wasm::TierUpCount::checkIfOptimizationThresholdReached):
(JSC::Wasm::TierUpCount::dontOptimizeAnytimeSoon):
(JSC::Wasm::TierUpCount::optimizeNextInvocation):
(JSC::Wasm::TierUpCount::optimizeSoon):
(JSC::Wasm::TierUpCount::setOptimizationThresholdBasedOnCompilationResult):
(JSC::Wasm::TierUpCount::TierUpCount): Deleted.
(JSC::Wasm::TierUpCount::loopDecrement): Deleted.
(JSC::Wasm::TierUpCount::functionEntryDecrement): Deleted.
(JSC::Wasm::TierUpCount::shouldStartTierUp): Deleted.
(JSC::Wasm::TierUpCount::count): Deleted.
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::createStack):
(JSC::Wasm::Validate::addLoop):
(JSC::Wasm::Validate::addElse):
(JSC::Wasm::Validate::checkBranchTarget):
(JSC::Wasm::Validate::addBranch):
(JSC::Wasm::Validate::addSwitch):
(JSC::Wasm::Validate::endBlock):
(JSC::Wasm::Validate::unify):
(JSC::Wasm::dumpExpressionStack):
(JSC::Wasm::Validate::dump):
Tools:
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/214633@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-20 00:21:29 +00:00
|
|
|
wasm/WasmOperations.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmPageCount.cpp
|
|
|
|
wasm/WasmPlan.cpp
|
[WebAssembly] Parse wasm modules in a streaming fashion
https://bugs.webkit.org/show_bug.cgi?id=188943
Reviewed by Mark Lam.
JSTests:
Wasm parsing error should not report the total byte size since streaming parsing does not
want to load all the bytes.
Add a simple test wasm/stress/streaming-basic.js for initial streaming parsing implementation.
* wasm/function-tests/invalid-duplicate-export.js:
* wasm/function-tests/memory-alignment.js:
(const.op.of.WASM.opcodes):
* wasm/function-tests/memory-section-and-import.js:
* wasm/function-tests/void-argument-type-should-be-a-validation-error.js:
* wasm/js-api/Module-compile.js:
(async.testPromiseAPI):
* wasm/js-api/element.js:
(assert.throws.new.WebAssembly.Module.builder.WebAssembly):
(assert.throws):
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(assert.throws):
* wasm/js-api/table.js:
(new.WebAssembly.Module):
(assert.throws):
(assertBadTableImport):
* wasm/js-api/test_Data.js:
(DataSectionWithoutMemory):
* wasm/js-api/test_Start.js:
(InvalidStartFunctionIndex):
* wasm/js-api/test_basic_api.js:
(const.c.in.constructorProperties.switch):
* wasm/js-api/version.js:
* wasm/stress/nameSection.wasm: Added.
* wasm/stress/streaming-basic.js: Added.
(check):
Source/JavaScriptCore:
This patch adds Wasm::StreamingParser, which parses wasm binary in a streaming fashion.
Currently, this StreamingParser is not enabled and integrated. In subsequent patches,
we start integrating it into BBQPlan and dropping the old ModuleParser.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* tools/JSDollarVM.cpp:
(WTF::WasmStreamingParser::WasmStreamingParser):
(WTF::WasmStreamingParser::create):
(WTF::WasmStreamingParser::createStructure):
(WTF::WasmStreamingParser::streamingParser):
(WTF::WasmStreamingParser::finishCreation):
(WTF::functionWasmStreamingParserAddBytes):
(WTF::functionWasmStreamingParserFinalize):
(JSC::functionCreateWasmStreamingParser):
(JSC::JSDollarVM::finishCreation):
The $vm Wasm::StreamingParser object is introduced for testing purpose. Added new stress test uses
this interface to test streaming parser in the JSC shell.
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::parseAndValidateModule):
(JSC::Wasm::BBQPlan::prepare):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
(JSC::Wasm::BBQPlan::work):
* wasm/WasmBBQPlan.h:
BBQPlan has m_source, but once ModuleInformation is parsed, it is no longer necessary.
In subsequent patches, we will remove this, and stream the data into the BBQPlan.
* wasm/WasmFormat.h:
* wasm/WasmModuleInformation.cpp:
(JSC::Wasm::ModuleInformation::ModuleInformation):
* wasm/WasmModuleInformation.h:
One of the largest change in this patch is that ModuleInformation no longer holds source bytes,
since source bytes can be added in a streaming fashion. Instead of holding all the source bytes
in ModuleInformation, each function (ModuleInformation::functions, FunctionData) should have
Vector<uint8_t> for its data. This data is eventually filled by StreamingParser, and compiling
a function with this data can be done concurrently with StreamingParser.
(JSC::Wasm::ModuleInformation::create):
(JSC::Wasm::ModuleInformation::memoryCount const):
(JSC::Wasm::ModuleInformation::tableCount const):
memoryCount and tableCount should be recorded in ModuleInformation.
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parse):
(JSC::Wasm::makeI32InitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseType): Deleted.
(JSC::Wasm::ModuleParser::parseImport): Deleted.
(JSC::Wasm::ModuleParser::parseFunction): Deleted.
(JSC::Wasm::ModuleParser::parseResizableLimits): Deleted.
(JSC::Wasm::ModuleParser::parseTableHelper): Deleted.
(JSC::Wasm::ModuleParser::parseTable): Deleted.
(JSC::Wasm::ModuleParser::parseMemoryHelper): Deleted.
(JSC::Wasm::ModuleParser::parseMemory): Deleted.
(JSC::Wasm::ModuleParser::parseGlobal): Deleted.
(JSC::Wasm::ModuleParser::parseExport): Deleted.
(JSC::Wasm::ModuleParser::parseStart): Deleted.
(JSC::Wasm::ModuleParser::parseElement): Deleted.
(JSC::Wasm::ModuleParser::parseCode): Deleted.
(JSC::Wasm::ModuleParser::parseInitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseGlobalType): Deleted.
(JSC::Wasm::ModuleParser::parseData): Deleted.
(JSC::Wasm::ModuleParser::parseCustom): Deleted.
Extract section parsing code out from ModuleParser. We create SectionParser and ModuleParser uses it.
SectionParser is also used by StreamingParser.
* wasm/WasmModuleParser.h:
(): Deleted.
* wasm/WasmNameSection.h:
(JSC::Wasm::NameSection::NameSection):
(JSC::Wasm::NameSection::create):
(JSC::Wasm::NameSection::setHash):
Hash calculation is deferred since all the source is not available in streaming parsing.
* wasm/WasmNameSectionParser.cpp:
(JSC::Wasm::NameSectionParser::parse):
* wasm/WasmNameSectionParser.h:
Use Ref<NameSection>.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
Wasm::Plan no longer have m_source since data will be eventually filled in a streaming fashion.
OMGPlan can get data of the function by using ModuleInformation::functions.
* wasm/WasmParser.h:
(JSC::Wasm::Parser::source const):
(JSC::Wasm::Parser::length const):
(JSC::Wasm::Parser::offset const):
(JSC::Wasm::Parser::fail const):
(JSC::Wasm::makeI32InitExpr):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
Wasm::Plan should not have all the source apriori. Streamed data will be pumped from the provider.
* wasm/WasmPlan.h:
* wasm/WasmSectionParser.cpp: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.cpp.
SectionParser is extracted from ModuleParser. And it is used by both the old (currently working)
ModuleParser and the new StreamingParser.
(JSC::Wasm::SectionParser::parseType):
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseFunction):
(JSC::Wasm::SectionParser::parseResizableLimits):
(JSC::Wasm::SectionParser::parseTableHelper):
(JSC::Wasm::SectionParser::parseTable):
(JSC::Wasm::SectionParser::parseMemoryHelper):
(JSC::Wasm::SectionParser::parseMemory):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseStart):
(JSC::Wasm::SectionParser::parseElement):
(JSC::Wasm::SectionParser::parseCode):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
(JSC::Wasm::SectionParser::parseData):
(JSC::Wasm::SectionParser::parseCustom):
* wasm/WasmSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.h.
* wasm/WasmStreamingParser.cpp: Added.
(JSC::Wasm::parseUInt7):
(JSC::Wasm::StreamingParser::fail):
(JSC::Wasm::StreamingParser::StreamingParser):
(JSC::Wasm::StreamingParser::parseModuleHeader):
(JSC::Wasm::StreamingParser::parseSectionID):
(JSC::Wasm::StreamingParser::parseSectionSize):
(JSC::Wasm::StreamingParser::parseCodeSectionSize):
Code section in Wasm binary is specially handled compared with the other sections since it includes
a bunch of functions. StreamingParser extracts each function in a streaming fashion and enable
streaming validation / compilation of Wasm functions.
(JSC::Wasm::StreamingParser::parseFunctionSize):
(JSC::Wasm::StreamingParser::parseFunctionPayload):
(JSC::Wasm::StreamingParser::parseSectionPayload):
(JSC::Wasm::StreamingParser::consume):
(JSC::Wasm::StreamingParser::consumeVarUInt32):
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::failOnState):
(JSC::Wasm::StreamingParser::finalize):
* wasm/WasmStreamingParser.h: Added.
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::errorMessage const):
This is our new StreamingParser implementation. StreamingParser::consumeXXX functions get data, and
StreamingParser::parseXXX functions parse consumed data. The user of StreamingParser calls
StreamingParser::addBytes() to pump the bytes stream into the parser. And once all the data is pumped,
the user calls StreamingParser::finalize. StreamingParser is a state machine which feeds on the
incoming byte stream.
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::source const): Deleted.
All the source should not be held.
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyValidateFunc):
Source/WTF:
Add maxByteLength function to get the maximum size for T.
* wtf/LEBDecoder.h:
(WTF::LEBDecoder::maxByteLength):
(WTF::LEBDecoder::decodeUInt):
(WTF::LEBDecoder::decodeInt):
Canonical link: https://commits.webkit.org/204074@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235420 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 06:38:29 +00:00
|
|
|
wasm/WasmSectionParser.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmSignature.cpp
|
[WebAssembly] Create a Wasm interpreter
https://bugs.webkit.org/show_bug.cgi?id=194257
<rdar://problem/44186794>
Reviewed by Saam Barati.
Source/JavaScriptCore:
Add an interpreter tier to WebAssembly which reuses the LLInt infrastructure. The interpreter
currently tiers up straight to OMG and can OSR enter at the prologue and from loops. The initial
implementation of the interpreter is very naive, but despite the lack of optimizations it still
shows a 2x improvement on the WebAssembly subtests in JetStream2 and 2x improvement on the
PSPDFKit benchmark. It reduces "compilation" times by ~3x and it's neutral on throughput.
The interpreter follows the same calling conventions as the BBQ/OMG, this means that:
- We have to allocate locals for all argument registers and write all arguments registers to the
stack in the prologue.
- Calls have to allocate space for at least as many arguments as the number of argument registers.
Before each call, all argument registers must be loaded from the stack, and after we return from
the call, all registers must be stored back to the stack, in case they contain return values. We
carefully layout the stack so that the arguments that would already have to be passed in the stack
end up in the right place. The stack layout for calls is:
[ gprs ][ fprs ][ optional stack arguments ][ callee frame ]
^ sp
- The return opcode has to load all registers from the stack, since they might need to contain
results of the function.
- The calling convention requires that the callee should store itself in the callee slot of the call
frame, which is impossible in the interpreter, since the code we execute is the same for all callees.
In order to work around that, we generate an entry thunk to the wasm interpreter for each function.
All this thunk does is store the callee in the call frame and tail call the interpreter.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::constantName const):
(JSC::BytecodeDumper<Block>::dumpValue):
(JSC::BytecodeDumper<Block>::dumpBytecode):
(JSC::CodeBlockBytecodeDumper<Block>::vm const):
(JSC::CodeBlockBytecodeDumper<Block>::identifier const):
(JSC::CodeBlockBytecodeDumper<Block>::dumpIdentifiers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpConstants):
(JSC::CodeBlockBytecodeDumper<Block>::dumpExceptionHandlers):
(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
* bytecode/BytecodeDumper.h:
(JSC::BytecodeDumper::dumpValue):
(JSC::BytecodeDumper::BytecodeDumper):
* bytecode/BytecodeGeneratorification.cpp:
(JSC::performGeneratorification):
* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Fits.h:
* bytecode/Instruction.h:
(JSC::BaseInstruction::BaseInstruction):
(JSC::BaseInstruction::Impl::opcodeID const):
(JSC::BaseInstruction::opcodeID const):
(JSC::BaseInstruction::name const):
(JSC::BaseInstruction::isWide16 const):
(JSC::BaseInstruction::isWide32 const):
(JSC::BaseInstruction::hasMetadata const):
(JSC::BaseInstruction::sizeShiftAmount const):
(JSC::BaseInstruction::size const):
(JSC::BaseInstruction::is const):
(JSC::BaseInstruction::as const):
(JSC::BaseInstruction::cast):
(JSC::BaseInstruction::cast const):
(JSC::BaseInstruction::wide16 const):
(JSC::BaseInstruction::wide32 const):
* bytecode/InstructionStream.h:
(JSC::InstructionStream::iterator::operator+=):
(JSC::InstructionStream::iterator::operator++):
(JSC::InstructionStreamWriter::iterator::operator+=):
(JSC::InstructionStreamWriter::iterator::operator++):
* bytecode/Opcode.cpp:
* bytecode/Opcode.h:
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecode/VirtualRegister.cpp:
(JSC::VirtualRegister::VirtualRegister):
* bytecode/VirtualRegister.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::GenericLabel<JSGeneratorTraits>::setLocation):
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/BytecodeGeneratorBase.h: Added.
* bytecompiler/BytecodeGeneratorBaseInlines.h: Added.
(JSC::shrinkToFit):
(JSC::BytecodeGeneratorBase<Traits>::BytecodeGeneratorBase):
(JSC::BytecodeGeneratorBase<Traits>::newLabel):
(JSC::BytecodeGeneratorBase<Traits>::newEmittedLabel):
(JSC::BytecodeGeneratorBase<Traits>::reclaimFreeRegisters):
(JSC::BytecodeGeneratorBase<Traits>::emitLabel):
(JSC::BytecodeGeneratorBase<Traits>::recordOpcode):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode16):
(JSC::BytecodeGeneratorBase<Traits>::alignWideOpcode32):
(JSC::BytecodeGeneratorBase<Traits>::write):
(JSC::BytecodeGeneratorBase<Traits>::newRegister):
(JSC::BytecodeGeneratorBase<Traits>::newTemporary):
(JSC::BytecodeGeneratorBase<Traits>::addVar):
(JSC::BytecodeGeneratorBase<Traits>::allocateCalleeSaveSpace):
* bytecompiler/Label.h:
(JSC::GenericBoundLabel::GenericBoundLabel):
(JSC::GenericBoundLabel::target):
(JSC::GenericBoundLabel::saveTarget):
(JSC::GenericBoundLabel::commitTarget):
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOperations.cpp:
* generator/Argument.rb:
* generator/DSL.rb:
* generator/GeneratedFile.rb:
* generator/Opcode.rb:
* generator/Options.rb:
* generator/Section.rb:
* generator/Wasm.rb: Added.
* interpreter/Register.h:
* interpreter/RegisterInlines.h:
(JSC::Register::operator=):
* jit/JITArithmetic.cpp:
* jit/JITOpcodes.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC::LLInt::wasmExceptionInstructions):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::wasmFunctionEntryThunk):
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* llint/WebAssembly.asm: Added.
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/parser.rb:
* offlineasm/registers.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:
* parser/Nodes.h:
* runtime/Error.cpp:
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator() const):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* runtime/Options.cpp:
(JSC::overrideDefaults):
* runtime/OptionsList.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::recordJITFrame):
(JSC::FrameWalker::resetAtMachineFrame):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::isControlTypeIf):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::isControlTypeIf):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::prepareImpl):
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):
(JSC::Wasm::BBQPlan::didCompleteCompilation):
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h: Removed.
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
(JSC::Wasm::Callee::dump const):
(JSC::Wasm::JITCallee::JITCallee):
(JSC::Wasm::LLIntCallee::setEntrypoint):
(JSC::Wasm::LLIntCallee::entrypoint const):
(JSC::Wasm::LLIntCallee::calleeSaveRegisters):
(JSC::Wasm:: const):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::setOSREntryCallee):
(JSC::Wasm::JITCallee::wasmToWasmCallsites):
(JSC::Wasm::JITCallee:: const):
* wasm/WasmCallingConvention.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmToWasmExitStub):
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmEmbedder.h:
* wasm/WasmEntryPlan.cpp: Added.
(JSC::Wasm::EntryPlan::EntryPlan):
(JSC::Wasm::EntryPlan::stateString):
(JSC::Wasm::EntryPlan::moveToState):
(JSC::Wasm::EntryPlan::didReceiveFunctionData):
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::prepare):
(JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder):
(JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder):
(JSC::Wasm::EntryPlan::complete):
(JSC::Wasm::EntryPlan::compileFunctions):
(JSC::Wasm::EntryPlan::work):
* wasm/WasmEntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmBBQPlan.h.
(JSC::Wasm::EntryPlan::parseAndValidateModule):
(JSC::Wasm::EntryPlan::exports const):
(JSC::Wasm::EntryPlan::internalFunctionCount const):
(JSC::Wasm::EntryPlan::takeModuleInformation):
(JSC::Wasm::EntryPlan::takeWasmToWasmExitStubs):
(JSC::Wasm::EntryPlan::takeWasmToWasmCallsites):
(JSC::Wasm::EntryPlan::hasBeenPrepared const):
(JSC::Wasm::EntryPlan::tryReserveCapacity):
* wasm/WasmFunctionCodeBlock.cpp: Added.
(JSC::Wasm::FunctionCodeBlock::setInstructions):
(JSC::Wasm::FunctionCodeBlock::dumpBytecode):
(JSC::Wasm::FunctionCodeBlock::addOutOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpTarget):
(JSC::Wasm::FunctionCodeBlock::addSignature):
(JSC::Wasm::FunctionCodeBlock::signature const):
(JSC::Wasm::FunctionCodeBlock::addJumpTable):
(JSC::Wasm::FunctionCodeBlock::jumpTable const const):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTables const):
* wasm/WasmFunctionCodeBlock.h: Added.
(JSC::Wasm::FunctionCodeBlock::FunctionCodeBlock):
(JSC::Wasm::FunctionCodeBlock::getConstant const):
(JSC::Wasm::FunctionCodeBlock::functionIndex const):
(JSC::Wasm::FunctionCodeBlock::addJumpTarget):
(JSC::Wasm::FunctionCodeBlock::numberOfJumpTargets):
(JSC::Wasm::FunctionCodeBlock::lastJumpTarget):
(JSC::Wasm::FunctionCodeBlock::outOfLineJumpOffset):
(JSC::Wasm::FunctionCodeBlock::bytecodeOffset):
(JSC::Wasm::FunctionCodeBlock::tierUpCounter):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmInstance.h:
* wasm/WasmLLIntGenerator.cpp: Added.
(JSC::Wasm::LLIntGenerator::ControlType::ControlType):
(JSC::Wasm::LLIntGenerator::ControlType::loop):
(JSC::Wasm::LLIntGenerator::ControlType::topLevel):
(JSC::Wasm::LLIntGenerator::ControlType::block):
(JSC::Wasm::LLIntGenerator::ControlType::if_):
(JSC::Wasm::LLIntGenerator::ControlType::targetLabelForBranch const):
(JSC::Wasm::LLIntGenerator::fail const):
(JSC::Wasm::LLIntGenerator::unifyValuesWithBlock):
(JSC::Wasm::LLIntGenerator::emptyExpression):
(JSC::Wasm::LLIntGenerator::createStack):
(JSC::Wasm::LLIntGenerator::isControlTypeIf):
(JSC::Wasm::LLIntGenerator::addEndToUnreachable):
(JSC::Wasm::LLIntGenerator::setParser):
(JSC::Wasm::LLIntGenerator::dump):
(JSC::Wasm::LLIntGenerator::virtualRegisterForLocal):
(JSC::Wasm::LLIntGenerator::tmpsForSignature):
(JSC::Wasm::LLIntGenerator::jsNullConstant):
(JSC::Wasm::LLIntGenerator::isConstant):
(JSC::Wasm::parseAndCompileBytecode):
(JSC::Wasm::LLIntGenerator::LLIntGenerator):
(JSC::Wasm::LLIntGenerator::finalize):
(JSC::Wasm::LLIntGenerator::callInformationFor):
(JSC::Wasm::LLIntGenerator::addArguments):
(JSC::Wasm::LLIntGenerator::addLocal):
(JSC::Wasm::LLIntGenerator::addConstant):
(JSC::Wasm::LLIntGenerator::getLocal):
(JSC::Wasm::LLIntGenerator::setLocal):
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
(JSC::Wasm::LLIntGenerator::addLoop):
(JSC::Wasm::LLIntGenerator::addTopLevel):
(JSC::Wasm::LLIntGenerator::addBlock):
(JSC::Wasm::LLIntGenerator::addIf):
(JSC::Wasm::LLIntGenerator::addElse):
(JSC::Wasm::LLIntGenerator::addElseToUnreachable):
(JSC::Wasm::LLIntGenerator::addReturn):
(JSC::Wasm::LLIntGenerator::addBranch):
(JSC::Wasm::LLIntGenerator::addSwitch):
(JSC::Wasm::LLIntGenerator::endBlock):
(JSC::Wasm::LLIntGenerator::addCall):
(JSC::Wasm::LLIntGenerator::addCallIndirect):
(JSC::Wasm::LLIntGenerator::addRefIsNull):
(JSC::Wasm::LLIntGenerator::addRefFunc):
(JSC::Wasm::LLIntGenerator::addTableGet):
(JSC::Wasm::LLIntGenerator::addTableSet):
(JSC::Wasm::LLIntGenerator::addTableSize):
(JSC::Wasm::LLIntGenerator::addTableGrow):
(JSC::Wasm::LLIntGenerator::addTableFill):
(JSC::Wasm::LLIntGenerator::addUnreachable):
(JSC::Wasm::LLIntGenerator::addCurrentMemory):
(JSC::Wasm::LLIntGenerator::addGrowMemory):
(JSC::Wasm::LLIntGenerator::addSelect):
(JSC::Wasm::LLIntGenerator::load):
(JSC::Wasm::LLIntGenerator::store):
(JSC::GenericLabel<Wasm::GeneratorTraits>::setLocation):
* wasm/WasmLLIntGenerator.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmLLIntPlan.cpp: Added.
(JSC::Wasm::LLIntPlan::prepareImpl):
(JSC::Wasm::LLIntPlan::compileFunction):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::initializeCallees):
* wasm/WasmLLIntPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
* wasm/WasmLLIntTierUpCounter.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::LLIntTierUpCounter::addOSREntryDataForLoop):
(JSC::Wasm::LLIntTierUpCounter::osrEntryDataForLoop const const):
* wasm/WasmLLIntTierUpCounter.h: Copied from Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.h.
(JSC::Wasm::LLIntTierUpCounter::LLIntTierUpCounter):
(JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
(JSC::Wasm::LLIntTierUpCounter::checkIfOptimizationThresholdReached):
(JSC::Wasm::LLIntTierUpCounter::optimizeSoon):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationResult):
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmOMGForOSREntryPlan.cpp:
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h:
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmSlowPaths.cpp: Added.
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
(JSC::LLInt::doWasmCall):
(JSC::LLInt::doWasmCallIndirect):
(JSC::LLInt::slow_path_wasm_throw_exception):
(JSC::LLInt::slow_path_wasm_popcount):
(JSC::LLInt::slow_path_wasm_popcountll):
* wasm/WasmSlowPaths.h: Added.
* wasm/WasmTable.cpp:
(JSC::Wasm::FuncRefTable::function const):
(JSC::Wasm::FuncRefTable::instance const):
* wasm/WasmTable.h:
* wasm/WasmTierUpCount.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::isControlTypeIf):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::calleeSaves const):
Tools:
Add a mode that runs WebAssembly tests without the LLInt (i.e. only Air)
and update the no-air mode to also disable the LLInt tier.
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/217068@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251886 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-31 22:32:52 +00:00
|
|
|
wasm/WasmSlowPaths.cpp
|
WebAssembly: add support for stream APIs
https://bugs.webkit.org/show_bug.cgi?id=173105
Reviewed by Keith Miller.
.:
* Source/cmake/OptionsFTW.cmake:
* Source/cmake/WebKitFeatures.cmake:
JSTests:
* wasm/stress/resources/tsf.wasm: Added.
* wasm/stress/wasm-streaming-compiler-compile.js: Added.
(shouldBe):
(slice):
(async main):
(main.catch):
* wasm/stress/wasm-streaming-compiler-instantiate.js: Added.
(shouldBe):
(slice):
(async main.):
(async main):
(main.catch):
LayoutTests/imported/w3c:
* web-platform-tests/wasm/wasm_stream_compile_test-expected.txt:
* web-platform-tests/wasm/wasm_stream_compile_test.html:
* web-platform-tests/wasm/wasm_stream_instantiate_test-expected.txt:
* web-platform-tests/wasm/wasm_stream_instantiate_test.html:
* web-platform-tests/wasm/webapi/abort.any-expected.txt:
* web-platform-tests/wasm/webapi/abort.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/body.any-expected.txt:
* web-platform-tests/wasm/webapi/body.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/contenttype.any-expected.txt:
* web-platform-tests/wasm/webapi/contenttype.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/empty-body.any-expected.txt:
* web-platform-tests/wasm/webapi/empty-body.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/historical.any-expected.txt:
* web-platform-tests/wasm/webapi/historical.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/idlharness.any-expected.txt:
* web-platform-tests/wasm/webapi/idlharness.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming-bad-imports.any-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming.any-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/invalid-args.any-expected.txt:
* web-platform-tests/wasm/webapi/invalid-args.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/invalid-code.any-expected.txt:
* web-platform-tests/wasm/webapi/invalid-code.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/modified-contenttype.any-expected.txt:
* web-platform-tests/wasm/webapi/modified-contenttype.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/origin.sub.any-expected.txt:
* web-platform-tests/wasm/webapi/origin.sub.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/rejected-arg.any-expected.txt:
* web-platform-tests/wasm/webapi/rejected-arg.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/status.any-expected.txt:
* web-platform-tests/wasm/webapi/status.any.worker-expected.txt:
Source/JavaScriptCore:
This patch implements WebAssembly.{compileStreaming,instantiateStreaming}. JavaScriptCore offers Wasm::StreamingCompiler interface to WebCore,
so that WebCore can feed FetchResponse and compile wasm code in a streaming fashion.
Wasm::StreamingCompiler drives Wasm::LLIntPlan while it does not use Wasm::Worklist since currently Wasm::Worklist is not suitable abstraction for
streaming compilation which generates compilation tasks incrementally. Instead, Wasm::StreamingCompiler generates Wasm::StreamingPlan and enqueues
them to Wasm::Worklist, and each StreamingPlan compiles one function at a time. And we gather these compiled functions into the one LLIntPlan and
finally Wasm::StreamingCompiler completes Wasm::LLIntPlan.
We already have Wasm::StreamingParser, which is designed for streaming compilation. We can pass bytes to this parser, and this parser invokes a callback
when a new wasm function is found. Then, Wasm::StreamingCompiler generates Wasm::StreamingPlan for that.
We add WasmStreamingCompiler JS objects to JSC shell to test streaming compilation easily.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/WebAssembly.js:
(compileStreaming):
(instantiateStreaming):
* runtime/DeferredWorkTimer.cpp:
(JSC::DeferredWorkTimer::cancelPendingWork):
* runtime/DeferredWorkTimer.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSGlobalObject.h:
* runtime/OptionsList.h:
* tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
* wasm/WasmBBQPlan.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmEntryPlan.cpp:
(JSC::Wasm::EntryPlan::EntryPlan):
* wasm/WasmEntryPlan.h:
* wasm/WasmLLIntPlan.cpp:
(JSC::Wasm::LLIntPlan::LLIntPlan):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::completeInStreaming):
(JSC::Wasm::LLIntPlan::didCompileFunctionInStreaming):
(JSC::Wasm::LLIntPlan::didFailInStreaming):
* wasm/WasmLLIntPlan.h:
* wasm/WasmModule.cpp:
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmStreamingCompiler.cpp: Added.
(JSC::Wasm::StreamingCompiler::StreamingCompiler):
(JSC::Wasm::StreamingCompiler::~StreamingCompiler):
(JSC::Wasm::StreamingCompiler::create):
(JSC::Wasm::StreamingCompiler::didReceiveFunctionData):
(JSC::Wasm::StreamingCompiler::didCompileFunction):
(JSC::Wasm::StreamingCompiler::didFinishParsing):
(JSC::Wasm::StreamingCompiler::completeIfNecessary):
(JSC::Wasm::StreamingCompiler::didComplete):
(JSC::Wasm::StreamingCompiler::finalize):
(JSC::Wasm::StreamingCompiler::fail):
(JSC::Wasm::StreamingCompiler::cancel):
* wasm/WasmStreamingCompiler.h: Added.
* wasm/WasmStreamingParser.cpp:
* wasm/WasmStreamingParser.h:
* wasm/WasmStreamingPlan.cpp: Copied from Source/JavaScriptCore/builtins/WebAssembly.js.
(JSC::Wasm::StreamingPlan::StreamingPlan):
(JSC::Wasm::StreamingPlan::work):
* wasm/WasmStreamingPlan.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssembly.h.
* wasm/js/JSWebAssembly.cpp:
(JSC::JSWebAssembly::finishCreation):
(JSC::JSWebAssembly::instantiateForStreaming):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* wasm/js/JSWebAssembly.h:
Source/WebCore:
Since WebAssembly.{compileStreaming,instantiateStreaming} needs to handle FetchResponse which is WebCore type, they need to be implemented in WebCore side.
To achieve that, JSC offers callback to JSGlobalObject, and WebCore JSDOMGlobalObject can implement them to offer WebAssembly.{compileStreaming,instantiateStreaming} features.
We use JSC's Wasm::StreamingCompiler to implement them. WebCore feeds bytes from FetchResponse and drives Wasm::StreamingCompiler.
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::handleResponseOnStreamingAction):
(WebCore::JSDOMGlobalObject::compileStreaming):
(WebCore::JSDOMGlobalObject::instantiateStreaming):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMPromiseDeferred.cpp:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::tryAllocate): Deleted.
(WebCore::isResponseCorrect): Deleted.
(WebCore::handleResponseOnStreamingAction): Deleted.
(WebCore::JSDOMWindowBase::compileStreaming): Deleted.
(WebCore::JSDOMWindowBase::instantiateStreaming): Deleted.
* bindings/js/JSDOMWindowBase.h:
* bindings/js/JSWorkerGlobalScopeBase.cpp:
* bindings/js/JSWorkletGlobalScopeBase.cpp:
Source/WTF:
* wtf/PlatformEnable.h:
Canonical link: https://commits.webkit.org/233426@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271993 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-28 01:31:34 +00:00
|
|
|
wasm/WasmStreamingCompiler.cpp
|
[WebAssembly] Parse wasm modules in a streaming fashion
https://bugs.webkit.org/show_bug.cgi?id=188943
Reviewed by Mark Lam.
JSTests:
Wasm parsing error should not report the total byte size since streaming parsing does not
want to load all the bytes.
Add a simple test wasm/stress/streaming-basic.js for initial streaming parsing implementation.
* wasm/function-tests/invalid-duplicate-export.js:
* wasm/function-tests/memory-alignment.js:
(const.op.of.WASM.opcodes):
* wasm/function-tests/memory-section-and-import.js:
* wasm/function-tests/void-argument-type-should-be-a-validation-error.js:
* wasm/js-api/Module-compile.js:
(async.testPromiseAPI):
* wasm/js-api/element.js:
(assert.throws.new.WebAssembly.Module.builder.WebAssembly):
(assert.throws):
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(assert.throws):
* wasm/js-api/table.js:
(new.WebAssembly.Module):
(assert.throws):
(assertBadTableImport):
* wasm/js-api/test_Data.js:
(DataSectionWithoutMemory):
* wasm/js-api/test_Start.js:
(InvalidStartFunctionIndex):
* wasm/js-api/test_basic_api.js:
(const.c.in.constructorProperties.switch):
* wasm/js-api/version.js:
* wasm/stress/nameSection.wasm: Added.
* wasm/stress/streaming-basic.js: Added.
(check):
Source/JavaScriptCore:
This patch adds Wasm::StreamingParser, which parses wasm binary in a streaming fashion.
Currently, this StreamingParser is not enabled and integrated. In subsequent patches,
we start integrating it into BBQPlan and dropping the old ModuleParser.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* tools/JSDollarVM.cpp:
(WTF::WasmStreamingParser::WasmStreamingParser):
(WTF::WasmStreamingParser::create):
(WTF::WasmStreamingParser::createStructure):
(WTF::WasmStreamingParser::streamingParser):
(WTF::WasmStreamingParser::finishCreation):
(WTF::functionWasmStreamingParserAddBytes):
(WTF::functionWasmStreamingParserFinalize):
(JSC::functionCreateWasmStreamingParser):
(JSC::JSDollarVM::finishCreation):
The $vm Wasm::StreamingParser object is introduced for testing purpose. Added new stress test uses
this interface to test streaming parser in the JSC shell.
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::parseAndValidateModule):
(JSC::Wasm::BBQPlan::prepare):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
(JSC::Wasm::BBQPlan::work):
* wasm/WasmBBQPlan.h:
BBQPlan has m_source, but once ModuleInformation is parsed, it is no longer necessary.
In subsequent patches, we will remove this, and stream the data into the BBQPlan.
* wasm/WasmFormat.h:
* wasm/WasmModuleInformation.cpp:
(JSC::Wasm::ModuleInformation::ModuleInformation):
* wasm/WasmModuleInformation.h:
One of the largest change in this patch is that ModuleInformation no longer holds source bytes,
since source bytes can be added in a streaming fashion. Instead of holding all the source bytes
in ModuleInformation, each function (ModuleInformation::functions, FunctionData) should have
Vector<uint8_t> for its data. This data is eventually filled by StreamingParser, and compiling
a function with this data can be done concurrently with StreamingParser.
(JSC::Wasm::ModuleInformation::create):
(JSC::Wasm::ModuleInformation::memoryCount const):
(JSC::Wasm::ModuleInformation::tableCount const):
memoryCount and tableCount should be recorded in ModuleInformation.
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parse):
(JSC::Wasm::makeI32InitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseType): Deleted.
(JSC::Wasm::ModuleParser::parseImport): Deleted.
(JSC::Wasm::ModuleParser::parseFunction): Deleted.
(JSC::Wasm::ModuleParser::parseResizableLimits): Deleted.
(JSC::Wasm::ModuleParser::parseTableHelper): Deleted.
(JSC::Wasm::ModuleParser::parseTable): Deleted.
(JSC::Wasm::ModuleParser::parseMemoryHelper): Deleted.
(JSC::Wasm::ModuleParser::parseMemory): Deleted.
(JSC::Wasm::ModuleParser::parseGlobal): Deleted.
(JSC::Wasm::ModuleParser::parseExport): Deleted.
(JSC::Wasm::ModuleParser::parseStart): Deleted.
(JSC::Wasm::ModuleParser::parseElement): Deleted.
(JSC::Wasm::ModuleParser::parseCode): Deleted.
(JSC::Wasm::ModuleParser::parseInitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseGlobalType): Deleted.
(JSC::Wasm::ModuleParser::parseData): Deleted.
(JSC::Wasm::ModuleParser::parseCustom): Deleted.
Extract section parsing code out from ModuleParser. We create SectionParser and ModuleParser uses it.
SectionParser is also used by StreamingParser.
* wasm/WasmModuleParser.h:
(): Deleted.
* wasm/WasmNameSection.h:
(JSC::Wasm::NameSection::NameSection):
(JSC::Wasm::NameSection::create):
(JSC::Wasm::NameSection::setHash):
Hash calculation is deferred since all the source is not available in streaming parsing.
* wasm/WasmNameSectionParser.cpp:
(JSC::Wasm::NameSectionParser::parse):
* wasm/WasmNameSectionParser.h:
Use Ref<NameSection>.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
Wasm::Plan no longer have m_source since data will be eventually filled in a streaming fashion.
OMGPlan can get data of the function by using ModuleInformation::functions.
* wasm/WasmParser.h:
(JSC::Wasm::Parser::source const):
(JSC::Wasm::Parser::length const):
(JSC::Wasm::Parser::offset const):
(JSC::Wasm::Parser::fail const):
(JSC::Wasm::makeI32InitExpr):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
Wasm::Plan should not have all the source apriori. Streamed data will be pumped from the provider.
* wasm/WasmPlan.h:
* wasm/WasmSectionParser.cpp: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.cpp.
SectionParser is extracted from ModuleParser. And it is used by both the old (currently working)
ModuleParser and the new StreamingParser.
(JSC::Wasm::SectionParser::parseType):
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseFunction):
(JSC::Wasm::SectionParser::parseResizableLimits):
(JSC::Wasm::SectionParser::parseTableHelper):
(JSC::Wasm::SectionParser::parseTable):
(JSC::Wasm::SectionParser::parseMemoryHelper):
(JSC::Wasm::SectionParser::parseMemory):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseStart):
(JSC::Wasm::SectionParser::parseElement):
(JSC::Wasm::SectionParser::parseCode):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
(JSC::Wasm::SectionParser::parseData):
(JSC::Wasm::SectionParser::parseCustom):
* wasm/WasmSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.h.
* wasm/WasmStreamingParser.cpp: Added.
(JSC::Wasm::parseUInt7):
(JSC::Wasm::StreamingParser::fail):
(JSC::Wasm::StreamingParser::StreamingParser):
(JSC::Wasm::StreamingParser::parseModuleHeader):
(JSC::Wasm::StreamingParser::parseSectionID):
(JSC::Wasm::StreamingParser::parseSectionSize):
(JSC::Wasm::StreamingParser::parseCodeSectionSize):
Code section in Wasm binary is specially handled compared with the other sections since it includes
a bunch of functions. StreamingParser extracts each function in a streaming fashion and enable
streaming validation / compilation of Wasm functions.
(JSC::Wasm::StreamingParser::parseFunctionSize):
(JSC::Wasm::StreamingParser::parseFunctionPayload):
(JSC::Wasm::StreamingParser::parseSectionPayload):
(JSC::Wasm::StreamingParser::consume):
(JSC::Wasm::StreamingParser::consumeVarUInt32):
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::failOnState):
(JSC::Wasm::StreamingParser::finalize):
* wasm/WasmStreamingParser.h: Added.
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::errorMessage const):
This is our new StreamingParser implementation. StreamingParser::consumeXXX functions get data, and
StreamingParser::parseXXX functions parse consumed data. The user of StreamingParser calls
StreamingParser::addBytes() to pump the bytes stream into the parser. And once all the data is pumped,
the user calls StreamingParser::finalize. StreamingParser is a state machine which feeds on the
incoming byte stream.
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::source const): Deleted.
All the source should not be held.
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyValidateFunc):
Source/WTF:
Add maxByteLength function to get the maximum size for T.
* wtf/LEBDecoder.h:
(WTF::LEBDecoder::maxByteLength):
(WTF::LEBDecoder::decodeUInt):
(WTF::LEBDecoder::decodeInt):
Canonical link: https://commits.webkit.org/204074@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235420 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 06:38:29 +00:00
|
|
|
wasm/WasmStreamingParser.cpp
|
WebAssembly: add support for stream APIs
https://bugs.webkit.org/show_bug.cgi?id=173105
Reviewed by Keith Miller.
.:
* Source/cmake/OptionsFTW.cmake:
* Source/cmake/WebKitFeatures.cmake:
JSTests:
* wasm/stress/resources/tsf.wasm: Added.
* wasm/stress/wasm-streaming-compiler-compile.js: Added.
(shouldBe):
(slice):
(async main):
(main.catch):
* wasm/stress/wasm-streaming-compiler-instantiate.js: Added.
(shouldBe):
(slice):
(async main.):
(async main):
(main.catch):
LayoutTests/imported/w3c:
* web-platform-tests/wasm/wasm_stream_compile_test-expected.txt:
* web-platform-tests/wasm/wasm_stream_compile_test.html:
* web-platform-tests/wasm/wasm_stream_instantiate_test-expected.txt:
* web-platform-tests/wasm/wasm_stream_instantiate_test.html:
* web-platform-tests/wasm/webapi/abort.any-expected.txt:
* web-platform-tests/wasm/webapi/abort.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/body.any-expected.txt:
* web-platform-tests/wasm/webapi/body.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/contenttype.any-expected.txt:
* web-platform-tests/wasm/webapi/contenttype.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/empty-body.any-expected.txt:
* web-platform-tests/wasm/webapi/empty-body.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/historical.any-expected.txt:
* web-platform-tests/wasm/webapi/historical.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/idlharness.any-expected.txt:
* web-platform-tests/wasm/webapi/idlharness.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming-bad-imports.any-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming.any-expected.txt:
* web-platform-tests/wasm/webapi/instantiateStreaming.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/invalid-args.any-expected.txt:
* web-platform-tests/wasm/webapi/invalid-args.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/invalid-code.any-expected.txt:
* web-platform-tests/wasm/webapi/invalid-code.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/modified-contenttype.any-expected.txt:
* web-platform-tests/wasm/webapi/modified-contenttype.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/origin.sub.any-expected.txt:
* web-platform-tests/wasm/webapi/origin.sub.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/rejected-arg.any-expected.txt:
* web-platform-tests/wasm/webapi/rejected-arg.any.worker-expected.txt:
* web-platform-tests/wasm/webapi/status.any-expected.txt:
* web-platform-tests/wasm/webapi/status.any.worker-expected.txt:
Source/JavaScriptCore:
This patch implements WebAssembly.{compileStreaming,instantiateStreaming}. JavaScriptCore offers Wasm::StreamingCompiler interface to WebCore,
so that WebCore can feed FetchResponse and compile wasm code in a streaming fashion.
Wasm::StreamingCompiler drives Wasm::LLIntPlan while it does not use Wasm::Worklist since currently Wasm::Worklist is not suitable abstraction for
streaming compilation which generates compilation tasks incrementally. Instead, Wasm::StreamingCompiler generates Wasm::StreamingPlan and enqueues
them to Wasm::Worklist, and each StreamingPlan compiles one function at a time. And we gather these compiled functions into the one LLIntPlan and
finally Wasm::StreamingCompiler completes Wasm::LLIntPlan.
We already have Wasm::StreamingParser, which is designed for streaming compilation. We can pass bytes to this parser, and this parser invokes a callback
when a new wasm function is found. Then, Wasm::StreamingCompiler generates Wasm::StreamingPlan for that.
We add WasmStreamingCompiler JS objects to JSC shell to test streaming compilation easily.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/WebAssembly.js:
(compileStreaming):
(instantiateStreaming):
* runtime/DeferredWorkTimer.cpp:
(JSC::DeferredWorkTimer::cancelPendingWork):
* runtime/DeferredWorkTimer.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSGlobalObject.h:
* runtime/OptionsList.h:
* tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
* wasm/WasmBBQPlan.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmEntryPlan.cpp:
(JSC::Wasm::EntryPlan::EntryPlan):
* wasm/WasmEntryPlan.h:
* wasm/WasmLLIntPlan.cpp:
(JSC::Wasm::LLIntPlan::LLIntPlan):
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
(JSC::Wasm::LLIntPlan::completeInStreaming):
(JSC::Wasm::LLIntPlan::didCompileFunctionInStreaming):
(JSC::Wasm::LLIntPlan::didFailInStreaming):
* wasm/WasmLLIntPlan.h:
* wasm/WasmModule.cpp:
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
* wasm/WasmStreamingCompiler.cpp: Added.
(JSC::Wasm::StreamingCompiler::StreamingCompiler):
(JSC::Wasm::StreamingCompiler::~StreamingCompiler):
(JSC::Wasm::StreamingCompiler::create):
(JSC::Wasm::StreamingCompiler::didReceiveFunctionData):
(JSC::Wasm::StreamingCompiler::didCompileFunction):
(JSC::Wasm::StreamingCompiler::didFinishParsing):
(JSC::Wasm::StreamingCompiler::completeIfNecessary):
(JSC::Wasm::StreamingCompiler::didComplete):
(JSC::Wasm::StreamingCompiler::finalize):
(JSC::Wasm::StreamingCompiler::fail):
(JSC::Wasm::StreamingCompiler::cancel):
* wasm/WasmStreamingCompiler.h: Added.
* wasm/WasmStreamingParser.cpp:
* wasm/WasmStreamingParser.h:
* wasm/WasmStreamingPlan.cpp: Copied from Source/JavaScriptCore/builtins/WebAssembly.js.
(JSC::Wasm::StreamingPlan::StreamingPlan):
(JSC::Wasm::StreamingPlan::work):
* wasm/WasmStreamingPlan.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssembly.h.
* wasm/js/JSWebAssembly.cpp:
(JSC::JSWebAssembly::finishCreation):
(JSC::JSWebAssembly::instantiateForStreaming):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* wasm/js/JSWebAssembly.h:
Source/WebCore:
Since WebAssembly.{compileStreaming,instantiateStreaming} needs to handle FetchResponse which is WebCore type, they need to be implemented in WebCore side.
To achieve that, JSC offers callback to JSGlobalObject, and WebCore JSDOMGlobalObject can implement them to offer WebAssembly.{compileStreaming,instantiateStreaming} features.
We use JSC's Wasm::StreamingCompiler to implement them. WebCore feeds bytes from FetchResponse and drives Wasm::StreamingCompiler.
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::handleResponseOnStreamingAction):
(WebCore::JSDOMGlobalObject::compileStreaming):
(WebCore::JSDOMGlobalObject::instantiateStreaming):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMPromiseDeferred.cpp:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::tryAllocate): Deleted.
(WebCore::isResponseCorrect): Deleted.
(WebCore::handleResponseOnStreamingAction): Deleted.
(WebCore::JSDOMWindowBase::compileStreaming): Deleted.
(WebCore::JSDOMWindowBase::instantiateStreaming): Deleted.
* bindings/js/JSDOMWindowBase.h:
* bindings/js/JSWorkerGlobalScopeBase.cpp:
* bindings/js/JSWorkletGlobalScopeBase.cpp:
Source/WTF:
* wtf/PlatformEnable.h:
Canonical link: https://commits.webkit.org/233426@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271993 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-28 01:31:34 +00:00
|
|
|
wasm/WasmStreamingPlan.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/WasmTable.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmThunks.cpp
|
[JSC] OSR entry to Wasm OMG
https://bugs.webkit.org/show_bug.cgi?id=200362
Reviewed by Michael Saboff.
JSTests:
* wasm/stress/osr-entry-basic.js: Added.
(instance.exports.loop):
* wasm/stress/osr-entry-many-locals-f32.js: Added.
* wasm/stress/osr-entry-many-locals-f64.js: Added.
* wasm/stress/osr-entry-many-locals-i32.js: Added.
* wasm/stress/osr-entry-many-locals-i64.js: Added.
* wasm/stress/osr-entry-many-stacks-f32.js: Added.
* wasm/stress/osr-entry-many-stacks-f64.js: Added.
* wasm/stress/osr-entry-many-stacks-i32.js: Added.
* wasm/stress/osr-entry-many-stacks-i64.js: Added.
Source/JavaScriptCore:
This patch implements Wasm OSR entry mechanism from BBQ tier to OMG tier.
We found that one of JetStream2 test heavily relies on OSR entry feature. gcc-loops-wasm consumes
most of time in BBQ tier since one of the function takes significantly long time. And since we did
not have OSR entry feature, we cannot use OMG function until that BBQ function finishes.
To implement Wasm OSR feature, we first capture all locals and stacks in the patchpoint to generate
the stackmap. Once the threshold is crossed, the patchpoint calls `MacroAssembler::probe` feature to
capture whole register context, and C++ runtime function reads stackmap and Probe::Context to perform
OSR entry. This patch intentionally makes OSR entry written in C++ runtime side as much as possible
to make it easily reusable for the other tiers. For example, we are planning to introduce Wasm interpreter,
and it can easily use this tier-up function. Because of this simplicity, this generic implementation can
cover both BBQ Air and BBQ B3 tier-up features. So, in the feature, it is possible that we revive BBQ B3,
and construct the wasm pipeline like, interpreter->BBQ B3->OMG B3.
To generate OMG code for OSR entry, we add a new mode OMGForOSREntry, which mimics the FTLForOSREntry.
In FTLForOSREntry, we cut unrelated blocks including the usual entry point in DFG tier and later convert
graph to SSA. This is possible because DFG is not SSA. On the other hand, B3 is SSA and we cannot take the
same thing without a hack.
This patch introduce a hack: making all wasm locals and stack values B3::Variable for OMGForOSREntry mode.
Then, we can cut blocks easily and we can generate the B3 graph without doing reachability analysis from the
OSR entry point. B3 will remove unreachable blocks later.
Tier-up function mimics DFG->FTL OSR entry heuristics and threshold as much as possible. And this patch adjusts
the tier-up count threshold to make it close to DFG->FTL ones. Wasm tier-up is now using ExecutionCounter, which
is inherited from Wasm::TierUpCount. Since wasm can execute concurrently, the tier-up counter can be racily updated.
But this is OK in practice. Even if we see some more tier-up function calls or tier-up function calls are delayed,
the critical part is guarded by a lock in tier-up function.
In iMac Pro, it shows ~4x runtime improvement for gcc-loops-wasm. On iOS device (iPhone XR), we saw ~2x improvement.
ToT:
HashSet-wasm:Score: 24.6pt stdev=4.6%
:Time:Geometric: 204ms stdev=4.4%
Runtime:Time: 689ms stdev=1.0%
Startup:Time: 60.3ms stdev=8.4%
gcc-loops-wasm:Score: 8.41pt stdev=6.7%
:Time:Geometric: 597ms stdev=6.5%
Runtime:Time: 8.509s stdev=0.7%
Startup:Time: 42ms stdev=12.4%
quicksort-wasm:Score: 347pt stdev=20.9%
:Time:Geometric: 15ms stdev=18.6%
Runtime:Time: 28.2ms stdev=7.9%
Startup:Time: 8.2ms stdev=35.0%
richards-wasm:Score: 77.6pt stdev=4.5%
:Time:Geometric: 64.6ms stdev=4.4%
Runtime:Time: 544ms stdev=3.3%
Startup:Time: 7.67ms stdev=6.7%
tsf-wasm:Score: 47.9pt stdev=4.5%
:Time:Geometric: 104ms stdev=4.8%
Runtime:Time: 259ms stdev=4.4%
Startup:Time: 42.2ms stdev=8.5%
Patched:
HashSet-wasm:Score: 24.1pt stdev=4.1%
:Time:Geometric: 208ms stdev=4.1%
Runtime:Time: 684ms stdev=1.1%
Startup:Time: 63.2ms stdev=8.1%
gcc-loops-wasm:Score: 15.7pt stdev=5.1%
:Time:Geometric: 319ms stdev=5.3%
Runtime:Time: 2.491s stdev=0.7%
Startup:Time: 41ms stdev=11.0%
quicksort-wasm:Score: 353pt stdev=13.7%
:Time:Geometric: 14ms stdev=12.7%
Runtime:Time: 26.2ms stdev=2.9%
Startup:Time: 8.0ms stdev=23.7%
richards-wasm:Score: 77.4pt stdev=5.3%
:Time:Geometric: 64.7ms stdev=5.3%
Runtime:Time: 536ms stdev=1.5%
Startup:Time: 7.83ms stdev=9.6%
tsf-wasm:Score: 47.3pt stdev=5.7%
:Time:Geometric: 106ms stdev=6.1%
Runtime:Time: 250ms stdev=3.5%
Startup:Time: 45ms stdev=13.8%
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchAdd32):
* b3/B3ValueRep.h:
* bytecode/CodeBlock.h:
* bytecode/ExecutionCounter.cpp:
(JSC::applyMemoryUsageHeuristics):
(JSC::ExecutionCounter<countingVariant>::setThreshold):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGJITCode.h:
* dfg/DFGOperations.cpp:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::prologueStackPointerDelta):
* runtime/Options.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::createStack):
(JSC::Wasm::AirIRGenerator::emitPatchpoint):
(JSC::Wasm::AirIRGenerator::outerLoopIndex const):
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::AirIRGenerator::addLoop):
(JSC::Wasm::AirIRGenerator::addElse):
(JSC::Wasm::AirIRGenerator::addBranch):
(JSC::Wasm::AirIRGenerator::addSwitch):
(JSC::Wasm::AirIRGenerator::endBlock):
(JSC::Wasm::AirIRGenerator::addEndToUnreachable):
(JSC::Wasm::AirIRGenerator::unifyValuesWithBlock):
(JSC::Wasm::AirIRGenerator::dump):
(JSC::Wasm::AirIRGenerator::emitTierUpCheck): Deleted.
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::Stack::Stack):
(JSC::Wasm::B3IRGenerator::Stack::append):
(JSC::Wasm::B3IRGenerator::Stack::takeLast):
(JSC::Wasm::B3IRGenerator::Stack::last):
(JSC::Wasm::B3IRGenerator::Stack::size const):
(JSC::Wasm::B3IRGenerator::Stack::isEmpty const):
(JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList):
(JSC::Wasm::B3IRGenerator::Stack::at const):
(JSC::Wasm::B3IRGenerator::Stack::variableAt const):
(JSC::Wasm::B3IRGenerator::Stack::shrink):
(JSC::Wasm::B3IRGenerator::Stack::swap):
(JSC::Wasm::B3IRGenerator::Stack::dump const):
(JSC::Wasm::B3IRGenerator::createStack):
(JSC::Wasm::B3IRGenerator::outerLoopIndex const):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addElse):
(JSC::Wasm::B3IRGenerator::addBranch):
(JSC::Wasm::B3IRGenerator::addSwitch):
(JSC::Wasm::B3IRGenerator::endBlock):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
(JSC::Wasm::B3IRGenerator::unifyValuesWithBlock):
(JSC::Wasm::B3IRGenerator::dump):
(JSC::Wasm::parseAndCompile):
(JSC::Wasm::B3IRGenerator::emitTierUpCheck): Deleted.
(JSC::Wasm::dumpExpressionStack): Deleted.
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::compileFunctions):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmBBQCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::entrypointLoadLocationFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::tierUpCount): Deleted.
* wasm/WasmCompilationMode.cpp:
(JSC::Wasm::makeString):
* wasm/WasmCompilationMode.h:
* wasm/WasmContext.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::Context::scratchBufferForSize):
* wasm/WasmContext.h:
* wasm/WasmContextInlines.h:
(JSC::Wasm::Context::tryLoadInstanceFromTLS):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
(JSC::Wasm::FunctionParser<Context>::parseBody):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
* wasm/WasmOMGForOSREntryPlan.cpp: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.cpp.
(JSC::Wasm::OMGForOSREntryPlan::OMGForOSREntryPlan):
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGForOSREntryPlan.h: Copied from Source/JavaScriptCore/wasm/WasmOMGPlan.h.
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
(JSC::Wasm::OMGPlan::runForIndex): Deleted.
* wasm/WasmOMGPlan.h:
* wasm/WasmOSREntryData.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
(JSC::Wasm::OSREntryValue::OSREntryValue):
(JSC::Wasm::OSREntryValue::type const):
(JSC::Wasm::OSREntryData::OSREntryData):
(JSC::Wasm::OSREntryData::functionIndex const):
(JSC::Wasm::OSREntryData::loopIndex const):
(JSC::Wasm::OSREntryData::values):
* wasm/WasmOperations.cpp: Added.
(JSC::Wasm::shouldTriggerOMGCompile):
(JSC::Wasm::triggerOMGReplacementCompile):
(JSC::Wasm::doOSREntry):
(JSC::Wasm::triggerOSREntryNow):
(JSC::Wasm::triggerTierUpNow):
* wasm/WasmOperations.h: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.h.
* wasm/WasmThunks.cpp:
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator): Deleted.
* wasm/WasmThunks.h:
* wasm/WasmTierUpCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmCompilationMode.cpp.
(JSC::Wasm::TierUpCount::TierUpCount):
(JSC::Wasm::TierUpCount::addOSREntryData):
* wasm/WasmTierUpCount.h:
(JSC::Wasm::TierUpCount::loopIncrement):
(JSC::Wasm::TierUpCount::functionEntryIncrement):
(JSC::Wasm::TierUpCount::osrEntryTriggers):
(JSC::Wasm::TierUpCount::outerLoops):
(JSC::Wasm::TierUpCount::getLock):
(JSC::Wasm::TierUpCount::optimizeAfterWarmUp):
(JSC::Wasm::TierUpCount::checkIfOptimizationThresholdReached):
(JSC::Wasm::TierUpCount::dontOptimizeAnytimeSoon):
(JSC::Wasm::TierUpCount::optimizeNextInvocation):
(JSC::Wasm::TierUpCount::optimizeSoon):
(JSC::Wasm::TierUpCount::setOptimizationThresholdBasedOnCompilationResult):
(JSC::Wasm::TierUpCount::TierUpCount): Deleted.
(JSC::Wasm::TierUpCount::loopDecrement): Deleted.
(JSC::Wasm::TierUpCount::functionEntryDecrement): Deleted.
(JSC::Wasm::TierUpCount::shouldStartTierUp): Deleted.
(JSC::Wasm::TierUpCount::count): Deleted.
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::createStack):
(JSC::Wasm::Validate::addLoop):
(JSC::Wasm::Validate::addElse):
(JSC::Wasm::Validate::checkBranchTarget):
(JSC::Wasm::Validate::addBranch):
(JSC::Wasm::Validate::addSwitch):
(JSC::Wasm::Validate::endBlock):
(JSC::Wasm::Validate::unify):
(JSC::Wasm::dumpExpressionStack):
(JSC::Wasm::Validate::dump):
Tools:
* Scripts/run-jsc-stress-tests:
Canonical link: https://commits.webkit.org/214633@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-20 00:21:29 +00:00
|
|
|
wasm/WasmTierUpCount.cpp
|
2021-01-14 22:48:43 +00:00
|
|
|
wasm/WasmValueLocation.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/WasmWorklist.cpp
|
|
|
|
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/js/JSToWasm.cpp
|
|
|
|
wasm/js/JSToWasm.h
|
2019-04-04 18:54:16 +00:00
|
|
|
wasm/js/JSToWasmICCallee.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/js/JSWebAssembly.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/js/JSWebAssemblyCodeBlock.cpp
|
|
|
|
wasm/js/JSWebAssemblyCompileError.cpp
|
Adopt the new WebAssembly.Global system
https://bugs.webkit.org/show_bug.cgi?id=186552
Reviewed by Keith Miller.
JSTests:
1. Update spec-harness to accept newer tests. And we update several tests that does not work with the old harness.
2. Add WebAssembly.Global tests.
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(new.WebAssembly.Module):
(assert.throws):
* wasm/js-api/global-external-init-from-import.js:
* wasm/js-api/globals-export.js:
* wasm/modules/js-wasm-global-namespace.js:
(assert.throws):
* wasm/modules/js-wasm-global.js:
(assert.throws):
* wasm/modules/wasm-import-wasm-export-i64-error.js:
* wasm/references/anyref_globals.js:
* wasm/references/func_ref.js:
(assert.eq.instance.exports.fix):
* wasm/spec-harness.js:
(getGlobal):
(let.console.log):
* wasm/spec-harness/sync_index.js: Renamed from JSTests/wasm/spec-harness/index.js.
(reinitializeRegistry.let.handler.get return):
(module):
* wasm/spec-tests/call.wast.js:
* wasm/spec-tests/exports.wast.js:
* wasm/spec-tests/globals.wast.js:
* wasm/spec-tests/if.wast.js:
* wasm/spec-tests/imports.wast.js:
* wasm/spec-tests/linking.wast.js:
* wasm/spec-tests/memory.wast.js:
* wasm/stress/immutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq.instance.exports.getI32):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq):
* wasm/stress/mutable-globals-cross.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance1):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance2):
* wasm/stress/mutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.instance.exports.setI32AsI64):
LayoutTests/imported/w3c:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any.worker-expected.txt:
Source/JavaScriptCore:
This patch adds WebAssembly.Global implementation. It is already included in the Wasm spec (this means, it is not in
staging right now: it was stage-4, and included in the spec). WebAssembly.Global is a wrapper object around
"global" binding. This object can hold "immutable" and "mutable" global binding, and we can access Wasm globals through
this object. Furthermore, we can share mutable global binding through this object across WebAssembly modules.
To implement it efficiently, this patch introduces BindingMode to Wasm globals. If the mode is EmbeddedInInstance,
we continue using the current existing mechanism. If the mode is Portable, we store a pointer to actual value in
Wasm globals array in Wasm::Instance, so that we can access it through one additional dereference.
And we mark all immutable globals as EmbeddedInInstance. If the binding is immutable, internally we do not need to
have one binding. We can just continue using the current mechanism since users cannot observe whether immutable bindings'
storage is shared or not. If the global is mutable, and it is exported outside of the module, we use Portable mode.
So, all the previously used wasm global bindings are EmbeddedInInstance. Only newly added "mutable" "exported" bindings
are Portable and requires one additional dereference.
To access portable bindings efficiently, we add new Wasm bytecodes, `get_global_portable_binding`, `set_global_portable_binding`,
and `set_global_ref_portable_binding`.
This patch improves WPT wasm coverage significantly.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeList.rb:
* heap/HeapCell.cpp:
(JSC::keepAlive):
(JSC::HeapCell::use const): Deleted.
* heap/HeapCell.h:
(JSC::keepAlive):
(JSC::HeapCell::use const):
* llint/WebAssembly.asm:
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::getGlobal):
(JSC::Wasm::AirIRGenerator::setGlobal):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::getGlobal):
(JSC::Wasm::B3IRGenerator::setGlobal):
* wasm/WasmFormat.h:
* wasm/WasmGlobal.cpp: Added.
(JSC::Wasm::Global::get const):
(JSC::Wasm::Global::set):
(JSC::Wasm::Global::visitAggregate):
* wasm/WasmGlobal.h: Added.
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::linkGlobal):
* wasm/WasmInstance.h:
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::globalsToBinding):
(JSC::Wasm::Instance::getGlobalBinding):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
* wasm/WasmModuleInformation.h:
* wasm/WasmOperations.cpp:
(JSC::Wasm::operationWasmWriteBarrierSlowPath):
* wasm/WasmOperations.h:
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
* wasm/WasmSectionParser.h:
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::setGlobal):
* wasm/js/JSWebAssembly.cpp:
* wasm/js/JSWebAssemblyGlobal.cpp: Added.
(JSC::JSWebAssemblyGlobal::create):
(JSC::JSWebAssemblyGlobal::createStructure):
(JSC::JSWebAssemblyGlobal::JSWebAssemblyGlobal):
(JSC::JSWebAssemblyGlobal::finishCreation):
(JSC::JSWebAssemblyGlobal::destroy):
(JSC::JSWebAssemblyGlobal::visitChildren):
* wasm/js/JSWebAssemblyGlobal.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::visitChildren):
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::destroy):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WebAssemblyGlobalConstructor.cpp: Added.
(JSC::constructJSWebAssemblyGlobal):
(JSC::callJSWebAssemblyGlobal):
(JSC::WebAssemblyGlobalConstructor::create):
(JSC::WebAssemblyGlobalConstructor::createStructure):
(JSC::WebAssemblyGlobalConstructor::finishCreation):
(JSC::WebAssemblyGlobalConstructor::WebAssemblyGlobalConstructor):
* wasm/js/WebAssemblyGlobalConstructor.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyGlobalPrototype.cpp: Added.
(JSC::getGlobal):
(JSC::webAssemblyGlobalProtoFuncValueOf):
(JSC::webAssemblyGlobalProtoGetterFuncValue):
(JSC::webAssemblyGlobalProtoSetterFuncValue):
(JSC::WebAssemblyGlobalPrototype::create):
(JSC::WebAssemblyGlobalPrototype::createStructure):
(JSC::WebAssemblyGlobalPrototype::finishCreation):
(JSC::WebAssemblyGlobalPrototype::WebAssemblyGlobalPrototype):
* wasm/js/WebAssemblyGlobalPrototype.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
Canonical link: https://commits.webkit.org/218038@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-12-04 01:36:56 +00:00
|
|
|
wasm/js/JSWebAssemblyGlobal.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/js/JSWebAssemblyInstance.cpp
|
|
|
|
wasm/js/JSWebAssemblyLinkError.cpp
|
|
|
|
wasm/js/JSWebAssemblyMemory.cpp
|
|
|
|
wasm/js/JSWebAssemblyModule.cpp
|
|
|
|
wasm/js/JSWebAssemblyRuntimeError.cpp
|
|
|
|
wasm/js/JSWebAssemblyTable.cpp
|
WebAssembly: no VM / JS version of everything but Instance
https://bugs.webkit.org/show_bug.cgi?id=177473
Reviewed by Filip Pizlo, Saam Barati.
JSTests:
- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.
* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):
Source/JavaScriptCore:
This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.
I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).
None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.
Interesting things to note:
- Remove VM from Plan and associated places. It can just live as a capture in
the callback lambda if it's needed.
- Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
collect. We now instead pass two lambdas at construction time for this
purpose: one to notify of memory pressure, and the other to ask for
syncrhonous memory reclamation. This allows whoever creates the memory to
dictate how to react to both these cases, and for a JS embedding that's to
call the GC (async or sync, respectively).
- Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
there, with an enum class for failure types.
- Exceeding max on memory growth now returns a range error as per spec. This
is a (very minor) breaking change: it used to throw OOM error. Update the
corresponding test.
- When generating the grow_memory opcode, no need to get the VM. Instead,
reach directly for Wasm::Memory and grow it.
- JSWebAssemblyMemory::grow can now always throw on failure, because it's only
ever called from JS (not from grow_memory as before).
- Wasm::Memory now takes a callback for successful growth. This allows JS
wrappers to register themselves when growth succeeds without Wasm::Memory
knowning anything about JS. It'll also allow creating a list of callbacks
for when we add thread support (we'll want to notify many wrappers, all
under a lock).
- Wasm::Memory is now back to being the source of truth about address / size,
used directly by generated code instead of JSWebAssemblyMemory.
- Move wasmToJS from the general WasmBinding header to its own header under
wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
and therefore isn't general WebAssembly.
- Make Wasm::Context an actual type (just a struct holding a
JSWebAssemlyInstance for now) instead of an alias for that. Notably this
doesn't add anything to the Context and doesn't change what actually gets
passed around in JIT code (fast TLS or registers) because these changes
potentially impact performance. The entire purpose of this change is to
allow passing Wasm::Context around without having to know about VM. Since VM
contains a Wasm::Context the JS embedding is effectively the same, but with
this setup a non-JS embedding is much better off.
- Move JSWebAssembly into the JS folder.
- OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
- wasm->JS stubs are now on the instance's tail as raw pointers, instead of
being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
called wasm->JS stub. This move means that the embedder must, after creating
a Wasm::CodeBlock, somehow create the stubs to call back into the
embedder. This removes an indirection in the generated code because
the B3 IR generator now reaches into the instance instead of
JSWebAssemblyCodeBlock.
- Move more CodeBlock things. Compilation completion is now marked by its own
atomic<bool> flag instead of a nullptr plan: that required using a lock, and
was causing a deadlock in stack-trace.js because before my changes
JSWebAssemblyCodeBlock did its own completion checking separately from
Wasm::CodeBlock, without getting the lock. Now that everything points to
Wasm::CodeBlock and there's no cached completion marker, the lock was being
acquired in a sanity-check assertion.
- Embedder -> Wasm wrappers are now generated through a function that's passed
in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
- WasmMemory doens't need to know about fault handling thunks. Only the IR
generator should know, and should make sure that the exception throwing
thunk is generated if any memory is present (note: with signal handling not
all of them generate an exception check).
- Make exception throwing pluggable: instead of having a hard-coded
JS-specific lambda we now have a regular C++ function being called from JIT
code when a WebAssembly exception is thrown. This allows any embedder to get
called as they wish. For now a process can only have a single of these
functions (i.e. only one embedder per process) because the trap handler is a
singleton. That can be fixed in in #177475.
- Create WasmEmbedder.h where all embedder plugging will live.
- Split up JSWebAssemblyTable into Wasm::Table which is
refcounted. JSWebAssemblyTable now only contains the JS functions in the
table, and Wasm::Table is what's used by the JIT code to lookup where to
call and do the instance check (for context switch). Note that this creates
an extra allocation for all the instances in Wasm::Table, and in exchange
removes an indirection in JIT code because the instance used to be obtained
off of the JS function. Also note that it's the embedder than keeps the
instances alive, not Wasm::Table (which holds a dumb pointer to the
instance), because doing otherwise would cause reference cycles.
- Add WasmInstance. It doesn't do much for now, owns globals.
- JSWebAssembly instance now doesn't just contain the imported functions as
JSObjects, it also has the corresponding import's instance and wasm
entrypoint. This triples the space allocated per instance's imported
function, but there shouldn't be that many imports. This has two upsides: it
creates smaller and faster code, and makes is easier to disassociate
embedder-specific things from embedder-neutral things. The small / faster
win is in two places: B3 IR generator only needs offsetOfImportFunction for
the call opcode (when the called index is an import) to know whether the
import is wasm->wasm or wasm->embedder (this isn't known at compile-time
because it's dependent on the import object), this is now done by seeing if
that import function has an associated target instance (only wasm->wasm
does); the other place is wasmBinding which uses offsetOfImportFunction to
figure out the wasm->wasm target instance, and then gets
WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
call. The disassociation comes because the target instance can be
Wasm::Instance once we change what the Context is, and
WasmEntrypointLoadLocation is already embedder-independent. As a next step I
can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
and leave importFunction in as an opaque pointer which is embedder-specific,
and in JS will remain WriteBarrier<JSObject>.
- Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
around instead of VM. This is a first step in allowing entry frames which
aren't stored on VM, but which are instead stored in an embedder-specific
location. That change won't really affect JS except through code churn, but
will allow WebAssembly to use some machinery in a generic manner without
having a VM.
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):
Source/WebCore:
* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.
Canonical link: https://commits.webkit.org/194750@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223738 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 02:23:29 +00:00
|
|
|
wasm/js/WasmToJS.cpp
|
|
|
|
wasm/js/WasmToJS.h
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/js/WebAssemblyCompileErrorConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyCompileErrorPrototype.cpp
|
|
|
|
wasm/js/WebAssemblyFunction.cpp
|
|
|
|
wasm/js/WebAssemblyFunctionBase.cpp
|
Adopt the new WebAssembly.Global system
https://bugs.webkit.org/show_bug.cgi?id=186552
Reviewed by Keith Miller.
JSTests:
1. Update spec-harness to accept newer tests. And we update several tests that does not work with the old harness.
2. Add WebAssembly.Global tests.
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(new.WebAssembly.Module):
(assert.throws):
* wasm/js-api/global-external-init-from-import.js:
* wasm/js-api/globals-export.js:
* wasm/modules/js-wasm-global-namespace.js:
(assert.throws):
* wasm/modules/js-wasm-global.js:
(assert.throws):
* wasm/modules/wasm-import-wasm-export-i64-error.js:
* wasm/references/anyref_globals.js:
* wasm/references/func_ref.js:
(assert.eq.instance.exports.fix):
* wasm/spec-harness.js:
(getGlobal):
(let.console.log):
* wasm/spec-harness/sync_index.js: Renamed from JSTests/wasm/spec-harness/index.js.
(reinitializeRegistry.let.handler.get return):
(module):
* wasm/spec-tests/call.wast.js:
* wasm/spec-tests/exports.wast.js:
* wasm/spec-tests/globals.wast.js:
* wasm/spec-tests/if.wast.js:
* wasm/spec-tests/imports.wast.js:
* wasm/spec-tests/linking.wast.js:
* wasm/spec-tests/memory.wast.js:
* wasm/stress/immutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq.instance.exports.getI32):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.assert.eq):
* wasm/stress/mutable-globals-cross.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance1):
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.instance2):
* wasm/stress/mutable-globals.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.i.instance.exports.setI32AsI64):
LayoutTests/imported/w3c:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/constructor/instantiate-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/toString.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/value-set.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any-expected.txt:
* web-platform-tests/wasm/jsapi/global/valueOf.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor-bad-imports.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any-expected.txt:
* web-platform-tests/wasm/jsapi/instance/constructor.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any-expected.txt:
* web-platform-tests/wasm/jsapi/interface.any.worker-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any-expected.txt:
* web-platform-tests/wasm/jsapi/module/exports.any.worker-expected.txt:
Source/JavaScriptCore:
This patch adds WebAssembly.Global implementation. It is already included in the Wasm spec (this means, it is not in
staging right now: it was stage-4, and included in the spec). WebAssembly.Global is a wrapper object around
"global" binding. This object can hold "immutable" and "mutable" global binding, and we can access Wasm globals through
this object. Furthermore, we can share mutable global binding through this object across WebAssembly modules.
To implement it efficiently, this patch introduces BindingMode to Wasm globals. If the mode is EmbeddedInInstance,
we continue using the current existing mechanism. If the mode is Portable, we store a pointer to actual value in
Wasm globals array in Wasm::Instance, so that we can access it through one additional dereference.
And we mark all immutable globals as EmbeddedInInstance. If the binding is immutable, internally we do not need to
have one binding. We can just continue using the current mechanism since users cannot observe whether immutable bindings'
storage is shared or not. If the global is mutable, and it is exported outside of the module, we use Portable mode.
So, all the previously used wasm global bindings are EmbeddedInInstance. Only newly added "mutable" "exported" bindings
are Portable and requires one additional dereference.
To access portable bindings efficiently, we add new Wasm bytecodes, `get_global_portable_binding`, `set_global_portable_binding`,
and `set_global_ref_portable_binding`.
This patch improves WPT wasm coverage significantly.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeList.rb:
* heap/HeapCell.cpp:
(JSC::keepAlive):
(JSC::HeapCell::use const): Deleted.
* heap/HeapCell.h:
(JSC::keepAlive):
(JSC::HeapCell::use const):
* llint/WebAssembly.asm:
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::getGlobal):
(JSC::Wasm::AirIRGenerator::setGlobal):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::getGlobal):
(JSC::Wasm::B3IRGenerator::setGlobal):
* wasm/WasmFormat.h:
* wasm/WasmGlobal.cpp: Added.
(JSC::Wasm::Global::get const):
(JSC::Wasm::Global::set):
(JSC::Wasm::Global::visitAggregate):
* wasm/WasmGlobal.h: Added.
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::linkGlobal):
* wasm/WasmInstance.h:
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::globalsToBinding):
(JSC::Wasm::Instance::getGlobalBinding):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::getGlobal):
(JSC::Wasm::LLIntGenerator::setGlobal):
* wasm/WasmModuleInformation.h:
* wasm/WasmOperations.cpp:
(JSC::Wasm::operationWasmWriteBarrierSlowPath):
* wasm/WasmOperations.h:
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
* wasm/WasmSectionParser.h:
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::Validate::setGlobal):
* wasm/js/JSWebAssembly.cpp:
* wasm/js/JSWebAssemblyGlobal.cpp: Added.
(JSC::JSWebAssemblyGlobal::create):
(JSC::JSWebAssemblyGlobal::createStructure):
(JSC::JSWebAssemblyGlobal::JSWebAssemblyGlobal):
(JSC::JSWebAssemblyGlobal::finishCreation):
(JSC::JSWebAssemblyGlobal::destroy):
(JSC::JSWebAssemblyGlobal::visitChildren):
* wasm/js/JSWebAssemblyGlobal.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::visitChildren):
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::destroy):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WebAssemblyGlobalConstructor.cpp: Added.
(JSC::constructJSWebAssemblyGlobal):
(JSC::callJSWebAssemblyGlobal):
(JSC::WebAssemblyGlobalConstructor::create):
(JSC::WebAssemblyGlobalConstructor::createStructure):
(JSC::WebAssemblyGlobalConstructor::finishCreation):
(JSC::WebAssemblyGlobalConstructor::WebAssemblyGlobalConstructor):
* wasm/js/WebAssemblyGlobalConstructor.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyGlobalPrototype.cpp: Added.
(JSC::getGlobal):
(JSC::webAssemblyGlobalProtoFuncValueOf):
(JSC::webAssemblyGlobalProtoGetterFuncValue):
(JSC::webAssemblyGlobalProtoSetterFuncValue):
(JSC::WebAssemblyGlobalPrototype::create):
(JSC::WebAssemblyGlobalPrototype::createStructure):
(JSC::WebAssemblyGlobalPrototype::finishCreation):
(JSC::WebAssemblyGlobalPrototype::WebAssemblyGlobalPrototype):
* wasm/js/WebAssemblyGlobalPrototype.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h.
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
Canonical link: https://commits.webkit.org/218038@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-12-04 01:36:56 +00:00
|
|
|
wasm/js/WebAssemblyGlobalConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyGlobalPrototype.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
wasm/js/WebAssemblyInstanceConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyInstancePrototype.cpp
|
|
|
|
wasm/js/WebAssemblyLinkErrorConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyLinkErrorPrototype.cpp
|
|
|
|
wasm/js/WebAssemblyMemoryConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyMemoryPrototype.cpp
|
|
|
|
wasm/js/WebAssemblyModuleConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyModulePrototype.cpp
|
|
|
|
wasm/js/WebAssemblyModuleRecord.cpp
|
|
|
|
wasm/js/WebAssemblyRuntimeErrorConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyRuntimeErrorPrototype.cpp
|
|
|
|
wasm/js/WebAssemblyTableConstructor.cpp
|
|
|
|
wasm/js/WebAssemblyTablePrototype.cpp
|
|
|
|
wasm/js/WebAssemblyWrapperFunction.cpp
|
|
|
|
|
|
|
|
yarr/RegularExpression.cpp
|
|
|
|
yarr/YarrCanonicalizeUCS2.cpp
|
Yarr JIT should include annotations with dumpDisassembly=true
https://bugs.webkit.org/show_bug.cgi?id=188415
Reviewed by Yusuke Suzuki.
Created a YarrDisassembler class that handles annotations similar to the baseline JIT.
Given that the Yarr creates matching code bu going through the YarrPattern ops forward and
then the backtracking code through the YarrPattern ops in reverse order, the disassembler
needs to do the same think.
Restructured some of the logging code in YarrPattern to eliminate redundent code and factor
out simple methods for what was needed by the YarrDisassembler.
Here is abbreviated sample output after this change.
Generated JIT code for 8-bit regular expression /ab*c/:
Code at [0x469561c03720, 0x469561c03840):
0x469561c03720: push %rbp
0x469561c03721: mov %rsp, %rbp
...
0x469561c03762: sub $0x40, %rsp
== Matching ==
0:OpBodyAlternativeBegin minimum size 2
0x469561c03766: add $0x2, %esi
0x469561c03769: cmp %edx, %esi
0x469561c0376b: ja 0x469561c037fa
1:OpTerm TypePatternCharacter 'a'
0x469561c03771: movzx -0x2(%rdi,%rsi), %eax
0x469561c03776: cmp $0x61, %eax
0x469561c03779: jnz 0x469561c037e9
2:OpTerm TypePatternCharacter 'b' {0,...} greedy
0x469561c0377f: xor %r9d, %r9d
0x469561c03782: cmp %edx, %esi
0x469561c03784: jz 0x469561c037a2
...
0x469561c0379d: jmp 0x469561c03782
0x469561c037a2: mov %r9, 0x8(%rsp)
3:OpTerm TypePatternCharacter 'c'
0x469561c037a7: movzx -0x1(%rdi,%rsi), %eax
0x469561c037ac: cmp $0x63, %eax
0x469561c037af: jnz 0x469561c037d1
4:OpBodyAlternativeEnd
0x469561c037b5: add $0x40, %rsp
...
0x469561c037cf: pop %rbp
0x469561c037d0: ret
== Backtracking ==
4:OpBodyAlternativeEnd
3:OpTerm TypePatternCharacter 'c'
2:OpTerm TypePatternCharacter 'b' {0,...} greedy
0x469561c037d1: mov 0x8(%rsp), %r9
...
0x469561c037e4: jmp 0x469561c037a2
1:OpTerm TypePatternCharacter 'a'
0:OpBodyAlternativeBegin minimum size 2
0x469561c037e9: mov %rsi, %rax
...
0x469561c0382f: pop %rbp
0x469561c03830: ret
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/RegExp.cpp:
(JSC::RegExp::compile):
(JSC::RegExp::compileMatchOnly):
* yarr/YarrDisassembler.cpp: Added.
(JSC::Yarr::YarrDisassembler::indentString):
(JSC::Yarr::YarrDisassembler::YarrDisassembler):
(JSC::Yarr::YarrDisassembler::~YarrDisassembler):
(JSC::Yarr::YarrDisassembler::dump):
(JSC::Yarr::YarrDisassembler::dumpHeader):
(JSC::Yarr::YarrDisassembler::dumpVectorForInstructions):
(JSC::Yarr::YarrDisassembler::dumpForInstructions):
(JSC::Yarr::YarrDisassembler::dumpDisassembly):
* yarr/YarrDisassembler.h: Added.
(JSC::Yarr::YarrJITInfo::~YarrJITInfo):
(JSC::Yarr::YarrDisassembler::setStartOfCode):
(JSC::Yarr::YarrDisassembler::setForGenerate):
(JSC::Yarr::YarrDisassembler::setForBacktrack):
(JSC::Yarr::YarrDisassembler::setEndOfGenerate):
(JSC::Yarr::YarrDisassembler::setEndOfBacktrack):
(JSC::Yarr::YarrDisassembler::setEndOfCode):
(JSC::Yarr::YarrDisassembler::indentString):
* yarr/YarrJIT.cpp:
(JSC::Yarr::YarrGenerator::generate):
(JSC::Yarr::YarrGenerator::backtrack):
(JSC::Yarr::YarrGenerator::YarrGenerator):
(JSC::Yarr::YarrGenerator::compile):
(JSC::Yarr::jitCompile):
* yarr/YarrJIT.h:
* yarr/YarrPattern.cpp:
(JSC::Yarr::dumpCharacterClass):
(JSC::Yarr::PatternTerm::dump):
(JSC::Yarr::YarrPattern::dumpPatternString):
(JSC::Yarr::YarrPattern::dumpPattern):
* yarr/YarrPattern.h:
Canonical link: https://commits.webkit.org/203528@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234713 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-08 22:42:30 +00:00
|
|
|
yarr/YarrDisassembler.cpp
|
2017-12-19 19:16:21 +00:00
|
|
|
yarr/YarrErrorCode.cpp
|
2019-03-11 06:20:53 +00:00
|
|
|
yarr/YarrFlags.cpp
|
2017-09-20 23:08:50 +00:00
|
|
|
yarr/YarrInterpreter.cpp
|
|
|
|
yarr/YarrJIT.cpp
|
|
|
|
yarr/YarrPattern.cpp
|
|
|
|
yarr/YarrSyntaxChecker.cpp
|
2017-10-09 23:14:46 +00:00
|
|
|
yarr/YarrUnicodeProperties.cpp
|
2017-09-26 15:34:19 +00:00
|
|
|
|
2017-10-18 19:14:51 +00:00
|
|
|
// Derived Sources
|
2017-09-26 15:34:19 +00:00
|
|
|
yarr/YarrCanonicalizeUnicode.cpp
|