author | Nicholas Nethercote <nnethercote@mozilla.com> |
Mon, 09 Sep 2013 15:50:19 -0700 | |
changeset 146317 | ea33604f6232a07d3e4be77718226d569490407f |
parent 146316 | ea1af870680c7ec875f0bce61c8541cc37a3b9d6 |
child 146318 | 25bfaa9538928bc70683aea449dc25b6ece6d4d1 |
child 146396 | bd53e981282f9ed59ca35ce59776c2f94e9f6e7d |
push id | 25251 |
push user | Ms2ger@gmail.com |
push date | Tue, 10 Sep 2013 08:13:39 +0000 |
treeherder | mozilla-central@25bfaa953892 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | terrence |
bugs | 914032 |
milestone | 26.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/gc/Barrier-inl.h | file | annotate | diff | comparison | revisions | |
js/src/gc/Barrier.h | file | annotate | diff | comparison | revisions | |
js/src/gc/Marking.h | file | annotate | diff | comparison | revisions | |
js/src/jsinfer.h | file | annotate | diff | comparison | revisions | |
js/src/jsinferinlines.h | file | annotate | diff | comparison | revisions | |
js/src/jsscript.h | file | annotate | diff | comparison | revisions | |
js/src/jsscriptinlines.h | file | annotate | diff | comparison | revisions | |
js/src/vm/Shape-inl.h | file | annotate | diff | comparison | revisions | |
js/src/vm/Shape.h | file | annotate | diff | comparison | revisions | |
js/src/vm/String-inl.h | file | annotate | diff | comparison | revisions | |
js/src/vm/String.h | file | annotate | diff | comparison | revisions |
--- a/js/src/gc/Barrier-inl.h +++ b/js/src/gc/Barrier-inl.h @@ -13,42 +13,16 @@ #include "gc/Marking.h" #include "gc/StoreBuffer.h" #include "vm/String-inl.h" namespace js { -template <typename T, typename Unioned> -void -EncapsulatedPtr<T, Unioned>::pre() -{ - T::writeBarrierPre(value); -} - -template <typename T> -inline void -RelocatablePtr<T>::post() -{ -#ifdef JSGC_GENERATIONAL - JS_ASSERT(this->value); - T::writeBarrierPostRelocate(this->value, &this->value); -#endif -} - -template <typename T> -inline void -RelocatablePtr<T>::relocate(JSRuntime *rt) -{ -#ifdef JSGC_GENERATIONAL - T::writeBarrierPostRemove(this->value, &this->value); -#endif -} - #ifdef JSGC_GENERATIONAL class DenseRangeRef : public gc::BufferableRef { JSObject *owner; uint32_t start; uint32_t end; public:
--- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -192,17 +192,17 @@ class EncapsulatedPtr Unioned *unsafeGetUnioned() { return &other; } T &operator*() const { return *value; } T *operator->() const { return value; } operator T*() const { return value; } protected: - void pre(); + void pre() { T::writeBarrierPre(value); } }; template <class T, class Unioned = uintptr_t> class HeapPtr : public EncapsulatedPtr<T, Unioned> { public: HeapPtr() : EncapsulatedPtr<T>(NULL) {} explicit HeapPtr(T *v) : EncapsulatedPtr<T>(v) { post(); } @@ -315,18 +315,28 @@ class RelocatablePtr : public Encapsulat JSRuntime *rt = this->value->runtimeFromMainThread(); this->value = v; relocate(rt); } return *this; } protected: - inline void post(); - inline void relocate(JSRuntime *rt); + void post() { +#ifdef JSGC_GENERATIONAL + JS_ASSERT(this->value); + T::writeBarrierPostRelocate(this->value, &this->value); +#endif + } + + void relocate(JSRuntime *rt) { +#ifdef JSGC_GENERATIONAL + T::writeBarrierPostRemove(this->value, &this->value); +#endif + } }; /* * This is a hack for RegExpStatics::updateFromMatch. It allows us to do two * barriers with only one branch to check if we're in an incremental GC. */ template<class T1, class T2> static inline void
--- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -3,17 +3,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef gc_Marking_h #define gc_Marking_h #include "gc/Barrier.h" -#include "jit/IonCode.h" #include "js/TypeDecls.h" class JSAtom; class JSLinearString; namespace js { class ArgumentsObject; @@ -25,16 +24,26 @@ struct GCMarker; class GlobalObject; class LazyScript; class ScopeObject; class Shape; class UnownedBaseShape; template<class, typename> class HeapPtr; +namespace jit { +class IonCode; +class IonScript; +class VMFunction; +} + +namespace types { +class Type; +} + 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
--- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -12,16 +12,17 @@ #include "mozilla/MemoryReporting.h" #include "jsalloc.h" #include "jsfriendapi.h" #include "ds/IdValuePair.h" #include "ds/LifoAlloc.h" #include "gc/Barrier.h" +#include "gc/Marking.h" #include "js/Utility.h" #include "js/Vector.h" namespace js { class TypeRepresentation; class TaggedProto @@ -880,17 +881,18 @@ struct TypeObjectAddendum return kind == TypedObject; } TypeTypedObject *asTypedObject() { JS_ASSERT(isTypedObject()); return (TypeTypedObject*) this; } - static inline void writeBarrierPre(TypeObjectAddendum *newScript); + static inline void writeBarrierPre(TypeObjectAddendum *type); + static void writeBarrierPost(TypeObjectAddendum *newScript, void *addr) {} }; /* * Information attached to a TypeObject if it is always constructed using 'new' * on a particular script. This is used to manage state related to the definite * properties on the type object: these definite properties depend on type * information which could change as the script executes (e.g. a scripted @@ -1147,20 +1149,44 @@ struct TypeObject : gc::Cell /* * Type objects don't have explicit finalizers. Memory owned by a type * object pending deletion is released when weak references are sweeped * from all the compartment's type objects. */ void finalize(FreeOp *fop) {} JS::Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } - static inline void writeBarrierPre(TypeObject *type); + static void writeBarrierPre(TypeObject *type) { +#ifdef JSGC_INCREMENTAL + if (!type || !type->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = type->shadowZone(); + if (shadowZone->needsBarrier()) { + TypeObject *tmp = type; + js::gc::MarkTypeObjectUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == type); + } +#endif + } + static void writeBarrierPost(TypeObject *type, void *addr) {} - static inline void readBarrier(TypeObject *type); + + static void readBarrier(TypeObject *type) { +#ifdef JSGC_INCREMENTAL + JS::shadow::Zone *shadowZone = type->shadowZone(); + if (shadowZone->needsBarrier()) { + TypeObject *tmp = type; + MarkTypeObjectUnbarriered(shadowZone->barrierTracer(), &tmp, "read barrier"); + JS_ASSERT(tmp == type); + } +#endif + } static inline ThingRootKind rootKind() { return THING_ROOT_TYPE_OBJECT; } private: inline uint32_t basePropertyCount() const; inline void setBasePropertyCount(uint32_t count); static void staticAsserts() {
--- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -1566,45 +1566,16 @@ inline int TypeObject::getTypedArrayType() { if (IsTypedArrayClass(clasp)) return clasp - &TypedArrayObject::classes[0]; return ScalarTypeRepresentation::TYPE_MAX; } inline void -TypeObject::writeBarrierPre(TypeObject *type) -{ -#ifdef JSGC_INCREMENTAL - if (!type || !type->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = type->zone(); - if (zone->needsBarrier()) { - TypeObject *tmp = type; - MarkTypeObjectUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == type); - } -#endif -} - -inline void -TypeObject::readBarrier(TypeObject *type) -{ -#ifdef JSGC_INCREMENTAL - JS::Zone *zone = type->zone(); - if (zone->needsBarrier()) { - TypeObject *tmp = type; - MarkTypeObjectUnbarriered(zone->barrierTracer(), &tmp, "read barrier"); - JS_ASSERT(tmp == type); - } -#endif -} - -inline void TypeObjectAddendum::writeBarrierPre(TypeObjectAddendum *type) { #ifdef JSGC_INCREMENTAL if (!type) return; switch (type->kind) { case NewScript:
--- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -16,22 +16,22 @@ #ifdef JS_THREADSAFE #include "jslock.h" #endif #include "jsobj.h" #include "jsopcode.h" #include "gc/Barrier.h" #include "gc/Rooting.h" +#include "jit/IonCode.h" #include "vm/Shape.h" namespace js { namespace jit { - struct IonScript; struct BaselineScript; struct IonScriptCounts; } # define ION_DISABLED_SCRIPT ((js::jit::IonScript *)0x1) # define ION_COMPILING_SCRIPT ((js::jit::IonScript *)0x2) # define BASELINE_DISABLED_SCRIPT ((js::jit::BaselineScript *)0x1) @@ -720,17 +720,22 @@ class JSScript : public js::gc::Cell return ion; } js::jit::IonScript *maybeIonScript() const { return ion; } js::jit::IonScript *const *addressOfIonScript() const { return &ion; } - inline void setIonScript(js::jit::IonScript *ionScript); + void setIonScript(js::jit::IonScript *ionScript) { + if (hasIonScript()) + js::jit::IonScript::writeBarrierPre(tenuredZone(), ion); + ion = ionScript; + updateBaselineOrIonRaw(); + } bool hasBaselineScript() const { return baseline && baseline != BASELINE_DISABLED_SCRIPT; } bool canBaselineCompile() const { return baseline != BASELINE_DISABLED_SCRIPT; } js::jit::BaselineScript *baselineScript() const { @@ -755,17 +760,21 @@ class JSScript : public js::gc::Cell js::jit::IonScript *parallelIonScript() const { JS_ASSERT(hasParallelIonScript()); return parallelIon; } js::jit::IonScript *maybeParallelIonScript() const { return parallelIon; } - inline void setParallelIonScript(js::jit::IonScript *ionScript); + void setParallelIonScript(js::jit::IonScript *ionScript) { + if (hasParallelIonScript()) + js::jit::IonScript::writeBarrierPre(tenuredZone(), parallelIon); + parallelIon = ionScript; + } static size_t offsetOfBaselineScript() { return offsetof(JSScript, baseline); } static size_t offsetOfIonScript() { return offsetof(JSScript, ion); } static size_t offsetOfParallelIonScript() { @@ -1049,18 +1058,33 @@ class JSScript : public js::gc::Cell #ifdef DEBUG uint32_t stepModeCount() { return hasDebugScript ? (debugScript()->stepMode & stepCountMask) : 0; } #endif void finalize(js::FreeOp *fop); JS::Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } - static inline void writeBarrierPre(JSScript *script); + static void writeBarrierPre(JSScript *script) { +#ifdef JSGC_INCREMENTAL + if (!script || !script->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = script->shadowZone(); + if (shadowZone->needsBarrier()) { + MOZ_ASSERT(!js::RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone)); + JSScript *tmp = script; + js::gc::MarkScriptUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == script); + } +#endif + } + static void writeBarrierPost(JSScript *script, void *addr) {} static inline js::ThingRootKind rootKind() { return js::THING_ROOT_SCRIPT; } void markChildren(JSTracer *trc); }; /* The array kind flags are stored in a 4-bit field; make sure they fit. */ @@ -1309,29 +1333,41 @@ class LazyScript : public js::gc::Cell return lineno_; } uint32_t column() const { return column_; } uint32_t staticLevel(JSContext *cx) const; - Zone *zone() const { - return Cell::tenuredZone(); - } + Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } void markChildren(JSTracer *trc); void finalize(js::FreeOp *fop); size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { return mallocSizeOf(table_); } - static inline void writeBarrierPre(LazyScript *lazy); + static void writeBarrierPre(LazyScript *lazy) { +#ifdef JSGC_INCREMENTAL + if (!lazy || !lazy->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = lazy->shadowZone(); + if (shadowZone->needsBarrier()) { + MOZ_ASSERT(!js::RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone)); + js::LazyScript *tmp = lazy; + MarkLazyScriptUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == lazy); + } +#endif + } }; /* If this fails, add/remove padding within LazyScript. */ JS_STATIC_ASSERT(sizeof(LazyScript) % js::gc::CellSize == 0); /* * New-script-hook calling is factored from JSScript::fullyInitFromEmitter() so * that it and callers of XDRScript() can share this code. In the case of
--- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -96,50 +96,16 @@ JSScript::global() const { /* * A JSScript always marks its compartment's global (via bindings) so we * can assert that maybeGlobal is non-null here. */ return *compartment()->maybeGlobal(); } -inline void -JSScript::writeBarrierPre(JSScript *script) -{ -#ifdef JSGC_INCREMENTAL - if (!script || !script->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = script->zone(); - if (zone->needsBarrier()) { - JS_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting()); - JSScript *tmp = script; - MarkScriptUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == script); - } -#endif -} - -/* static */ inline void -js::LazyScript::writeBarrierPre(js::LazyScript *lazy) -{ -#ifdef JSGC_INCREMENTAL - if (!lazy || !lazy->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = lazy->zone(); - if (zone->needsBarrier()) { - JS_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting()); - js::LazyScript *tmp = lazy; - MarkLazyScriptUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == lazy); - } -#endif -} - inline JSPrincipals * JSScript::principals() { return compartment()->principals; } inline JSFunction * JSScript::originalFunction() const { @@ -151,31 +117,16 @@ JSScript::originalFunction() const { inline void JSScript::setOriginalFunctionObject(JSObject *fun) { JS_ASSERT(isCallsiteClone); JS_ASSERT(fun->is<JSFunction>()); enclosingScopeOrOriginalFunction_ = fun; } inline void -JSScript::setIonScript(js::jit::IonScript *ionScript) { - if (hasIonScript()) - js::jit::IonScript::writeBarrierPre(tenuredZone(), ion); - ion = ionScript; - updateBaselineOrIonRaw(); -} - -inline void -JSScript::setParallelIonScript(js::jit::IonScript *ionScript) { - if (hasParallelIonScript()) - js::jit::IonScript::writeBarrierPre(tenuredZone(), parallelIon); - parallelIon = ionScript; -} - -inline void JSScript::setBaselineScript(js::jit::BaselineScript *baselineScript) { #ifdef JS_ION if (hasBaselineScript()) js::jit::BaselineScript::writeBarrierPre(tenuredZone(), baseline); #endif baseline = baselineScript; updateBaselineOrIonRaw(); }
--- a/js/src/vm/Shape-inl.h +++ b/js/src/vm/Shape-inl.h @@ -357,83 +357,25 @@ EmptyShape::EmptyShape(UnownedBaseShape : js::Shape(base, nfixed) { /* Only empty shapes can be NON_NATIVE. */ if (!getObjectClass()->isNative()) flags |= NON_NATIVE; } inline void -Shape::writeBarrierPre(Shape *shape) -{ -#ifdef JSGC_INCREMENTAL - if (!shape || !shape->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = shape->zone(); - if (zone->needsBarrier()) { - Shape *tmp = shape; - MarkShapeUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == shape); - } -#endif -} - -inline void -Shape::readBarrier(Shape *shape) -{ -#ifdef JSGC_INCREMENTAL - JS::Zone *zone = shape->zone(); - if (zone->needsBarrier()) { - Shape *tmp = shape; - MarkShapeUnbarriered(zone->barrierTracer(), &tmp, "read barrier"); - JS_ASSERT(tmp == shape); - } -#endif -} - -inline void Shape::markChildren(JSTracer *trc) { MarkBaseShape(trc, &base_, "base"); gc::MarkId(trc, &propidRef(), "propid"); if (parent) MarkShape(trc, &parent, "parent"); } inline void -BaseShape::writeBarrierPre(BaseShape *base) -{ -#ifdef JSGC_INCREMENTAL - if (!base || !base->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = base->zone(); - if (zone->needsBarrier()) { - BaseShape *tmp = base; - MarkBaseShapeUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == base); - } -#endif -} - -inline void -BaseShape::readBarrier(BaseShape *base) -{ -#ifdef JSGC_INCREMENTAL - JS::Zone *zone = base->zone(); - if (zone->needsBarrier()) { - BaseShape *tmp = base; - MarkBaseShapeUnbarriered(zone->barrierTracer(), &tmp, "read barrier"); - JS_ASSERT(tmp == base); - } -#endif -} - -inline void BaseShape::markChildren(JSTracer *trc) { if (hasGetterObject()) MarkObjectUnbarriered(trc, &getterObj, "getter"); if (hasSetterObject()) MarkObjectUnbarriered(trc, &setterObj, "setter");
--- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -9,24 +9,25 @@ #include "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" #include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/TemplateLib.h" #include "jsapi.h" +#include "jsfriendapi.h" #include "jsinfer.h" -#include "jsfriendapi.h" #include "jspropertytree.h" #include "jstypes.h" #include "NamespaceImports.h" #include "gc/Barrier.h" #include "gc/Heap.h" +#include "gc/Marking.h" #include "gc/Rooting.h" #include "js/HashTable.h" #include "js/RootingAPI.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4800) #pragma warning(push) @@ -625,16 +626,17 @@ class BaseShape : public js::gc::Cell ShapeTable &table() const { JS_ASSERT(table_ && isOwned()); return *table_; } void setTable(ShapeTable *table) { JS_ASSERT(isOwned()); table_ = table; } uint32_t slotSpan() const { JS_ASSERT(isOwned()); return slotSpan_; } void setSlotSpan(uint32_t slotSpan) { JS_ASSERT(isOwned()); slotSpan_ = slotSpan; } JSCompartment *compartment() const { return compartment_; } JS::Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } /* Lookup base shapes from the compartment's baseShapes table. */ static UnownedBaseShape* getUnowned(ExclusiveContext *cx, const StackBaseShape &base); /* Get the canonical base shape. */ inline UnownedBaseShape* unowned(); /* Get the canonical base shape for an owned one. */ @@ -645,19 +647,42 @@ class BaseShape : public js::gc::Cell /* Check that an owned base shape is consistent with its unowned base. */ inline void assertConsistency(); /* For JIT usage */ static inline size_t offsetOfParent() { return offsetof(BaseShape, parent); } static inline size_t offsetOfFlags() { return offsetof(BaseShape, flags); } - static inline void writeBarrierPre(BaseShape *shape); - static void writeBarrierPost(BaseShape *shape, void *addr) {} - static inline void readBarrier(BaseShape *shape); + static void writeBarrierPre(BaseShape *base) { +#ifdef JSGC_INCREMENTAL + if (!base || !base->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = base->shadowZone(); + if (shadowZone->needsBarrier()) { + BaseShape *tmp = base; + js::gc::MarkBaseShapeUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == base); + } +#endif + } + + static void writeBarrierPost(BaseShape *base, void *addr) {} + + static inline void readBarrier(BaseShape *base) { +#ifdef JSGC_INCREMENTAL + JS::shadow::Zone *shadowZone = base->shadowZone(); + if (shadowZone->needsBarrier()) { + BaseShape *tmp = base; + js::gc::MarkBaseShapeUnbarriered(shadowZone->barrierTracer(), &tmp, "read barrier"); + JS_ASSERT(tmp == base); + } +#endif + } static inline ThingRootKind rootKind() { return THING_ROOT_BASE_SHAPE; } inline void markChildren(JSTracer *trc); private: static void staticAsserts() { JS_STATIC_ASSERT(offsetof(BaseShape, clasp) == offsetof(js::shadow::BaseShape, clasp)); @@ -1131,26 +1156,49 @@ class Shape : public js::gc::Cell void dumpSubtree(JSContext *cx, int level, FILE *fp) const; #endif void sweep(); void finalize(FreeOp *fop); void removeChild(Shape *child); JS::Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } - static inline void writeBarrierPre(Shape *shape); + static void writeBarrierPre(Shape *shape) { +#ifdef JSGC_INCREMENTAL + if (!shape || !shape->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = shape->shadowZone(); + if (shadowZone->needsBarrier()) { + Shape *tmp = shape; + js::gc::MarkShapeUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == shape); + } +#endif + } + static void writeBarrierPost(Shape *shape, void *addr) {} /* * All weak references need a read barrier for incremental GC. This getter * method implements the read barrier. It's used to obtain initial shapes * from the compartment. */ - static inline void readBarrier(Shape *shape); + static inline void readBarrier(Shape *shape) { +#ifdef JSGC_INCREMENTAL + JS::shadow::Zone *shadowZone = shape->shadowZone(); + if (shadowZone->needsBarrier()) { + Shape *tmp = shape; + js::gc::MarkShapeUnbarriered(shadowZone->barrierTracer(), &tmp, "read barrier"); + JS_ASSERT(tmp == shape); + } +#endif + } static inline ThingRootKind rootKind() { return THING_ROOT_SHAPE; } inline void markChildren(JSTracer *trc); inline Shape *search(ExclusiveContext *cx, jsid id) { Shape **_; return search(cx, this, id, &_);
--- a/js/src/vm/String-inl.h +++ b/js/src/vm/String-inl.h @@ -96,55 +96,16 @@ StringWriteBarrierPost(js::ThreadSafeCon static inline void StringWriteBarrierPostRemove(js::ThreadSafeContext *maybecx, JSString **strp) { } } /* namespace js */ -inline void -JSString::writeBarrierPre(JSString *str) -{ -#ifdef JSGC_INCREMENTAL - if (!str || !str->runtimeFromAnyThread()->needsBarrier()) - return; - - JS::Zone *zone = str->zone(); - if (zone->needsBarrier()) { - JSString *tmp = str; - MarkStringUnbarriered(zone->barrierTracer(), &tmp, "write barrier"); - JS_ASSERT(tmp == str); - } -#endif -} - -inline bool -JSString::needWriteBarrierPre(JS::Zone *zone) -{ -#ifdef JSGC_INCREMENTAL - return zone->needsBarrier(); -#else - return false; -#endif -} - -inline void -JSString::readBarrier(JSString *str) -{ -#ifdef JSGC_INCREMENTAL - JS::Zone *zone = str->zone(); - if (zone->needsBarrier()) { - JSString *tmp = str; - MarkStringUnbarriered(zone->barrierTracer(), &tmp, "read barrier"); - JS_ASSERT(tmp == str); - } -#endif -} - JS_ALWAYS_INLINE bool JSString::validateLength(js::ThreadSafeContext *maybecx, size_t length) { if (JS_UNLIKELY(length > JSString::MAX_LENGTH)) { js_ReportAllocationOverflow(maybecx); return false; }
--- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -11,16 +11,17 @@ #include "mozilla/PodOperations.h" #include "jsapi.h" #include "jsfriendapi.h" #include "jsstr.h" #include "gc/Barrier.h" #include "gc/Heap.h" +#include "gc/Marking.h" #include "gc/Rooting.h" #include "js/CharacterEncoding.h" #include "js/RootingAPI.h" class JSDependentString; class JSExtensibleString; class JSExternalString; class JSInlineString; @@ -422,25 +423,57 @@ class JSString : public js::gc::Cell return offsetof(JSString, d.lengthAndFlags); } static size_t offsetOfChars() { return offsetof(JSString, d.u1.chars); } JS::Zone *zone() const { return tenuredZone(); } + JS::shadow::Zone *shadowZone() const { return JS::shadow::Zone::asShadowZone(zone()); } + bool isInsideZone(JS::Zone *zone_) { return tenuredIsInsideZone(zone_); } js::gc::AllocKind getAllocKind() const { return tenuredGetAllocKind(); } - static inline void writeBarrierPre(JSString *str); + static void writeBarrierPre(JSString *str) { +#ifdef JSGC_INCREMENTAL + if (!str || !str->shadowRuntimeFromAnyThread()->needsBarrier()) + return; + + JS::shadow::Zone *shadowZone = str->shadowZone(); + if (shadowZone->needsBarrier()) { + JSString *tmp = str; + js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier"); + JS_ASSERT(tmp == str); + } +#endif + } + static void writeBarrierPost(JSString *str, void *addr) {} static void writeBarrierPostRelocate(JSString *str, void *addr) {} static void writeBarrierPostRemove(JSString *str, void *addr) {} - static inline bool needWriteBarrierPre(JS::Zone *zone); - static inline void readBarrier(JSString *str); + + static bool needWriteBarrierPre(JS::Zone *zone) { +#ifdef JSGC_INCREMENTAL + return JS::shadow::Zone::asShadowZone(zone)->needsBarrier(); +#else + return false; +#endif + } + + static void readBarrier(JSString *str) { +#ifdef JSGC_INCREMENTAL + JS::shadow::Zone *shadowZone = str->shadowZone(); + if (shadowZone->needsBarrier()) { + JSString *tmp = str; + js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &tmp, "read barrier"); + JS_ASSERT(tmp == str); + } +#endif + } static inline js::ThingRootKind rootKind() { return js::THING_ROOT_STRING; } #ifdef DEBUG void dump(); static void dumpChars(const jschar *s, size_t len); bool equals(const char *s); #endif