Bug 910771 (part 4) - Move all the methods of EncapsulatedValue, HeapValue, RelocatableValue, and HeapSlot from gc/Barrier-inl.h to gc/Barrier.h. r=terrence.

This commit is contained in:
Nicholas Nethercote 2013-09-04 20:34:22 -07:00
Родитель 519a3c2851
Коммит 9339a831e1
6 изменённых файлов: 350 добавлений и 403 удалений

Просмотреть файл

@ -18,15 +18,6 @@
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()
@ -53,353 +44,6 @@ RelocatablePtr<T>::relocate(JSRuntime *rt)
#endif
}
inline
EncapsulatedValue::~EncapsulatedValue()
{
pre();
}
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() && runtimeFromAnyThread(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(), runtimeFromMainThread(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 ||
zone->runtimeFromAnyThread()->isAtomsZone(ZoneOfValue(value)));
}
#endif
pre(zone);
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(zone->runtimeFromAnyThread());
}
inline void
HeapValue::writeBarrierPost(const Value &value, Value *addr)
{
#ifdef JSGC_GENERATIONAL
if (value.isMarkable())
runtimeFromMainThread(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(runtimeFromMainThread(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 = runtimeFromMainThread(value);
relocate(rt);
value = v;
} 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 = runtimeFromMainThread(value);
relocate(rt);
value = v.value;
} else {
value = v.value;
}
return *this;
}
inline void
RelocatableValue::post()
{
#ifdef JSGC_GENERATIONAL
JS_ASSERT(value.isMarkable());
runtimeFromMainThread(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, v);
}
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, s);
}
inline
HeapSlot::~HeapSlot()
{
pre();
}
inline void
HeapSlot::init(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
value = v;
post(obj, kind, slot, v);
}
inline void
HeapSlot::init(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot, const Value &v)
{
value = v;
post(rt, obj, kind, slot, v);
}
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, v);
}
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->runtimeFromAnyThread(), obj, kind, slot, v);
}
inline void
HeapSlot::writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target)
{
#ifdef JSGC_GENERATIONAL
writeBarrierPost(obj->runtimeFromAnyThread(), obj, kind, slot, target);
#endif
}
inline void
HeapSlot::writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot, Value target)
{
#ifdef JSGC_GENERATIONAL
JS_ASSERT_IF(kind == Slot, obj->getSlotAddressUnchecked(slot)->get() == target);
JS_ASSERT_IF(kind == Element,
static_cast<HeapSlot *>(obj->getDenseElements() + slot)->get() == target);
if (target.isObject())
rt->gcStoreBuffer.putSlot(obj, kind, slot, &target.toObject());
#endif
}
inline void
HeapSlot::post(JSObject *owner, Kind kind, uint32_t slot, Value target)
{
HeapSlot::writeBarrierPost(owner, kind, slot, target);
}
inline void
HeapSlot::post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, Value target)
{
HeapSlot::writeBarrierPost(rt, owner, kind, slot, target);
}
#ifdef JSGC_GENERATIONAL
class DenseRangeRef : public gc::BufferableRef
{
@ -449,7 +93,6 @@ HashTableWriteBarrierPost(JSRuntime *rt, Map *map, const Key &key)
#endif
}
inline
EncapsulatedId::~EncapsulatedId()
{

54
js/src/gc/Barrier.cpp Normal file
Просмотреть файл

@ -0,0 +1,54 @@
/* -*- 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 "gc/Barrier.h"
#include "jsobj.h"
#include "vm/ObjectImpl-inl.h"
namespace js {
#ifdef DEBUG
bool
HeapValue::preconditionForSet(Zone *zone)
{
if (!value.isMarkable())
return true;
return ZoneOfValue(value) == zone ||
zone->runtimeFromAnyThread()->isAtomsZone(ZoneOfValue(value));
}
bool
HeapSlot::preconditionForSet(JSObject *owner, Kind kind, uint32_t slot)
{
return kind == Slot
? &owner->getSlotRef(slot) == this
: &owner->getDenseElement(slot) == (const Value *)this;
}
bool
HeapSlot::preconditionForSet(Zone *zone, JSObject *owner, Kind kind, uint32_t slot)
{
bool ok = kind == Slot
? &owner->getSlotRef(slot) == this
: &owner->getDenseElement(slot) == (const Value *)this;
return ok && owner->zone() == zone;
}
void
HeapSlot::preconditionForWriteBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target)
{
JS_ASSERT_IF(kind == Slot, obj->getSlotAddressUnchecked(slot)->get() == target);
JS_ASSERT_IF(kind == Element,
static_cast<HeapSlot *>(obj->getDenseElements() + slot)->get() == target);
}
#endif // DEBUG
} // namespace js

Просмотреть файл

@ -120,6 +120,24 @@ namespace js {
class PropertyName;
namespace gc {
// Direct value access used by the write barriers and the jits.
void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
}
JS::Zone *
ZoneOfObject(const JSObject &obj);
JS_ALWAYS_INLINE JS::Zone *
ZoneOfValue(const JS::Value &value)
{
JS_ASSERT(value.isMarkable());
if (value.isObject())
return ZoneOfObject(value.toObject());
return static_cast<js::gc::Cell *>(value.toGCThing())->tenuredZone();
}
template<class T, typename Unioned = uintptr_t>
class EncapsulatedPtr
{
@ -393,7 +411,10 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
EncapsulatedValue(const EncapsulatedValue &v) : value(v) {
JS_ASSERT(!IsPoisonedValue(v));
}
inline ~EncapsulatedValue();
~EncapsulatedValue() {
pre();
}
void init(const Value &v) {
JS_ASSERT(!IsPoisonedValue(v));
@ -404,8 +425,19 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
value = v;
}
inline EncapsulatedValue &operator=(const Value &v);
inline EncapsulatedValue &operator=(const EncapsulatedValue &v);
EncapsulatedValue &operator=(const Value &v) {
pre();
JS_ASSERT(!IsPoisonedValue(v));
value = v;
return *this;
}
EncapsulatedValue &operator=(const EncapsulatedValue &v) {
pre();
JS_ASSERT(!IsPoisonedValue(v));
value = v.get();
return *this;
}
bool operator==(const EncapsulatedValue &v) const { return value == v.value; }
bool operator!=(const EncapsulatedValue &v) const { return value != v.value; }
@ -418,12 +450,28 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
uint64_t asRawBits() const { return value.asRawBits(); }
static inline void writeBarrierPre(const Value &v);
static inline void writeBarrierPre(Zone *zone, const Value &v);
static void writeBarrierPre(const Value &v) {
#ifdef JSGC_INCREMENTAL
if (v.isMarkable() && shadowRuntimeFromAnyThread(v)->needsBarrier())
writeBarrierPre(ZoneOfValue(v), v);
#endif
}
static void writeBarrierPre(Zone *zone, const Value &v) {
#ifdef JSGC_INCREMENTAL
JS::shadow::Zone *shadowZone = JS::shadow::Zone::asShadowZone(zone);
if (shadowZone->needsBarrier()) {
JS_ASSERT_IF(v.isMarkable(), shadowRuntimeFromMainThread(v)->needsBarrier());
Value tmp(v);
js::gc::MarkValueUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier");
JS_ASSERT(tmp == v);
}
#endif
}
protected:
inline void pre();
inline void pre(Zone *zone);
void pre() { writeBarrierPre(value); }
void pre(Zone *zone) { writeBarrierPre(zone, value); }
static JSRuntime *runtimeFromMainThread(const Value &v) {
JS_ASSERT(v.isMarkable());
@ -448,16 +496,61 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
class HeapValue : public EncapsulatedValue
{
public:
explicit inline HeapValue();
explicit inline HeapValue(const Value &v);
explicit inline HeapValue(const HeapValue &v);
inline ~HeapValue();
explicit HeapValue()
: EncapsulatedValue(UndefinedValue())
{
post();
}
inline void init(const Value &v);
inline void init(JSRuntime *rt, const Value &v);
explicit HeapValue(const Value &v)
: EncapsulatedValue(v)
{
JS_ASSERT(!IsPoisonedValue(v));
post();
}
inline HeapValue &operator=(const Value &v);
inline HeapValue &operator=(const HeapValue &v);
explicit HeapValue(const HeapValue &v)
: EncapsulatedValue(v.value)
{
JS_ASSERT(!IsPoisonedValue(v.value));
post();
}
~HeapValue() {
pre();
}
void init(const Value &v) {
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post();
}
void init(JSRuntime *rt, const Value &v) {
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(rt);
}
HeapValue &operator=(const Value &v) {
pre();
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post();
return *this;
}
HeapValue &operator=(const HeapValue &v) {
pre();
JS_ASSERT(!IsPoisonedValue(v.value));
value = v.value;
post();
return *this;
}
#ifdef DEBUG
bool preconditionForSet(Zone *zone);
#endif
/*
* This is a faster version of operator=. Normally, operator= has to
@ -465,30 +558,116 @@ class HeapValue : public EncapsulatedValue
* the barrier. If you already know the compartment, it's faster to pass it
* in.
*/
inline void set(Zone *zone, const Value &v);
void set(Zone *zone, const Value &v) {
JS::shadow::Zone *shadowZone = JS::shadow::Zone::asShadowZone(zone);
JS_ASSERT(preconditionForSet(zone));
pre(zone);
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(shadowZone->runtimeFromAnyThread());
}
static inline void writeBarrierPost(const Value &v, Value *addr);
static inline void writeBarrierPost(JSRuntime *rt, const Value &v, Value *addr);
static void writeBarrierPost(const Value &value, Value *addr) {
#ifdef JSGC_GENERATIONAL
if (value.isMarkable())
shadowRuntimeFromMainThread(value)->gcStoreBufferPtr()->putValue(addr);
#endif
}
static void writeBarrierPost(JSRuntime *rt, const Value &value, Value *addr) {
#ifdef JSGC_GENERATIONAL
if (value.isMarkable()) {
JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
shadowRuntime->gcStoreBufferPtr()->putValue(addr);
}
#endif
}
private:
inline void post();
inline void post(JSRuntime *rt);
void post() {
writeBarrierPost(value, &value);
}
void post(JSRuntime *rt) {
writeBarrierPost(rt, value, &value);
}
};
class RelocatableValue : public EncapsulatedValue
{
public:
explicit inline RelocatableValue();
explicit inline RelocatableValue(const Value &v);
inline RelocatableValue(const RelocatableValue &v);
inline ~RelocatableValue();
explicit RelocatableValue()
: EncapsulatedValue(UndefinedValue())
{}
inline RelocatableValue &operator=(const Value &v);
inline RelocatableValue &operator=(const RelocatableValue &v);
explicit RelocatableValue(const Value &v)
: EncapsulatedValue(v)
{
JS_ASSERT(!IsPoisonedValue(v));
if (v.isMarkable())
post();
}
RelocatableValue(const RelocatableValue &v)
: EncapsulatedValue(v.value)
{
JS_ASSERT(!IsPoisonedValue(v.value));
if (v.value.isMarkable())
post();
}
~RelocatableValue()
{
if (value.isMarkable())
relocate(runtimeFromMainThread(value));
}
RelocatableValue &operator=(const Value &v) {
pre();
JS_ASSERT(!IsPoisonedValue(v));
if (v.isMarkable()) {
value = v;
post();
} else if (value.isMarkable()) {
JSRuntime *rt = runtimeFromMainThread(value);
relocate(rt);
value = v;
} else {
value = v;
}
return *this;
}
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 = runtimeFromMainThread(value);
relocate(rt);
value = v.value;
} else {
value = v.value;
}
return *this;
}
private:
inline void post();
inline void relocate(JSRuntime *rt);
void post() {
#ifdef JSGC_GENERATIONAL
JS_ASSERT(value.isMarkable());
shadowRuntimeFromMainThread(value)->gcStoreBufferPtr()->putRelocatableValue(&value);
#endif
}
void relocate(JSRuntime *rt) {
#ifdef JSGC_GENERATIONAL
JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
shadowRuntime->gcStoreBufferPtr()->removeRelocatableValue(&value);
#endif
}
};
class HeapSlot : public EncapsulatedValue
@ -507,24 +686,90 @@ class HeapSlot : public EncapsulatedValue
Element
};
explicit inline HeapSlot() MOZ_DELETE;
explicit inline HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const Value &v);
explicit inline HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const HeapSlot &v);
inline ~HeapSlot();
explicit HeapSlot() MOZ_DELETE;
inline void init(JSObject *owner, Kind kind, uint32_t slot, const Value &v);
inline void init(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, const Value &v);
explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
: EncapsulatedValue(v)
{
JS_ASSERT(!IsPoisonedValue(v));
post(obj, kind, slot, v);
}
inline void set(JSObject *owner, Kind kind, uint32_t slot, const Value &v);
inline void set(Zone *zone, JSObject *owner, Kind kind, uint32_t slot, const Value &v);
explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const HeapSlot &s)
: EncapsulatedValue(s.value)
{
JS_ASSERT(!IsPoisonedValue(s.value));
post(obj, kind, slot, s);
}
static inline void writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target);
static inline void writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot,
Value target);
~HeapSlot() {
pre();
}
void init(JSObject *owner, Kind kind, uint32_t slot, const Value &v) {
value = v;
post(owner, kind, slot, v);
}
void init(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, const Value &v) {
value = v;
post(rt, owner, kind, slot, v);
}
#ifdef DEBUG
bool preconditionForSet(JSObject *owner, Kind kind, uint32_t slot);
bool preconditionForSet(Zone *zone, JSObject *owner, Kind kind, uint32_t slot);
static void preconditionForWriteBarrierPost(JSObject *obj, Kind kind, uint32_t slot,
Value target);
#endif
void set(JSObject *owner, Kind kind, uint32_t slot, const Value &v) {
JS_ASSERT(preconditionForSet(owner, kind, slot));
pre();
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(owner, kind, slot, v);
}
void set(Zone *zone, JSObject *owner, Kind kind, uint32_t slot, const Value &v) {
JS_ASSERT(preconditionForSet(zone, owner, kind, slot));
JS::shadow::Zone *shadowZone = JS::shadow::Zone::asShadowZone(zone);
pre(zone);
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(shadowZone->runtimeFromAnyThread(), owner, kind, slot, v);
}
static void writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target)
{
#ifdef JSGC_GENERATIONAL
js::gc::Cell *cell = reinterpret_cast<js::gc::Cell*>(obj);
writeBarrierPost(cell->runtimeFromAnyThread(), obj, kind, slot, target);
#endif
}
static void writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot,
Value target)
{
#ifdef DEBUG
preconditionForWriteBarrierPost(obj, kind, slot, target);
#endif
#ifdef JSGC_GENERATIONAL
if (target.isObject()) {
JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
shadowRuntime->gcStoreBufferPtr()->putSlot(obj, kind, slot, &target.toObject());
}
#endif
}
private:
inline void post(JSObject *owner, Kind kind, uint32_t slot, Value target);
inline void post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, Value target);
void post(JSObject *owner, Kind kind, uint32_t slot, Value target) {
HeapSlot::writeBarrierPost(owner, kind, slot, target);
}
void post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, Value target) {
HeapSlot::writeBarrierPost(rt, owner, kind, slot, target);
}
};
/*

Просмотреть файл

@ -223,10 +223,6 @@ MarkCrossCompartmentSlot(JSTracer *trc, JSObject *src, HeapSlot *dst_slot, const
void
MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name);
/* Direct value access used by the write barriers and the methodjit. */
void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
/*
* MarkChildren<JSObject> is exposed solely for preWriteBarrier on
* JSObject::TradeGuts. It should not be considered external interface.

Просмотреть файл

@ -234,3 +234,11 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
}
#endif
}
JS::Zone *
js::ZoneOfObject(const JSObject &obj)
{
return obj.zone();
}

Просмотреть файл

@ -79,7 +79,7 @@ EXPORTS.js += [
CPP_SOURCES += [
'ArgumentsObject.cpp',
'TypedObject.cpp',
'Barrier.cpp',
'BytecodeCompiler.cpp',
'BytecodeEmitter.cpp',
'CallNonGenericMethod.cpp',
@ -136,6 +136,7 @@ CPP_SOURCES += [
'Tracer.cpp',
'TypeRepresentation.cpp',
'TypedArrayObject.cpp',
'TypedObject.cpp',
'Unicode.cpp',
'Value.cpp',
'Verifier.cpp',