summaryrefslogtreecommitdiffstats
path: root/js/src/gc/Tenuring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/gc/Tenuring.cpp')
-rw-r--r--js/src/gc/Tenuring.cpp77
1 files changed, 58 insertions, 19 deletions
diff --git a/js/src/gc/Tenuring.cpp b/js/src/gc/Tenuring.cpp
index 84526e2109..a9506cfa14 100644
--- a/js/src/gc/Tenuring.cpp
+++ b/js/src/gc/Tenuring.cpp
@@ -74,6 +74,14 @@ void TenuringTracer::onObjectEdge(JSObject** objp, const char* name) {
return;
}
+ onNonForwardedNurseryObjectEdge(objp);
+}
+
+void TenuringTracer::onNonForwardedNurseryObjectEdge(JSObject** objp) {
+ JSObject* obj = *objp;
+ MOZ_ASSERT(IsInsideNursery(obj));
+ MOZ_ASSERT(!obj->isForwarded());
+
UpdateAllocSiteOnTenure(obj);
// Take a fast path for tenuring a plain object which is by far the most
@@ -98,6 +106,14 @@ void TenuringTracer::onStringEdge(JSString** strp, const char* name) {
return;
}
+ onNonForwardedNurseryStringEdge(strp);
+}
+
+void TenuringTracer::onNonForwardedNurseryStringEdge(JSString** strp) {
+ JSString* str = *strp;
+ MOZ_ASSERT(IsInsideNursery(str));
+ MOZ_ASSERT(!str->isForwarded());
+
UpdateAllocSiteOnTenure(str);
*strp = moveToTenured(str);
@@ -115,6 +131,14 @@ void TenuringTracer::onBigIntEdge(JS::BigInt** bip, const char* name) {
return;
}
+ onNonForwardedNurseryBigIntEdge(bip);
+}
+
+void TenuringTracer::onNonForwardedNurseryBigIntEdge(JS::BigInt** bip) {
+ JS::BigInt* bi = *bip;
+ MOZ_ASSERT(IsInsideNursery(bi));
+ MOZ_ASSERT(!bi->isForwarded());
+
UpdateAllocSiteOnTenure(bi);
*bip = moveToTenured(bi);
@@ -137,37 +161,52 @@ void TenuringTracer::traverse(JS::Value* thingp) {
Value value = *thingp;
CheckTracedThing(this, value);
+ if (!value.isGCThing()) {
+ return;
+ }
+
+ Cell* cell = value.toGCThing();
+ if (!IsInsideNursery(cell)) {
+ return;
+ }
+
+ if (cell->isForwarded()) {
+ const gc::RelocationOverlay* overlay =
+ gc::RelocationOverlay::fromCell(cell);
+ thingp->changeGCThingPayload(overlay->forwardingAddress());
+ return;
+ }
+
// We only care about a few kinds of GC thing here and this generates much
// tighter code than using MapGCThingTyped.
- Value post;
if (value.isObject()) {
JSObject* obj = &value.toObject();
- onObjectEdge(&obj, "value");
- post = JS::ObjectValue(*obj);
+ onNonForwardedNurseryObjectEdge(&obj);
+ MOZ_ASSERT(obj != &value.toObject());
+ *thingp = JS::ObjectValue(*obj);
+ return;
}
#ifdef ENABLE_RECORD_TUPLE
- else if (value.isExtendedPrimitive()) {
+ if (value.isExtendedPrimitive()) {
JSObject* obj = &value.toExtendedPrimitive();
- onObjectEdge(&obj, "value");
- post = JS::ExtendedPrimitiveValue(*obj);
+ onNonForwardedNurseryObjectEdge(&obj);
+ MOZ_ASSERT(obj != &value.toExtendedPrimitive());
+ *thingp = JS::ExtendedPrimitiveValue(*obj);
+ return;
}
#endif
- else if (value.isString()) {
+ if (value.isString()) {
JSString* str = value.toString();
- onStringEdge(&str, "value");
- post = JS::StringValue(str);
- } else if (value.isBigInt()) {
- JS::BigInt* bi = value.toBigInt();
- onBigIntEdge(&bi, "value");
- post = JS::BigIntValue(bi);
- } else {
- MOZ_ASSERT_IF(value.isGCThing(), !IsInsideNursery(value.toGCThing()));
+ onNonForwardedNurseryStringEdge(&str);
+ MOZ_ASSERT(str != value.toString());
+ *thingp = JS::StringValue(str);
return;
}
-
- if (post != value) {
- *thingp = post;
- }
+ MOZ_ASSERT(value.isBigInt());
+ JS::BigInt* bi = value.toBigInt();
+ onNonForwardedNurseryBigIntEdge(&bi);
+ MOZ_ASSERT(bi != value.toBigInt());
+ *thingp = JS::BigIntValue(bi);
}
void TenuringTracer::traverse(wasm::AnyRef* thingp) {