/* -*- 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/. */

#include "jspropertytree.h"

#include "jstypes.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsgc.h"

#include "vm/Shape.h"

#include "jsgcinlines.h"

#include "vm/Shape-inl.h"

using namespace js;

inline HashNumber
ShapeHasher::hash(const Lookup &l)
{
    return l.hash();
}

inline bool
ShapeHasher::match(const Key k, const Lookup &l)
{
    return k->matches(l);
}

Shape *
PropertyTree::newShape(JSContext *cx)
{
    Shape *shape = js_NewGCShape(cx);
    if (!shape)
        JS_ReportOutOfMemory(cx);
    return shape;
}

static KidsHash *
HashChildren(Shape *kid1, Shape *kid2)
{
    KidsHash *hash = js_new<KidsHash>();
    if (!hash || !hash->init(2)) {
        js_delete(hash);
        return NULL;
    }

    JS_ALWAYS_TRUE(hash->putNew(kid1, kid1));
    JS_ALWAYS_TRUE(hash->putNew(kid2, kid2));
    return hash;
}

bool
PropertyTree::insertChild(JSContext *cx, Shape *parent, Shape *child)
{
    JS_ASSERT(!parent->inDictionary());
    JS_ASSERT(!child->parent);
    JS_ASSERT(!child->inDictionary());
    JS_ASSERT(cx->compartment() == compartment);
    JS_ASSERT(child->compartment() == parent->compartment());

    KidsPointer *kidp = &parent->kids;

    if (kidp->isNull()) {
        child->setParent(parent);
        kidp->setShape(child);
        return true;
    }

    if (kidp->isShape()) {
        Shape *shape = kidp->toShape();
        JS_ASSERT(shape != child);
        JS_ASSERT(!shape->matches(child));

        KidsHash *hash = HashChildren(shape, child);
        if (!hash) {
            JS_ReportOutOfMemory(cx);
            return false;
        }
        kidp->setHash(hash);
        child->setParent(parent);
        return true;
    }

    if (!kidp->toHash()->putNew(child, child)) {
        JS_ReportOutOfMemory(cx);
        return false;
    }

    child->setParent(parent);
    return true;
}

void
Shape::removeChild(Shape *child)
{
    JS_ASSERT(!child->inDictionary());
    JS_ASSERT(child->parent == this);

    KidsPointer *kidp = &kids;

    if (kidp->isShape()) {
        JS_ASSERT(kidp->toShape() == child);
        kidp->setNull();
        child->parent = NULL;
        return;
    }

    KidsHash *hash = kidp->toHash();
    JS_ASSERT(hash->count() >= 2);      /* otherwise kidp->isShape() should be true */

    hash->remove(child);
    child->parent = NULL;

    if (hash->count() == 1) {
        /* Convert from HASH form back to SHAPE form. */
        KidsHash::Range r = hash->all();
        Shape *otherChild = r.front();
        JS_ASSERT((r.popFront(), r.empty()));    /* No more elements! */
        kidp->setShape(otherChild);
        js_delete(hash);
    }
}

Shape *
PropertyTree::getChild(JSContext *cx, Shape *parent_, uint32_t nfixed, const StackShape &child)
{
    {
        Shape *shape = NULL;

        JS_ASSERT(parent_);

        /*
         * The property tree has extremely low fan-out below its root in
         * popular embeddings with real-world workloads. Patterns such as
         * defining closures that capture a constructor's environment as
         * getters or setters on the new object that is passed in as
         * |this| can significantly increase fan-out below the property
         * tree root -- see bug 335700 for details.
         */
        KidsPointer *kidp = &parent_->kids;
        if (kidp->isShape()) {
            Shape *kid = kidp->toShape();
            if (kid->matches(child))
                shape = kid;
        } else if (kidp->isHash()) {
            if (KidsHash::Ptr p = kidp->toHash()->lookup(child))
                shape = *p;
        } else {
            /* If kidp->isNull(), we always insert. */
        }

#ifdef JSGC_INCREMENTAL
        if (shape) {
            JS::Zone *zone = shape->zone();
            if (zone->needsBarrier()) {
                /*
                 * We need a read barrier for the shape tree, since these are weak
                 * pointers.
                 */
                Shape *tmp = shape;
                MarkShapeUnbarriered(zone->barrierTracer(), &tmp, "read barrier");
                JS_ASSERT(tmp == shape);
            } else if (zone->isGCSweeping() && !shape->isMarked() &&
                       !shape->arenaHeader()->allocatedDuringIncremental)
            {
                /*
                 * The shape we've found is unreachable and due to be finalized, so
                 * remove our weak reference to it and don't use it.
                 */
                JS_ASSERT(parent_->isMarked());
                parent_->removeChild(shape);
                shape = NULL;
            }
        }
#endif

        if (shape)
            return shape;
    }

    StackShape::AutoRooter childRoot(cx, &child);
    RootedShape parent(cx, parent_);

    Shape *shape = newShape(cx);
    if (!shape)
        return NULL;

    new (shape) Shape(child, nfixed);

    if (!insertChild(cx, parent, shape))
        return NULL;

    return shape;
}

void
Shape::sweep()
{
    if (inDictionary())
        return;

    /*
     * We detach the child from the parent if the parent is reachable.
     *
     * Note that due to incremental sweeping, the parent pointer may point
     * to the original reachable parent, or it may point to a new live
     * object allocated in the same cell that used to hold the parent.
     *
     * There are three cases:
     *
     * Case 1: parent is not marked - parent is unreachable, may have been
     *         finalized, and the cell may subsequently have been
     *         reallocated to a compartment that is not being marked (cells
     *         are marked when allocated in a compartment that is currenly
     *         being marked by the collector).
     *
     * Case 2: parent is marked and is in a different compartment - parent
     *         has been freed and reallocated to compartment that was being
     *         marked.
     *
     * Case 3: parent is marked and is in the same compartment - parent is
     *         stil reachable and we need to detach from it.
     */
    if (parent && parent->isMarked() && parent->compartment() == compartment())
        parent->removeChild(this);
}

void
Shape::finalize(FreeOp *fop)
{
    if (!inDictionary() && kids.isHash())
        fop->delete_(kids.toHash());
}

#ifdef DEBUG

void
KidsPointer::checkConsistency(Shape *aKid) const
{
    if (isShape()) {
        JS_ASSERT(toShape() == aKid);
    } else {
        JS_ASSERT(isHash());
        KidsHash *hash = toHash();
        KidsHash::Ptr ptr = hash->lookup(aKid);
        JS_ASSERT(*ptr == aKid);
    }
}

void
Shape::dump(JSContext *cx, FILE *fp) const
{
    jsid propid = this->propid();

    JS_ASSERT(!JSID_IS_VOID(propid));

    if (JSID_IS_INT(propid)) {
        fprintf(fp, "[%ld]", (long) JSID_TO_INT(propid));
    } else {
        JSLinearString *str;
        if (JSID_IS_ATOM(propid)) {
            str = JSID_TO_ATOM(propid);
        } else {
            JS_ASSERT(JSID_IS_OBJECT(propid));
            RootedValue v(cx, IdToValue(propid));
            JSString *s = ToStringSlow<CanGC>(cx, v);
            fputs("object ", fp);
            str = s ? s->ensureLinear(cx) : NULL;
        }
        if (!str)
            fputs("<error>", fp);
        else
            FileEscapedString(fp, str, '"');
    }

    fprintf(fp, " g/s %p/%p slot %d attrs %x ",
            JS_FUNC_TO_DATA_PTR(void *, base()->rawGetter),
            JS_FUNC_TO_DATA_PTR(void *, base()->rawSetter),
            hasSlot() ? slot() : -1, attrs);

    if (attrs) {
        int first = 1;
        fputs("(", fp);
#define DUMP_ATTR(name, display) if (attrs & JSPROP_##name) fputs(&(" " #display)[first], fp), first = 0
        DUMP_ATTR(ENUMERATE, enumerate);
        DUMP_ATTR(READONLY, readonly);
        DUMP_ATTR(PERMANENT, permanent);
        DUMP_ATTR(GETTER, getter);
        DUMP_ATTR(SETTER, setter);
        DUMP_ATTR(SHARED, shared);
#undef  DUMP_ATTR
        fputs(") ", fp);
    }

    fprintf(fp, "flags %x ", flags);
    if (flags) {
        int first = 1;
        fputs("(", fp);
#define DUMP_FLAG(name, display) if (flags & name) fputs(&(" " #display)[first], fp), first = 0
        DUMP_FLAG(HAS_SHORTID, has_shortid);
        DUMP_FLAG(IN_DICTIONARY, in_dictionary);
#undef  DUMP_FLAG
        fputs(") ", fp);
    }

    fprintf(fp, "shortid %d\n", maybeShortid());
}

void
Shape::dumpSubtree(JSContext *cx, int level, FILE *fp) const
{
    if (!parent) {
        JS_ASSERT(level == 0);
        JS_ASSERT(JSID_IS_EMPTY(propid_));
        fprintf(fp, "class %s emptyShape\n", getObjectClass()->name);
    } else {
        fprintf(fp, "%*sid ", level, "");
        dump(cx, fp);
    }

    if (!kids.isNull()) {
        ++level;
        if (kids.isShape()) {
            Shape *kid = kids.toShape();
            JS_ASSERT(kid->parent == this);
            kid->dumpSubtree(cx, level, fp);
        } else {
            const KidsHash &hash = *kids.toHash();
            for (KidsHash::Range range = hash.all(); !range.empty(); range.popFront()) {
                Shape *kid = range.front();

                JS_ASSERT(kid->parent == this);
                kid->dumpSubtree(cx, level, fp);
            }
        }
    }
}

void
js::PropertyTree::dumpShapes(JSRuntime *rt)
{
#if defined(STARBOARD)
    return;
#else
    static bool init = false;
    static FILE *dumpfp = NULL;
    if (!init) {
        init = true;
        const char *name = getenv("JS_DUMP_SHAPES_FILE");
        if (!name)
            return;
        dumpfp = fopen(name, "a");
    }

    if (!dumpfp)
        return;

    fprintf(dumpfp, "rt->gcNumber = %lu", (unsigned long)rt->gcNumber);

    for (gc::GCCompartmentsIter c(rt); !c.done(); c.next()) {
        fprintf(dumpfp, "*** Compartment %p ***\n", (void *)c.get());

        /*
        typedef JSCompartment::EmptyShapeSet HS;
        HS &h = c->emptyShapes;
        for (HS::Range r = h.all(); !r.empty(); r.popFront()) {
            Shape *empty = r.front();
            empty->dumpSubtree(rt, 0, dumpfp);
            putc('\n', dumpfp);
        }
        */
    }
#endif
}
#endif
