summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Heap
AgeCommit message (Collapse)Author
2021-12-11Everywhere: Fix -Winconsistent-missing-override warnings from ClangDaniel Bertalan
This option is already enabled when building Lagom, so let's enable it for the main build too. We will no longer be surprised by Lagom Clang CI builds failing while everything compiles locally. Furthermore, the stronger `-Wsuggest-override` warning is enabled in this commit, which enforces the use of the `override` keyword in all classes, not just those which already have some methods marked as `override`. This works with both GCC and Clang.
2021-12-09LibJS: Add Handle::operator->()Andreas Kling
2021-11-17AK: Convert AK::Format formatting helpers to returning ErrorOr<void>Andreas Kling
This isn't a complete conversion to ErrorOr<void>, but a good chunk. The end goal here is to propagate buffer allocation failures to the caller, and allow the use of TRY() with formatting functions.
2021-10-08LibJS: Prune WeakContainers before freeing HeapBlocksAndreas Kling
WeakContainers need to look at the Cell::State bits to know if their weak pointees got swept by garbage collection. So we must do this before potentially freeing one or more HeapBlocks by notifying the allocator that a block became empty.
2021-10-08LibJS: Make BlockAllocator cache reuse blocks in random orderAndreas Kling
2021-10-08LibJS: Increase GC heap BlockAllocator cache sizeAndreas Kling
Let's accept keeping up to 8 MiB of HeapBlock memory cached. This allows the GC allocator to reuse memory instead of asking the kernel for more.
2021-10-05LibJS: Make WeakContainer pruning do less workAndreas Kling
Instead of iterating *all* swept cells when pruning weak containers, only iterate the cells actually *in* the container. Also, instead of compiling a list of all swept cells, we can simply check the Cell::state() flag to know if something should be pruned.
2021-10-02LibJS: Put zombie cell tracking code behind a compile-time flagAndreas Kling
Since this is a debug-only feature, let's not have it impact GC marking performance when you don't need it.
2021-10-02LibJS: Keep track of PrimitiveStrings and share themAndreas Kling
VM now has a string cache which tracks all live PrimitiveStrings and reuses an existing one if possible. This drastically reduces the number of GC-allocated strings in many real-word situations.
2021-10-01LibJS: Remove transition avoidance & start caching prototype transitionsAndreas Kling
The way that transition avoidance (foo_without_transition) was implemented led to shapes being unshareable and caused shape explosion instead, precisely what we were trying to avoid. This patch removes all the attempts to avoid transitioning shapes, and instead *adds* transitions when changing an object's prototype. This makes transitions flow naturally, and as a result we end up with way fewer shape objects in real-world situations. When we run out of big problems, we can get back to avoiding transitions as an optimization, but for now, let's avoid ballooning our processes with a unique shape for every object.
2021-09-17LibJS: Increase time between garbage collectionsAndreas Kling
This patch ups the max number of heap allocations between each GC from 10'000 to 100'000. This is still relatively aggressive but already does a good job of cutting down on time spent in GC.
2021-09-16LibJS: Use default instead of an empty constructor/destructorBrian Gianforcaro
Default implementations allow for more optimizations. See: https://pvs-studio.com/en/docs/warnings/v832/
2021-09-12LibJS: Use ElapsedTimer::start_new();Brian Gianforcaro
2021-09-11LibJS: Fix ASAN poisoning range in new HeapBlocksAndreas Kling
When poisoning HeapBlock::m_storage, we have to compute the storage size by excluding the HeapBlock header.
2021-09-11LibJS+js+test-js: Add GC debug mode that keeps cells "alive" as zombiesAndreas Kling
This patch adds a `-z` option to js and test-js. When run in this mode, garbage cells are never actually destroyed. We instead keep them around in a special zombie state. This allows us to validate that zombies don't get marked in future GC scans (since there were not supposed to be any more references!) :^) Cells get notified when they become a zombie (via did_become_zombie()) and this is used by WeakContainer cells to deregister themselves from the heap.
2021-09-11LibJS: Tweak the WeakContainer::remove_swept_cells() API a little bitAndreas Kling
Make this API take a Span<Cell*> instead of a Vector<Cell*>&. This is behavior neutral, but stops the API looking like it wants to do mutable things to the Vector.
2021-09-10AK+Everywhere: Reduce the number of template parameters of IntrusiveListAli Mohammad Pur
This makes the user-facing type only take the node member pointer, and lets the compiler figure out the other needed types from that.
2021-09-08test-js: Add a mark_as_garbage method to force GC to collect that objectdavidot
This should fix the flaky tests of test-js. It also fixes the tests when running with the -g flag since the values will not be garbage collected too soon.
2021-09-05LibJS: Declare type aliases with "using" instead of "typedef"Brian Gianforcaro
2021-08-28LibJS: Avoid pointless transitions and metadata lookups in storage_set()Linus Groh
- Replace the misleading abuse of the m_transitions_enabled flag for the fast path without lookup with a new m_initialized boolean that's set either by Heap::allocate() after calling the Object's initialize(), or by the GlobalObject in its special initialize_global_object(). This makes it work regardless of the shape's uniqueness. - When we're adding a new property past the initialization phase, there's no need to do a second metadata lookup to retrieve the storage value offset - it's known to always be the shape's property count minus one. Also, instead of doing manual storage resizing and assignment via indexing, just use Vector::append(). - When we didn't add a new property but are overwriting an existing one, the property count and therefore storage value offset doesn't change, so we don't have to retrieve it either. As a result, Object::set_shape() is now solely responsible for updating the m_shape pointer and is not resizing storage anymore, so I moved it into the header.
2021-08-12Kernel: Make sys$perf_register_string() generate the string ID'sAndreas Kling
Making userspace provide a global string ID was silly, and made the API extremely difficult to use correctly in a global profiling context. Instead, simply make the kernel do the string ID allocation for us. This also allows us to convert the string storage to a Vector in the kernel (and an array in the JSON profile data.)
2021-08-12LibJS: Emit a profile signpost when starting a garbage collectionAndreas Kling
2021-08-01LibJS: Remove unused header includesBrian Gianforcaro
2021-08-01LibJS: Remove unused includes out of Cell.h, move to the usersBrian Gianforcaro
Almost everything in LibJS includes Cell.h, don't force all code to include AK/TypeCasts.h + AK/String.h. Instead include them where they are actually used and required.
2021-07-21LibJS: Use IntrusiveList for keeping track of WeakContainersAndreas Kling
2021-07-21LibJS: Use IntrusiveList for keeping track of MarkedValueListsAndreas Kling
2021-07-21LibJS: Use IntrusiveList for keeping track of HandleImplsAndreas Kling
This allows us to remove a HashTable from heap and cuts down on some of the malloc traffic when creating handles.
2021-07-01LibJS: Drop "Record" suffix from all the *Environment record classesAndreas Kling
"Records" in the spec are basically C++ classes, so let's drop this mouthful of a suffix.
2021-06-27LibJS: Fix typo "sweeped" => "swept" everywhereAndreas Kling
2021-06-23LibJS: Make EnvironmentRecord inherit directly from CellAndreas Kling
Previously, EnvironmentRecord was a JS::Object. This was done because GlobalObject inherited from EnvironmentRecord. Now that this is no longer the case, we can simplify things by making EnvironmentRecord inherit from Cell directly. This also removes the need for environment records to have a shape, which was awkward. This will be removed in the following patch.
2021-06-13LibJS: Don't generate unused HeapBlock names on non-SerenityOS systemsAndreas Kling
These are just ignored by the BlockAllocator anyway.
2021-06-12LibJS: Generify the garbage collector's weak container notificationsIdan Horowitz
This will allow us to use the same interface for other JS weak containers like the WeakMap & WeakRef.
2021-06-09LibJS: Notify WeakSets when heap cells are sweepedIdan Horowitz
This is an implementation of the following optional optimization: https://tc39.es/ecma262/#sec-weakref-execution
2021-06-06LibJS: Add dbgln() to Heap::allocator_for_size() before crashingLinus Groh
If we can't get a CellAllocator for the requested cell size, at least print a debug message before dying.
2021-05-29LibJS: Instrument HeapBlock cell allocation for ASANAndrew Kaster
Mark the entirety of a heap block's storage poisoned at construction. Unpoison all of a Cell's memory before allocating it, and re-poison as much as possible on deallocation. Unfortunately, the entirety of the FreelistEntry must be kept unpoisoned in order for reallocation to work correctly. Decreasing the size of FreelistEntry or adding a larger redzone to Cells would make the instrumentation even better.
2021-05-29LibJS: Expose minimum possible cell size of JS::HeapAndrew Kaster
Use this to avoid creating a 16 byte cell allocator on x86_64, where the size of FreelistEntry is 24 bytes. Every JS::Cell must be at least the size of the FreelistEntry or things start crashing, so the 16 byte allocator was wasted on that platform.
2021-05-29LibJS: Remove unused HeapBlock private member functionAndrew Kaster
FreelistEntries are constructed manually in deallocate() instead of using this helper.
2021-05-28LibJS: Poison unused heap blocks until they are re-allocatedAndrew Kaster
This is the coarsest grained ASAN instrumentation possible for the LibJS heap. Future instrumentation could add red-zones to heap block allocations, and poison the entire heap block and only un-poison used cells at the CellAllocator level.
2021-05-28LibJS: Add inline capacity to BlockAllocator's blocks VectorIdan Horowitz
There's no need to dynamically allocate a constant sized vector :^)
2021-05-27LibJS: Update mmap name after recycling a HeapBlock :^)Andreas Kling
Fixes #7507.
2021-05-27LibJS: Make sure aligned_alloc() doesn't return a null pointerGunnar Beutner
The previous VERIFY() call checked that aligned_alloc() didn't return MAP_FAILED. When out of memory aligned_alloc() returns a null pointer so let's check for that instead.
2021-05-27LibJS: Remove unused HeapBlock::operator delete()Andreas Kling
2021-05-27LibJS: Make BlockAllocator use free() on non-Serenity platformsAndreas Kling
If we use aligned_alloc() to allocate, we have to use free() to free.
2021-05-27LibJS: Rename Allocator => CellAllocatorAndreas Kling
Now that we have a BlockAllocator as well, it seems appropriate to name the allocator-that-allocates-cells something more specific to match.
2021-05-27LibJS: Recycle up to 64 HeapBlocks to improve performance :^)Andreas Kling
This patch adds a BlockAllocator to the GC heap where we now cache up to 64 HeapBlock-sized mmap's that get recycled when allocating HeapBlocks. This improves test-js runtime performance by ~35%, pretty cool! :^)
2021-05-25LibJS: Fix broken dbgln_if(HEAP_DEBUG)Andreas Kling
2021-05-25LibJS: Fix clang-tidy warnings about redundant types in Heap.cppAndreas Kling
2021-05-25LibJS: Make Value::as_cell() return a Cell&Andreas Kling
2021-05-25LibJS: Make Cell::Visitor::visit_impl() take a Cell&Andreas Kling
Passing a null cell pointer is not supported.
2021-05-25LibJS: Replace Cell live bit with a cell stateAndreas Kling
So far we only have two states: Live and Dead. In the future, we can add additional states to support incremental sweeping and/or multi- stage cell destruction.