commit fbb75c78ef3221c211308b858dd2931f4f41295f
parent b56e4e2c3b1597960913d606d526f149eb40952c
Author: Jan de Mooij <jdemooij@mozilla.com>
Date: Tue, 18 Nov 2025 12:03:03 +0000
Bug 1992990 part 4 - Move ShapeListObject to its own .h/.cpp file. r=iain
This lets us use this object without pulling in BaselineCacheIRCompiler.
Differential Revision: https://phabricator.services.mozilla.com/D272480
Diffstat:
5 files changed, 139 insertions(+), 100 deletions(-)
diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -20,6 +20,7 @@
#include "jit/Linker.h"
#include "jit/MoveEmitter.h"
#include "jit/RegExpStubConstants.h"
+#include "jit/ShapeList.h"
#include "jit/SharedICHelpers.h"
#include "jit/VMFunctions.h"
#include "js/experimental/JitInfo.h" // JSJitInfo
@@ -2035,90 +2036,6 @@ static void ResetEnteredCounts(const ICEntry* icEntry) {
}
}
-static const uint32_t MaxFoldedShapes = 16;
-
-const JSClass ShapeListObject::class_ = {
- "JIT ShapeList",
- 0,
- &classOps_,
-};
-
-const JSClassOps ShapeListObject::classOps_ = {
- nullptr, // addProperty
- nullptr, // delProperty
- nullptr, // enumerate
- nullptr, // newEnumerate
- nullptr, // resolve
- nullptr, // mayResolve
- nullptr, // finalize
- nullptr, // call
- nullptr, // construct
- ShapeListObject::trace, // trace
-};
-
-/* static */ ShapeListObject* ShapeListObject::create(JSContext* cx) {
- NativeObject* obj = NewTenuredObjectWithGivenProto(cx, &class_, nullptr);
- if (!obj) {
- return nullptr;
- }
-
- // Register this object so the GC can sweep its weak pointers.
- if (!cx->zone()->registerObjectWithWeakPointers(obj)) {
- ReportOutOfMemory(cx);
- return nullptr;
- }
-
- return &obj->as<ShapeListObject>();
-}
-
-Shape* ShapeListObject::get(uint32_t index) const {
- Shape* shape = getUnbarriered(index);
- gc::ReadBarrier(shape);
- return shape;
-}
-
-Shape* ShapeListObject::getUnbarriered(uint32_t index) const {
- Value value = ListObject::get(index);
- return static_cast<Shape*>(value.toPrivate());
-}
-
-void ShapeListObject::trace(JSTracer* trc, JSObject* obj) {
- if (trc->traceWeakEdges()) {
- obj->as<ShapeListObject>().traceWeak(trc);
- }
-}
-
-bool ShapeListObject::traceWeak(JSTracer* trc) {
- uint32_t length = getDenseInitializedLength();
- if (length == 0) {
- return false; // Object may be uninitialized.
- }
-
- const HeapSlot* src = elements_;
- const HeapSlot* end = src + length;
- HeapSlot* dst = elements_;
- while (src != end) {
- Shape* shape = static_cast<Shape*>(src->toPrivate());
- MOZ_ASSERT(shape->is<Shape>());
- if (TraceManuallyBarrieredWeakEdge(trc, &shape, "ShapeListObject shape")) {
- dst->unbarrieredSet(PrivateValue(shape));
- dst++;
- }
- src++;
- }
-
- MOZ_ASSERT(dst <= end);
- uint32_t newLength = dst - elements_;
- setDenseInitializedLength(newLength);
-
- if (length != newLength) {
- JitSpew(JitSpew_StubFolding, "Cleared %u/%u shapes from %p",
- length - newLength, length, this);
- }
-
- return length != 0;
-}
-
bool js::jit::TryFoldingStubs(JSContext* cx, ICFallbackStub* fallback,
JSScript* script, ICScript* icScript) {
ICEntry* icEntry = icScript->icEntryForStub(fallback);
@@ -2422,7 +2339,7 @@ static bool AddToFoldedStub(JSContext* cx, const CacheIRWriter& writer,
// Limit the maximum number of shapes we will add before giving up.
// If we give up, transition the stub.
- if (foldedShapes->length() == MaxFoldedShapes) {
+ if (foldedShapes->length() == ShapeListObject::MaxLength) {
MOZ_ASSERT(fallback->state().mode() != ICState::Mode::Generic);
fallback->state().forceTransition();
fallback->discardStubs(cx->zone(), icEntry);
diff --git a/js/src/jit/BaselineCacheIRCompiler.h b/js/src/jit/BaselineCacheIRCompiler.h
@@ -170,21 +170,6 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
CACHE_IR_COMPILER_UNSHARED_GENERATED
};
-// Special object used for storing a list of shapes to guard against. These are
-// only used in the fields of CacheIR stubs and do not escape.
-class ShapeListObject : public ListObject {
- public:
- static const JSClass class_;
- static const JSClassOps classOps_;
- static ShapeListObject* create(JSContext* cx);
- static void trace(JSTracer* trc, JSObject* obj);
-
- Shape* get(uint32_t index) const;
- Shape* getUnbarriered(uint32_t index) const;
-
- bool traceWeak(JSTracer* trc);
-};
-
} // namespace jit
} // namespace js
diff --git a/js/src/jit/ShapeList.cpp b/js/src/jit/ShapeList.cpp
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * 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 "jit/ShapeList.h"
+
+#include "gc/GC.h"
+
+#include "vm/List-inl.h"
+
+using namespace js;
+using namespace js::jit;
+
+const JSClass ShapeListObject::class_ = {
+ "JIT ShapeList",
+ 0,
+ &classOps_,
+};
+
+const JSClassOps ShapeListObject::classOps_ = {
+ nullptr, // addProperty
+ nullptr, // delProperty
+ nullptr, // enumerate
+ nullptr, // newEnumerate
+ nullptr, // resolve
+ nullptr, // mayResolve
+ nullptr, // finalize
+ nullptr, // call
+ nullptr, // construct
+ ShapeListObject::trace, // trace
+};
+
+/* static */ ShapeListObject* ShapeListObject::create(JSContext* cx) {
+ NativeObject* obj = NewTenuredObjectWithGivenProto(cx, &class_, nullptr);
+ if (!obj) {
+ return nullptr;
+ }
+
+ // Register this object so the GC can sweep its weak pointers.
+ if (!cx->zone()->registerObjectWithWeakPointers(obj)) {
+ ReportOutOfMemory(cx);
+ return nullptr;
+ }
+
+ return &obj->as<ShapeListObject>();
+}
+
+Shape* ShapeListObject::get(uint32_t index) const {
+ Shape* shape = getUnbarriered(index);
+ gc::ReadBarrier(shape);
+ return shape;
+}
+
+Shape* ShapeListObject::getUnbarriered(uint32_t index) const {
+ Value value = ListObject::get(index);
+ return static_cast<Shape*>(value.toPrivate());
+}
+
+void ShapeListObject::trace(JSTracer* trc, JSObject* obj) {
+ if (trc->traceWeakEdges()) {
+ obj->as<ShapeListObject>().traceWeak(trc);
+ }
+}
+
+bool ShapeListObject::traceWeak(JSTracer* trc) {
+ uint32_t length = getDenseInitializedLength();
+ if (length == 0) {
+ return false; // Object may be uninitialized.
+ }
+
+ const HeapSlot* src = elements_;
+ const HeapSlot* end = src + length;
+ HeapSlot* dst = elements_;
+ while (src != end) {
+ Shape* shape = static_cast<Shape*>(src->toPrivate());
+ MOZ_ASSERT(shape->is<Shape>());
+ if (TraceManuallyBarrieredWeakEdge(trc, &shape, "ShapeListObject shape")) {
+ dst->unbarrieredSet(PrivateValue(shape));
+ dst++;
+ }
+ src++;
+ }
+
+ MOZ_ASSERT(dst <= end);
+ uint32_t newLength = dst - elements_;
+ setDenseInitializedLength(newLength);
+
+ if (length != newLength) {
+ JitSpew(JitSpew_StubFolding, "Cleared %u/%u shapes from %p",
+ length - newLength, length, this);
+ }
+
+ return length != 0;
+}
diff --git a/js/src/jit/ShapeList.h b/js/src/jit/ShapeList.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * 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 jit_ShapeList_h
+#define jit_ShapeList_h
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "jstypes.h"
+
+#include "js/Class.h"
+#include "vm/List.h"
+
+namespace js::jit {
+
+// Special object used for storing a list of shapes to guard against. These are
+// only used in the fields of CacheIR stubs and do not escape.
+class ShapeListObject : public ListObject {
+ public:
+ static const JSClass class_;
+ static const JSClassOps classOps_;
+
+ static constexpr size_t MaxLength = 16;
+
+ static ShapeListObject* create(JSContext* cx);
+ static void trace(JSTracer* trc, JSObject* obj);
+
+ Shape* get(uint32_t index) const;
+ Shape* getUnbarriered(uint32_t index) const;
+
+ bool traceWeak(JSTracer* trc);
+};
+
+} // namespace js::jit
+
+#endif // jit_ShapeList_h
diff --git a/js/src/jit/moz.build b/js/src/jit/moz.build
@@ -83,6 +83,7 @@ UNIFIED_SOURCES += [
"SafepointIndex.cpp",
"Safepoints.cpp",
"ScalarReplacement.cpp",
+ "ShapeList.cpp",
"shared/Assembler-shared.cpp",
"shared/AtomicOperations-shared-jit.cpp",
"shared/CodeGenerator-shared.cpp",