/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#ifndef SlotVisitor_h
#define SlotVisitor_h
-#include "CopiedSpace.h"
-#include "MarkStack.h"
+#include "HandleTypes.h"
+#include "MarkStackInlines.h"
+
+#include <wtf/text/StringHash.h>
namespace JSC {
+class ConservativeRoots;
+class GCThreadSharedData;
class Heap;
+template<typename T> class Weak;
+template<typename T> class WriteBarrierBase;
+template<typename T> class JITWriteBarrier;
+
+class SlotVisitor {
+ WTF_MAKE_NONCOPYABLE(SlotVisitor);
+ friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
-class SlotVisitor : public MarkStack {
- friend class HeapRootVisitor;
public:
- SlotVisitor(MarkStackThreadSharedData&);
+ SlotVisitor(GCThreadSharedData&);
+ ~SlotVisitor();
- void donate()
- {
- ASSERT(m_isInParallelMode);
- if (Options::numberOfGCMarkers == 1)
- return;
-
- donateKnownParallel();
- }
+ void append(ConservativeRoots&);
- void drain();
+ template<typename T> void append(JITWriteBarrier<T>*);
+ template<typename T> void append(WriteBarrierBase<T>*);
+ void appendValues(WriteBarrierBase<Unknown>*, size_t count);
- void donateAndDrain()
- {
- donate();
- drain();
- }
+ template<typename T>
+ void appendUnbarrieredPointer(T**);
+ void appendUnbarrieredValue(JSValue*);
+ template<typename T>
+ void appendUnbarrieredWeak(Weak<T>*);
+
+ void addOpaqueRoot(void*);
+ bool containsOpaqueRoot(void*);
+ TriState containsOpaqueRootTriState(void*);
+ int opaqueRootCount();
+
+ GCThreadSharedData& sharedData() { return m_shared; }
+ bool isEmpty() { return m_stack.isEmpty(); }
+
+ void setup();
+ void reset();
+
+ size_t visitCount() const { return m_visitCount; }
+
+ void donate();
+ void drain();
+ void donateAndDrain();
enum SharedDrainMode { SlaveDrain, MasterDrain };
void drainFromShared(SharedDrainMode);
void harvestWeakReferences();
void finalizeUnconditionalFinalizers();
- void startCopying();
- void copyAndAppend(void**, size_t, JSValue*, unsigned);
- void doneCopying();
-
+ void copyLater(JSCell*, void*, size_t);
+
+#if ENABLE(SIMPLE_HEAP_PROFILING)
+ VTableSpectrum m_visitedTypeCounts;
+#endif
+
+ void addWeakReferenceHarvester(WeakReferenceHarvester*);
+ void addUnconditionalFinalizer(UnconditionalFinalizer*);
+
+#if ENABLE(OBJECT_MARK_LOGGING)
+ inline void resetChildCount() { m_logChildCount = 0; }
+ inline unsigned childCount() { return m_logChildCount; }
+ inline void incrementChildCount() { m_logChildCount++; }
+#endif
+
private:
- void* allocateNewSpace(void*, size_t);
+ friend class ParallelModeEnabler;
+
+ JS_EXPORT_PRIVATE static void validate(JSCell*);
- void donateSlow();
+ void append(JSValue*);
+ void append(JSValue*, size_t count);
+ void append(JSCell**);
+
+ void internalAppend(JSCell*);
+ void internalAppend(JSValue);
+ void internalAppend(JSValue*);
+
+ JS_EXPORT_PRIVATE void mergeOpaqueRoots();
+ void mergeOpaqueRootsIfNecessary();
+ void mergeOpaqueRootsIfProfitable();
+
+ void donateKnownParallel();
+
+ MarkStackArray m_stack;
+ HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
+
+ size_t m_visitCount;
+ bool m_isInParallelMode;
- void donateKnownParallel()
+ GCThreadSharedData& m_shared;
+
+ bool m_shouldHashCons; // Local per-thread copy of shared flag for performance reasons
+ typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
+ UniqueStringMap m_uniqueStrings;
+
+#if ENABLE(OBJECT_MARK_LOGGING)
+ unsigned m_logChildCount;
+#endif
+
+public:
+#if !ASSERT_DISABLED
+ bool m_isCheckingForDefaultMarkViolation;
+ bool m_isDraining;
+#endif
+};
+
+class ParallelModeEnabler {
+public:
+ ParallelModeEnabler(SlotVisitor& stack)
+ : m_stack(stack)
+ {
+ ASSERT(!m_stack.m_isInParallelMode);
+ m_stack.m_isInParallelMode = true;
+ }
+
+ ~ParallelModeEnabler()
{
- if (!m_stack.canDonateSomeCells())
- return;
- donateSlow();
+ ASSERT(m_stack.m_isInParallelMode);
+ m_stack.m_isInParallelMode = false;
}
- CopiedBlock* m_copyBlock;
+private:
+ SlotVisitor& m_stack;
};
-inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared)
- : MarkStack(shared)
- , m_copyBlock(0)
-{
-}
-
} // namespace JSC
#endif // SlotVisitor_h