/* -*- 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 gc_Barrier_inl_h
#define gc_Barrier_inl_h

#include "gc/Barrier.h"
#include "gc/Marking.h"
#include "gc/StoreBuffer.h"

#include "vm/String-inl.h"

namespace js {

JS_ALWAYS_INLINE JS::Zone *
ZoneOfValue(const JS::Value &value)
{
    JS_ASSERT(value.isMarkable());
    if (value.isObject())
        return value.toObject().zone();
    return static_cast<js::gc::Cell *>(value.toGCThing())->tenuredZone();
}

template <typename T, typename Unioned>
void
EncapsulatedPtr<T, Unioned>::pre()
{
    T::writeBarrierPre(value);
}

template <typename T>
inline void
RelocatablePtr<T>::post()
{
#ifdef JSGC_GENERATIONAL
    JS_ASSERT(this->value);
    this->value->runtime()->gcStoreBuffer.putRelocatableCell((gc::Cell **)&this->value);
#endif
}

template <typename T>
inline void
RelocatablePtr<T>::relocate(JSRuntime *rt)
{
#ifdef JSGC_GENERATIONAL
    rt->gcStoreBuffer.removeRelocatableCell((gc::Cell **)&this->value);
#endif
}

inline
EncapsulatedValue::~EncapsulatedValue()
{
    pre();
}

inline void
EncapsulatedValue::init(const Value &v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
}

inline void
EncapsulatedValue::init(JSRuntime *rt, const Value &v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
}

inline EncapsulatedValue &
EncapsulatedValue::operator=(const Value &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    return *this;
}

inline EncapsulatedValue &
EncapsulatedValue::operator=(const EncapsulatedValue &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v));
    value = v.get();
    return *this;
}

inline void
EncapsulatedValue::writeBarrierPre(const Value &value)
{
#ifdef JSGC_INCREMENTAL
    if (value.isMarkable() && runtime(value)->needsBarrier())
        writeBarrierPre(ZoneOfValue(value), value);
#endif
}

inline void
EncapsulatedValue::writeBarrierPre(Zone *zone, const Value &value)
{
#ifdef JSGC_INCREMENTAL
    if (zone->needsBarrier()) {
        JS_ASSERT_IF(value.isMarkable(), runtime(value)->needsBarrier());
        Value tmp(value);
        js::gc::MarkValueUnbarriered(zone->barrierTracer(), &tmp, "write barrier");
        JS_ASSERT(tmp == value);
    }
#endif
}

inline void
EncapsulatedValue::pre()
{
    writeBarrierPre(value);
}

inline void
EncapsulatedValue::pre(Zone *zone)
{
    writeBarrierPre(zone, value);
}

inline
HeapValue::HeapValue()
    : EncapsulatedValue(UndefinedValue())
{
    post();
}

inline
HeapValue::HeapValue(const Value &v)
    : EncapsulatedValue(v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    post();
}

inline
HeapValue::HeapValue(const HeapValue &v)
    : EncapsulatedValue(v.value)
{
    JS_ASSERT(!IsPoisonedValue(v.value));
    post();
}

inline
HeapValue::~HeapValue()
{
    pre();
}

inline void
HeapValue::init(const Value &v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post();
}

inline void
HeapValue::init(JSRuntime *rt, const Value &v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post(rt);
}

inline HeapValue &
HeapValue::operator=(const Value &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post();
    return *this;
}

inline HeapValue &
HeapValue::operator=(const HeapValue &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v.value));
    value = v.value;
    post();
    return *this;
}

inline void
HeapValue::set(Zone *zone, const Value &v)
{
#ifdef DEBUG
    if (value.isMarkable()) {
        JS_ASSERT(ZoneOfValue(value) == zone ||
                  ZoneOfValue(value) == zone->rt->atomsCompartment->zone());
    }
#endif

    pre(zone);
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post(zone->rt);
}

inline void
HeapValue::writeBarrierPost(const Value &value, Value *addr)
{
#ifdef JSGC_GENERATIONAL
    if (value.isMarkable())
        runtime(value)->gcStoreBuffer.putValue(addr);
#endif
}

inline void
HeapValue::writeBarrierPost(JSRuntime *rt, const Value &value, Value *addr)
{
#ifdef JSGC_GENERATIONAL
    if (value.isMarkable())
        rt->gcStoreBuffer.putValue(addr);
#endif
}

inline void
HeapValue::post()
{
    writeBarrierPost(value, &value);
}

inline void
HeapValue::post(JSRuntime *rt)
{
    writeBarrierPost(rt, value, &value);
}

inline
RelocatableValue::RelocatableValue()
    : EncapsulatedValue(UndefinedValue())
{
}

inline
RelocatableValue::RelocatableValue(const Value &v)
    : EncapsulatedValue(v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    if (v.isMarkable())
        post();
}

inline
RelocatableValue::RelocatableValue(const RelocatableValue &v)
    : EncapsulatedValue(v.value)
{
    JS_ASSERT(!IsPoisonedValue(v.value));
    if (v.value.isMarkable())
        post();
}

inline
RelocatableValue::~RelocatableValue()
{
    if (value.isMarkable())
        relocate(runtime(value));
}

inline RelocatableValue &
RelocatableValue::operator=(const Value &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v));
    if (v.isMarkable()) {
        value = v;
        post();
    } else if (value.isMarkable()) {
        JSRuntime *rt = runtime(value);
        value = v;
        relocate(rt);
    } else {
        value = v;
    }
    return *this;
}

inline RelocatableValue &
RelocatableValue::operator=(const RelocatableValue &v)
{
    pre();
    JS_ASSERT(!IsPoisonedValue(v.value));
    if (v.value.isMarkable()) {
        value = v.value;
        post();
    } else if (value.isMarkable()) {
        JSRuntime *rt = runtime(value);
        value = v.value;
        relocate(rt);
    } else {
        value = v.value;
    }
    return *this;
}

inline void
RelocatableValue::post()
{
#ifdef JSGC_GENERATIONAL
    JS_ASSERT(value.isMarkable());
    runtime(value)->gcStoreBuffer.putRelocatableValue(&value);
#endif
}

inline void
RelocatableValue::relocate(JSRuntime *rt)
{
#ifdef JSGC_GENERATIONAL
    rt->gcStoreBuffer.removeRelocatableValue(&value);
#endif
}

inline
HeapSlot::HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
    : EncapsulatedValue(v)
{
    JS_ASSERT(!IsPoisonedValue(v));
    post(obj, kind, slot);
}

inline
HeapSlot::HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const HeapSlot &s)
    : EncapsulatedValue(s.value)
{
    JS_ASSERT(!IsPoisonedValue(s.value));
    post(obj, kind, slot);
}

inline
HeapSlot::~HeapSlot()
{
    pre();
}

inline void
HeapSlot::init(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
    value = v;
    post(obj, kind, slot);
}

inline void
HeapSlot::init(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
    value = v;
    post(rt, obj, kind, slot);
}

inline void
HeapSlot::set(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
    JS_ASSERT_IF(kind == Slot, &obj->getSlotRef(slot) == this);
    JS_ASSERT_IF(kind == Element, &obj->getDenseElement(slot) == (const Value *)this);

    pre();
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post(obj, kind, slot);
}

inline void
HeapSlot::set(Zone *zone, JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
    JS_ASSERT_IF(kind == Slot, &obj->getSlotRef(slot) == this);
    JS_ASSERT_IF(kind == Element, &obj->getDenseElement(slot) == (const Value *)this);
    JS_ASSERT(obj->zone() == zone);

    pre(zone);
    JS_ASSERT(!IsPoisonedValue(v));
    value = v;
    post(zone->rt, obj, kind, slot);
}

inline void
HeapSlot::writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot)
{
#ifdef JSGC_GENERATIONAL
    obj->runtime()->gcStoreBuffer.putSlot(obj, kind, slot);
#endif
}

inline void
HeapSlot::writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot)
{
#ifdef JSGC_GENERATIONAL
    rt->gcStoreBuffer.putSlot(obj, kind, slot);
#endif
}

inline void
HeapSlot::post(JSObject *owner, Kind kind, uint32_t slot)
{
    HeapSlot::writeBarrierPost(owner, kind, slot);
}

inline void
HeapSlot::post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot)
{
    HeapSlot::writeBarrierPost(rt, owner, kind, slot);
}

#ifdef JSGC_GENERATIONAL
class DenseRangeRef : public gc::BufferableRef
{
    JSObject *owner;
    uint32_t start;
    uint32_t end;

  public:
    DenseRangeRef(JSObject *obj, uint32_t start, uint32_t end)
      : owner(obj), start(start), end(end)
    {
        JS_ASSERT(start < end);
    }

    void mark(JSTracer *trc) {
        /* Apply forwarding, if we have already visited owner. */
        IsObjectMarked(&owner);
        uint32_t initLen = owner->getDenseInitializedLength();
        uint32_t clampedStart = Min(start, initLen);
        gc::MarkArraySlots(trc, Min(end, initLen) - clampedStart,
                           owner->getDenseElements() + clampedStart, "element");
    }
};
#endif

inline void
DenseRangeWriteBarrierPost(JSRuntime *rt, JSObject *obj, uint32_t start, uint32_t count)
{
#ifdef JSGC_GENERATIONAL
    if (count > 0)
        rt->gcStoreBuffer.putGeneric(DenseRangeRef(obj, start, start + count));
#endif
}

/*
 * This is a post barrier for HashTables whose key can be moved during a GC.
 */
template <class Map, class Key>
inline void
HashTableWriteBarrierPost(JSRuntime *rt, Map *map, const Key &key)
{
#ifdef JSGC_GENERATIONAL
    if (key && IsInsideNursery(rt, key))
        rt->gcStoreBuffer.putGeneric(gc::HashKeyRef<Map, Key>(map, key));
#endif
}

inline
EncapsulatedId::~EncapsulatedId()
{
    pre();
}

inline EncapsulatedId &
EncapsulatedId::operator=(const EncapsulatedId &v)
{
    if (v.value != value)
        pre();
    JS_ASSERT(!IsPoisonedId(v.value));
    value = v.value;
    return *this;
}

inline void
EncapsulatedId::pre()
{
#ifdef JSGC_INCREMENTAL
    if (JSID_IS_OBJECT(value)) {
        JSObject *obj = JSID_TO_OBJECT(value);
        Zone *zone = obj->zone();
        if (zone->needsBarrier()) {
            js::gc::MarkObjectUnbarriered(zone->barrierTracer(), &obj, "write barrier");
            JS_ASSERT(obj == JSID_TO_OBJECT(value));
        }
    } else if (JSID_IS_STRING(value)) {
        JSString *str = JSID_TO_STRING(value);
        Zone *zone = str->zone();
        if (zone->needsBarrier()) {
            js::gc::MarkStringUnbarriered(zone->barrierTracer(), &str, "write barrier");
            JS_ASSERT(str == JSID_TO_STRING(value));
        }
    }
#endif
}

inline
RelocatableId::~RelocatableId()
{
    pre();
}

inline RelocatableId &
RelocatableId::operator=(jsid id)
{
    if (id != value)
        pre();
    JS_ASSERT(!IsPoisonedId(id));
    value = id;
    return *this;
}

inline RelocatableId &
RelocatableId::operator=(const RelocatableId &v)
{
    if (v.value != value)
        pre();
    JS_ASSERT(!IsPoisonedId(v.value));
    value = v.value;
    return *this;
}

inline
HeapId::HeapId(jsid id)
    : EncapsulatedId(id)
{
    JS_ASSERT(!IsPoisonedId(id));
    post();
}

inline
HeapId::~HeapId()
{
    pre();
}

inline void
HeapId::init(jsid id)
{
    JS_ASSERT(!IsPoisonedId(id));
    value = id;
    post();
}

inline void
HeapId::post()
{
}

inline HeapId &
HeapId::operator=(jsid id)
{
    if (id != value)
        pre();
    JS_ASSERT(!IsPoisonedId(id));
    value = id;
    post();
    return *this;
}

inline HeapId &
HeapId::operator=(const HeapId &v)
{
    if (v.value != value)
        pre();
    JS_ASSERT(!IsPoisonedId(v.value));
    value = v.value;
    post();
    return *this;
}

inline const Value &
ReadBarrieredValue::get() const
{
    if (value.isObject())
        JSObject::readBarrier(&value.toObject());
    else if (value.isString())
        JSString::readBarrier(value.toString());
    else
        JS_ASSERT(!value.isMarkable());

    return value;
}

inline
ReadBarrieredValue::operator const Value &() const
{
    return get();
}

inline JSObject &
ReadBarrieredValue::toObject() const
{
    return get().toObject();
}

} /* namespace js */

#endif /* gc_Barrier_inl_h */
