WebKit Bugzilla
Attachment 341234 Details for
Bug 185967
: Rope string sweeping should avoid touching unresolved ropes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
work in progress
blah.patch (text/plain), 40.75 KB, created by
Filip Pizlo
on 2018-05-24 16:47:21 PDT
(
hide
)
Description:
work in progress
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2018-05-24 16:47:21 PDT
Size:
40.75 KB
patch
obsolete
>Index: Source/JavaScriptCore/heap/IsoCellSet.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoCellSet.h (revision 232161) >+++ Source/JavaScriptCore/heap/IsoCellSet.h (working copy) >@@ -45,11 +45,14 @@ public: > IsoCellSet(IsoSubspace& subspace); > ~IsoCellSet(); > >- bool add(HeapCell* cell); // Returns true if the cell was newly added. >+ bool add(HeapCell*); // Returns true if the cell was newly added. > >- bool remove(HeapCell* cell); // Returns true if the cell was previously present and got removed. >+ bool remove(HeapCell*); // Returns true if the cell was previously present and got removed. > >- bool contains(HeapCell* cell) const; >+ bool contains(HeapCell*) const; >+ >+ bool contains(MarkedBlock::Handle*) const; >+ Bitmap<MarkedBlock::atomsPerBlock>* bits(MarkedBlock::Handle*) const; > > JS_EXPORT_PRIVATE RefPtr<SharedTask<MarkedBlock::Handle*()>> parallelNotEmptyMarkedBlockSource(); > >Index: Source/JavaScriptCore/heap/IsoCellSetInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoCellSetInlines.h (revision 232161) >+++ Source/JavaScriptCore/heap/IsoCellSetInlines.h (working copy) >@@ -60,6 +60,16 @@ inline bool IsoCellSet::contains(HeapCel > return false; > } > >+inline bool IsoCellSet::contains(MarkedBlock::Handle* handle) const >+{ >+ return m_blocksWithBits[handle->index()]; >+} >+ >+inline Bitmap<MarkedBlock::atomsPerBlock>* IsoCellSet::bits(MarkedBlock::Handle* handle) const >+{ >+ return m_bits[handle->index()].get(); >+} >+ > template<typename Func> > void IsoCellSet::forEachMarkedCell(const Func& func) > { >Index: Source/JavaScriptCore/heap/IsoSubspace.cpp >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.cpp (revision 232161) >+++ Source/JavaScriptCore/heap/IsoSubspace.cpp (working copy) >@@ -79,7 +79,7 @@ void IsoSubspace::didRemoveBlock(size_t > }); > } > >-void IsoSubspace::didBeginSweepingToFreeList(MarkedBlock::Handle* block) >+void IsoSubspace::didSweepToFreeList(MarkedBlock::Handle* block) > { > m_cellSets.forEach( > [&] (IsoCellSet* set) { >Index: Source/JavaScriptCore/heap/IsoSubspace.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.h (revision 232161) >+++ Source/JavaScriptCore/heap/IsoSubspace.h (working copy) >@@ -52,7 +52,7 @@ private: > > void didResizeBits(size_t newSize) override; > void didRemoveBlock(size_t blockIndex) override; >- void didBeginSweepingToFreeList(MarkedBlock::Handle*) override; >+ void didSweepToFreeList(MarkedBlock::Handle*) override; > > size_t m_size; > BlockDirectory m_directory; >Index: Source/JavaScriptCore/heap/MarkedBlock.cpp >=================================================================== >--- Source/JavaScriptCore/heap/MarkedBlock.cpp (revision 232161) >+++ Source/JavaScriptCore/heap/MarkedBlock.cpp (working copy) >@@ -426,60 +426,59 @@ void MarkedBlock::Handle::sweep(FreeList > if (space()->isMarking()) > blockFooter().m_lock.lock(); > >- subspace()->didBeginSweepingToFreeList(this); >- >- if (needsDestruction) { >+ if (needsDestruction) > subspace()->finishSweep(*this, freeList); >- return; >- } >- >- // Handle the no-destructor specializations here, since we have the most of those. This >- // ensures that they don't get re-specialized for every destructor space. >- >- EmptyMode emptyMode = this->emptyMode(); >- ScribbleMode scribbleMode = this->scribbleMode(); >- NewlyAllocatedMode newlyAllocatedMode = this->newlyAllocatedMode(); >- MarksMode marksMode = this->marksMode(); >- >- auto trySpecialized = [&] () -> bool { >- if (sweepMode != SweepToFreeList) >- return false; >- if (scribbleMode != DontScribble) >- return false; >- if (newlyAllocatedMode != DoesNotHaveNewlyAllocated) >- return false; >+ else { >+ // Handle the no-destructor specializations here, since we have the most of those. This >+ // ensures that they don't get re-specialized for every destructor space. >+ >+ EmptyMode emptyMode = this->emptyMode(); >+ ScribbleMode scribbleMode = this->scribbleMode(); >+ NewlyAllocatedMode newlyAllocatedMode = this->newlyAllocatedMode(); >+ MarksMode marksMode = this->marksMode(); >+ >+ auto trySpecialized = [&] () -> bool { >+ if (sweepMode != SweepToFreeList) >+ return false; >+ if (scribbleMode != DontScribble) >+ return false; >+ if (newlyAllocatedMode != DoesNotHaveNewlyAllocated) >+ return false; > >- switch (emptyMode) { >- case IsEmpty: >- switch (marksMode) { >- case MarksNotStale: >- specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&, JSCell*) { }); >- return true; >- case MarksStale: >- specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&, JSCell*) { }); >- return true; >+ switch (emptyMode) { >+ case IsEmpty: >+ switch (marksMode) { >+ case MarksNotStale: >+ specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, HasNoDestructor(), [] (VM&, JSCell*) { }); >+ return true; >+ case MarksStale: >+ specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, HasNoDestructor(), [] (VM&, JSCell*) { }); >+ return true; >+ } >+ break; >+ case NotEmpty: >+ switch (marksMode) { >+ case MarksNotStale: >+ specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, HasNoDestructor(), [] (VM&, JSCell*) { }); >+ return true; >+ case MarksStale: >+ specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, HasNoDestructor(), [] (VM&, JSCell*) { }); >+ return true; >+ } >+ break; > } >- break; >- case NotEmpty: >- switch (marksMode) { >- case MarksNotStale: >- specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&, JSCell*) { }); >- return true; >- case MarksStale: >- specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&, JSCell*) { }); >- return true; >- } >- break; >- } > >- return false; >- }; >+ return false; >+ }; > >- if (trySpecialized()) >- return; >- >- // The template arguments don't matter because the first one is false. >- specializedSweep<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(freeList, emptyMode, sweepMode, BlockHasNoDestructors, scribbleMode, newlyAllocatedMode, marksMode, [] (VM&, JSCell*) { }); >+ if (!trySpecialized()) { >+ // The template arguments don't matter because the first one is false. >+ specializedSweep<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(freeList, emptyMode, sweepMode, BlockHasNoDestructors, scribbleMode, newlyAllocatedMode, marksMode, HasNoDestructor(), [] (VM&, JSCell*) { }); >+ } >+ } >+ >+ if (sweepMode == SweepToFreeList) >+ subspace()->didSweepToFreeList(this); > } > > bool MarkedBlock::Handle::isFreeListedCell(const void* target) const >Index: Source/JavaScriptCore/heap/MarkedBlock.h >=================================================================== >--- Source/JavaScriptCore/heap/MarkedBlock.h (revision 232161) >+++ Source/JavaScriptCore/heap/MarkedBlock.h (working copy) >@@ -133,10 +133,16 @@ public: > // mistake of making a pop freelist rather than a bump freelist. > void sweep(FreeList*); > >- // This is to be called by Subspace. > template<typename DestroyFunc> > void finishSweepKnowingHeapCellType(FreeList*, const DestroyFunc&); > >+ struct HasNoDestructor { >+ ALWAYS_INLINE bool operator()(size_t) const { return false; } >+ }; >+ >+ template<typename HasDestructorFunc, typename DestroyFunc> >+ void finishSweepKnowingHeapCellType(FreeList*, const HasDestructorFunc&, const DestroyFunc&); >+ > void unsweepWithNoNewlyAllocated(); > > void zap(const FreeList&); >@@ -209,8 +215,8 @@ public: > NewlyAllocatedMode newlyAllocatedMode(); > MarksMode marksMode(); > >- template<bool, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, typename DestroyFunc> >- void specializedSweep(FreeList*, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, const DestroyFunc&); >+ template<bool, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, typename HasDestructorFunc, typename DestroyFunc> >+ void specializedSweep(FreeList*, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, const HasDestructorFunc&, const DestroyFunc&); > > void setIsFreeListed(); > >Index: Source/JavaScriptCore/heap/MarkedBlockInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/MarkedBlockInlines.h (revision 232161) >+++ Source/JavaScriptCore/heap/MarkedBlockInlines.h (working copy) >@@ -224,8 +224,8 @@ inline bool MarkedBlock::Handle::isLiveC > // > // Only the DoesNotNeedDestruction one should be specialized by MarkedBlock. > >-template<bool specialize, MarkedBlock::Handle::EmptyMode specializedEmptyMode, MarkedBlock::Handle::SweepMode specializedSweepMode, MarkedBlock::Handle::SweepDestructionMode specializedDestructionMode, MarkedBlock::Handle::ScribbleMode specializedScribbleMode, MarkedBlock::Handle::NewlyAllocatedMode specializedNewlyAllocatedMode, MarkedBlock::Handle::MarksMode specializedMarksMode, typename DestroyFunc> >-void MarkedBlock::Handle::specializedSweep(FreeList* freeList, MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode, MarkedBlock::Handle::MarksMode marksMode, const DestroyFunc& destroyFunc) >+template<bool specialize, MarkedBlock::Handle::EmptyMode specializedEmptyMode, MarkedBlock::Handle::SweepMode specializedSweepMode, MarkedBlock::Handle::SweepDestructionMode specializedDestructionMode, MarkedBlock::Handle::ScribbleMode specializedScribbleMode, MarkedBlock::Handle::NewlyAllocatedMode specializedNewlyAllocatedMode, MarkedBlock::Handle::MarksMode specializedMarksMode, typename HasDestructorFunc, typename DestroyFunc> >+void MarkedBlock::Handle::specializedSweep(FreeList* freeList, MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode, MarkedBlock::Handle::MarksMode marksMode, const HasDestructorFunc& hasDestructor, const DestroyFunc& destroyFunc) > { > if (specialize) { > emptyMode = specializedEmptyMode; >@@ -259,6 +259,9 @@ void MarkedBlock::Handle::specializedSwe > > m_directory->setIsDestructible(NoLockingNecessary, this, false); > >+ unsigned endAtom = m_endAtom; >+ unsigned atomsPerCell = m_atomsPerCell; >+ > if (Options::useBumpAllocator() > && emptyMode == IsEmpty > && newlyAllocatedMode == DoesNotHaveNewlyAllocated) { >@@ -285,8 +288,11 @@ void MarkedBlock::Handle::specializedSwe > if (space()->isMarking()) > footer.m_lock.unlock(); > if (destructionMode != BlockHasNoDestructors) { >- for (char* cell = payloadBegin; cell < payloadEnd; cell += cellSize) >- destroy(cell); >+ for (size_t i = 0; i < endAtom; i += atomsPerCell) { >+ HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&block.atoms()[i]); >+ if (hasDestructor(i)) >+ destroy(cell); >+ } > } > if (sweepMode == SweepToFreeList) { > if (scribbleMode == Scribble) >@@ -322,7 +328,7 @@ void MarkedBlock::Handle::specializedSwe > ++count; > } > }; >- for (size_t i = 0; i < m_endAtom; i += m_atomsPerCell) { >+ for (size_t i = 0; i < endAtom; i += atomsPerCell) { > if (emptyMode == NotEmpty > && ((marksMode == MarksNotStale && footer.m_marks.get(i)) > || (newlyAllocatedMode == HasNewlyAllocated && footer.m_newlyAllocated.get(i)))) { >@@ -330,6 +336,9 @@ void MarkedBlock::Handle::specializedSwe > continue; > } > >+ if (!hasDestructor(i)) >+ continue; >+ > if (destructionMode == BlockHasDestructorsAndCollectorIsRunning) > deadCells.append(i); > else >@@ -358,8 +367,8 @@ void MarkedBlock::Handle::specializedSwe > dataLog("Slowly swept block ", RawPointer(&block), " with cell size ", cellSize, " and attributes ", m_attributes, ": ", pointerDump(freeList), "\n"); > } > >-template<typename DestroyFunc> >-void MarkedBlock::Handle::finishSweepKnowingHeapCellType(FreeList* freeList, const DestroyFunc& destroyFunc) >+template<typename HasDestructorFunc, typename DestroyFunc> >+void MarkedBlock::Handle::finishSweepKnowingHeapCellType(FreeList* freeList, const HasDestructorFunc& hasDestructor, const DestroyFunc& destroyFunc) > { > SweepMode sweepMode = freeList ? SweepToFreeList : SweepOnly; > SweepDestructionMode destructionMode = this->sweepDestructionMode(); >@@ -382,20 +391,20 @@ void MarkedBlock::Handle::finishSweepKno > case SweepOnly: > switch (marksMode) { > case MarksNotStale: >- specializedSweep<true, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc); >+ specializedSweep<true, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, hasDestructor, destroyFunc); > return true; > case MarksStale: >- specializedSweep<true, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, destroyFunc); >+ specializedSweep<true, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, hasDestructor, destroyFunc); > return true; > } > RELEASE_ASSERT_NOT_REACHED(); > case SweepToFreeList: > switch (marksMode) { > case MarksNotStale: >- specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc); >+ specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, hasDestructor, destroyFunc); > return true; > case MarksStale: >- specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, destroyFunc); >+ specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, hasDestructor, destroyFunc); > return true; > } > } >@@ -405,20 +414,20 @@ void MarkedBlock::Handle::finishSweepKno > case SweepOnly: > switch (marksMode) { > case MarksNotStale: >- specializedSweep<true, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc); >+ specializedSweep<true, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, hasDestructor, destroyFunc); > return true; > case MarksStale: >- specializedSweep<true, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, destroyFunc); >+ specializedSweep<true, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, NotEmpty, SweepOnly, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, hasDestructor, destroyFunc); > return true; > } > RELEASE_ASSERT_NOT_REACHED(); > case SweepToFreeList: > switch (marksMode) { > case MarksNotStale: >- specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc); >+ specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(freeList, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, hasDestructor, destroyFunc); > return true; > case MarksStale: >- specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, destroyFunc); >+ specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(freeList, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, hasDestructor, destroyFunc); > return true; > } > } >@@ -431,7 +440,13 @@ void MarkedBlock::Handle::finishSweepKno > return; > > // The template arguments don't matter because the first one is false. >- specializedSweep<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(freeList, emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, marksMode, destroyFunc); >+ specializedSweep<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(freeList, emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, marksMode, hasDestructor, destroyFunc); >+} >+ >+template<typename DestroyFunc> >+void MarkedBlock::Handle::finishSweepKnowingHeapCellType(FreeList* freeList, const DestroyFunc& destroyFunc) >+{ >+ finishSweepKnowingHeapCellType(freeList, HasNoDestructor(), destroyFunc); > } > > inline MarkedBlock::Handle::SweepDestructionMode MarkedBlock::Handle::sweepDestructionMode() >Index: Source/JavaScriptCore/heap/Subspace.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Subspace.cpp (revision 232161) >+++ Source/JavaScriptCore/heap/Subspace.cpp (working copy) >@@ -142,7 +142,7 @@ void Subspace::didRemoveBlock(size_t) > { > } > >-void Subspace::didBeginSweepingToFreeList(MarkedBlock::Handle*) >+void Subspace::didSweepToFreeList(MarkedBlock::Handle*) > { > } > >Index: Source/JavaScriptCore/heap/Subspace.h >=================================================================== >--- Source/JavaScriptCore/heap/Subspace.h (revision 232161) >+++ Source/JavaScriptCore/heap/Subspace.h (working copy) >@@ -99,7 +99,7 @@ public: > > virtual void didResizeBits(size_t newSize); > virtual void didRemoveBlock(size_t blockIndex); >- virtual void didBeginSweepingToFreeList(MarkedBlock::Handle*); >+ virtual void didSweepToFreeList(MarkedBlock::Handle*); // This is the last thing that sweep does. > > protected: > void initialize(HeapCellType*, AlignedMemoryAllocator*); >Index: Source/JavaScriptCore/runtime/JSCellInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCellInlines.h (revision 232161) >+++ Source/JavaScriptCore/runtime/JSCellInlines.h (working copy) >@@ -170,7 +170,7 @@ ALWAYS_INLINE void* tryAllocateCellHelpe > } > > template<typename T> >-void* allocateCell(Heap& heap, size_t size) >+ALWAYS_INLINE void* allocateCell(Heap& heap, size_t size) > { > return tryAllocateCellHelper<T>(heap, size, nullptr, AllocationFailureMode::Assert); > } >Index: Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.cpp (nonexistent) >+++ Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.cpp (working copy) >@@ -0,0 +1,87 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JSStringHeapCellType.h" >+ >+#include "MarkedBlockInlines.h" >+#include "JSCInlines.h" >+ >+namespace JSC { >+ >+class JSRopeStringHasDestructorFunc { >+public: >+ JSRopeStringHasDestructorFunc(Bitmap<MarkedBlock::atomsPerBlock>* bits) >+ : m_bits(bits) >+ { >+ } >+ >+ ALWAYS_INLINE bool operator()(size_t i) const >+ { >+ return m_bits->get(i); >+ } >+ >+private: >+ Bitmap<MarkedBlock::atomsPerBlock>* m_bits; >+}; >+ >+struct JSRopeStringDestroyFunc { >+ ALWAYS_INLINE void operator()(VM&, JSCell* cell) const >+ { >+ static_cast<JSRopeString*>(cell)->JSRopeString::~JSRopeString(); >+ } >+}; >+ >+JSRopeStringHeapCellType::JSRopeStringHeapCellType() >+ : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell)) >+{ >+} >+ >+JSRopeStringHeapCellType::~JSRopeStringHeapCellType() >+{ >+} >+ >+void JSRopeStringHeapCellType::finishSweep(MarkedBlock::Handle& handle, FreeList* freeList) >+{ >+ VM& vm = *handle.vm(); >+ >+ if (vm.ropeStringsWithDestructors.contains(&handle)) { >+ handle.finishSweepKnowingHeapCellType( >+ freeList, >+ JSRopeStringHasDestructorFunc(vm.ropeStringsWithDestructors.bits(&handle)), >+ JSStringDestroyFunc()); >+ return; >+ } >+ >+ handle.finishSweepKnowingHeapCellType(freeList, JSStringDestroyFunc()); >+} >+ >+void JSRopeStringHeapCellType::destroy(VM& vm, JSCell* cell) >+{ >+ JSRopeStringDestroyFunc()(vm, cell); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.h (nonexistent) >+++ Source/JavaScriptCore/runtime/JSRopeStringHeapCellType.h (working copy) >@@ -0,0 +1,42 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "HeapCellType.h" >+ >+namespace JSC { >+ >+class JSRopeStringHeapCellType : public HeapCellType { >+public: >+ JS_EXPORT_PRIVATE JSRopeStringHeapCellType(); >+ JS_EXPORT_PRIVATE virtual ~JSRopeStringHeapCellType(); >+ >+ void finishSweep(MarkedBlock::Handle&, FreeList*) override; >+ void destroy(VM&, JSCell*) override; >+}; >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/runtime/JSString.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSString.cpp (revision 232161) >+++ Source/JavaScriptCore/runtime/JSString.cpp (working copy) >@@ -181,6 +181,7 @@ void JSRopeString::resolveRopeToAtomicSt > if (length() > maxLengthForOnStackResolve) { > resolveRope(exec); > m_value = AtomicString(m_value); >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > return; > } >@@ -189,11 +190,13 @@ void JSRopeString::resolveRopeToAtomicSt > LChar buffer[maxLengthForOnStackResolve]; > resolveRopeInternal8(buffer); > m_value = AtomicString(buffer, length()); >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > } else { > UChar buffer[maxLengthForOnStackResolve]; > resolveRopeInternal16(buffer); > m_value = AtomicString(buffer, length()); >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > } > >@@ -216,6 +219,7 @@ RefPtr<AtomicStringImpl> JSRopeString::r > resolveRope(exec); > if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(m_value.impl())) { > m_value = *existingAtomicString; >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > clearFibers(); > return existingAtomicString; >@@ -228,6 +232,7 @@ RefPtr<AtomicStringImpl> JSRopeString::r > resolveRopeInternal8(buffer); > if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, length())) { > m_value = *existingAtomicString; >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > clearFibers(); > return existingAtomicString; >@@ -237,6 +242,7 @@ RefPtr<AtomicStringImpl> JSRopeString::r > resolveRopeInternal16(buffer); > if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, length())) { > m_value = *existingAtomicString; >+ didBecomeDestructible(exec->vm()); > setIs8Bit(m_value.impl()->is8Bit()); > clearFibers(); > return existingAtomicString; >@@ -253,6 +259,7 @@ void JSRopeString::resolveRope(ExecState > if (isSubstring()) { > ASSERT(!substringBase()->isRope()); > m_value = substringBase()->m_value.substringSharingImpl(substringOffset(), length()); >+ didBecomeDestructible(exec->vm()); > substringBase().clear(); > return; > } >@@ -262,6 +269,7 @@ void JSRopeString::resolveRope(ExecState > if (auto newImpl = StringImpl::tryCreateUninitialized(length(), buffer)) { > Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost()); > m_value = WTFMove(newImpl); >+ didBecomeDestructible(exec->vm()); > } else { > outOfMemory(exec); > return; >@@ -276,6 +284,7 @@ void JSRopeString::resolveRope(ExecState > if (auto newImpl = StringImpl::tryCreateUninitialized(length(), buffer)) { > Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost()); > m_value = WTFMove(newImpl); >+ didBecomeDestructible(exec->vm()); > } else { > outOfMemory(exec); > return; >@@ -376,6 +385,11 @@ void JSRopeString::resolveRopeSlowCase(U > ASSERT(buffer == position); > } > >+void JSRopeString::didBecomeDestructible(VM& vm) >+{ >+ vm.ropeStringsWithDestructors.add(this); >+} >+ > void JSRopeString::outOfMemory(ExecState* exec) const > { > VM& vm = exec->vm(); >Index: Source/JavaScriptCore/runtime/JSString.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSString.h (revision 232161) >+++ Source/JavaScriptCore/runtime/JSString.h (working copy) >@@ -87,10 +87,8 @@ public: > static const bool needsDestruction = true; > static void destroy(JSCell*); > >- // We specialize the string subspace to get the fastest possible sweep. This wouldn't be >- // necessary if JSString didn't have a destructor. > template<typename> >- static CompleteSubspace* subspaceFor(VM& vm) >+ static IsoSubspace* subspaceFor(VM& vm) > { > return &vm.stringSpace; > } >@@ -240,6 +238,12 @@ class JSRopeString final : public JSStri > friend JSRopeString* jsStringBuilder(VM*); > > public: >+ template<typename> >+ static IsoSubspace* subspaceFor(VM& vm) >+ { >+ return &vm.ropeStringSpace; >+ } >+ > template <class OverflowHandler = CrashOnOverflow> > class RopeBuilder : public OverflowHandler { > public: >@@ -292,28 +296,28 @@ private: > { > } > >- void finishCreation(VM& vm, JSString* s1, JSString* s2) >+ ALWAYS_INLINE void finishCreation(VM& vm, JSString* s1, JSString* s2) > { > Base::finishCreation(vm); > ASSERT(!sumOverflows<int32_t>(s1->length(), s2->length())); > setLength(s1->length() + s2->length()); > setIs8Bit(s1->is8Bit() && s2->is8Bit()); > setIsSubstring(false); >- fiber(0).set(vm, this, s1); >- fiber(1).set(vm, this, s2); >+ fiber(0).setWithoutWriteBarrier(s1); >+ fiber(1).setWithoutWriteBarrier(s2); > fiber(2).clear(); > } > >- void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3) >+ ALWAYS_INLINE void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3) > { > Base::finishCreation(vm); > ASSERT(!sumOverflows<int32_t>(s1->length(), s2->length(), s3->length())); > setLength(s1->length() + s2->length() + s3->length()); > setIs8Bit(s1->is8Bit() && s2->is8Bit() && s3->is8Bit()); > setIsSubstring(false); >- fiber(0).set(vm, this, s1); >- fiber(1).set(vm, this, s2); >- fiber(2).set(vm, this, s3); >+ fiber(0).setWithoutWriteBarrier(s1); >+ fiber(1).setWithoutWriteBarrier(s2); >+ fiber(2).setWithoutWriteBarrier(s3); > } > > void finishCreation(VM& vm, ExecState* exec, JSString* base, unsigned offset, unsigned length) >@@ -402,13 +406,13 @@ public: > static const unsigned s_maxInternalRopeLength = 3; > > private: >- static JSString* create(VM& vm, JSString* s1, JSString* s2) >+ ALWAYS_INLINE static JSString* create(VM& vm, JSString* s1, JSString* s2) > { > JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm); > newString->finishCreation(vm, s1, s2); > return newString; > } >- static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3) >+ ALWAYS_INLINE static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3) > { > JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm); > newString->finishCreation(vm, s1, s2, s3); >@@ -431,7 +435,9 @@ private: > void clearFibers() const; > StringView unsafeView(ExecState*) const; > StringViewWithUnderlyingString viewWithUnderlyingString(ExecState*) const; >- >+ >+ void didBecomeDestructible(VM&); >+ > WriteBarrierBase<JSString>& fiber(unsigned i) const > { > ASSERT(!isSubstring()); >Index: Source/JavaScriptCore/runtime/VM.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/VM.cpp (revision 232161) >+++ Source/JavaScriptCore/runtime/VM.cpp (working copy) >@@ -92,6 +92,7 @@ > #include "JSMapIterator.h" > #include "JSPromiseDeferred.h" > #include "JSPropertyNameEnumerator.h" >+#include "JSRopeStringHeapCellType.h" > #include "JSSegmentedVariableObjectHeapCellType.h" > #include "JSScriptFetchParameters.h" > #include "JSScriptFetcher.h" >@@ -252,6 +253,7 @@ VM::VM(VMType vmType, HeapType heapType) > , cellDangerousBitsHeapCellType(std::make_unique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell))) > , destructibleCellHeapCellType(std::make_unique<HeapCellType>(CellAttributes(NeedsDestruction, HeapCell::JSCell))) > , stringHeapCellType(std::make_unique<JSStringHeapCellType>()) >+ , ropeStringHeapCellType(std::make_unique<JSRopeStringHeapCellType>()) > , destructibleObjectHeapCellType(std::make_unique<JSDestructibleObjectHeapCellType>()) > , segmentedVariableObjectHeapCellType(std::make_unique<JSSegmentedVariableObjectHeapCellType>()) > #if ENABLE(WEBASSEMBLY) >@@ -263,7 +265,6 @@ VM::VM(VMType vmType, HeapType heapType) > , cellDangerousBitsSpace("JSCell DangerousBits", heap, cellDangerousBitsHeapCellType.get(), fastMallocAllocator.get()) > , jsValueGigacageCellSpace("JSValue Gigacage JSCell", heap, cellJSValueOOBHeapCellType.get(), jsValueGigacageAllocator.get()) > , destructibleCellSpace("Destructible JSCell", heap, destructibleCellHeapCellType.get(), fastMallocAllocator.get()) >- , stringSpace("JSString", heap, stringHeapCellType.get(), fastMallocAllocator.get()) > , destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) > , eagerlySweptDestructibleObjectSpace("Eagerly Swept JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) > , segmentedVariableObjectSpace("JSSegmentedVariableObjectSpace", heap, segmentedVariableObjectHeapCellType.get(), fastMallocAllocator.get()) >@@ -300,7 +301,9 @@ VM::VM(VMType vmType, HeapType heapType) > , propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable) > , proxyRevokeSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ProxyRevoke) > , regExpConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), RegExpConstructor) >+ , ropeStringSpace ISO_SUBSPACE_INIT(heap, ropeStringHeapCellType.get(), JSRopeString) > , strictModeTypeErrorFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), StrictModeTypeErrorFunction) >+ , stringSpace ISO_SUBSPACE_INIT(heap, stringHeapCellType.get(), JSString) > , structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData) > , structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure) > , weakSetSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakSet) >@@ -314,6 +317,7 @@ VM::VM(VMType vmType, HeapType heapType) > , executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace) > , inferredTypesWithFinalizers(inferredTypeSpace) > , inferredValuesWithFinalizers(inferredValueSpace) >+ , ropeStringsWithDestructors(ropeStringSpace) > , evalCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), EvalCodeBlock) > , functionCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionCodeBlock) > , moduleProgramCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramCodeBlock) >Index: Source/JavaScriptCore/runtime/VM.h >=================================================================== >--- Source/JavaScriptCore/runtime/VM.h (revision 232161) >+++ Source/JavaScriptCore/runtime/VM.h (working copy) >@@ -309,6 +309,7 @@ public: > std::unique_ptr<HeapCellType> cellDangerousBitsHeapCellType; > std::unique_ptr<HeapCellType> destructibleCellHeapCellType; > std::unique_ptr<JSStringHeapCellType> stringHeapCellType; >+ std::unique_ptr<JSRopeStringHeapCellType> ropeStringHeapCellType; > std::unique_ptr<JSDestructibleObjectHeapCellType> destructibleObjectHeapCellType; > std::unique_ptr<JSSegmentedVariableObjectHeapCellType> segmentedVariableObjectHeapCellType; > #if ENABLE(WEBASSEMBLY) >@@ -341,7 +342,6 @@ public: > CompleteSubspace cellDangerousBitsSpace; > CompleteSubspace jsValueGigacageCellSpace; // FIXME: This space is problematic because we have things in here like DirectArguments and ScopedArguments; those should be split into JSValueOOB cells and JSValueStrict auxiliaries. https://bugs.webkit.org/show_bug.cgi?id=182858 > CompleteSubspace destructibleCellSpace; >- CompleteSubspace stringSpace; > CompleteSubspace destructibleObjectSpace; > CompleteSubspace eagerlySweptDestructibleObjectSpace; > CompleteSubspace segmentedVariableObjectSpace; >@@ -379,7 +379,9 @@ public: > IsoSubspace propertyTableSpace; > IsoSubspace proxyRevokeSpace; > IsoSubspace regExpConstructorSpace; >+ IsoSubspace ropeStringSpace; > IsoSubspace strictModeTypeErrorFunctionSpace; >+ IsoSubspace stringSpace; > IsoSubspace structureRareDataSpace; > IsoSubspace structureSpace; > IsoSubspace weakSetSpace; >@@ -394,6 +396,7 @@ public: > IsoCellSet executableToCodeBlockEdgesWithFinalizers; > IsoCellSet inferredTypesWithFinalizers; > IsoCellSet inferredValuesWithFinalizers; >+ IsoCellSet ropeStringsWithDestructors; > > struct SpaceAndFinalizerSet { > IsoSubspace space;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185967
:
341234
|
341338
|
341361
|
341413