1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "frontend/ParseMaps-inl.h"
11 #include "frontend/FullParseHandler.h"
12 #include "frontend/SyntaxParseHandler.h"
15 using namespace js::frontend
;
18 ParseMapPool::checkInvariants()
21 * Having all values be of the same size permits us to easily reuse the
22 * allocated space for each of the map types.
24 JS_STATIC_ASSERT(sizeof(Definition
*) == sizeof(jsatomid
));
25 JS_STATIC_ASSERT(sizeof(Definition
*) == sizeof(DefinitionList
));
26 JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry
) == sizeof(AtomIndexMap::Entry
));
27 JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry
) == sizeof(AtomDefnListMap::Entry
));
28 JS_STATIC_ASSERT(sizeof(AtomMapT::Entry
) == sizeof(AtomDefnListMap::Entry
));
29 /* Ensure that the HasTable::clear goes quickly via memset. */
30 JS_STATIC_ASSERT(mozilla::IsPod
<AtomIndexMap::WordMap::Entry
>::value
);
31 JS_STATIC_ASSERT(mozilla::IsPod
<AtomDefnListMap::WordMap::Entry
>::value
);
32 JS_STATIC_ASSERT(mozilla::IsPod
<AtomDefnMap::WordMap::Entry
>::value
);
36 ParseMapPool::purgeAll()
38 for (void **it
= all
.begin(), **end
= all
.end(); it
!= end
; ++it
)
39 js_delete
<AtomMapT
>(asAtomMap(*it
));
42 recyclable
.clearAndFree();
46 ParseMapPool::allocateFresh()
48 size_t newAllLength
= all
.length() + 1;
49 if (!all
.reserve(newAllLength
) || !recyclable
.reserve(newAllLength
))
52 AtomMapT
*map
= js_new
<AtomMapT
>();
56 all
.infallibleAppend(map
);
60 DefinitionList::Node
*
61 DefinitionList::allocNode(ExclusiveContext
*cx
, LifoAlloc
&alloc
, uintptr_t head
, Node
*tail
)
63 Node
*result
= alloc
.new_
<Node
>(head
, tail
);
65 js_ReportOutOfMemory(cx
);
70 template <typename ParseHandler
>
72 AtomDecls
<ParseHandler
>::dump()
74 for (AtomDefnListRange r
= map
->all(); !r
.empty(); r
.popFront()) {
75 fprintf(stderr
, "atom: ");
76 js_DumpAtom(r
.front().key());
77 const DefinitionList
&dlist
= r
.front().value();
78 for (DefinitionList::Range dr
= dlist
.all(); !dr
.empty(); dr
.popFront()) {
79 fprintf(stderr
, " defn: %p\n", (void *) dr
.front
<ParseHandler
>());
85 DumpAtomDefnMap(const AtomDefnMapPtr
&map
)
88 fprintf(stderr
, "empty\n");
92 for (AtomDefnRange r
= map
->all(); !r
.empty(); r
.popFront()) {
93 fprintf(stderr
, "atom: ");
94 js_DumpAtom(r
.front().key());
95 fprintf(stderr
, "defn: %p\n", (void *) r
.front().value().get
<FullParseHandler
>());
100 template <typename ParseHandler
>
102 AtomDecls
<ParseHandler
>::addShadow(JSAtom
*atom
, typename
ParseHandler::DefinitionNode defn
)
104 AtomDefnListAddPtr p
= map
->lookupForAdd(atom
);
106 return map
->add(p
, atom
, DefinitionList(ParseHandler::definitionToBits(defn
)));
108 return p
.value().pushFront
<ParseHandler
>(cx
, alloc
, defn
);
112 frontend::InitAtomMap(frontend::AtomIndexMap
*indices
, HeapPtrAtom
*atoms
)
114 if (indices
->isMap()) {
115 typedef AtomIndexMap::WordMap WordMap
;
116 const WordMap
&wm
= indices
->asMap();
117 for (WordMap::Range r
= wm
.all(); !r
.empty(); r
.popFront()) {
118 JSAtom
*atom
= r
.front().key();
119 jsatomid index
= r
.front().value();
120 JS_ASSERT(index
< indices
->count());
121 atoms
[index
].init(atom
);
124 for (const AtomIndexMap::InlineElem
*it
= indices
->asInline(), *end
= indices
->inlineEnd();
126 JSAtom
*atom
= it
->key
;
129 JS_ASSERT(it
->value
< indices
->count());
130 atoms
[it
->value
].init(atom
);
135 template class js::frontend::AtomDecls
<FullParseHandler
>;
136 template class js::frontend::AtomDecls
<SyntaxParseHandler
>;