From 32761a6cee1d0dee366b885b7b9c777e67885688 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Sun, 10 Apr 2016 09:28:39 +0000 Subject: webkitgtk-2.4.11 --- Source/JavaScriptCore/heap/CodeBlockSet.cpp | 143 ++++++++++++---------------- 1 file changed, 61 insertions(+), 82 deletions(-) (limited to 'Source/JavaScriptCore/heap/CodeBlockSet.cpp') 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 namespace JSC { static const bool verbose = false; -CodeBlockSet::CodeBlockSet() -{ -} +CodeBlockSet::CodeBlockSet() { } CodeBlockSet::~CodeBlockSet() { + HashSet::iterator iter = m_set.begin(); + HashSet::iterator end = m_set.end(); + for (; iter != end; ++iter) + (*iter)->deref(); } -void CodeBlockSet::add(CodeBlock* codeBlock) +void CodeBlockSet::add(PassRefPtr 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::iterator iter = m_set.begin(); + HashSet::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 toRemove; + if (verbose) + dataLog("Fixpointing over unmarked, set size = ", m_set.size(), "...\n"); + for (;;) { + HashSet::iterator iter = m_set.begin(); + HashSet::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& set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks; - Vector unmarked; - for (CodeBlock* codeBlock : set) { - if (Heap::isMarked(codeBlock)) + if (verbose) + dataLog("Tracing ", m_set.size(), " code blocks.\n"); + HashSet::iterator iter = m_set.begin(); + HashSet::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(candidateCodeBlock); - if (!HashSet::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 -- cgit v1.2.1