mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 721463 - Clean up and minimize marking interfaces; r=billm
Currently, the marking interfaces are a giant pile of duplicated and, frequently, unused code. This patch reworks the interface to clean up jsgcmark.h.
This commit is contained in:
parent
72d2af4861
commit
753ee85563
@ -257,7 +257,7 @@ Parser::trace(JSTracer *trc)
|
||||
{
|
||||
ObjectBox *objbox = traceListHead;
|
||||
while (objbox) {
|
||||
MarkRoot(trc, objbox->object, "parser.object");
|
||||
MarkObjectRoot(trc, objbox->object, "parser.object");
|
||||
if (objbox->isFunctionBox)
|
||||
static_cast<FunctionBox *>(objbox)->bindings.trace(trc);
|
||||
objbox = objbox->traceLink;
|
||||
|
@ -4291,7 +4291,7 @@ prop_iter_trace(JSTracer *trc, JSObject *obj)
|
||||
} else {
|
||||
/* Non-native case: mark each id in the JSIdArray private. */
|
||||
JSIdArray *ida = (JSIdArray *) pdata;
|
||||
MarkIdRange(trc, ida->vector, ida->vector + ida->length, "prop iter");
|
||||
MarkIdRange(trc, ida->length, ida->vector, "prop iter");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,16 +386,15 @@ js_TraceAtomState(JSTracer *trc)
|
||||
JSAtomState *state = &rt->atomState;
|
||||
|
||||
if (rt->gcKeepAtoms) {
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
|
||||
MarkRoot(trc, r.front().asPtr(), "locked_atom");
|
||||
}
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
|
||||
MarkStringRoot(trc, r.front().asPtr(), "locked_atom");
|
||||
} else {
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
|
||||
AtomStateEntry entry = r.front();
|
||||
if (!entry.isTagged())
|
||||
continue;
|
||||
|
||||
MarkRoot(trc, entry.asPtr(), "interned_atom");
|
||||
MarkStringRoot(trc, entry.asPtr(), "interned_atom");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
||||
JS_ASSERT(trc->runtime->gcCurrentCompartment);
|
||||
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront())
|
||||
MarkRoot(trc, e.front().key, "cross-compartment wrapper");
|
||||
MarkValueRoot(trc, e.front().key, "cross-compartment wrapper");
|
||||
}
|
||||
|
||||
void
|
||||
@ -432,7 +432,7 @@ JSCompartment::markTypes(JSTracer *trc)
|
||||
|
||||
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
MarkRoot(trc, script, "mark_types_script");
|
||||
MarkScriptRoot(trc, script, "mark_types_script");
|
||||
}
|
||||
|
||||
for (size_t thingKind = FINALIZE_OBJECT0;
|
||||
@ -441,12 +441,12 @@ JSCompartment::markTypes(JSTracer *trc)
|
||||
for (CellIterUnderGC i(this, AllocKind(thingKind)); !i.done(); i.next()) {
|
||||
JSObject *object = i.get<JSObject>();
|
||||
if (object->hasSingletonType())
|
||||
MarkRoot(trc, object, "mark_types_singleton");
|
||||
MarkObjectRoot(trc, object, "mark_types_singleton");
|
||||
}
|
||||
}
|
||||
|
||||
for (CellIterUnderGC i(this, FINALIZE_TYPE_OBJECT); !i.done(); i.next())
|
||||
MarkRoot(trc, i.get<types::TypeObject>(), "mark_types_scan");
|
||||
MarkTypeObjectRoot(trc, i.get<types::TypeObject>(), "mark_types_scan");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1853,30 +1853,29 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
|
||||
#endif
|
||||
const char *name = entry.value.name ? entry.value.name : "root";
|
||||
if (entry.value.type == JS_GC_ROOT_GCTHING_PTR)
|
||||
MarkRootGCThing(trc, *reinterpret_cast<void **>(entry.key), name);
|
||||
MarkGCThingRoot(trc, *reinterpret_cast<void **>(entry.key), name);
|
||||
else
|
||||
MarkRoot(trc, *reinterpret_cast<Value *>(entry.key), name);
|
||||
MarkValueRoot(trc, *reinterpret_cast<Value *>(entry.key), name);
|
||||
}
|
||||
|
||||
static void
|
||||
gc_lock_traversal(const GCLocks::Entry &entry, JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(entry.value >= 1);
|
||||
MarkRootGCThing(trc, entry.key, "locked object");
|
||||
MarkGCThingRoot(trc, entry.key, "locked object");
|
||||
}
|
||||
|
||||
void
|
||||
AutoIdArray::trace(JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(tag == IDARRAY);
|
||||
gc::MarkIdRange(trc, idArray->vector, idArray->vector + idArray->length,
|
||||
"JSAutoIdArray.idArray");
|
||||
gc::MarkIdRange(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray");
|
||||
}
|
||||
|
||||
void
|
||||
AutoEnumStateRooter::trace(JSTracer *trc)
|
||||
{
|
||||
gc::MarkRoot(trc, obj, "JS::AutoEnumStateRooter.obj");
|
||||
gc::MarkObjectRoot(trc, obj, "JS::AutoEnumStateRooter.obj");
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -1884,7 +1883,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
{
|
||||
switch (tag) {
|
||||
case JSVAL:
|
||||
MarkRoot(trc, static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
|
||||
MarkValueRoot(trc, static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
|
||||
return;
|
||||
|
||||
case PARSER:
|
||||
@ -1897,7 +1896,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
|
||||
case IDARRAY: {
|
||||
JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
|
||||
MarkIdRange(trc, ida->vector, ida->vector + ida->length, "JS::AutoIdArray.idArray");
|
||||
MarkIdRange(trc, ida->length, ida->vector, "JS::AutoIdArray.idArray");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1906,10 +1905,10 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
|
||||
for (size_t i = 0, len = descriptors.length(); i < len; i++) {
|
||||
PropDesc &desc = descriptors[i];
|
||||
MarkRoot(trc, desc.pd, "PropDesc::pd");
|
||||
MarkRoot(trc, desc.value, "PropDesc::value");
|
||||
MarkRoot(trc, desc.get, "PropDesc::get");
|
||||
MarkRoot(trc, desc.set, "PropDesc::set");
|
||||
MarkValueRoot(trc, desc.pd, "PropDesc::pd");
|
||||
MarkValueRoot(trc, desc.value, "PropDesc::value");
|
||||
MarkValueRoot(trc, desc.get, "PropDesc::get");
|
||||
MarkValueRoot(trc, desc.set, "PropDesc::set");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1917,12 +1916,12 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
case DESCRIPTOR : {
|
||||
PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this);
|
||||
if (desc.obj)
|
||||
MarkRoot(trc, desc.obj, "Descriptor::obj");
|
||||
MarkRoot(trc, desc.value, "Descriptor::value");
|
||||
MarkObjectRoot(trc, desc.obj, "Descriptor::obj");
|
||||
MarkValueRoot(trc, desc.value, "Descriptor::value");
|
||||
if ((desc.attrs & JSPROP_GETTER) && desc.getter)
|
||||
MarkRoot(trc, CastAsObject(desc.getter), "Descriptor::get");
|
||||
MarkObjectRoot(trc, CastAsObject(desc.getter), "Descriptor::get");
|
||||
if (desc.attrs & JSPROP_SETTER && desc.setter)
|
||||
MarkRoot(trc, CastAsObject(desc.setter), "Descriptor::set");
|
||||
MarkObjectRoot(trc, CastAsObject(desc.setter), "Descriptor::set");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1939,51 +1938,52 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
|
||||
case OBJECT:
|
||||
if (JSObject *obj = static_cast<AutoObjectRooter *>(this)->obj)
|
||||
MarkRoot(trc, obj, "JS::AutoObjectRooter.obj");
|
||||
MarkObjectRoot(trc, obj, "JS::AutoObjectRooter.obj");
|
||||
return;
|
||||
|
||||
case ID:
|
||||
MarkRoot(trc, static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_");
|
||||
MarkIdRoot(trc, static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_");
|
||||
return;
|
||||
|
||||
case VALVECTOR: {
|
||||
AutoValueVector::VectorImpl &vector = static_cast<AutoValueVector *>(this)->vector;
|
||||
MarkRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
|
||||
MarkValueRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case STRING:
|
||||
if (JSString *str = static_cast<AutoStringRooter *>(this)->str)
|
||||
MarkRoot(trc, str, "JS::AutoStringRooter.str");
|
||||
MarkStringRoot(trc, str, "JS::AutoStringRooter.str");
|
||||
return;
|
||||
|
||||
case IDVECTOR: {
|
||||
AutoIdVector::VectorImpl &vector = static_cast<AutoIdVector *>(this)->vector;
|
||||
MarkRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
|
||||
MarkIdRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case SHAPEVECTOR: {
|
||||
AutoShapeVector::VectorImpl &vector = static_cast<js::AutoShapeVector *>(this)->vector;
|
||||
MarkRootRange(trc, vector.length(), vector.begin(), "js::AutoShapeVector.vector");
|
||||
MarkShapeRootRange(trc, vector.length(), const_cast<Shape **>(vector.begin()),
|
||||
"js::AutoShapeVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case OBJVECTOR: {
|
||||
AutoObjectVector::VectorImpl &vector = static_cast<AutoObjectVector *>(this)->vector;
|
||||
MarkRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
|
||||
MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case VALARRAY: {
|
||||
AutoValueArray *array = static_cast<AutoValueArray *>(this);
|
||||
MarkRootRange(trc, array->length(), array->start(), "js::AutoValueArray");
|
||||
MarkValueRootRange(trc, array->length(), array->start(), "js::AutoValueArray");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(tag >= 0);
|
||||
MarkRootRange(trc, tag, static_cast<AutoArrayRooter *>(this)->array,
|
||||
MarkValueRootRange(trc, tag, static_cast<AutoArrayRooter *>(this)->array,
|
||||
"JS::AutoArrayRooter.array");
|
||||
}
|
||||
|
||||
@ -2003,9 +2003,9 @@ MarkContext(JSTracer *trc, JSContext *acx)
|
||||
|
||||
/* Mark other roots-by-definition in acx. */
|
||||
if (acx->globalObject && !acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL))
|
||||
MarkRoot(trc, acx->globalObject, "global object");
|
||||
MarkObjectRoot(trc, acx->globalObject, "global object");
|
||||
if (acx->isExceptionPending())
|
||||
MarkRoot(trc, acx->getPendingException(), "exception");
|
||||
MarkValueRoot(trc, acx->getPendingException(), "exception");
|
||||
|
||||
if (acx->autoGCRooters)
|
||||
acx->autoGCRooters->traceAll(trc);
|
||||
@ -2013,7 +2013,7 @@ MarkContext(JSTracer *trc, JSContext *acx)
|
||||
if (acx->sharpObjectMap.depth > 0)
|
||||
js_TraceSharpMap(trc, &acx->sharpObjectMap);
|
||||
|
||||
MarkRoot(trc, acx->iterValue, "iterValue");
|
||||
MarkValueRoot(trc, acx->iterValue, "iterValue");
|
||||
}
|
||||
|
||||
void
|
||||
@ -2045,7 +2045,7 @@ MarkRuntime(JSTracer *trc)
|
||||
if (rt->scriptPCCounters) {
|
||||
const ScriptOpcodeCountsVector &vec = *rt->scriptPCCounters;
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
MarkRoot(trc, vec[i].script, "scriptPCCounters");
|
||||
MarkScriptRoot(trc, vec[i].script, "scriptPCCounters");
|
||||
}
|
||||
|
||||
js_TraceAtomState(trc);
|
||||
@ -2070,7 +2070,7 @@ MarkRuntime(JSTracer *trc)
|
||||
for (CellIterUnderGC i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->pcCounters)
|
||||
MarkRoot(trc, script, "profilingScripts");
|
||||
MarkScriptRoot(trc, script, "profilingScripts");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,8 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is SpiderMonkey code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
*/
|
||||
/* 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 "jsgcmark.h"
|
||||
#include "jsprf.h"
|
||||
@ -105,10 +72,13 @@ PushMarkStack(GCMarker *gcmarker, JSString *thing);
|
||||
static inline void
|
||||
PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing);
|
||||
|
||||
/*** Object Marking ***/
|
||||
|
||||
template<typename T>
|
||||
static inline void
|
||||
CheckMarkedThing(JSTracer *trc, T *thing)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(thing);
|
||||
JS_ASSERT(trc->debugPrinter || trc->debugPrintArg);
|
||||
JS_ASSERT_IF(trc->runtime->gcCurrentCompartment, IS_GC_MARKING_TRACER(trc));
|
||||
@ -121,7 +91,7 @@ CheckMarkedThing(JSTracer *trc, T *thing)
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
Mark(JSTracer *trc, T *thing)
|
||||
MarkInternal(JSTracer *trc, T *thing)
|
||||
{
|
||||
CheckMarkedThing(trc, thing);
|
||||
|
||||
@ -148,114 +118,265 @@ Mark(JSTracer *trc, T *thing)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MarkStringUnbarriered(JSTracer *trc, JSString *str, const char *name)
|
||||
template <typename T>
|
||||
static void
|
||||
MarkUnbarriered(JSTracer *trc, T *thing, const char *name)
|
||||
{
|
||||
JS_ASSERT(str);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, str);
|
||||
MarkInternal(trc, thing);
|
||||
}
|
||||
|
||||
void
|
||||
MarkString(JSTracer *trc, const MarkablePtr<JSString> &str, const char *name)
|
||||
template <typename T>
|
||||
static void
|
||||
Mark(JSTracer *trc, const HeapPtr<T> &thing, const char *name)
|
||||
{
|
||||
MarkStringUnbarriered(trc, str.value, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkObjectUnbarriered(JSTracer *trc, JSObject *obj, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(obj);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, obj);
|
||||
MarkInternal(trc, thing.get());
|
||||
}
|
||||
|
||||
void
|
||||
MarkObject(JSTracer *trc, const MarkablePtr<JSObject> &obj, const char *name)
|
||||
template <typename T>
|
||||
static void
|
||||
MarkRoot(JSTracer *trc, T *thing, const char *name)
|
||||
{
|
||||
MarkObjectUnbarriered(trc, obj.value, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkScriptUnbarriered(JSTracer *trc, JSScript *script, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(script);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, script);
|
||||
MarkInternal(trc, thing);
|
||||
}
|
||||
|
||||
void
|
||||
MarkScript(JSTracer *trc, const MarkablePtr<JSScript> &script, const char *name)
|
||||
{
|
||||
MarkScriptUnbarriered(trc, script.value, name);
|
||||
template <typename T>
|
||||
static void
|
||||
MarkRange(JSTracer *trc, size_t len, HeapPtr<T> *vec, const char *name) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (T *obj = vec[i]) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkInternal(trc, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkShapeUnbarriered(JSTracer *trc, const Shape *shape, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(shape);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, shape);
|
||||
template <typename T>
|
||||
static void
|
||||
MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkInternal(trc, vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkShape(JSTracer *trc, const MarkablePtr<const Shape> &shape, const char *name)
|
||||
{
|
||||
MarkShapeUnbarriered(trc, shape.value, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkBaseShapeUnbarriered(JSTracer *trc, BaseShape *base, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(base);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, base);
|
||||
}
|
||||
|
||||
void
|
||||
MarkBaseShape(JSTracer *trc, const MarkablePtr<BaseShape> &base, const char *name)
|
||||
{
|
||||
MarkBaseShapeUnbarriered(trc, base.value, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkTypeObjectUnbarriered(JSTracer *trc, types::TypeObject *type, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(type);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, type);
|
||||
}
|
||||
|
||||
void
|
||||
MarkTypeObject(JSTracer *trc, const MarkablePtr<types::TypeObject> &type, const char *name)
|
||||
{
|
||||
MarkTypeObjectUnbarriered(trc, type.value, name);
|
||||
}
|
||||
#define DeclMarkerImpl(base, type) \
|
||||
void \
|
||||
Mark##base(JSTracer *trc, const HeapPtr<type> &thing, const char *name) \
|
||||
{ \
|
||||
Mark<type>(trc, thing, name); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
Mark##base##Root(JSTracer *trc, type *thing, const char *name) \
|
||||
{ \
|
||||
MarkRoot<type>(trc, thing, name); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
Mark##base##Unbarriered(JSTracer *trc, type *thing, const char *name) \
|
||||
{ \
|
||||
MarkUnbarriered<type>(trc, thing, name); \
|
||||
} \
|
||||
\
|
||||
void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *vec, const char *name) \
|
||||
{ \
|
||||
MarkRange<type>(trc, len, vec, name); \
|
||||
} \
|
||||
\
|
||||
void Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *name) \
|
||||
{ \
|
||||
MarkRootRange<type>(trc, len, vec, name); \
|
||||
} \
|
||||
|
||||
DeclMarkerImpl(BaseShape, BaseShape)
|
||||
DeclMarkerImpl(Object, ArgumentsObject)
|
||||
DeclMarkerImpl(Object, GlobalObject)
|
||||
DeclMarkerImpl(Object, JSObject)
|
||||
DeclMarkerImpl(Object, JSFunction)
|
||||
DeclMarkerImpl(Script, JSScript)
|
||||
DeclMarkerImpl(Shape, Shape)
|
||||
DeclMarkerImpl(String, JSAtom)
|
||||
DeclMarkerImpl(String, JSString)
|
||||
DeclMarkerImpl(String, JSFlatString)
|
||||
DeclMarkerImpl(String, JSLinearString)
|
||||
DeclMarkerImpl(TypeObject, types::TypeObject)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
void
|
||||
MarkXMLUnbarriered(JSTracer *trc, JSXML *xml, const char *name)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(xml);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
Mark(trc, xml);
|
||||
}
|
||||
|
||||
void
|
||||
MarkXML(JSTracer *trc, const MarkablePtr<JSXML> &xml, const char *name)
|
||||
{
|
||||
MarkXMLUnbarriered(trc, xml.value, name);
|
||||
}
|
||||
DeclMarkerImpl(XML, JSXML)
|
||||
#endif
|
||||
|
||||
#define JS_SAME_COMPARTMENT_ASSERT(thing1, thing2) \
|
||||
JS_ASSERT((thing1)->compartment() == (thing2)->compartment())
|
||||
/*** Externally Typed Marking ***/
|
||||
|
||||
void
|
||||
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
JS_ASSERT(kind == GetGCThingTraceKind(thing));
|
||||
switch (kind) {
|
||||
case JSTRACE_OBJECT:
|
||||
MarkInternal(trc, reinterpret_cast<JSObject *>(thing));
|
||||
break;
|
||||
case JSTRACE_STRING:
|
||||
MarkInternal(trc, reinterpret_cast<JSString *>(thing));
|
||||
break;
|
||||
case JSTRACE_SCRIPT:
|
||||
MarkInternal(trc, static_cast<JSScript *>(thing));
|
||||
break;
|
||||
case JSTRACE_SHAPE:
|
||||
MarkInternal(trc, reinterpret_cast<Shape *>(thing));
|
||||
break;
|
||||
case JSTRACE_BASE_SHAPE:
|
||||
MarkInternal(trc, reinterpret_cast<BaseShape *>(thing));
|
||||
break;
|
||||
case JSTRACE_TYPE_OBJECT:
|
||||
MarkInternal(trc, reinterpret_cast<types::TypeObject *>(thing));
|
||||
break;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSTRACE_XML:
|
||||
MarkInternal(trc, static_cast<JSXML *>(thing));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkGCThingRoot(JSTracer *trc, void *thing, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
if (!thing)
|
||||
return;
|
||||
MarkKind(trc, thing, GetGCThingTraceKind(thing));
|
||||
}
|
||||
|
||||
/*** ID Marking ***/
|
||||
|
||||
static inline void
|
||||
MarkIdInternal(JSTracer *trc, const jsid &id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
MarkInternal(trc, JSID_TO_STRING(id));
|
||||
else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
|
||||
MarkInternal(trc, JSID_TO_OBJECT(id));
|
||||
}
|
||||
|
||||
void
|
||||
MarkId(JSTracer *trc, const HeapId &id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdInternal(trc, id);
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRoot(JSTracer *trc, const jsid &id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdInternal(trc, id);
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkIdInternal(trc, vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkIdInternal(trc, vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Value Marking ***/
|
||||
|
||||
static inline void
|
||||
MarkValueInternal(JSTracer *trc, const Value &v)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
JS_ASSERT(v.toGCThing());
|
||||
return MarkKind(trc, v.toGCThing(), v.gcKind());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, const Value &v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkValueInternal(trc, vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkValueInternal(trc, vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Special Marking ***/
|
||||
|
||||
/*
|
||||
* The unioned HeapPtr stored in script->globalObj needs special treatment to
|
||||
* typecheck correctly.
|
||||
*/
|
||||
static void
|
||||
MarkObject(JSTracer *trc, const HeapPtr<GlobalObject, JSScript *> &thing, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkInternal(trc, thing.get());
|
||||
}
|
||||
|
||||
void
|
||||
MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkInternal(trc, const_cast<Shape *>(thing.get()));
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)v.toGCThing();
|
||||
JSRuntime *rt = trc->runtime;
|
||||
if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
|
||||
return;
|
||||
|
||||
MarkValue(trc, v, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Push Mark Stack ***/
|
||||
|
||||
#define JS_COMPARTMENT_ASSERT(rt, thing) \
|
||||
JS_ASSERT_IF((rt)->gcCurrentCompartment, \
|
||||
@ -266,7 +387,7 @@ MarkXML(JSTracer *trc, const MarkablePtr<JSXML> &xml, const char *name)
|
||||
(thing)->compartment() == (rt)->gcCurrentCompartment || \
|
||||
(thing)->compartment() == (rt)->atomsCompartment);
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, JSXML *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -275,7 +396,7 @@ PushMarkStack(GCMarker *gcmarker, JSXML *thing)
|
||||
gcmarker->pushXML(thing);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, JSObject *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -284,7 +405,7 @@ PushMarkStack(GCMarker *gcmarker, JSObject *thing)
|
||||
gcmarker->pushObject(thing);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, JSFunction *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -293,7 +414,7 @@ PushMarkStack(GCMarker *gcmarker, JSFunction *thing)
|
||||
gcmarker->pushObject(thing);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -302,7 +423,10 @@ PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing)
|
||||
gcmarker->pushType(thing);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSScript *script);
|
||||
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, JSScript *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -319,7 +443,7 @@ PushMarkStack(GCMarker *gcmarker, JSScript *thing)
|
||||
static void
|
||||
ScanShape(GCMarker *gcmarker, const Shape *shape);
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, const Shape *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -332,7 +456,7 @@ PushMarkStack(GCMarker *gcmarker, const Shape *thing)
|
||||
static inline void
|
||||
ScanBaseShape(GCMarker *gcmarker, BaseShape *base);
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, BaseShape *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -342,305 +466,6 @@ PushMarkStack(GCMarker *gcmarker, BaseShape *thing)
|
||||
ScanBaseShape(gcmarker, thing);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name)
|
||||
{
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
if (JSAtom *atom = vec[i]) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
Mark(trc, atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkObjectRange(JSTracer *trc, size_t len, HeapPtr<JSObject> *vec, const char *name)
|
||||
{
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
if (JSObject *obj = vec[i]) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
Mark(trc, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkXMLRange(JSTracer *trc, size_t len, HeapPtr<JSXML> *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (JSXML *xml = vec[i]) {
|
||||
JS_SET_TRACING_INDEX(trc, "xml_vector", i);
|
||||
Mark(trc, xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdUnbarriered(JSTracer *trc, jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
Mark(trc, JSID_TO_STRING(id));
|
||||
else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
|
||||
Mark(trc, JSID_TO_OBJECT(id));
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdUnbarriered(JSTracer *trc, jsid id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdUnbarriered(trc, id);
|
||||
}
|
||||
|
||||
void
|
||||
MarkId(JSTracer *trc, const HeapId &id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdUnbarriered(trc, id.get(), name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRangeUnbarriered(JSTracer *trc, jsid *beg, jsid *end, const char *name)
|
||||
{
|
||||
for (jsid *idp = beg; idp != end; ++idp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, (idp - beg));
|
||||
MarkIdUnbarriered(trc, *idp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRangeUnbarriered(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
{
|
||||
MarkIdRangeUnbarriered(trc, vec, vec + len, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRange(JSTracer *trc, HeapId *beg, HeapId *end, const char *name)
|
||||
{
|
||||
for (HeapId *idp = beg; idp != end; ++idp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, (idp - beg));
|
||||
MarkIdUnbarriered(trc, *idp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
JS_ASSERT(kind == GetGCThingTraceKind(thing));
|
||||
switch (kind) {
|
||||
case JSTRACE_OBJECT:
|
||||
Mark(trc, reinterpret_cast<JSObject *>(thing));
|
||||
break;
|
||||
case JSTRACE_STRING:
|
||||
Mark(trc, reinterpret_cast<JSString *>(thing));
|
||||
break;
|
||||
case JSTRACE_SCRIPT:
|
||||
Mark(trc, static_cast<JSScript *>(thing));
|
||||
break;
|
||||
case JSTRACE_SHAPE:
|
||||
Mark(trc, reinterpret_cast<Shape *>(thing));
|
||||
break;
|
||||
case JSTRACE_BASE_SHAPE:
|
||||
Mark(trc, reinterpret_cast<BaseShape *>(thing));
|
||||
break;
|
||||
case JSTRACE_TYPE_OBJECT:
|
||||
MarkTypeObjectUnbarriered(trc, reinterpret_cast<types::TypeObject *>(thing), "type_stack");
|
||||
break;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSTRACE_XML:
|
||||
Mark(trc, static_cast<JSXML *>(thing));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
|
||||
void
|
||||
MarkValueRaw(JSTracer *trc, const js::Value &v)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
JS_ASSERT(v.toGCThing());
|
||||
return MarkKind(trc, v.toGCThing(), v.gcKind());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueRaw(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
{
|
||||
MarkValueUnbarriered(trc, v, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)v.toGCThing();
|
||||
JSRuntime *rt = trc->runtime;
|
||||
if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
|
||||
return;
|
||||
|
||||
MarkValue(trc, v, name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, const HeapValue *beg, const HeapValue *end, const char *name)
|
||||
{
|
||||
for (const HeapValue *vp = beg; vp < end; ++vp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, vp - beg);
|
||||
MarkValueRaw(trc, vp->get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name)
|
||||
{
|
||||
MarkValueRange(trc, vec, vec + len, name);
|
||||
}
|
||||
|
||||
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
|
||||
void
|
||||
MarkGCThing(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
MarkKind(trc, thing, kind);
|
||||
}
|
||||
|
||||
void
|
||||
MarkGCThing(JSTracer *trc, void *thing)
|
||||
{
|
||||
if (!thing)
|
||||
return;
|
||||
MarkKind(trc, thing, GetGCThingTraceKind(thing));
|
||||
}
|
||||
|
||||
void
|
||||
MarkGCThing(JSTracer *trc, void *thing, const char *name, size_t index)
|
||||
{
|
||||
JS_SET_TRACING_INDEX(trc, name, index);
|
||||
MarkGCThing(trc, thing);
|
||||
}
|
||||
|
||||
void
|
||||
Mark(JSTracer *trc, void *thing, JSGCTraceKind kind, const char *name)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkKind(trc, thing, kind);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSObject *thing, const char *name)
|
||||
{
|
||||
MarkObjectUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSString *thing, const char *name)
|
||||
{
|
||||
MarkStringUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSScript *thing, const char *name)
|
||||
{
|
||||
MarkScriptUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, const Shape *thing, const char *name)
|
||||
{
|
||||
MarkShapeUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, types::TypeObject *thing, const char *name)
|
||||
{
|
||||
MarkTypeObjectUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSXML *thing, const char *name)
|
||||
{
|
||||
MarkXMLUnbarriered(trc, thing, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, const Value &v, const char *name)
|
||||
{
|
||||
MarkValueUnbarriered(trc, v, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, jsid id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdUnbarriered(trc, id);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootGCThing(JSTracer *trc, void *thing, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkGCThing(trc, thing);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, const Shape **vec, const char *name)
|
||||
{
|
||||
const Shape **end = vec + len;
|
||||
for (const Shape **sp = vec; sp < end; ++sp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, sp - vec);
|
||||
MarkShapeUnbarriered(trc, *sp, name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, JSObject **vec, const char *name)
|
||||
{
|
||||
JSObject **end = vec + len;
|
||||
for (JSObject **sp = vec; sp < end; ++sp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, sp - vec);
|
||||
MarkObjectUnbarriered(trc, *sp, name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, const Value *beg, const Value *end, const char *name)
|
||||
{
|
||||
for (const Value *vp = beg; vp < end; ++vp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, vp - beg);
|
||||
MarkValueRaw(trc, *vp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name)
|
||||
{
|
||||
MarkRootRange(trc, vec, vec + len, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, jsid *beg, jsid *end, const char *name)
|
||||
{
|
||||
MarkIdRangeUnbarriered(trc, beg, end, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
{
|
||||
MarkIdRangeUnbarriered(trc, len, vec, name);
|
||||
}
|
||||
|
||||
static void
|
||||
ScanShape(GCMarker *gcmarker, const Shape *shape)
|
||||
{
|
||||
@ -679,7 +504,7 @@ ScanBaseShape(GCMarker *gcmarker, BaseShape *base)
|
||||
*/
|
||||
if (base->isOwned()) {
|
||||
UnownedBaseShape *unowned = base->baseUnowned();
|
||||
JS_SAME_COMPARTMENT_ASSERT(base, unowned);
|
||||
JS_ASSERT(base->compartment() == unowned->compartment());
|
||||
unowned->markIfUnmarked(gcmarker->getMarkColor());
|
||||
}
|
||||
}
|
||||
@ -815,12 +640,12 @@ MarkChildren(JSTracer *trc, JSObject *obj)
|
||||
uint32_t nslots = obj->slotSpan();
|
||||
for (uint32_t i = 0; i < nslots; i++) {
|
||||
JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i);
|
||||
MarkValueRaw(trc, obj->nativeGetSlot(i));
|
||||
MarkValueInternal(trc, obj->nativeGetSlot(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSString *str)
|
||||
{
|
||||
/*
|
||||
@ -836,8 +661,7 @@ MarkChildren(JSTracer *trc, JSString *str)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSScript *script)
|
||||
{
|
||||
CheckScript(script, NULL);
|
||||
@ -845,7 +669,7 @@ MarkChildren(JSTracer *trc, JSScript *script)
|
||||
JS_ASSERT_IF(trc->runtime->gcCheckCompartment,
|
||||
script->compartment() == trc->runtime->gcCheckCompartment);
|
||||
|
||||
MarkAtomRange(trc, script->natoms, script->atoms, "atoms");
|
||||
MarkStringRootRange(trc, script->natoms, script->atoms, "atoms");
|
||||
|
||||
if (JSScript::isValidOffset(script->objectsOffset)) {
|
||||
JSObjectArray *objarray = script->objects();
|
||||
@ -880,16 +704,16 @@ MarkChildren(JSTracer *trc, JSScript *script)
|
||||
script->markTrapClosures(trc);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, const Shape *shape)
|
||||
{
|
||||
MarkBaseShapeUnbarriered(trc, shape->base(), "base");
|
||||
MarkIdUnbarriered(trc, shape->maybePropid(), "propid");
|
||||
MarkId(trc, shape->maybePropid(), "propid");
|
||||
if (shape->previous())
|
||||
MarkShape(trc, shape->previous(), "parent");
|
||||
}
|
||||
|
||||
inline void
|
||||
static inline void
|
||||
MarkBaseShapeGetterSetter(JSTracer *trc, BaseShape *base)
|
||||
{
|
||||
if (base->hasGetterObject())
|
||||
@ -898,7 +722,7 @@ MarkBaseShapeGetterSetter(JSTracer *trc, BaseShape *base)
|
||||
MarkObjectUnbarriered(trc, base->setterObject(), "setter");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, BaseShape *base)
|
||||
{
|
||||
MarkBaseShapeGetterSetter(trc, base);
|
||||
@ -952,7 +776,7 @@ MarkCycleCollectorChildren(JSTracer *trc, const Shape *shape)
|
||||
JSObject *prevParent = NULL;
|
||||
do {
|
||||
MarkCycleCollectorChildren(trc, shape->base(), &prevParent);
|
||||
MarkIdUnbarriered(trc, shape->maybePropid(), "propid");
|
||||
MarkId(trc, shape->maybePropid(), "propid");
|
||||
shape = shape->previous();
|
||||
} while (shape);
|
||||
}
|
||||
@ -987,7 +811,7 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
|
||||
PushMarkStack(gcmarker, type->interpretedFunction);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
{
|
||||
if (!type->singleton) {
|
||||
@ -1015,7 +839,7 @@ MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
}
|
||||
|
||||
#ifdef JS_HAS_XML_SUPPORT
|
||||
void
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSXML *xml)
|
||||
{
|
||||
js_TraceXML(trc, xml);
|
||||
|
@ -1,41 +1,8 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is SpiderMonkey code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
*/
|
||||
/* 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 jsgcmark_h___
|
||||
#define jsgcmark_h___
|
||||
@ -51,72 +18,112 @@
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
/*** Object Marking ***/
|
||||
|
||||
/*
|
||||
* These functions expose marking functionality for all of the different GC
|
||||
* thing kinds. For each GC thing, there are several variants. As an example,
|
||||
* these are the variants generated for JSObject. They are listed from most to
|
||||
* least desirable for use:
|
||||
*
|
||||
* MarkObject(JSTracer *trc, const HeapPtr<JSObject> &thing, const char *name);
|
||||
* This function should be used for marking JSObjects, in preference to all
|
||||
* others below. Use it when you have HeapPtr<JSObject>, which
|
||||
* automatically implements write barriers.
|
||||
*
|
||||
* MarkObjectRoot(JSTracer *trc, JSObject *thing, const char *name);
|
||||
* This function is only valid during the root marking phase of GC (i.e.,
|
||||
* when MarkRuntime is on the stack).
|
||||
*
|
||||
* MarkObjectUnbarriered(JSTracer *trc, JSObject *thing, const char *name);
|
||||
* Like MarkObject, this function can be called at any time. It is more
|
||||
* forgiving, since it doesn't demand a HeapPtr as an argument. Its use
|
||||
* should always be accompanied by a comment explaining how write barriers
|
||||
* are implemented for the given field.
|
||||
*
|
||||
* Additionally, the functions MarkObjectRange and MarkObjectRootRange are
|
||||
* defined for marking arrays of object pointers.
|
||||
*/
|
||||
#define DeclMarker(base, type) \
|
||||
void Mark##base(JSTracer *trc, const HeapPtr<type> &thing, const char *name); \
|
||||
void Mark##base##Root(JSTracer *trc, type *thing, const char *name); \
|
||||
void Mark##base##Unbarriered(JSTracer *trc, type *thing, const char *name); \
|
||||
void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name); \
|
||||
void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name);
|
||||
|
||||
DeclMarker(BaseShape, BaseShape)
|
||||
DeclMarker(Object, ArgumentsObject)
|
||||
DeclMarker(Object, GlobalObject)
|
||||
DeclMarker(Object, JSObject)
|
||||
DeclMarker(Object, JSFunction)
|
||||
DeclMarker(Script, JSScript)
|
||||
DeclMarker(Shape, Shape)
|
||||
DeclMarker(String, JSAtom)
|
||||
DeclMarker(String, JSString)
|
||||
DeclMarker(String, JSFlatString)
|
||||
DeclMarker(String, JSLinearString)
|
||||
DeclMarker(TypeObject, types::TypeObject)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
DeclMarker(XML, JSXML)
|
||||
#endif
|
||||
|
||||
/*** Externally Typed Marking ***/
|
||||
|
||||
/*
|
||||
* Note: this must only be called by the GC and only when we are tracing through
|
||||
* MarkRoots. It is explicitly for ConservativeStackMarking and should go away
|
||||
* after we transition to exact rooting.
|
||||
*/
|
||||
void
|
||||
MarkObjectUnbarriered(JSTracer *trc, JSObject *obj, const char *name);
|
||||
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind);
|
||||
|
||||
void
|
||||
MarkObject(JSTracer *trc, const MarkablePtr<JSObject> &obj, const char *name);
|
||||
MarkGCThingRoot(JSTracer *trc, void *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkStringUnbarriered(JSTracer *trc, JSString *str, const char *name);
|
||||
|
||||
void
|
||||
MarkString(JSTracer *trc, const MarkablePtr<JSString> &str, const char *name);
|
||||
|
||||
void
|
||||
MarkScriptUnbarriered(JSTracer *trc, JSScript *script, const char *name);
|
||||
|
||||
void
|
||||
MarkScript(JSTracer *trc, const MarkablePtr<JSScript> &script, const char *name);
|
||||
|
||||
void
|
||||
MarkShapeUnbarriered(JSTracer *trc, const Shape *shape, const char *name);
|
||||
|
||||
void
|
||||
MarkShape(JSTracer *trc, const MarkablePtr<const Shape> &shape, const char *name);
|
||||
|
||||
void
|
||||
MarkBaseShapeUnbarriered(JSTracer *trc, BaseShape *shape, const char *name);
|
||||
|
||||
void
|
||||
MarkTypeObjectUnbarriered(JSTracer *trc, types::TypeObject *type, const char *name);
|
||||
|
||||
void
|
||||
MarkTypeObject(JSTracer *trc, const MarkablePtr<types::TypeObject> &type, const char *name);
|
||||
|
||||
void
|
||||
MarkXMLUnbarriered(JSTracer *trc, JSXML *xml, const char *name);
|
||||
|
||||
void
|
||||
MarkXML(JSTracer *trc, const MarkablePtr<JSXML> &xml, const char *name);
|
||||
|
||||
void
|
||||
MarkObjectRange(JSTracer *trc, size_t len, HeapPtr<JSObject> *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkXMLRange(JSTracer *trc, size_t len, HeapPtr<JSXML> *vec, const char *name);
|
||||
/*** ID Marking ***/
|
||||
|
||||
void
|
||||
MarkId(JSTracer *trc, const HeapId &id, const char *name);
|
||||
|
||||
void
|
||||
MarkIdRange(JSTracer *trc, js::HeapId *beg, js::HeapId *end, const char *name);
|
||||
MarkIdRoot(JSTracer *trc, const jsid &id, const char *name);
|
||||
|
||||
void
|
||||
MarkIdRangeUnbarriered(JSTracer *trc, size_t len, jsid *vec, const char *name);
|
||||
MarkIdRange(JSTracer *trc, size_t len, js::HeapId *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkIdRangeUnbarriered(JSTracer *trc, jsid *beg, jsid *end, const char *name);
|
||||
MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind);
|
||||
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name);
|
||||
/*** Value Marking ***/
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, const Value &v, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name);
|
||||
|
||||
inline void
|
||||
MarkValueRootRange(JSTracer *trc, const Value *begin, const Value *end, const char *name)
|
||||
{
|
||||
MarkValueRootRange(trc, end - begin, begin, name);
|
||||
}
|
||||
|
||||
/*** Special Cases ***/
|
||||
|
||||
/* TypeNewObject contains a HeapPtr<const Shape> that needs a unique cast. */
|
||||
void
|
||||
MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name);
|
||||
|
||||
/* Direct value access used by the write barriers and the methodjit */
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name);
|
||||
|
||||
/*
|
||||
* Mark a value that may be in a different compartment from the compartment
|
||||
* being GC'd. (Although it won't be marked if it's in the wrong compartment.)
|
||||
@ -124,84 +131,27 @@ MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name);
|
||||
void
|
||||
MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, const HeapValue *beg, const HeapValue *end, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSObject *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSString *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSScript *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, const Shape *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, types::TypeObject *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, JSXML *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, const Value &v, const char *name);
|
||||
|
||||
void
|
||||
MarkRoot(JSTracer *trc, jsid id, const char *name);
|
||||
|
||||
void
|
||||
MarkRootGCThing(JSTracer *trc, void *thing, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, const Shape **vec, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, JSObject **vec, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, const Value *beg, const Value *end, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, jsid *beg, jsid *end, const char *name);
|
||||
|
||||
void
|
||||
MarkRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
|
||||
|
||||
/*
|
||||
* MarkChildren<JSObject> is exposed solely for preWriteBarrier on
|
||||
* JSObject::TradeGuts. It should not be considered external interface.
|
||||
*/
|
||||
void
|
||||
MarkChildren(JSTracer *trc, JSObject *obj);
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, JSString *str);
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, const Shape *shape);
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, JSScript *script);
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, JSXML *xml);
|
||||
|
||||
/*
|
||||
* Trace through the shape and any shapes it contains to mark
|
||||
* non-shape children.
|
||||
* non-shape children. This is exposed to the JS API as
|
||||
* JS_TraceShapeCycleCollectorChildren.
|
||||
*/
|
||||
void
|
||||
MarkCycleCollectorChildren(JSTracer *trc, const Shape *shape);
|
||||
|
||||
/*** Generic ***/
|
||||
/*
|
||||
* Use function overloading to decide which function should be called based on
|
||||
* the type of the object. The static type is used at compile time to link to
|
||||
* the corresponding Mark/IsMarked function.
|
||||
* The Mark() functions interface should only be used by code that must be
|
||||
* templated. Other uses should use the more specific, type-named functions.
|
||||
*/
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
{
|
||||
@ -209,13 +159,13 @@ Mark(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
}
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, const MarkablePtr<JSObject> &o, const char *name)
|
||||
Mark(JSTracer *trc, const HeapPtr<JSObject> &o, const char *name)
|
||||
{
|
||||
MarkObject(trc, o, name);
|
||||
}
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, const MarkablePtr<JSXML> &xml, const char *name)
|
||||
Mark(JSTracer *trc, const HeapPtr<JSXML> &xml, const char *name)
|
||||
{
|
||||
MarkXML(trc, xml, name);
|
||||
}
|
||||
@ -228,12 +178,6 @@ IsMarked(const js::Value &v)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(JSObject *o)
|
||||
{
|
||||
return !IsAboutToBeFinalized(o);
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(Cell *cell)
|
||||
{
|
||||
|
@ -1343,7 +1343,7 @@ TypeNewScript::writeBarrierPre(TypeNewScript *newScript)
|
||||
JSCompartment *comp = newScript->fun->compartment();
|
||||
if (comp->needsBarrier()) {
|
||||
MarkObjectUnbarriered(comp->barrierTracer(), newScript->fun, "write barrier");
|
||||
MarkShapeUnbarriered(comp->barrierTracer(), newScript->shape, "write barrier");
|
||||
MarkShape(comp->barrierTracer(), newScript->shape, "write barrier");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ js_LeaveSharpObject(JSContext *cx, JSIdArray **idap)
|
||||
static intN
|
||||
gc_sharp_table_entry_marker(JSHashEntry *he, intN i, void *arg)
|
||||
{
|
||||
MarkRoot((JSTracer *)arg, (JSObject *)he->key, "sharp table entry");
|
||||
MarkObjectRoot((JSTracer *)arg, (JSObject *)he->key, "sharp table entry");
|
||||
return JS_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
@ -771,7 +771,7 @@ struct Shape : public js::gc::Cell
|
||||
}
|
||||
|
||||
jsid propid() const { JS_ASSERT(!isEmptyShape()); return maybePropid(); }
|
||||
jsid maybePropid() const { JS_ASSERT(!JSID_IS_VOID(propid_)); return propid_; }
|
||||
const HeapId &maybePropid() const { JS_ASSERT(!JSID_IS_VOID(propid_)); return propid_; }
|
||||
|
||||
int16_t shortid() const { JS_ASSERT(hasShortID()); return maybeShortid(); }
|
||||
int16_t maybeShortid() const { return shortid_; }
|
||||
|
@ -395,7 +395,7 @@ Shape::writeBarrierPre(const js::Shape *shape)
|
||||
|
||||
JSCompartment *comp = shape->compartment();
|
||||
if (comp->needsBarrier())
|
||||
MarkShapeUnbarriered(comp->barrierTracer(), shape, "write barrier");
|
||||
MarkShapeUnbarriered(comp->barrierTracer(), const_cast<Shape *>(shape), "write barrier");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ Shape::readBarrier(const Shape *shape)
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
JSCompartment *comp = shape->compartment();
|
||||
if (comp->needsBarrier())
|
||||
MarkShapeUnbarriered(comp->barrierTracer(), shape, "read barrier");
|
||||
MarkShapeUnbarriered(comp->barrierTracer(), const_cast<Shape *>(shape), "read barrier");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -861,18 +861,23 @@ attr_identity(const JSXML *xmla, const JSXML *xmlb)
|
||||
return qname_identity(xmla->name, xmlb->name);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<T> *cursor)
|
||||
js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<JSXML> *cursor)
|
||||
{
|
||||
for (; cursor; cursor = cursor->next) {
|
||||
if (cursor->root)
|
||||
Mark(trc, (const MarkablePtr<T> &)cursor->root, "cursor_root");
|
||||
MarkXML(trc, (const HeapPtr<JSXML> &)cursor->root, "cursor_root");
|
||||
}
|
||||
}
|
||||
|
||||
template void js_XMLArrayCursorTrace<JSXML>(JSTracer *trc, JSXMLArrayCursor<JSXML> *cursor);
|
||||
template void js_XMLArrayCursorTrace<JSObject>(JSTracer *trc, JSXMLArrayCursor<JSObject> *cursor);
|
||||
void
|
||||
js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<JSObject> *cursor)
|
||||
{
|
||||
for (; cursor; cursor = cursor->next) {
|
||||
if (cursor->root)
|
||||
MarkObject(trc, (const HeapPtr<JSObject> &)cursor->root, "cursor_root");
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static HeapPtr<T> *
|
||||
|
@ -123,9 +123,8 @@ struct JSXMLArrayCursor
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void
|
||||
js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<T> *cursor);
|
||||
void js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<JSXML> *cursor);
|
||||
void js_XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor<JSObject> *cursor);
|
||||
|
||||
#define JSXML_PRESET_CAPACITY JS_BIT(31)
|
||||
#define JSXML_CAPACITY_MASK JS_BITMASK(31)
|
||||
|
@ -455,7 +455,7 @@ StackSpace::markFrameSlots(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbyt
|
||||
|
||||
if (!fp->isScriptFrame()) {
|
||||
JS_ASSERT(fp->isDummyFrame());
|
||||
gc::MarkRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
|
||||
gc::MarkValueRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -464,7 +464,7 @@ StackSpace::markFrameSlots(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbyt
|
||||
|
||||
JSScript *script = fp->script();
|
||||
if (!script->hasAnalysis() || !script->analysis()->ranLifetimes()) {
|
||||
gc::MarkRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
|
||||
gc::MarkValueRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -485,12 +485,12 @@ StackSpace::markFrameSlots(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbyt
|
||||
|
||||
/* Will this slot be synced by the JIT? */
|
||||
if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset))
|
||||
gc::MarkRoot(trc, *vp, "vm_stack");
|
||||
gc::MarkValueRoot(trc, *vp, "vm_stack");
|
||||
else
|
||||
*vp = UndefinedValue();
|
||||
}
|
||||
|
||||
gc::MarkRootRange(trc, fixedEnd, slotsEnd, "vm_stack");
|
||||
gc::MarkValueRootRange(trc, fixedEnd, slotsEnd, "vm_stack");
|
||||
}
|
||||
|
||||
void
|
||||
@ -527,7 +527,7 @@ StackSpace::mark(JSTracer *trc)
|
||||
pc = fp->prevpc(&site);
|
||||
JS_ASSERT_IF(fp->prev(), !site);
|
||||
}
|
||||
gc::MarkRootRange(trc, seg->slotsBegin(), slotsEnd, "vm_stack");
|
||||
gc::MarkValueRootRange(trc, seg->slotsBegin(), slotsEnd, "vm_stack");
|
||||
nextSegEnd = (Value *)seg;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user