summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/WeakBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap/WeakBlock.cpp')
-rw-r--r--Source/JavaScriptCore/heap/WeakBlock.cpp75
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;
}