1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/frontend/ParseMaps.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,136 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "frontend/ParseMaps-inl.h" 1.11 + 1.12 +#include "jscntxt.h" 1.13 + 1.14 +#include "frontend/FullParseHandler.h" 1.15 +#include "frontend/SyntaxParseHandler.h" 1.16 + 1.17 +using namespace js; 1.18 +using namespace js::frontend; 1.19 + 1.20 +void 1.21 +ParseMapPool::checkInvariants() 1.22 +{ 1.23 + /* 1.24 + * Having all values be of the same size permits us to easily reuse the 1.25 + * allocated space for each of the map types. 1.26 + */ 1.27 + JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(jsatomid)); 1.28 + JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(DefinitionList)); 1.29 + JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomIndexMap::Entry)); 1.30 + JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomDefnListMap::Entry)); 1.31 + JS_STATIC_ASSERT(sizeof(AtomMapT::Entry) == sizeof(AtomDefnListMap::Entry)); 1.32 + /* Ensure that the HasTable::clear goes quickly via memset. */ 1.33 + JS_STATIC_ASSERT(mozilla::IsPod<AtomIndexMap::WordMap::Entry>::value); 1.34 + JS_STATIC_ASSERT(mozilla::IsPod<AtomDefnListMap::WordMap::Entry>::value); 1.35 + JS_STATIC_ASSERT(mozilla::IsPod<AtomDefnMap::WordMap::Entry>::value); 1.36 +} 1.37 + 1.38 +void 1.39 +ParseMapPool::purgeAll() 1.40 +{ 1.41 + for (void **it = all.begin(), **end = all.end(); it != end; ++it) 1.42 + js_delete<AtomMapT>(asAtomMap(*it)); 1.43 + 1.44 + all.clearAndFree(); 1.45 + recyclable.clearAndFree(); 1.46 +} 1.47 + 1.48 +void * 1.49 +ParseMapPool::allocateFresh() 1.50 +{ 1.51 + size_t newAllLength = all.length() + 1; 1.52 + if (!all.reserve(newAllLength) || !recyclable.reserve(newAllLength)) 1.53 + return nullptr; 1.54 + 1.55 + AtomMapT *map = js_new<AtomMapT>(); 1.56 + if (!map) 1.57 + return nullptr; 1.58 + 1.59 + all.infallibleAppend(map); 1.60 + return (void *) map; 1.61 +} 1.62 + 1.63 +DefinitionList::Node * 1.64 +DefinitionList::allocNode(ExclusiveContext *cx, LifoAlloc &alloc, uintptr_t head, Node *tail) 1.65 +{ 1.66 + Node *result = alloc.new_<Node>(head, tail); 1.67 + if (!result) 1.68 + js_ReportOutOfMemory(cx); 1.69 + return result; 1.70 +} 1.71 + 1.72 +#ifdef DEBUG 1.73 +template <typename ParseHandler> 1.74 +void 1.75 +AtomDecls<ParseHandler>::dump() 1.76 +{ 1.77 + for (AtomDefnListRange r = map->all(); !r.empty(); r.popFront()) { 1.78 + fprintf(stderr, "atom: "); 1.79 + js_DumpAtom(r.front().key()); 1.80 + const DefinitionList &dlist = r.front().value(); 1.81 + for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) { 1.82 + fprintf(stderr, " defn: %p\n", (void *) dr.front<ParseHandler>()); 1.83 + } 1.84 + } 1.85 +} 1.86 + 1.87 +void 1.88 +DumpAtomDefnMap(const AtomDefnMapPtr &map) 1.89 +{ 1.90 + if (map->empty()) { 1.91 + fprintf(stderr, "empty\n"); 1.92 + return; 1.93 + } 1.94 + 1.95 + for (AtomDefnRange r = map->all(); !r.empty(); r.popFront()) { 1.96 + fprintf(stderr, "atom: "); 1.97 + js_DumpAtom(r.front().key()); 1.98 + fprintf(stderr, "defn: %p\n", (void *) r.front().value().get<FullParseHandler>()); 1.99 + } 1.100 +} 1.101 +#endif 1.102 + 1.103 +template <typename ParseHandler> 1.104 +bool 1.105 +AtomDecls<ParseHandler>::addShadow(JSAtom *atom, typename ParseHandler::DefinitionNode defn) 1.106 +{ 1.107 + AtomDefnListAddPtr p = map->lookupForAdd(atom); 1.108 + if (!p) 1.109 + return map->add(p, atom, DefinitionList(ParseHandler::definitionToBits(defn))); 1.110 + 1.111 + return p.value().pushFront<ParseHandler>(cx, alloc, defn); 1.112 +} 1.113 + 1.114 +void 1.115 +frontend::InitAtomMap(frontend::AtomIndexMap *indices, HeapPtrAtom *atoms) 1.116 +{ 1.117 + if (indices->isMap()) { 1.118 + typedef AtomIndexMap::WordMap WordMap; 1.119 + const WordMap &wm = indices->asMap(); 1.120 + for (WordMap::Range r = wm.all(); !r.empty(); r.popFront()) { 1.121 + JSAtom *atom = r.front().key(); 1.122 + jsatomid index = r.front().value(); 1.123 + JS_ASSERT(index < indices->count()); 1.124 + atoms[index].init(atom); 1.125 + } 1.126 + } else { 1.127 + for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd(); 1.128 + it != end; ++it) { 1.129 + JSAtom *atom = it->key; 1.130 + if (!atom) 1.131 + continue; 1.132 + JS_ASSERT(it->value < indices->count()); 1.133 + atoms[it->value].init(atom); 1.134 + } 1.135 + } 1.136 +} 1.137 + 1.138 +template class js::frontend::AtomDecls<FullParseHandler>; 1.139 +template class js::frontend::AtomDecls<SyntaxParseHandler>;