X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..93a3786624b2768d89bfa27e46598dc64e2fb70a:/parser/ParserArena.cpp diff --git a/parser/ParserArena.cpp b/parser/ParserArena.cpp index 2617506..c53f307 100644 --- a/parser/ParserArena.cpp +++ b/parser/ParserArena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2010 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,12 +27,39 @@ #include "ParserArena.h" #include "Nodes.h" +#include namespace JSC { +ParserArena::ParserArena() + : m_freeableMemory(0) + , m_freeablePoolEnd(0) +{ +} + +inline void* ParserArena::freeablePool() +{ + ASSERT(m_freeablePoolEnd); + return m_freeablePoolEnd - freeablePoolSize; +} + +inline void ParserArena::deallocateObjects() +{ + size_t size = m_deletableObjects.size(); + for (size_t i = 0; i < size; ++i) + m_deletableObjects[i]->~ParserArenaDeletable(); + + if (m_freeablePoolEnd) + fastFree(freeablePool()); + + size = m_freeablePools.size(); + for (size_t i = 0; i < size; ++i) + fastFree(m_freeablePools[i]); +} + ParserArena::~ParserArena() { - deleteAllValues(m_deletableObjects); + deallocateObjects(); } bool ParserArena::contains(ParserArenaRefCounted* object) const @@ -52,9 +79,44 @@ void ParserArena::removeLast() void ParserArena::reset() { - deleteAllValues(m_deletableObjects); - m_deletableObjects.shrink(0); - m_refCountedObjects.shrink(0); + // Since this code path is used only when parsing fails, it's not bothering to reuse + // any of the memory the arena allocated. We could improve that later if we want to + // efficiently reuse the same arena. + + deallocateObjects(); + + m_freeableMemory = 0; + m_freeablePoolEnd = 0; + if (m_identifierArena) + m_identifierArena->clear(); + m_freeablePools.clear(); + m_deletableObjects.clear(); + m_refCountedObjects.clear(); +} + +void ParserArena::allocateFreeablePool() +{ + if (m_freeablePoolEnd) + m_freeablePools.append(freeablePool()); + + char* pool = static_cast(fastMalloc(freeablePoolSize)); + m_freeableMemory = pool; + m_freeablePoolEnd = pool + freeablePoolSize; + ASSERT(freeablePool() == pool); +} + +bool ParserArena::isEmpty() const +{ + return !m_freeablePoolEnd + && (!m_identifierArena || m_identifierArena->isEmpty()) + && m_freeablePools.isEmpty() + && m_deletableObjects.isEmpty() + && m_refCountedObjects.isEmpty(); +} + +void ParserArena::derefWithArena(PassRefPtr object) +{ + m_refCountedObjects.append(object); } }