summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/Array.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/builtin/Array.h140
1 files changed, 2 insertions, 138 deletions
diff --git a/js/src/builtin/Array.h b/js/src/builtin/Array.h
index f861505e7b..1a8335f0d4 100644
--- a/js/src/builtin/Array.h
+++ b/js/src/builtin/Array.h
@@ -15,6 +15,8 @@
namespace js {
+enum class ArraySortResult : uint32_t;
+
namespace jit {
class TrampolineNativeFrameLayout;
}
@@ -172,144 +174,6 @@ extern bool ArrayLengthGetter(JSContext* cx, HandleObject obj, HandleId id,
extern bool ArrayLengthSetter(JSContext* cx, HandleObject obj, HandleId id,
HandleValue v, ObjectOpResult& result);
-// Note: we use uint32_t because the JIT code uses branch32.
-enum class ArraySortResult : uint32_t {
- Failure,
- Done,
- CallJS,
- CallJSSameRealmNoRectifier
-};
-
-// We use a JIT trampoline to optimize sorting with a comparator function. The
-// trampoline frame has an ArraySortData instance that contains all state used
-// by the sorting algorithm. The sorting algorithm is implemented as a C++
-// "generator" that can yield to the trampoline to perform a fast JIT => JIT
-// call to the comparator function. When the comparator function returns, the
-// trampoline calls back into C++ to resume the sorting algorithm.
-//
-// ArraySortData stores the JS Values in a js::Vector. To ensure we don't leak
-// its memory, we have debug assertions to check that for each C++ constructor
-// call we call |freeMallocData| exactly once. C++ code calls |freeMallocData|
-// when it's done sorting and the JIT exception handler calls it when unwinding
-// the trampoline frame.
-class ArraySortData {
- public:
- enum class ComparatorKind : uint8_t {
- Unoptimized,
- JS,
- JSSameRealmNoRectifier,
- };
-
- static constexpr size_t ComparatorActualArgs = 2;
-
- // Insertion sort is used if the length is < InsertionSortLimit.
- static constexpr size_t InsertionSortLimit = 24;
-
- using ValueVector = GCVector<Value, 8, SystemAllocPolicy>;
-
- protected: // Silence Clang warning about unused private fields.
- // Data for the comparator call. These fields must match the JitFrameLayout
- // to let us perform efficient calls to the comparator from JIT code.
- // This is asserted in the JIT trampoline code.
- // callArgs[0] is also used to store the return value of the sort function and
- // the comparator.
- uintptr_t descriptor_;
- JSObject* comparator_ = nullptr;
- Value thisv;
- Value callArgs[ComparatorActualArgs];
-
- private:
- ValueVector vec;
- Value item;
- JSContext* cx_;
- JSObject* obj_ = nullptr;
-
- Value* list;
- Value* out;
-
- // The value of the .length property.
- uint32_t length;
-
- // The number of items to sort. Can be less than |length| if the object has
- // holes.
- uint32_t denseLen;
-
- uint32_t windowSize;
- uint32_t start;
- uint32_t mid;
- uint32_t end;
- uint32_t i, j, k;
-
- // The state value determines where we resume in sortWithComparator.
- enum class State : uint8_t {
- Initial,
- InsertionSortCall1,
- InsertionSortCall2,
- MergeSortCall1,
- MergeSortCall2
- };
- State state = State::Initial;
- ComparatorKind comparatorKind_;
-
- // Optional padding to ensure proper alignment of the comparator JIT frame.
-#if !defined(JS_64BIT) && !defined(DEBUG)
- protected: // Silence Clang warning about unused private field.
- size_t padding;
-#endif
-
- public:
- explicit ArraySortData(JSContext* cx);
-
- void MOZ_ALWAYS_INLINE init(JSObject* obj, JSObject* comparator,
- ValueVector&& vec, uint32_t length,
- uint32_t denseLen);
-
- JSContext* cx() const { return cx_; }
-
- JSObject* comparator() const {
- MOZ_ASSERT(comparator_);
- return comparator_;
- }
-
- Value returnValue() const { return callArgs[0]; }
- void setReturnValue(JSObject* obj) { callArgs[0].setObject(*obj); }
-
- Value comparatorArg(size_t index) {
- MOZ_ASSERT(index < ComparatorActualArgs);
- return callArgs[index];
- }
- Value comparatorThisValue() const { return thisv; }
- Value comparatorReturnValue() const { return callArgs[0]; }
- void setComparatorArgs(const Value& x, const Value& y) {
- callArgs[0] = x;
- callArgs[1] = y;
- }
- void setComparatorReturnValue(const Value& v) { callArgs[0] = v; }
-
- ComparatorKind comparatorKind() const { return comparatorKind_; }
-
- static ArraySortResult sortWithComparator(ArraySortData* d);
-
- void freeMallocData();
- void trace(JSTracer* trc);
-
- static constexpr int32_t offsetOfDescriptor() {
- return offsetof(ArraySortData, descriptor_);
- }
- static constexpr int32_t offsetOfComparator() {
- return offsetof(ArraySortData, comparator_);
- }
- static constexpr int32_t offsetOfComparatorReturnValue() {
- return offsetof(ArraySortData, callArgs[0]);
- }
- static constexpr int32_t offsetOfComparatorThis() {
- return offsetof(ArraySortData, thisv);
- }
- static constexpr int32_t offsetOfComparatorArgs() {
- return offsetof(ArraySortData, callArgs);
- }
-};
-
extern ArraySortResult ArraySortFromJit(
JSContext* cx, jit::TrampolineNativeFrameLayout* frame);