PageRenderTime 30ms CodeModel.GetById 13ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/js/src/frontend/ParseMaps.cpp

http://github.com/zpao/v8monkey
C++ | 196 lines | 131 code | 20 blank | 45 comment | 28 complexity | 18fb2bbaa3d87f3cb82fa9951e656487 MD5 | raw file
  1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2 * vim: set ts=4 sw=4 et tw=99 ft=cpp:
  3 *
  4 * ***** BEGIN LICENSE BLOCK *****
  5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6 *
  7 * The contents of this file are subject to the Mozilla Public License Version
  8 * 1.1 (the "License"); you may not use this file except in compliance with
  9 * the License. You may obtain a copy of the License at
 10 * http://www.mozilla.org/MPL/
 11 *
 12 * Software distributed under the License is distributed on an "AS IS" basis,
 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 14 * for the specific language governing rights and limitations under the
 15 * License.
 16 *
 17 * The Original Code is SpiderMonkey JavaScript engine.
 18 *
 19 * The Initial Developer of the Original Code is
 20 * Mozilla Corporation.
 21 * Portions created by the Initial Developer are Copyright (C) 2011
 22 * the Initial Developer. All Rights Reserved.
 23 *
 24 * Contributor(s):
 25 *   Chris Leary <cdleary@mozilla.com>
 26 *
 27 * Alternatively, the contents of this file may be used under the terms of
 28 * either the GNU General Public License Version 2 or later (the "GPL"), or
 29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 30 * in which case the provisions of the GPL or the LGPL are applicable instead
 31 * of those above. If you wish to allow use of your version of this file only
 32 * under the terms of either the GPL or the LGPL, and not to allow others to
 33 * use your version of this file under the terms of the MPL, indicate your
 34 * decision by deleting the provisions above and replace them with the notice
 35 * and other provisions required by the GPL or the LGPL. If you do not delete
 36 * the provisions above, a recipient may use your version of this file under
 37 * the terms of any one of the MPL, the GPL or the LGPL.
 38 *
 39 * ***** END LICENSE BLOCK ***** */
 40
 41#include "ParseMaps-inl.h"
 42#include "jscompartment.h"
 43
 44using namespace js;
 45
 46void
 47ParseMapPool::checkInvariants()
 48{
 49    /*
 50     * Having all values be of the same size permits us to easily reuse the
 51     * allocated space for each of the map types.
 52     */
 53    JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(jsatomid));
 54    JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(DefnOrHeader));
 55    JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomIndexMap::Entry));
 56    JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomDOHMap::Entry));
 57    JS_STATIC_ASSERT(sizeof(AtomMapT::Entry) == sizeof(AtomDOHMap::Entry));
 58    /* Ensure that the HasTable::clear goes quickly via memset. */
 59    JS_STATIC_ASSERT(tl::IsPodType<AtomIndexMap::WordMap::Entry>::result);
 60    JS_STATIC_ASSERT(tl::IsPodType<AtomDOHMap::WordMap::Entry>::result);
 61    JS_STATIC_ASSERT(tl::IsPodType<AtomDefnMap::WordMap::Entry>::result);
 62}
 63
 64void
 65ParseMapPool::purgeAll()
 66{
 67    for (void **it = all.begin(), **end = all.end(); it != end; ++it)
 68        cx->delete_<AtomMapT>(asAtomMap(*it));
 69
 70    all.clearAndFree();
 71    recyclable.clearAndFree();
 72}
 73
 74void *
 75ParseMapPool::allocateFresh()
 76{
 77    size_t newAllLength = all.length() + 1;
 78    if (!all.reserve(newAllLength) || !recyclable.reserve(newAllLength))
 79        return NULL;
 80
 81    AtomMapT *map = cx->new_<AtomMapT>(cx);
 82    if (!map)
 83        return NULL;
 84
 85    all.infallibleAppend(map);
 86    return (void *) map;
 87}
 88
 89#ifdef DEBUG
 90void
 91AtomDecls::dump()
 92{
 93    for (AtomDOHRange r = map->all(); !r.empty(); r.popFront()) {
 94        fprintf(stderr, "atom: ");
 95        js_DumpAtom(r.front().key());
 96        const DefnOrHeader &doh = r.front().value();
 97        if (doh.isHeader()) {
 98            AtomDeclNode *node = doh.header();
 99            do {
100                fprintf(stderr, "  node: %p\n", (void *) node);
101                fprintf(stderr, "    defn: %p\n", (void *) node->defn);
102                node = node->next;
103            } while (node);
104        } else {
105            fprintf(stderr, "  defn: %p\n", (void *) doh.defn());
106        }
107    }
108}
109
110void
111DumpAtomDefnMap(const AtomDefnMapPtr &map)
112{
113    if (map->empty()) {
114        fprintf(stderr, "empty\n");
115        return;
116    }
117
118    for (AtomDefnRange r = map->all(); !r.empty(); r.popFront()) {
119        fprintf(stderr, "atom: ");
120        js_DumpAtom(r.front().key());
121        fprintf(stderr, "defn: %p\n", (void *) r.front().value());
122    }
123}
124#endif
125
126AtomDeclNode *
127AtomDecls::allocNode(Definition *defn)
128{
129    AtomDeclNode *p = cx->tempLifoAlloc().new_<AtomDeclNode>(defn);
130    if (!p) {
131        js_ReportOutOfMemory(cx);
132        return NULL;
133    }
134    return p;
135}
136
137bool
138AtomDecls::addShadow(JSAtom *atom, Definition *defn)
139{
140    AtomDeclNode *node = allocNode(defn);
141    if (!node)
142        return false;
143
144    AtomDOHAddPtr p = map->lookupForAdd(atom);
145    if (!p)
146        return map->add(p, atom, DefnOrHeader(node));
147
148    AtomDeclNode *toShadow;
149    if (p.value().isHeader()) {
150        toShadow = p.value().header();
151    } else {
152        toShadow = allocNode(p.value().defn());
153        if (!toShadow)
154            return false;
155    }
156    node->next = toShadow;
157    p.value() = DefnOrHeader(node);
158    return true;
159}
160
161AtomDeclNode *
162AtomDecls::lastAsNode(DefnOrHeader *doh)
163{
164    if (doh->isHeader()) {
165        AtomDeclNode *last = doh->header();
166        while (last->next)
167            last = last->next;
168        return last;
169    }
170
171    /* Otherwise, we need to turn the existing defn into a node. */
172    AtomDeclNode *node = allocNode(doh->defn());
173    if (!node)
174        return NULL;
175    *doh = DefnOrHeader(node);
176    return node;
177}
178
179bool
180AtomDecls::addHoist(JSAtom *atom, Definition *defn)
181{
182    AtomDeclNode *node = allocNode(defn);
183    if (!node)
184        return false;
185
186    AtomDOHAddPtr p = map->lookupForAdd(atom);
187    if (p) {
188        AtomDeclNode *last = lastAsNode(&p.value());
189        if (!last)
190            return false;
191        last->next = node;
192        return true;
193    }
194
195    return map->add(p, atom, DefnOrHeader(node));
196}