зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1024250; r=billm
This commit is contained in:
Родитель
9bc76bfb73
Коммит
68b8d91b1f
|
@ -151,12 +151,40 @@
|
|||
*/
|
||||
|
||||
class JSAtom;
|
||||
struct JSCompartment;
|
||||
class JSFlatString;
|
||||
class JSLinearString;
|
||||
|
||||
namespace JS {
|
||||
class Symbol;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
class ArgumentsObject;
|
||||
class ArrayBufferObject;
|
||||
class ArrayBufferViewObject;
|
||||
class SharedArrayBufferObject;
|
||||
class BaseShape;
|
||||
class DebugScopeObject;
|
||||
class GlobalObject;
|
||||
class LazyScript;
|
||||
class Nursery;
|
||||
class ObjectImpl;
|
||||
class PropertyName;
|
||||
class SavedFrame;
|
||||
class ScopeObject;
|
||||
class ScriptSourceObject;
|
||||
class Shape;
|
||||
class UnownedBaseShape;
|
||||
|
||||
namespace types {
|
||||
struct TypeObject;
|
||||
}
|
||||
|
||||
namespace jit {
|
||||
class JitCode;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
|
@ -173,6 +201,32 @@ StringIsPermanentAtom(JSString *str);
|
|||
|
||||
namespace gc {
|
||||
|
||||
template <typename T> struct MapTypeToTraceKind {};
|
||||
template <> struct MapTypeToTraceKind<ArgumentsObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ArrayBufferViewObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<BaseShape> { static const JSGCTraceKind kind = JSTRACE_BASE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<DebugScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<GlobalObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JS::Symbol> { static const JSGCTraceKind kind = JSTRACE_SYMBOL; };
|
||||
template <> struct MapTypeToTraceKind<JSAtom> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSFlatString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSFunction> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSLinearString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSScript> { static const JSGCTraceKind kind = JSTRACE_SCRIPT; };
|
||||
template <> struct MapTypeToTraceKind<JSString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<LazyScript> { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
|
||||
template <> struct MapTypeToTraceKind<ObjectImpl> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<SavedFrame> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<Shape> { static const JSGCTraceKind kind = JSTRACE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<SharedArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<UnownedBaseShape> { static const JSGCTraceKind kind = JSTRACE_BASE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<jit::JitCode> { static const JSGCTraceKind kind = JSTRACE_JITCODE; };
|
||||
template <> struct MapTypeToTraceKind<types::TypeObject>{ static const JSGCTraceKind kind = JSTRACE_TYPE_OBJECT; };
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MarkUnbarriered(JSTracer *trc, T **thingp, const char *name);
|
||||
|
@ -206,6 +260,7 @@ class BarrieredCell : public gc::Cell
|
|||
static MOZ_ALWAYS_INLINE void readBarrier(T *thing) {
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
JS_ASSERT(!CurrentThreadIsIonCompiling());
|
||||
JS_ASSERT(!T::isNullLike(thing));
|
||||
JS::shadow::Zone *shadowZone = thing->shadowZoneFromAnyThread();
|
||||
if (shadowZone->needsIncrementalBarrier()) {
|
||||
MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));
|
||||
|
@ -213,6 +268,8 @@ class BarrieredCell : public gc::Cell
|
|||
js::gc::MarkUnbarriered<T>(shadowZone->barrierTracer(), &tmp, "read barrier");
|
||||
JS_ASSERT(tmp == thing);
|
||||
}
|
||||
if (JS::GCThingIsMarkedGray(thing))
|
||||
JS::UnmarkGrayGCThingRecursively(thing, MapTypeToTraceKind<T>::kind);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -771,6 +828,10 @@ class ReadBarriered
|
|||
return value;
|
||||
}
|
||||
|
||||
T unbarrieredGet() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
operator T() const { return get(); }
|
||||
|
||||
T &operator*() const { return *get(); }
|
||||
|
|
|
@ -1142,7 +1142,7 @@ ScanBaseShape(GCMarker *gcmarker, BaseShape *base)
|
|||
|
||||
if (JSObject *parent = base->getObjectParent()) {
|
||||
MaybePushMarkStackBetweenSlices(gcmarker, parent);
|
||||
} else if (GlobalObject *global = base->compartment()->maybeGlobal()) {
|
||||
} else if (GlobalObject *global = base->compartment()->unsafeUnbarrieredMaybeGlobal()) {
|
||||
PushMarkStack(gcmarker, global);
|
||||
}
|
||||
|
||||
|
@ -1961,10 +1961,13 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
|||
JS_FRIEND_API(bool)
|
||||
JS::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(kind != JSTRACE_SHAPE);
|
||||
|
||||
JSRuntime *rt = static_cast<Cell *>(thing)->runtimeFromMainThread();
|
||||
|
||||
// When the ReadBarriered type is used in a HashTable, it is difficult or
|
||||
// impossible to suppress the implicit cast operator while iterating for GC.
|
||||
if (rt->isHeapBusy())
|
||||
return false;
|
||||
|
||||
bool unmarkedArg = false;
|
||||
if (!IsInsideNursery(static_cast<Cell *>(thing))) {
|
||||
if (!JS::GCThingIsMarkedGray(thing))
|
||||
|
|
|
@ -183,6 +183,9 @@ struct JSCompartment
|
|||
*/
|
||||
inline js::GlobalObject *maybeGlobal() const;
|
||||
|
||||
/* An unbarriered getter for use while tracing. */
|
||||
inline js::GlobalObject *unsafeUnbarrieredMaybeGlobal() const;
|
||||
|
||||
inline void initGlobal(js::GlobalObject &global);
|
||||
|
||||
public:
|
||||
|
|
|
@ -28,6 +28,12 @@ JSCompartment::maybeGlobal() const
|
|||
return global_;
|
||||
}
|
||||
|
||||
js::GlobalObject *
|
||||
JSCompartment::unsafeUnbarrieredMaybeGlobal() const
|
||||
{
|
||||
return *global_.unsafeGet();
|
||||
}
|
||||
|
||||
js::AutoCompartment::AutoCompartment(ExclusiveContext *cx, JSObject *target)
|
||||
: cx_(cx),
|
||||
origin_(cx->compartment_)
|
||||
|
|
|
@ -4520,7 +4520,7 @@ GCRuntime::endSweepPhase(JSGCInvocationKind gckind, bool lastGC)
|
|||
|
||||
for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
|
||||
if (e.front().key().kind != CrossCompartmentKey::StringWrapper)
|
||||
AssertNotOnGrayList(&e.front().value().get().toObject());
|
||||
AssertNotOnGrayList(&e.front().value().unbarrieredGet().toObject());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,32 +20,8 @@
|
|||
#include "js/SliceBudget.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
class JSAtom;
|
||||
struct JSCompartment;
|
||||
class JSFlatString;
|
||||
class JSLinearString;
|
||||
|
||||
namespace JS {
|
||||
class Symbol;
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
class ArgumentsObject;
|
||||
class ArrayBufferObject;
|
||||
class ArrayBufferViewObject;
|
||||
class SharedArrayBufferObject;
|
||||
class BaseShape;
|
||||
class DebugScopeObject;
|
||||
class GlobalObject;
|
||||
class LazyScript;
|
||||
class Nursery;
|
||||
class PropertyName;
|
||||
class SavedFrame;
|
||||
class ScopeObject;
|
||||
class Shape;
|
||||
class UnownedBaseShape;
|
||||
|
||||
namespace gc {
|
||||
class ForkJoinNursery;
|
||||
}
|
||||
|
@ -104,32 +80,6 @@ MapAllocToTraceKind(AllocKind kind)
|
|||
return map[kind];
|
||||
}
|
||||
|
||||
template <typename T> struct MapTypeToTraceKind {};
|
||||
template <> struct MapTypeToTraceKind<ObjectImpl> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSFunction> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ArgumentsObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ArrayBufferViewObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<SharedArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<DebugScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<GlobalObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<SavedFrame> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSScript> { static const JSGCTraceKind kind = JSTRACE_SCRIPT; };
|
||||
template <> struct MapTypeToTraceKind<LazyScript> { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
|
||||
template <> struct MapTypeToTraceKind<Shape> { static const JSGCTraceKind kind = JSTRACE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<BaseShape> { static const JSGCTraceKind kind = JSTRACE_BASE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<UnownedBaseShape> { static const JSGCTraceKind kind = JSTRACE_BASE_SHAPE; };
|
||||
template <> struct MapTypeToTraceKind<types::TypeObject>{ static const JSGCTraceKind kind = JSTRACE_TYPE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<JSAtom> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSFlatString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JSLinearString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<JS::Symbol> { static const JSGCTraceKind kind = JSTRACE_SYMBOL; };
|
||||
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<jit::JitCode> { static const JSGCTraceKind kind = JSTRACE_JITCODE; };
|
||||
|
||||
/* Return a printable string for the given kind, for diagnostic purposes. */
|
||||
const char *
|
||||
TraceKindAsAscii(JSGCTraceKind kind);
|
||||
|
|
|
@ -2322,7 +2322,7 @@ TypeCompartment::markSetsUnknown(JSContext *cx, TypeObject *target)
|
|||
}
|
||||
|
||||
for (gc::ZoneCellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
RootedScript script(cx, i.get<JSScript>());
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->types) {
|
||||
unsigned count = TypeScript::NumTypeSets(script);
|
||||
StackTypeSet *typeArray = script->types->typeArray();
|
||||
|
@ -4122,7 +4122,7 @@ TypeCompartment::sweep(FreeOp *fop)
|
|||
bool remove = false;
|
||||
TypeObject *typeObject = nullptr;
|
||||
if (!key.type.isUnknown() && key.type.isTypeObject()) {
|
||||
typeObject = key.type.typeObject();
|
||||
typeObject = key.type.typeObjectNoBarrier();
|
||||
if (IsTypeObjectAboutToBeFinalized(&typeObject))
|
||||
remove = true;
|
||||
}
|
||||
|
@ -4131,7 +4131,7 @@ TypeCompartment::sweep(FreeOp *fop)
|
|||
|
||||
if (remove) {
|
||||
e.removeFront();
|
||||
} else if (typeObject && typeObject != key.type.typeObject()) {
|
||||
} else if (typeObject && typeObject != key.type.typeObjectNoBarrier()) {
|
||||
ArrayTableKey newKey;
|
||||
newKey.type = Type::ObjectType(typeObject);
|
||||
newKey.proto = key.proto;
|
||||
|
@ -4160,10 +4160,10 @@ TypeCompartment::sweep(FreeOp *fop)
|
|||
JS_ASSERT(!entry.types[i].isSingleObject());
|
||||
TypeObject *typeObject = nullptr;
|
||||
if (entry.types[i].isTypeObject()) {
|
||||
typeObject = entry.types[i].typeObject();
|
||||
typeObject = entry.types[i].typeObjectNoBarrier();
|
||||
if (IsTypeObjectAboutToBeFinalized(&typeObject))
|
||||
remove = true;
|
||||
else if (typeObject != entry.types[i].typeObject())
|
||||
else if (typeObject != entry.types[i].typeObjectNoBarrier())
|
||||
entry.types[i] = Type::ObjectType(typeObject);
|
||||
}
|
||||
}
|
||||
|
@ -4203,7 +4203,7 @@ JSCompartment::sweepNewTypeObjectTable(TypeObjectWithNewScriptSet &table)
|
|||
e.removeFront();
|
||||
} else if (entry.newFunction && IsObjectAboutToBeFinalized(&entry.newFunction)) {
|
||||
e.removeFront();
|
||||
} else if (entry.object != e.front().object) {
|
||||
} else if (entry.object.unbarrieredGet() != e.front().object.unbarrieredGet()) {
|
||||
TypeObjectWithNewScriptSet::Lookup lookup(entry.object->clasp(),
|
||||
entry.object->proto(),
|
||||
entry.newFunction);
|
||||
|
|
|
@ -664,7 +664,13 @@ JSObject::global() const
|
|||
while (JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
#endif
|
||||
return *compartment()->maybeGlobal();
|
||||
/*
|
||||
* The global is read-barriered so that it is kept live by access through
|
||||
* the JSCompartment. When accessed through a JSObject, however, the global
|
||||
* will be already be kept live by the black JSObject's parent pointer, so
|
||||
* does not need to be read-barriered.
|
||||
*/
|
||||
return *compartment()->unsafeUnbarrieredMaybeGlobal();
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
|
|
@ -145,10 +145,10 @@ PropertyTree::getChild(ExclusiveContext *cx, Shape *parentArg, StackShape &unroo
|
|||
if (kidp->isShape()) {
|
||||
Shape *kid = kidp->toShape();
|
||||
if (kid->matches(unrootedChild))
|
||||
existingShape = kid;
|
||||
existingShape = kid;
|
||||
} else if (kidp->isHash()) {
|
||||
if (KidsHash::Ptr p = kidp->toHash()->lookup(unrootedChild))
|
||||
existingShape = *p;
|
||||
existingShape = *p;
|
||||
} else {
|
||||
/* If kidp->isNull(), we always insert. */
|
||||
}
|
||||
|
@ -174,6 +174,8 @@ PropertyTree::getChild(ExclusiveContext *cx, Shape *parentArg, StackShape &unroo
|
|||
JS_ASSERT(parent->isMarked());
|
||||
parent->removeChild(existingShape);
|
||||
existingShape = nullptr;
|
||||
} else if (existingShape->isMarked(gc::GRAY)) {
|
||||
JS::UnmarkGrayGCThingRecursively(existingShape, JSTRACE_SHAPE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -271,10 +271,6 @@ WeakMap_get_impl(JSContext *cx, CallArgs args)
|
|||
|
||||
if (ObjectValueMap *map = args.thisv().toObject().as<WeakMapObject>().getMap()) {
|
||||
if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
|
||||
// Read barrier to prevent an incorrectly gray value from escaping the
|
||||
// weak map. See the comment before UnmarkGrayChildren in gc/Marking.cpp
|
||||
ExposeValueToActiveJS(ptr->value().get());
|
||||
|
||||
args.rval().set(ptr->value());
|
||||
return true;
|
||||
}
|
||||
|
@ -450,6 +446,7 @@ JS_NondeterministicGetWeakMapKeys(JSContext *cx, HandleObject objArg, MutableHan
|
|||
// Prevent GC from mutating the weakmap while iterating.
|
||||
AutoSuppressGC suppress(cx);
|
||||
for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
|
||||
JS::ExposeObjectToActiveJS(r.front().key());
|
||||
RootedObject key(cx, r.front().key());
|
||||
if (!cx->compartment()->wrap(cx, &key))
|
||||
return false;
|
||||
|
|
|
@ -111,6 +111,8 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
|||
typedef typename Base::Enum Enum;
|
||||
typedef typename Base::Lookup Lookup;
|
||||
typedef typename Base::Range Range;
|
||||
typedef typename Base::Ptr Ptr;
|
||||
typedef typename Base::AddPtr AddPtr;
|
||||
|
||||
explicit WeakMap(JSContext *cx, JSObject *memOf = nullptr)
|
||||
: Base(cx->runtime()), WeakMapBase(memOf, cx->compartment()) { }
|
||||
|
@ -124,7 +126,34 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
|||
return true;
|
||||
}
|
||||
|
||||
// Overwritten to add a read barrier to prevent an incorrectly gray value
|
||||
// from escaping the weak map. See the comment before UnmarkGrayChildren in
|
||||
// gc/Marking.cpp
|
||||
Ptr lookup(const Lookup &l) const {
|
||||
Ptr p = Base::lookup(l);
|
||||
if (p)
|
||||
exposeGCThingToActiveJS(p->value());
|
||||
return p;
|
||||
}
|
||||
|
||||
AddPtr lookupForAdd(const Lookup &l) const {
|
||||
AddPtr p = Base::lookupForAdd(l);
|
||||
if (p)
|
||||
exposeGCThingToActiveJS(p->value());
|
||||
return p;
|
||||
}
|
||||
|
||||
Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
|
||||
Ptr p = Base::lookupWithDefault(k, defaultValue);
|
||||
if (p)
|
||||
exposeGCThingToActiveJS(p->value());
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
void exposeGCThingToActiveJS(const JS::Value &v) const { JS::ExposeValueToActiveJS(v); }
|
||||
void exposeGCThingToActiveJS(JSObject *obj) const { JS::ExposeObjectToActiveJS(obj); }
|
||||
|
||||
bool markValue(JSTracer *trc, Value *x) {
|
||||
if (gc::IsMarked(x))
|
||||
return false;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/Vector.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/DebuggerMemory.h"
|
||||
|
@ -1426,10 +1427,13 @@ Debugger::slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global
|
|||
AutoObjectVector watchers(cx);
|
||||
for (JSCList *link = JS_LIST_HEAD(&cx->runtime()->onNewGlobalObjectWatchers);
|
||||
link != &cx->runtime()->onNewGlobalObjectWatchers;
|
||||
link = JS_NEXT_LINK(link)) {
|
||||
link = JS_NEXT_LINK(link))
|
||||
{
|
||||
Debugger *dbg = fromOnNewGlobalObjectWatchersLink(link);
|
||||
JS_ASSERT(dbg->observesNewGlobalObject());
|
||||
if (!watchers.append(dbg->object))
|
||||
JSObject *obj = dbg->object;
|
||||
JS::ExposeObjectToActiveJS(obj);
|
||||
if (!watchers.append(obj))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2674,6 +2678,10 @@ class Debugger::ScriptQuery {
|
|||
return false;
|
||||
}
|
||||
|
||||
/* We cannot touch the gray bits while isHeapBusy, so do this now. */
|
||||
for (JSScript **i = vector->begin(); i != vector->end(); ++i)
|
||||
JS::ExposeScriptToActiveJS(*i);
|
||||
|
||||
/*
|
||||
* For most queries, we just accumulate results in 'vector' as we find
|
||||
* them. But if this is an 'innermost' query, then we've accumulated the
|
||||
|
@ -2683,7 +2691,9 @@ class Debugger::ScriptQuery {
|
|||
if (innermost) {
|
||||
for (CompartmentToScriptMap::Range r = innermostForCompartment.all();
|
||||
!r.empty();
|
||||
r.popFront()) {
|
||||
r.popFront())
|
||||
{
|
||||
JS::ExposeScriptToActiveJS(r.front().value());
|
||||
if (!v->append(r.front().value())) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
|
|
|
@ -452,8 +452,8 @@ SavedStacks::sweep(JSRuntime *rt)
|
|||
|
||||
sweepPCLocationMap();
|
||||
|
||||
if (savedFrameProto && IsObjectAboutToBeFinalized(&savedFrameProto)) {
|
||||
savedFrameProto = nullptr;
|
||||
if (savedFrameProto && IsObjectAboutToBeFinalized(savedFrameProto.unsafeGet())) {
|
||||
savedFrameProto.set(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,9 +593,11 @@ SavedStacks::getOrCreateSavedFramePrototype(JSContext *cx)
|
|||
|| !JS_DefineProperties(cx, proto, SavedFrame::properties)
|
||||
|| !JS_DefineFunctions(cx, proto, SavedFrame::methods)
|
||||
|| !JSObject::freeze(cx, proto))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
savedFrameProto = proto;
|
||||
savedFrameProto.set(proto);
|
||||
// The only object with the SavedFrame::class_ that doesn't have a source
|
||||
// should be the prototype.
|
||||
savedFrameProto->setReservedSlot(SavedFrame::JSSLOT_SOURCE, NullValue());
|
||||
|
|
|
@ -115,7 +115,7 @@ class SavedStacks {
|
|||
|
||||
private:
|
||||
SavedFrame::Set frames;
|
||||
JSObject *savedFrameProto;
|
||||
ReadBarrieredObject savedFrameProto;
|
||||
|
||||
bool insertFrames(JSContext *cx, FrameIter &iter, MutableHandleSavedFrame frame,
|
||||
unsigned maxFrameCount = 0);
|
||||
|
|
|
@ -1528,7 +1528,7 @@ JSCompartment::sweepBaseShapeTable()
|
|||
|
||||
if (baseShapes.initialized()) {
|
||||
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
|
||||
UnownedBaseShape *base = e.front();
|
||||
UnownedBaseShape *base = e.front().unbarrieredGet();
|
||||
if (IsBaseShapeAboutToBeFinalized(&base))
|
||||
e.removeFront();
|
||||
}
|
||||
|
@ -1816,7 +1816,7 @@ JSCompartment::sweepInitialShapeTable()
|
|||
if (initialShapes.initialized()) {
|
||||
for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {
|
||||
const InitialShapeEntry &entry = e.front();
|
||||
Shape *shape = entry.shape;
|
||||
Shape *shape = entry.shape.unbarrieredGet();
|
||||
JSObject *proto = entry.proto.raw();
|
||||
if (IsShapeAboutToBeFinalized(&shape) || (entry.proto.isObject() && IsObjectAboutToBeFinalized(&proto))) {
|
||||
e.removeFront();
|
||||
|
@ -1826,7 +1826,7 @@ JSCompartment::sweepInitialShapeTable()
|
|||
JS_ASSERT(!parent || !IsObjectAboutToBeFinalized(&parent));
|
||||
JS_ASSERT(parent == shape->getObjectParent());
|
||||
#endif
|
||||
if (shape != entry.shape || proto != entry.proto.raw()) {
|
||||
if (shape != entry.shape.unbarrieredGet() || proto != entry.proto.raw()) {
|
||||
ReadBarrieredShape readBarrieredShape(shape);
|
||||
InitialShapeEntry newKey(readBarrieredShape, TaggedProto(proto));
|
||||
e.rekeyFront(newKey.getLookup(), newKey);
|
||||
|
|
|
@ -369,7 +369,8 @@ InterpreterFrame::mark(JSTracer *trc)
|
|||
}
|
||||
if (IS_GC_MARKING_TRACER(trc))
|
||||
script()->compartment()->zone()->active = true;
|
||||
gc::MarkValueUnbarriered(trc, returnValue().address(), "rval");
|
||||
if (hasReturnValue())
|
||||
gc::MarkValueUnbarriered(trc, &rval_, "rval");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче