Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef vm_ArrayObject_h
8 : #define vm_ArrayObject_h
9 :
10 : #include "vm/NativeObject.h"
11 :
12 : namespace js {
13 :
14 : class AutoSetNewObjectMetadata;
15 :
16 : class ArrayObject : public NativeObject
17 : {
18 : public:
19 : // Array(x) eagerly allocates dense elements if x <= this value. Without
20 : // the subtraction the max would roll over to the next power-of-two (4096)
21 : // due to the way that growElements() and goodAllocated() work.
22 : static const uint32_t EagerAllocationMaxLength = 2048 - ObjectElements::VALUES_PER_HEADER;
23 :
24 : static const Class class_;
25 :
26 15701 : bool lengthIsWritable() const {
27 15701 : return !getElementsHeader()->hasNonwritableArrayLength();
28 : }
29 :
30 17095 : uint32_t length() const {
31 17095 : return getElementsHeader()->length;
32 : }
33 :
34 8 : void setNonWritableLength(JSContext* cx) {
35 8 : if (getElementsHeader()->numShiftedElements() > 0)
36 0 : moveShiftedElements();
37 :
38 : // When an array's length becomes non-writable, writes to indexes
39 : // greater than or equal to the length don't change the array. We
40 : // handle this with a check for non-writable length in most places.
41 : // But in JIT code every check counts -- so we piggyback the check on
42 : // the already-required range check for |index < capacity| by making
43 : // capacity of arrays with non-writable length never exceed the length.
44 8 : ObjectElements* header = getElementsHeader();
45 8 : uint32_t len = header->initializedLength;
46 8 : if (header->capacity > len) {
47 7 : shrinkElements(cx, len);
48 7 : header = getElementsHeader();
49 7 : header->capacity = len;
50 : }
51 8 : header->setNonwritableArrayLength();
52 8 : }
53 :
54 : inline void setLength(JSContext* cx, uint32_t length);
55 :
56 : // Variant of setLength for use on arrays where the length cannot overflow int32_t.
57 2994 : void setLengthInt32(uint32_t length) {
58 2994 : MOZ_ASSERT(lengthIsWritable());
59 2994 : MOZ_ASSERT(length <= INT32_MAX);
60 2994 : getElementsHeader()->length = length;
61 2994 : }
62 :
63 : // Make an array object with the specified initial state.
64 : static inline ArrayObject*
65 : createArray(JSContext* cx,
66 : gc::AllocKind kind,
67 : gc::InitialHeap heap,
68 : HandleShape shape,
69 : HandleObjectGroup group,
70 : uint32_t length,
71 : AutoSetNewObjectMetadata& metadata);
72 :
73 : // Make a copy-on-write array object which shares the elements of an
74 : // existing object.
75 : static inline ArrayObject*
76 : createCopyOnWriteArray(JSContext* cx,
77 : gc::InitialHeap heap,
78 : HandleArrayObject sharedElementsOwner);
79 :
80 : private:
81 : // Helper for the above methods.
82 : static inline ArrayObject*
83 : createArrayInternal(JSContext* cx,
84 : gc::AllocKind kind,
85 : gc::InitialHeap heap,
86 : HandleShape shape,
87 : HandleObjectGroup group,
88 : AutoSetNewObjectMetadata&);
89 :
90 : static inline ArrayObject*
91 : finishCreateArray(ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata);
92 : };
93 :
94 : } // namespace js
95 :
96 : #endif // vm_ArrayObject_h
97 :
|