diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/heap/CodeBlockSet.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/heap/CodeBlockSet.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/CodeBlockSet.cpp | 143 |
1 files changed, 61 insertions, 82 deletions
diff --git a/Source/JavaScriptCore/heap/CodeBlockSet.cpp b/Source/JavaScriptCore/heap/CodeBlockSet.cpp index 0cfcd1fed..c04cbacd6 100644 --- a/Source/JavaScriptCore/heap/CodeBlockSet.cpp +++ b/Source/JavaScriptCore/heap/CodeBlockSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,115 +27,94 @@ #include "CodeBlockSet.h" #include "CodeBlock.h" -#include "JSCInlines.h" #include "SlotVisitor.h" -#include <wtf/CommaPrinter.h> namespace JSC { static const bool verbose = false; -CodeBlockSet::CodeBlockSet() -{ -} +CodeBlockSet::CodeBlockSet() { } CodeBlockSet::~CodeBlockSet() { + HashSet<CodeBlock*>::iterator iter = m_set.begin(); + HashSet<CodeBlock*>::iterator end = m_set.end(); + for (; iter != end; ++iter) + (*iter)->deref(); } -void CodeBlockSet::add(CodeBlock* codeBlock) +void CodeBlockSet::add(PassRefPtr<CodeBlock> codeBlock) { - LockHolder locker(&m_lock); - bool isNewEntry = m_newCodeBlocks.add(codeBlock).isNewEntry; + CodeBlock* block = codeBlock.leakRef(); + bool isNewEntry = m_set.add(block).isNewEntry; ASSERT_UNUSED(isNewEntry, isNewEntry); } -void CodeBlockSet::promoteYoungCodeBlocks(const LockHolder&) -{ - ASSERT(m_lock.isLocked()); - m_oldCodeBlocks.add(m_newCodeBlocks.begin(), m_newCodeBlocks.end()); - m_newCodeBlocks.clear(); -} - -void CodeBlockSet::clearMarksForFullCollection() +void CodeBlockSet::clearMarks() { - LockHolder locker(&m_lock); - for (CodeBlock* codeBlock : m_oldCodeBlocks) - codeBlock->clearVisitWeaklyHasBeenCalled(); - - // We promote after we clear marks on the old generation CodeBlocks because - // none of the young generations CodeBlocks need to be cleared. - promoteYoungCodeBlocks(locker); + HashSet<CodeBlock*>::iterator iter = m_set.begin(); + HashSet<CodeBlock*>::iterator end = m_set.end(); + for (; iter != end; ++iter) { + CodeBlock* codeBlock = *iter; + codeBlock->m_mayBeExecuting = false; + codeBlock->m_visitAggregateHasBeenCalled = false; + } } -void CodeBlockSet::lastChanceToFinalize() +void CodeBlockSet::deleteUnmarkedAndUnreferenced() { - LockHolder locker(&m_lock); - for (CodeBlock* codeBlock : m_newCodeBlocks) - codeBlock->classInfo()->methodTable.destroy(codeBlock); - - for (CodeBlock* codeBlock : m_oldCodeBlocks) - codeBlock->classInfo()->methodTable.destroy(codeBlock); + // This needs to be a fixpoint because code blocks that are unmarked may + // refer to each other. For example, a DFG code block that is owned by + // the GC may refer to an FTL for-entry code block that is also owned by + // the GC. + Vector<CodeBlock*, 16> toRemove; + if (verbose) + dataLog("Fixpointing over unmarked, set size = ", m_set.size(), "...\n"); + for (;;) { + HashSet<CodeBlock*>::iterator iter = m_set.begin(); + HashSet<CodeBlock*>::iterator end = m_set.end(); + for (; iter != end; ++iter) { + CodeBlock* codeBlock = *iter; + if (!codeBlock->hasOneRef()) + continue; + if (codeBlock->m_mayBeExecuting) + continue; + codeBlock->deref(); + toRemove.append(codeBlock); + } + if (verbose) + dataLog(" Removing ", toRemove.size(), " blocks.\n"); + if (toRemove.isEmpty()) + break; + for (unsigned i = toRemove.size(); i--;) + m_set.remove(toRemove[i]); + toRemove.resize(0); + } } -void CodeBlockSet::deleteUnmarkedAndUnreferenced(HeapOperation collectionType) +void CodeBlockSet::traceMarked(SlotVisitor& visitor) { - LockHolder locker(&m_lock); - HashSet<CodeBlock*>& set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks; - Vector<CodeBlock*> unmarked; - for (CodeBlock* codeBlock : set) { - if (Heap::isMarked(codeBlock)) + if (verbose) + dataLog("Tracing ", m_set.size(), " code blocks.\n"); + HashSet<CodeBlock*>::iterator iter = m_set.begin(); + HashSet<CodeBlock*>::iterator end = m_set.end(); + for (; iter != end; ++iter) { + CodeBlock* codeBlock = *iter; + if (!codeBlock->m_mayBeExecuting) continue; - unmarked.append(codeBlock); + codeBlock->visitAggregate(visitor); } - - for (CodeBlock* codeBlock : unmarked) { - codeBlock->classInfo()->methodTable.destroy(codeBlock); - set.remove(codeBlock); - } - - // Any remaining young CodeBlocks are live and need to be promoted to the set of old CodeBlocks. - if (collectionType == EdenCollection) - promoteYoungCodeBlocks(locker); -} - -bool CodeBlockSet::contains(const LockHolder&, void* candidateCodeBlock) -{ - RELEASE_ASSERT(m_lock.isLocked()); - CodeBlock* codeBlock = static_cast<CodeBlock*>(candidateCodeBlock); - if (!HashSet<CodeBlock*>::isValidValue(codeBlock)) - return false; - return m_oldCodeBlocks.contains(codeBlock) || m_newCodeBlocks.contains(codeBlock) || m_currentlyExecuting.contains(codeBlock); } -void CodeBlockSet::writeBarrierCurrentlyExecutingCodeBlocks(Heap* heap) +void CodeBlockSet::rememberCurrentlyExecutingCodeBlocks(Heap* heap) { - LockHolder locker(&m_lock); - if (verbose) - dataLog("Remembering ", m_currentlyExecuting.size(), " code blocks.\n"); - for (CodeBlock* codeBlock : m_currentlyExecuting) - heap->writeBarrier(codeBlock); - - // It's safe to clear this set because we won't delete the CodeBlocks - // in it until the next GC, and we'll recompute it at that time. +#if ENABLE(GGC) + for (size_t i = 0; i < m_currentlyExecuting.size(); ++i) + heap->addToRememberedSet(m_currentlyExecuting[i]->ownerExecutable()); m_currentlyExecuting.clear(); -} - -void CodeBlockSet::dump(PrintStream& out) const -{ - CommaPrinter comma; - out.print("{old = ["); - for (CodeBlock* codeBlock : m_oldCodeBlocks) - out.print(comma, pointerDump(codeBlock)); - out.print("], new = ["); - comma = CommaPrinter(); - for (CodeBlock* codeBlock : m_newCodeBlocks) - out.print(comma, pointerDump(codeBlock)); - out.print("], currentlyExecuting = ["); - comma = CommaPrinter(); - for (CodeBlock* codeBlock : m_currentlyExecuting) - out.print(comma, pointerDump(codeBlock)); - out.print("]}"); +#else + UNUSED_PARAM(heap); +#endif // ENABLE(GGC) } } // namespace JSC |