1 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Communicator client code, released
17 : * March 31, 1998.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Netscape Communications Corporation.
21 : * Portions created by the Initial Developer are Copyright (C) 1998
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef jsarrayinlines_h___
41 : #define jsarrayinlines_h___
42 :
43 : #include "jsinferinlines.h"
44 : #include "jsobjinlines.h"
45 :
46 : inline void
47 2417993 : JSObject::markDenseArrayNotPacked(JSContext *cx)
48 : {
49 2417993 : JS_ASSERT(isDenseArray());
50 2417993 : MarkTypeObjectFlags(cx, this, js::types::OBJECT_FLAG_NON_PACKED_ARRAY);
51 2417993 : }
52 :
53 : inline void
54 46922289 : JSObject::ensureDenseArrayInitializedLength(JSContext *cx, uint32_t index, uint32_t extra)
55 : {
56 : /*
57 : * Ensure that the array's contents have been initialized up to index, and
58 : * mark the elements through 'index + extra' as initialized in preparation
59 : * for a write.
60 : */
61 46922289 : JS_ASSERT(index + extra <= getDenseArrayCapacity());
62 46922289 : uint32_t &initlen = getElementsHeader()->initializedLength;
63 46922289 : if (initlen < index)
64 805604 : markDenseArrayNotPacked(cx);
65 :
66 46922289 : if (initlen < index + extra) {
67 36145518 : JSCompartment *comp = compartment();
68 36145518 : size_t offset = initlen;
69 158120884 : for (js::HeapSlot *sp = elements + initlen;
70 79060442 : sp != elements + (index + extra);
71 : sp++, offset++)
72 42914924 : sp->init(comp, this, offset, js::MagicValue(JS_ARRAY_HOLE));
73 36145518 : initlen = index + extra;
74 : }
75 46922289 : }
76 :
77 : inline JSObject::EnsureDenseResult
78 46924758 : JSObject::ensureDenseArrayElements(JSContext *cx, unsigned index, unsigned extra)
79 : {
80 46924758 : JS_ASSERT(isDenseArray());
81 :
82 46924758 : unsigned currentCapacity = getDenseArrayCapacity();
83 :
84 : unsigned requiredCapacity;
85 46924758 : if (extra == 1) {
86 : /* Optimize for the common case. */
87 46875900 : if (index < currentCapacity) {
88 46769533 : ensureDenseArrayInitializedLength(cx, index, 1);
89 46769533 : return ED_OK;
90 : }
91 106367 : requiredCapacity = index + 1;
92 106367 : if (requiredCapacity == 0) {
93 : /* Overflow. */
94 0 : return ED_SPARSE;
95 : }
96 : } else {
97 48858 : requiredCapacity = index + extra;
98 48858 : if (requiredCapacity < index) {
99 : /* Overflow. */
100 0 : return ED_SPARSE;
101 : }
102 48858 : if (requiredCapacity <= currentCapacity) {
103 44396 : ensureDenseArrayInitializedLength(cx, index, extra);
104 44396 : return ED_OK;
105 : }
106 : }
107 :
108 : /*
109 : * We use the extra argument also as a hint about number of non-hole
110 : * elements to be inserted.
111 : */
112 125826 : if (requiredCapacity > MIN_SPARSE_INDEX &&
113 14997 : willBeSparseDenseArray(requiredCapacity, extra)) {
114 3433 : return ED_SPARSE;
115 : }
116 107396 : if (!growElements(cx, requiredCapacity))
117 0 : return ED_FAILED;
118 :
119 107396 : ensureDenseArrayInitializedLength(cx, index, extra);
120 107396 : return ED_OK;
121 : }
122 :
123 : #endif /* jsarrayinlines_h___ */
|