diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/WeakBlock.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/WeakBlock.cpp | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp index 957090569..0ac318060 100644 --- a/Source/JavaScriptCore/heap/WeakBlock.cpp +++ b/Source/JavaScriptCore/heap/WeakBlock.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,22 +26,30 @@ #include "config.h" #include "WeakBlock.h" +#include "CellContainerInlines.h" #include "Heap.h" -#include "HeapRootVisitor.h" +#include "JSCInlines.h" #include "JSObject.h" -#include "Operations.h" -#include "Structure.h" +#include "WeakHandleOwner.h" namespace JSC { -WeakBlock* WeakBlock::create(DeadBlock* block) +WeakBlock* WeakBlock::create(Heap& heap, CellContainer container) { - Region* region = block->region(); - return new (NotNull, block) WeakBlock(region); + heap.didAllocateBlock(WeakBlock::blockSize); + return new (NotNull, fastMalloc(blockSize)) WeakBlock(container); } -WeakBlock::WeakBlock(Region* region) - : HeapBlock<WeakBlock>(region) +void WeakBlock::destroy(Heap& heap, WeakBlock* block) +{ + block->~WeakBlock(); + fastFree(block); + heap.didFreeBlock(WeakBlock::blockSize); +} + +WeakBlock::WeakBlock(CellContainer container) + : DoublyLinkedListNode<WeakBlock>() + , m_container(container) { for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; @@ -76,54 +84,75 @@ void WeakBlock::sweep() finalize(weakImpl); if (weakImpl->state() == WeakImpl::Deallocated) addToFreeList(&sweepResult.freeList, weakImpl); - else + else { sweepResult.blockIsFree = false; + if (weakImpl->state() == WeakImpl::Live) + sweepResult.blockIsLogicallyEmpty = false; + } } m_sweepResult = sweepResult; ASSERT(!m_sweepResult.isNull()); } -void WeakBlock::visit(HeapRootVisitor& heapRootVisitor) +template<typename ContainerType> +void WeakBlock::specializedVisit(ContainerType& container, SlotVisitor& visitor) { - // If a block is completely empty, a visit won't have any effect. - if (isEmpty()) - return; - - SlotVisitor& visitor = heapRootVisitor.visitor(); + HeapVersion markingVersion = visitor.markingVersion(); - for (size_t i = 0; i < weakImplCount(); ++i) { + size_t count = weakImplCount(); + for (size_t i = 0; i < count; ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() != WeakImpl::Live) continue; - const JSValue& jsValue = weakImpl->jsValue(); - if (Heap::isLive(jsValue.asCell())) - continue; - WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner(); if (!weakHandleOwner) continue; + JSValue jsValue = weakImpl->jsValue(); + if (container.isMarkedConcurrently(markingVersion, jsValue.asCell())) + continue; + if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor)) continue; - heapRootVisitor.visit(&const_cast<JSValue&>(jsValue)); + visitor.appendUnbarriered(jsValue); } } +void WeakBlock::visit(SlotVisitor& visitor) +{ + // If a block is completely empty, a visit won't have any effect. + if (isEmpty()) + return; + + // If this WeakBlock doesn't belong to a CellContainer, we won't even be here. + ASSERT(m_container); + + if (m_container.isLargeAllocation()) + specializedVisit(m_container.largeAllocation(), visitor); + else + specializedVisit(m_container.markedBlock(), visitor); +} + void WeakBlock::reap() { // If a block is completely empty, a reaping won't have any effect. if (isEmpty()) return; + // If this WeakBlock doesn't belong to a CellContainer, we won't even be here. + ASSERT(m_container); + + HeapVersion markingVersion = m_container.heap()->objectSpace().markingVersion(); + for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() > WeakImpl::Dead) continue; - if (Heap::isLive(weakImpl->jsValue().asCell())) { + if (m_container.isMarked(markingVersion, weakImpl->jsValue().asCell())) { ASSERT(weakImpl->state() == WeakImpl::Live); continue; } |