/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef jspropertytree_h #define jspropertytree_h #include "jsalloc.h" #include "js/HashTable.h" #include "js/RootingAPI.h" namespace js { class Shape; struct StackShape; struct ShapeHasher { typedef Shape *Key; typedef StackShape Lookup; static inline HashNumber hash(const Lookup &l); static inline bool match(Key k, const Lookup &l); }; typedef HashSet KidsHash; class KidsPointer { private: enum { SHAPE = 0, HASH = 1, TAG = 1 }; uintptr_t w; public: bool isNull() const { return !w; } void setNull() { w = 0; } bool isShape() const { return (w & TAG) == SHAPE && !isNull(); } Shape *toShape() const { JS_ASSERT(isShape()); return reinterpret_cast(w & ~uintptr_t(TAG)); } void setShape(Shape *shape) { JS_ASSERT(shape); JS_ASSERT((reinterpret_cast(static_cast(shape)) & TAG) == 0); w = reinterpret_cast(static_cast(shape)) | SHAPE; } bool isHash() const { return (w & TAG) == HASH; } KidsHash *toHash() const { JS_ASSERT(isHash()); return reinterpret_cast(w & ~uintptr_t(TAG)); } void setHash(KidsHash *hash) { JS_ASSERT(hash); JS_ASSERT((reinterpret_cast(hash) & TAG) == 0); w = reinterpret_cast(hash) | HASH; } #ifdef DEBUG void checkConsistency(Shape *aKid) const; #endif }; class PropertyTree { friend class ::JSFunction; JSCompartment *compartment; bool insertChild(JSContext *cx, Shape *parent, Shape *child); PropertyTree(); public: /* * Use a lower limit for objects that are accessed using SETELEM (o[x] = y). * These objects are likely used as hashmaps and dictionary mode is more * efficient in this case. */ enum { MAX_HEIGHT = 512, MAX_HEIGHT_WITH_ELEMENTS_ACCESS = 128 }; PropertyTree(JSCompartment *comp) : compartment(comp) { } Shape *newShape(JSContext *cx); Shape *getChild(JSContext *cx, Shape *parent, uint32_t nfixed, const StackShape &child); #ifdef DEBUG static void dumpShapes(JSRuntime *rt); #endif }; } /* namespace js */ #endif /* jspropertytree_h */