#include "AutoAdmin.h"
#include "AutoBitmap.h"
#include "AutoBlockIterator.h"
#include "AutoCollector.h"
#include "AutoConfiguration.h"
#include "AutoDefs.h"
#include "AutoEnvironment.h"
#include "AutoLarge.h"
#include "AutoLock.h"
#include "AutoRange.h"
#include "AutoRegion.h"
#include "AutoStatistics.h"
#include "AutoSubzone.h"
#include "AutoMemoryScanner.h"
#include "AutoThread.h"
#include "AutoWriteBarrierIterator.h"
#include "AutoThreadLocalCollector.h"
#include "AutoZone.h"
#include "auto_weak.h"
#include "auto_trace.h"
namespace Auto {
struct dump_all_blocks_visitor {
void (^node_dump)(const void *address, unsigned long size, unsigned int layout, unsigned long refcount);
dump_all_blocks_visitor(void) {}
inline bool visit(Zone *zone, Subzone *subzone, usword_t q) {
node_dump(subzone->quantum_address(q), subzone->size(q), subzone->layout(q), subzone->refcount(q));
return true;
}
inline bool visit(Zone *zone, Large *large) {
node_dump(large->address(), large->size(), large->layout(), large->refcount());
return true;
}
};
void Zone::dump(
auto_zone_stack_dump stack_dump,
auto_zone_register_dump register_dump,
auto_zone_node_dump thread_local_node_dump, auto_zone_root_dump root_dump,
auto_zone_node_dump global_node_dump,
auto_zone_weak_dump weak_dump_entry)
{
Mutex lock(&_registered_threads_mutex);
Thread *thread = threads();
while (thread != NULL) {
if (!thread->is_current_thread() && thread->is_bound()) {
thread->suspend();
}
thread = thread->next();
}
dump_all_blocks_visitor visitor;
visitor.node_dump = global_node_dump;
visitAllocatedBlocks(this, visitor);
thread = threads();
while (thread != NULL) {
thread->dump(stack_dump, register_dump, thread_local_node_dump);
thread = thread->next();
}
if (root_dump) {
SpinLock lock(&_roots_lock);
PtrHashSet::iterator i = _roots.begin();
while (i != _roots.end()) {
root_dump((const void **)*i);
i++;
}
}
if (weak_dump_entry) {
SpinLock lock(&weak_refs_table_lock);
weak_dump_table(this, weak_dump_entry);
}
thread = threads();
while (thread != NULL) {
if (!thread->is_current_thread() && thread->is_bound()) thread->resume();
thread = thread->next();
}
}
};