libv8 3.10.8.0 → 3.11.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. data/Rakefile +10 -3
  2. data/ext/libv8/compiler.rb +46 -0
  3. data/ext/libv8/extconf.rb +5 -1
  4. data/ext/libv8/make.rb +13 -0
  5. data/lib/libv8/version.rb +1 -1
  6. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +11 -0
  7. data/patches/src_platform-freebsd.cc.patch +10 -0
  8. data/vendor/v8/ChangeLog +124 -0
  9. data/vendor/v8/DEPS +27 -0
  10. data/vendor/v8/Makefile +7 -0
  11. data/vendor/v8/SConstruct +15 -2
  12. data/vendor/v8/build/common.gypi +129 -157
  13. data/vendor/v8/build/gyp_v8 +11 -25
  14. data/vendor/v8/build/standalone.gypi +9 -3
  15. data/vendor/v8/include/v8.h +5 -3
  16. data/vendor/v8/src/SConscript +1 -0
  17. data/vendor/v8/src/api.cc +4 -33
  18. data/vendor/v8/src/api.h +2 -2
  19. data/vendor/v8/src/arm/builtins-arm.cc +5 -4
  20. data/vendor/v8/src/arm/code-stubs-arm.cc +21 -14
  21. data/vendor/v8/src/arm/codegen-arm.cc +2 -2
  22. data/vendor/v8/src/arm/debug-arm.cc +3 -1
  23. data/vendor/v8/src/arm/full-codegen-arm.cc +3 -102
  24. data/vendor/v8/src/arm/ic-arm.cc +30 -33
  25. data/vendor/v8/src/arm/lithium-arm.cc +20 -7
  26. data/vendor/v8/src/arm/lithium-arm.h +10 -4
  27. data/vendor/v8/src/arm/lithium-codegen-arm.cc +106 -60
  28. data/vendor/v8/src/arm/macro-assembler-arm.cc +49 -39
  29. data/vendor/v8/src/arm/macro-assembler-arm.h +5 -4
  30. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +115 -55
  31. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +7 -6
  32. data/vendor/v8/src/arm/simulator-arm.h +6 -6
  33. data/vendor/v8/src/arm/stub-cache-arm.cc +64 -19
  34. data/vendor/v8/src/array.js +7 -3
  35. data/vendor/v8/src/ast.cc +11 -6
  36. data/vendor/v8/src/bootstrapper.cc +9 -11
  37. data/vendor/v8/src/builtins.cc +61 -31
  38. data/vendor/v8/src/code-stubs.cc +23 -9
  39. data/vendor/v8/src/code-stubs.h +1 -0
  40. data/vendor/v8/src/codegen.h +3 -3
  41. data/vendor/v8/src/compiler.cc +1 -1
  42. data/vendor/v8/src/contexts.h +2 -18
  43. data/vendor/v8/src/d8.cc +94 -93
  44. data/vendor/v8/src/d8.h +1 -1
  45. data/vendor/v8/src/debug-agent.cc +3 -3
  46. data/vendor/v8/src/debug.cc +41 -1
  47. data/vendor/v8/src/debug.h +50 -0
  48. data/vendor/v8/src/elements-kind.cc +134 -0
  49. data/vendor/v8/src/elements-kind.h +210 -0
  50. data/vendor/v8/src/elements.cc +356 -190
  51. data/vendor/v8/src/elements.h +36 -28
  52. data/vendor/v8/src/factory.cc +44 -4
  53. data/vendor/v8/src/factory.h +11 -7
  54. data/vendor/v8/src/flag-definitions.h +3 -0
  55. data/vendor/v8/src/frames.h +3 -0
  56. data/vendor/v8/src/full-codegen.cc +2 -1
  57. data/vendor/v8/src/func-name-inferrer.h +2 -0
  58. data/vendor/v8/src/globals.h +3 -0
  59. data/vendor/v8/src/heap-inl.h +16 -4
  60. data/vendor/v8/src/heap.cc +38 -32
  61. data/vendor/v8/src/heap.h +3 -17
  62. data/vendor/v8/src/hydrogen-instructions.cc +28 -5
  63. data/vendor/v8/src/hydrogen-instructions.h +142 -44
  64. data/vendor/v8/src/hydrogen.cc +160 -55
  65. data/vendor/v8/src/hydrogen.h +2 -0
  66. data/vendor/v8/src/ia32/assembler-ia32.h +3 -0
  67. data/vendor/v8/src/ia32/builtins-ia32.cc +5 -4
  68. data/vendor/v8/src/ia32/code-stubs-ia32.cc +22 -16
  69. data/vendor/v8/src/ia32/codegen-ia32.cc +2 -2
  70. data/vendor/v8/src/ia32/debug-ia32.cc +29 -2
  71. data/vendor/v8/src/ia32/full-codegen-ia32.cc +8 -101
  72. data/vendor/v8/src/ia32/ic-ia32.cc +23 -19
  73. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +126 -80
  74. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +2 -1
  75. data/vendor/v8/src/ia32/lithium-ia32.cc +15 -9
  76. data/vendor/v8/src/ia32/lithium-ia32.h +14 -6
  77. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +50 -40
  78. data/vendor/v8/src/ia32/macro-assembler-ia32.h +5 -4
  79. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +113 -43
  80. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +9 -4
  81. data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
  82. data/vendor/v8/src/ia32/stub-cache-ia32.cc +52 -14
  83. data/vendor/v8/src/ic.cc +77 -20
  84. data/vendor/v8/src/ic.h +18 -2
  85. data/vendor/v8/src/incremental-marking-inl.h +21 -5
  86. data/vendor/v8/src/incremental-marking.cc +35 -8
  87. data/vendor/v8/src/incremental-marking.h +12 -3
  88. data/vendor/v8/src/isolate.cc +12 -2
  89. data/vendor/v8/src/isolate.h +1 -1
  90. data/vendor/v8/src/jsregexp.cc +66 -26
  91. data/vendor/v8/src/jsregexp.h +60 -31
  92. data/vendor/v8/src/list-inl.h +8 -0
  93. data/vendor/v8/src/list.h +3 -0
  94. data/vendor/v8/src/lithium.cc +5 -2
  95. data/vendor/v8/src/liveedit.cc +57 -5
  96. data/vendor/v8/src/mark-compact-inl.h +17 -11
  97. data/vendor/v8/src/mark-compact.cc +100 -143
  98. data/vendor/v8/src/mark-compact.h +44 -20
  99. data/vendor/v8/src/messages.js +131 -99
  100. data/vendor/v8/src/mips/builtins-mips.cc +5 -4
  101. data/vendor/v8/src/mips/code-stubs-mips.cc +23 -15
  102. data/vendor/v8/src/mips/codegen-mips.cc +2 -2
  103. data/vendor/v8/src/mips/debug-mips.cc +3 -1
  104. data/vendor/v8/src/mips/full-codegen-mips.cc +4 -102
  105. data/vendor/v8/src/mips/ic-mips.cc +34 -36
  106. data/vendor/v8/src/mips/lithium-codegen-mips.cc +116 -68
  107. data/vendor/v8/src/mips/lithium-mips.cc +20 -7
  108. data/vendor/v8/src/mips/lithium-mips.h +11 -4
  109. data/vendor/v8/src/mips/macro-assembler-mips.cc +50 -39
  110. data/vendor/v8/src/mips/macro-assembler-mips.h +5 -4
  111. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +110 -50
  112. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +6 -5
  113. data/vendor/v8/src/mips/simulator-mips.h +5 -5
  114. data/vendor/v8/src/mips/stub-cache-mips.cc +66 -20
  115. data/vendor/v8/src/mksnapshot.cc +5 -1
  116. data/vendor/v8/src/objects-debug.cc +103 -6
  117. data/vendor/v8/src/objects-inl.h +215 -116
  118. data/vendor/v8/src/objects-printer.cc +13 -8
  119. data/vendor/v8/src/objects.cc +608 -331
  120. data/vendor/v8/src/objects.h +129 -94
  121. data/vendor/v8/src/parser.cc +16 -4
  122. data/vendor/v8/src/platform-freebsd.cc +1 -0
  123. data/vendor/v8/src/platform-linux.cc +9 -30
  124. data/vendor/v8/src/platform-posix.cc +28 -7
  125. data/vendor/v8/src/platform-win32.cc +15 -3
  126. data/vendor/v8/src/platform.h +2 -1
  127. data/vendor/v8/src/profile-generator-inl.h +25 -2
  128. data/vendor/v8/src/profile-generator.cc +300 -822
  129. data/vendor/v8/src/profile-generator.h +97 -214
  130. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +2 -1
  131. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +2 -2
  132. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +6 -5
  133. data/vendor/v8/src/regexp-macro-assembler-tracer.h +1 -1
  134. data/vendor/v8/src/regexp-macro-assembler.cc +7 -3
  135. data/vendor/v8/src/regexp-macro-assembler.h +10 -2
  136. data/vendor/v8/src/regexp.js +6 -0
  137. data/vendor/v8/src/runtime.cc +265 -212
  138. data/vendor/v8/src/runtime.h +6 -5
  139. data/vendor/v8/src/scopes.cc +20 -0
  140. data/vendor/v8/src/scopes.h +6 -3
  141. data/vendor/v8/src/spaces.cc +0 -2
  142. data/vendor/v8/src/string-stream.cc +2 -2
  143. data/vendor/v8/src/v8-counters.h +0 -2
  144. data/vendor/v8/src/v8natives.js +2 -2
  145. data/vendor/v8/src/v8utils.h +6 -3
  146. data/vendor/v8/src/version.cc +1 -1
  147. data/vendor/v8/src/x64/assembler-x64.h +2 -1
  148. data/vendor/v8/src/x64/builtins-x64.cc +5 -4
  149. data/vendor/v8/src/x64/code-stubs-x64.cc +25 -16
  150. data/vendor/v8/src/x64/codegen-x64.cc +2 -2
  151. data/vendor/v8/src/x64/debug-x64.cc +14 -1
  152. data/vendor/v8/src/x64/disasm-x64.cc +1 -1
  153. data/vendor/v8/src/x64/full-codegen-x64.cc +10 -106
  154. data/vendor/v8/src/x64/ic-x64.cc +20 -16
  155. data/vendor/v8/src/x64/lithium-codegen-x64.cc +156 -79
  156. data/vendor/v8/src/x64/lithium-codegen-x64.h +2 -1
  157. data/vendor/v8/src/x64/lithium-x64.cc +18 -8
  158. data/vendor/v8/src/x64/lithium-x64.h +7 -2
  159. data/vendor/v8/src/x64/macro-assembler-x64.cc +50 -40
  160. data/vendor/v8/src/x64/macro-assembler-x64.h +5 -4
  161. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +122 -51
  162. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +17 -8
  163. data/vendor/v8/src/x64/simulator-x64.h +4 -4
  164. data/vendor/v8/src/x64/stub-cache-x64.cc +55 -17
  165. data/vendor/v8/test/cctest/cctest.status +1 -0
  166. data/vendor/v8/test/cctest/test-api.cc +24 -0
  167. data/vendor/v8/test/cctest/test-func-name-inference.cc +38 -0
  168. data/vendor/v8/test/cctest/test-heap-profiler.cc +21 -77
  169. data/vendor/v8/test/cctest/test-heap.cc +164 -3
  170. data/vendor/v8/test/cctest/test-list.cc +12 -0
  171. data/vendor/v8/test/cctest/test-mark-compact.cc +5 -5
  172. data/vendor/v8/test/cctest/test-regexp.cc +14 -8
  173. data/vendor/v8/test/cctest/testcfg.py +2 -0
  174. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +176 -0
  175. data/vendor/v8/test/mjsunit/array-construct-transition.js +3 -3
  176. data/vendor/v8/test/mjsunit/array-literal-transitions.js +10 -10
  177. data/vendor/v8/test/mjsunit/big-array-literal.js +3 -0
  178. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +4 -2
  179. data/vendor/v8/test/mjsunit/debug-liveedit-stack-padding.js +88 -0
  180. data/vendor/v8/test/mjsunit/elements-kind.js +4 -4
  181. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +2 -2
  182. data/vendor/v8/test/mjsunit/elements-transition.js +5 -5
  183. data/vendor/v8/test/mjsunit/error-constructors.js +68 -33
  184. data/vendor/v8/test/mjsunit/harmony/proxies.js +14 -6
  185. data/vendor/v8/test/mjsunit/mjsunit.status +1 -0
  186. data/vendor/v8/test/mjsunit/packed-elements.js +112 -0
  187. data/vendor/v8/test/mjsunit/regexp-capture-3.js +6 -0
  188. data/vendor/v8/test/mjsunit/regexp-global.js +132 -0
  189. data/vendor/v8/test/mjsunit/regexp.js +11 -0
  190. data/vendor/v8/test/mjsunit/regress/regress-117409.js +52 -0
  191. data/vendor/v8/test/mjsunit/regress/regress-126412.js +33 -0
  192. data/vendor/v8/test/mjsunit/regress/regress-128018.js +35 -0
  193. data/vendor/v8/test/mjsunit/regress/regress-128146.js +33 -0
  194. data/vendor/v8/test/mjsunit/regress/regress-1639-2.js +4 -1
  195. data/vendor/v8/test/mjsunit/regress/regress-1639.js +14 -8
  196. data/vendor/v8/test/mjsunit/regress/regress-1849.js +3 -3
  197. data/vendor/v8/test/mjsunit/regress/regress-1878.js +2 -2
  198. data/vendor/v8/test/mjsunit/regress/regress-2071.js +79 -0
  199. data/vendor/v8/test/mjsunit/regress/regress-2153.js +32 -0
  200. data/vendor/v8/test/mjsunit/regress/regress-crbug-122271.js +4 -4
  201. data/vendor/v8/test/mjsunit/regress/regress-crbug-126414.js +32 -0
  202. data/vendor/v8/test/mjsunit/regress/regress-smi-only-concat.js +2 -2
  203. data/vendor/v8/test/mjsunit/regress/regress-transcendental.js +49 -0
  204. data/vendor/v8/test/mjsunit/stack-traces.js +14 -0
  205. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +4 -3
  206. data/vendor/v8/test/test262/testcfg.py +6 -1
  207. data/vendor/v8/tools/check-static-initializers.sh +11 -3
  208. data/vendor/v8/tools/fuzz-harness.sh +92 -0
  209. data/vendor/v8/tools/grokdump.py +658 -67
  210. data/vendor/v8/tools/gyp/v8.gyp +21 -39
  211. data/vendor/v8/tools/js2c.py +3 -3
  212. data/vendor/v8/tools/jsmin.py +2 -2
  213. data/vendor/v8/tools/presubmit.py +2 -1
  214. data/vendor/v8/tools/test-wrapper-gypbuild.py +25 -11
  215. metadata +624 -612
@@ -39,8 +39,14 @@
39
39
  // Inheritance hierarchy:
40
40
  // - ElementsAccessorBase (abstract)
41
41
  // - FastElementsAccessor (abstract)
42
- // - FastObjectElementsAccessor
42
+ // - FastSmiOrObjectElementsAccessor
43
+ // - FastPackedSmiElementsAccessor
44
+ // - FastHoleySmiElementsAccessor
45
+ // - FastPackedObjectElementsAccessor
46
+ // - FastHoleyObjectElementsAccessor
43
47
  // - FastDoubleElementsAccessor
48
+ // - FastPackedDoubleElementsAccessor
49
+ // - FastHoleyDoubleElementsAccessor
44
50
  // - ExternalElementsAccessor (abstract)
45
51
  // - ExternalByteElementsAccessor
46
52
  // - ExternalUnsignedByteElementsAccessor
@@ -65,9 +71,15 @@ namespace internal {
65
71
  // identical. Note that the order must match that of the ElementsKind enum for
66
72
  // the |accessor_array[]| below to work.
67
73
  #define ELEMENTS_LIST(V) \
68
- V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray) \
69
- V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
70
- V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
74
+ V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
75
+ V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \
76
+ FixedArray) \
77
+ V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
78
+ V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
79
+ V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \
80
+ FixedDoubleArray) \
81
+ V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
82
+ FixedDoubleArray) \
71
83
  V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
72
84
  SeededNumberDictionary) \
73
85
  V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \
@@ -139,8 +151,6 @@ void CopyObjectToObjectElements(FixedArray* from,
139
151
  uint32_t to_start,
140
152
  int raw_copy_size) {
141
153
  ASSERT(to->map() != HEAP->fixed_cow_array_map());
142
- ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
143
- ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
144
154
  int copy_size = raw_copy_size;
145
155
  if (raw_copy_size < 0) {
146
156
  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
@@ -148,7 +158,7 @@ void CopyObjectToObjectElements(FixedArray* from,
148
158
  copy_size = Min(from->length() - from_start,
149
159
  to->length() - to_start);
150
160
  #ifdef DEBUG
151
- // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
161
+ // FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
152
162
  // marked with the hole.
153
163
  if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
154
164
  for (int i = to_start + copy_size; i < to->length(); ++i) {
@@ -160,12 +170,15 @@ void CopyObjectToObjectElements(FixedArray* from,
160
170
  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
161
171
  (copy_size + static_cast<int>(from_start)) <= from->length());
162
172
  if (copy_size == 0) return;
173
+ ASSERT(IsFastSmiOrObjectElementsKind(from_kind));
174
+ ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
163
175
  Address to_address = to->address() + FixedArray::kHeaderSize;
164
176
  Address from_address = from->address() + FixedArray::kHeaderSize;
165
177
  CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
166
178
  reinterpret_cast<Object**>(from_address) + from_start,
167
179
  copy_size);
168
- if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
180
+ if (IsFastObjectElementsKind(from_kind) &&
181
+ IsFastObjectElementsKind(to_kind)) {
169
182
  Heap* heap = from->GetHeap();
170
183
  if (!heap->InNewSpace(to)) {
171
184
  heap->RecordWrites(to->address(),
@@ -190,7 +203,7 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
190
203
  raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
191
204
  copy_size = from->max_number_key() + 1 - from_start;
192
205
  #ifdef DEBUG
193
- // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
206
+ // Fast object arrays cannot be uninitialized. Ensure they are already
194
207
  // marked with the hole.
195
208
  if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
196
209
  for (int i = to_start + copy_size; i < to->length(); ++i) {
@@ -200,7 +213,7 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
200
213
  #endif
201
214
  }
202
215
  ASSERT(to != from);
203
- ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
216
+ ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
204
217
  if (copy_size == 0) return;
205
218
  uint32_t to_length = to->length();
206
219
  if (to_start + copy_size > to_length) {
@@ -216,7 +229,7 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
216
229
  to->set_the_hole(i + to_start);
217
230
  }
218
231
  }
219
- if (to_kind == FAST_ELEMENTS) {
232
+ if (IsFastObjectElementsKind(to_kind)) {
220
233
  if (!heap->InNewSpace(to)) {
221
234
  heap->RecordWrites(to->address(),
222
235
  to->OffsetOfElementAt(to_start),
@@ -234,7 +247,7 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
234
247
  ElementsKind to_kind,
235
248
  uint32_t to_start,
236
249
  int raw_copy_size) {
237
- ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
250
+ ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
238
251
  int copy_size = raw_copy_size;
239
252
  if (raw_copy_size < 0) {
240
253
  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
@@ -242,7 +255,7 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
242
255
  copy_size = Min(from->length() - from_start,
243
256
  to->length() - to_start);
244
257
  #ifdef DEBUG
245
- // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
258
+ // FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
246
259
  // marked with the hole.
247
260
  if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
248
261
  for (int i = to_start + copy_size; i < to->length(); ++i) {
@@ -255,14 +268,14 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
255
268
  (copy_size + static_cast<int>(from_start)) <= from->length());
256
269
  if (copy_size == 0) return from;
257
270
  for (int i = 0; i < copy_size; ++i) {
258
- if (to_kind == FAST_SMI_ONLY_ELEMENTS) {
271
+ if (IsFastSmiElementsKind(to_kind)) {
259
272
  UNIMPLEMENTED();
260
273
  return Failure::Exception();
261
274
  } else {
262
275
  MaybeObject* maybe_value = from->get(i + from_start);
263
276
  Object* value;
264
- ASSERT(to_kind == FAST_ELEMENTS);
265
- // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects
277
+ ASSERT(IsFastObjectElementsKind(to_kind));
278
+ // Because Double -> Object elements transitions allocate HeapObjects
266
279
  // iteratively, the allocate must succeed within a single GC cycle,
267
280
  // otherwise the retry after the GC will also fail. In order to ensure
268
281
  // that no GC is triggered, allocate HeapNumbers from old space if they
@@ -404,6 +417,38 @@ class ElementsAccessorBase : public ElementsAccessor {
404
417
 
405
418
  virtual ElementsKind kind() const { return ElementsTraits::Kind; }
406
419
 
420
+ static void ValidateContents(JSObject* holder, int length) {
421
+ }
422
+
423
+ static void ValidateImpl(JSObject* holder) {
424
+ FixedArrayBase* fixed_array_base = holder->elements();
425
+ // When objects are first allocated, its elements are Failures.
426
+ if (fixed_array_base->IsFailure()) return;
427
+ if (!fixed_array_base->IsHeapObject()) return;
428
+ Map* map = fixed_array_base->map();
429
+ // Arrays that have been shifted in place can't be verified.
430
+ Heap* heap = holder->GetHeap();
431
+ if (map == heap->raw_unchecked_one_pointer_filler_map() ||
432
+ map == heap->raw_unchecked_two_pointer_filler_map() ||
433
+ map == heap->free_space_map()) {
434
+ return;
435
+ }
436
+ int length = 0;
437
+ if (holder->IsJSArray()) {
438
+ Object* length_obj = JSArray::cast(holder)->length();
439
+ if (length_obj->IsSmi()) {
440
+ length = Smi::cast(length_obj)->value();
441
+ }
442
+ } else {
443
+ length = fixed_array_base->length();
444
+ }
445
+ ElementsAccessorSubclass::ValidateContents(holder, length);
446
+ }
447
+
448
+ virtual void Validate(JSObject* holder) {
449
+ ElementsAccessorSubclass::ValidateImpl(holder);
450
+ }
451
+
407
452
  static bool HasElementImpl(Object* receiver,
408
453
  JSObject* holder,
409
454
  uint32_t key,
@@ -424,10 +469,10 @@ class ElementsAccessorBase : public ElementsAccessor {
424
469
  receiver, holder, key, BackingStore::cast(backing_store));
425
470
  }
426
471
 
427
- virtual MaybeObject* Get(Object* receiver,
428
- JSObject* holder,
429
- uint32_t key,
430
- FixedArrayBase* backing_store) {
472
+ MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver,
473
+ JSObject* holder,
474
+ uint32_t key,
475
+ FixedArrayBase* backing_store) {
431
476
  if (backing_store == NULL) {
432
477
  backing_store = holder->elements();
433
478
  }
@@ -435,62 +480,65 @@ class ElementsAccessorBase : public ElementsAccessor {
435
480
  receiver, holder, key, BackingStore::cast(backing_store));
436
481
  }
437
482
 
438
- static MaybeObject* GetImpl(Object* receiver,
439
- JSObject* obj,
440
- uint32_t key,
441
- BackingStore* backing_store) {
483
+ MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
484
+ JSObject* obj,
485
+ uint32_t key,
486
+ BackingStore* backing_store) {
442
487
  return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
443
488
  ? backing_store->get(key)
444
489
  : backing_store->GetHeap()->the_hole_value();
445
490
  }
446
491
 
447
- virtual MaybeObject* SetLength(JSArray* array,
448
- Object* length) {
492
+ MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array,
493
+ Object* length) {
449
494
  return ElementsAccessorSubclass::SetLengthImpl(
450
495
  array, length, BackingStore::cast(array->elements()));
451
496
  }
452
497
 
453
- static MaybeObject* SetLengthImpl(JSObject* obj,
454
- Object* length,
455
- BackingStore* backing_store);
498
+ MUST_USE_RESULT static MaybeObject* SetLengthImpl(
499
+ JSObject* obj,
500
+ Object* length,
501
+ BackingStore* backing_store);
456
502
 
457
- virtual MaybeObject* SetCapacityAndLength(JSArray* array,
458
- int capacity,
459
- int length) {
503
+ MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength(
504
+ JSArray* array,
505
+ int capacity,
506
+ int length) {
460
507
  return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
461
508
  array,
462
509
  capacity,
463
510
  length);
464
511
  }
465
512
 
466
- static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
467
- int capacity,
468
- int length) {
513
+ MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength(
514
+ JSObject* obj,
515
+ int capacity,
516
+ int length) {
469
517
  UNIMPLEMENTED();
470
518
  return obj;
471
519
  }
472
520
 
473
- virtual MaybeObject* Delete(JSObject* obj,
474
- uint32_t key,
475
- JSReceiver::DeleteMode mode) = 0;
521
+ MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
522
+ uint32_t key,
523
+ JSReceiver::DeleteMode mode) = 0;
476
524
 
477
- static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
478
- uint32_t from_start,
479
- FixedArrayBase* to,
480
- ElementsKind to_kind,
481
- uint32_t to_start,
482
- int copy_size) {
525
+ MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
526
+ uint32_t from_start,
527
+ FixedArrayBase* to,
528
+ ElementsKind to_kind,
529
+ uint32_t to_start,
530
+ int copy_size) {
483
531
  UNREACHABLE();
484
532
  return NULL;
485
533
  }
486
534
 
487
- virtual MaybeObject* CopyElements(JSObject* from_holder,
488
- uint32_t from_start,
489
- FixedArrayBase* to,
490
- ElementsKind to_kind,
491
- uint32_t to_start,
492
- int copy_size,
493
- FixedArrayBase* from) {
535
+ MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
536
+ uint32_t from_start,
537
+ FixedArrayBase* to,
538
+ ElementsKind to_kind,
539
+ uint32_t to_start,
540
+ int copy_size,
541
+ FixedArrayBase* from) {
494
542
  if (from == NULL) {
495
543
  from = from_holder->elements();
496
544
  }
@@ -501,10 +549,11 @@ class ElementsAccessorBase : public ElementsAccessor {
501
549
  from, from_start, to, to_kind, to_start, copy_size);
502
550
  }
503
551
 
504
- virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
505
- JSObject* holder,
506
- FixedArray* to,
507
- FixedArrayBase* from) {
552
+ MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
553
+ Object* receiver,
554
+ JSObject* holder,
555
+ FixedArray* to,
556
+ FixedArrayBase* from) {
508
557
  int len0 = to->length();
509
558
  #ifdef DEBUG
510
559
  if (FLAG_enable_slow_asserts) {
@@ -620,6 +669,7 @@ class FastElementsAccessor
620
669
  KindTraits>(name) {}
621
670
  protected:
622
671
  friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
672
+ friend class NonStrictArgumentsElementsAccessor;
623
673
 
624
674
  typedef typename KindTraits::BackingStore BackingStore;
625
675
 
@@ -630,10 +680,21 @@ class FastElementsAccessor
630
680
  Object* length_object,
631
681
  uint32_t length) {
632
682
  uint32_t old_capacity = backing_store->length();
683
+ Object* old_length = array->length();
684
+ bool same_size = old_length->IsSmi() &&
685
+ static_cast<uint32_t>(Smi::cast(old_length)->value()) == length;
686
+ ElementsKind kind = array->GetElementsKind();
687
+
688
+ if (!same_size && IsFastElementsKind(kind) &&
689
+ !IsFastHoleyElementsKind(kind)) {
690
+ kind = GetHoleyElementsKind(kind);
691
+ MaybeObject* maybe_obj = array->TransitionElementsKind(kind);
692
+ if (maybe_obj->IsFailure()) return maybe_obj;
693
+ }
633
694
 
634
695
  // Check whether the backing store should be shrunk.
635
696
  if (length <= old_capacity) {
636
- if (array->HasFastTypeElements()) {
697
+ if (array->HasFastSmiOrObjectElements()) {
637
698
  MaybeObject* maybe_obj = array->EnsureWritableFastElements();
638
699
  if (!maybe_obj->To(&backing_store)) return maybe_obj;
639
700
  }
@@ -665,39 +726,40 @@ class FastElementsAccessor
665
726
  MaybeObject* result = FastElementsAccessorSubclass::
666
727
  SetFastElementsCapacityAndLength(array, new_capacity, length);
667
728
  if (result->IsFailure()) return result;
729
+ array->ValidateElements();
668
730
  return length_object;
669
731
  }
670
732
 
671
733
  // Request conversion to slow elements.
672
734
  return array->GetHeap()->undefined_value();
673
735
  }
674
- };
675
-
676
-
677
- class FastObjectElementsAccessor
678
- : public FastElementsAccessor<FastObjectElementsAccessor,
679
- ElementsKindTraits<FAST_ELEMENTS>,
680
- kPointerSize> {
681
- public:
682
- explicit FastObjectElementsAccessor(const char* name)
683
- : FastElementsAccessor<FastObjectElementsAccessor,
684
- ElementsKindTraits<FAST_ELEMENTS>,
685
- kPointerSize>(name) {}
686
736
 
687
737
  static MaybeObject* DeleteCommon(JSObject* obj,
688
- uint32_t key) {
689
- ASSERT(obj->HasFastElements() ||
690
- obj->HasFastSmiOnlyElements() ||
738
+ uint32_t key,
739
+ JSReceiver::DeleteMode mode) {
740
+ ASSERT(obj->HasFastSmiOrObjectElements() ||
741
+ obj->HasFastDoubleElements() ||
691
742
  obj->HasFastArgumentsElements());
743
+ typename KindTraits::BackingStore* backing_store =
744
+ KindTraits::BackingStore::cast(obj->elements());
692
745
  Heap* heap = obj->GetHeap();
693
- FixedArray* backing_store = FixedArray::cast(obj->elements());
694
746
  if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
695
- backing_store = FixedArray::cast(backing_store->get(1));
747
+ backing_store =
748
+ KindTraits::BackingStore::cast(
749
+ FixedArray::cast(backing_store)->get(1));
696
750
  } else {
697
- Object* writable;
698
- MaybeObject* maybe = obj->EnsureWritableFastElements();
699
- if (!maybe->ToObject(&writable)) return maybe;
700
- backing_store = FixedArray::cast(writable);
751
+ ElementsKind kind = KindTraits::Kind;
752
+ if (IsFastPackedElementsKind(kind)) {
753
+ MaybeObject* transitioned =
754
+ obj->TransitionElementsKind(GetHoleyElementsKind(kind));
755
+ if (transitioned->IsFailure()) return transitioned;
756
+ }
757
+ if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
758
+ Object* writable;
759
+ MaybeObject* maybe = obj->EnsureWritableFastElements();
760
+ if (!maybe->ToObject(&writable)) return maybe;
761
+ backing_store = KindTraits::BackingStore::cast(writable);
762
+ }
701
763
  }
702
764
  uint32_t length = static_cast<uint32_t>(
703
765
  obj->IsJSArray()
@@ -709,15 +771,14 @@ class FastObjectElementsAccessor
709
771
  // has too few used values, normalize it.
710
772
  // To avoid doing the check on every delete we require at least
711
773
  // one adjacent hole to the value being deleted.
712
- Object* hole = heap->the_hole_value();
713
774
  const int kMinLengthForSparsenessCheck = 64;
714
775
  if (backing_store->length() >= kMinLengthForSparsenessCheck &&
715
776
  !heap->InNewSpace(backing_store) &&
716
- ((key > 0 && backing_store->get(key - 1) == hole) ||
717
- (key + 1 < length && backing_store->get(key + 1) == hole))) {
777
+ ((key > 0 && backing_store->is_the_hole(key - 1)) ||
778
+ (key + 1 < length && backing_store->is_the_hole(key + 1)))) {
718
779
  int num_used = 0;
719
780
  for (int i = 0; i < backing_store->length(); ++i) {
720
- if (backing_store->get(i) != hole) ++num_used;
781
+ if (!backing_store->is_the_hole(i)) ++num_used;
721
782
  // Bail out early if more than 1/4 is used.
722
783
  if (4 * num_used > backing_store->length()) break;
723
784
  }
@@ -730,27 +791,75 @@ class FastObjectElementsAccessor
730
791
  return heap->true_value();
731
792
  }
732
793
 
794
+ virtual MaybeObject* Delete(JSObject* obj,
795
+ uint32_t key,
796
+ JSReceiver::DeleteMode mode) {
797
+ return DeleteCommon(obj, key, mode);
798
+ }
799
+
800
+ static bool HasElementImpl(
801
+ Object* receiver,
802
+ JSObject* holder,
803
+ uint32_t key,
804
+ typename KindTraits::BackingStore* backing_store) {
805
+ if (key >= static_cast<uint32_t>(backing_store->length())) {
806
+ return false;
807
+ }
808
+ return !backing_store->is_the_hole(key);
809
+ }
810
+
811
+ static void ValidateContents(JSObject* holder, int length) {
812
+ #if DEBUG
813
+ FixedArrayBase* elements = holder->elements();
814
+ Heap* heap = elements->GetHeap();
815
+ Map* map = elements->map();
816
+ ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
817
+ (map == heap->fixed_array_map() ||
818
+ map == heap->fixed_cow_array_map())) ||
819
+ (IsFastDoubleElementsKind(KindTraits::Kind) ==
820
+ ((map == heap->fixed_array_map() && length == 0) ||
821
+ map == heap->fixed_double_array_map())));
822
+ for (int i = 0; i < length; i++) {
823
+ typename KindTraits::BackingStore* backing_store =
824
+ KindTraits::BackingStore::cast(elements);
825
+ ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) ||
826
+ static_cast<Object*>(backing_store->get(i))->IsSmi()) ||
827
+ (IsFastHoleyElementsKind(KindTraits::Kind) ==
828
+ backing_store->is_the_hole(i)));
829
+ }
830
+ #endif
831
+ }
832
+ };
833
+
834
+
835
+ template<typename FastElementsAccessorSubclass,
836
+ typename KindTraits>
837
+ class FastSmiOrObjectElementsAccessor
838
+ : public FastElementsAccessor<FastElementsAccessorSubclass,
839
+ KindTraits,
840
+ kPointerSize> {
841
+ public:
842
+ explicit FastSmiOrObjectElementsAccessor(const char* name)
843
+ : FastElementsAccessor<FastElementsAccessorSubclass,
844
+ KindTraits,
845
+ kPointerSize>(name) {}
846
+
733
847
  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
734
848
  uint32_t from_start,
735
849
  FixedArrayBase* to,
736
850
  ElementsKind to_kind,
737
851
  uint32_t to_start,
738
852
  int copy_size) {
739
- switch (to_kind) {
740
- case FAST_SMI_ONLY_ELEMENTS:
741
- case FAST_ELEMENTS: {
742
- CopyObjectToObjectElements(
743
- FixedArray::cast(from), ElementsTraits::Kind, from_start,
744
- FixedArray::cast(to), to_kind, to_start, copy_size);
745
- return from;
746
- }
747
- case FAST_DOUBLE_ELEMENTS:
748
- CopyObjectToDoubleElements(
749
- FixedArray::cast(from), from_start,
750
- FixedDoubleArray::cast(to), to_start, copy_size);
751
- return from;
752
- default:
753
- UNREACHABLE();
853
+ if (IsFastSmiOrObjectElementsKind(to_kind)) {
854
+ CopyObjectToObjectElements(
855
+ FixedArray::cast(from), KindTraits::Kind, from_start,
856
+ FixedArray::cast(to), to_kind, to_start, copy_size);
857
+ } else if (IsFastDoubleElementsKind(to_kind)) {
858
+ CopyObjectToDoubleElements(
859
+ FixedArray::cast(from), from_start,
860
+ FixedDoubleArray::cast(to), to_start, copy_size);
861
+ } else {
862
+ UNREACHABLE();
754
863
  }
755
864
  return to->GetHeap()->undefined_value();
756
865
  }
@@ -759,51 +868,85 @@ class FastObjectElementsAccessor
759
868
  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
760
869
  uint32_t capacity,
761
870
  uint32_t length) {
762
- JSObject::SetFastElementsCapacityMode set_capacity_mode =
763
- obj->HasFastSmiOnlyElements()
764
- ? JSObject::kAllowSmiOnlyElements
765
- : JSObject::kDontAllowSmiOnlyElements;
871
+ JSObject::SetFastElementsCapacitySmiMode set_capacity_mode =
872
+ obj->HasFastSmiElements()
873
+ ? JSObject::kAllowSmiElements
874
+ : JSObject::kDontAllowSmiElements;
766
875
  return obj->SetFastElementsCapacityAndLength(capacity,
767
876
  length,
768
877
  set_capacity_mode);
769
878
  }
879
+ };
770
880
 
771
- protected:
772
- friend class FastElementsAccessor<FastObjectElementsAccessor,
773
- ElementsKindTraits<FAST_ELEMENTS>,
774
- kPointerSize>;
775
881
 
776
- virtual MaybeObject* Delete(JSObject* obj,
777
- uint32_t key,
778
- JSReceiver::DeleteMode mode) {
779
- return DeleteCommon(obj, key);
780
- }
882
+ class FastPackedSmiElementsAccessor
883
+ : public FastSmiOrObjectElementsAccessor<
884
+ FastPackedSmiElementsAccessor,
885
+ ElementsKindTraits<FAST_SMI_ELEMENTS> > {
886
+ public:
887
+ explicit FastPackedSmiElementsAccessor(const char* name)
888
+ : FastSmiOrObjectElementsAccessor<
889
+ FastPackedSmiElementsAccessor,
890
+ ElementsKindTraits<FAST_SMI_ELEMENTS> >(name) {}
781
891
  };
782
892
 
783
893
 
894
+ class FastHoleySmiElementsAccessor
895
+ : public FastSmiOrObjectElementsAccessor<
896
+ FastHoleySmiElementsAccessor,
897
+ ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> > {
898
+ public:
899
+ explicit FastHoleySmiElementsAccessor(const char* name)
900
+ : FastSmiOrObjectElementsAccessor<
901
+ FastHoleySmiElementsAccessor,
902
+ ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> >(name) {}
903
+ };
904
+
905
+
906
+ class FastPackedObjectElementsAccessor
907
+ : public FastSmiOrObjectElementsAccessor<
908
+ FastPackedObjectElementsAccessor,
909
+ ElementsKindTraits<FAST_ELEMENTS> > {
910
+ public:
911
+ explicit FastPackedObjectElementsAccessor(const char* name)
912
+ : FastSmiOrObjectElementsAccessor<
913
+ FastPackedObjectElementsAccessor,
914
+ ElementsKindTraits<FAST_ELEMENTS> >(name) {}
915
+ };
916
+
917
+
918
+ class FastHoleyObjectElementsAccessor
919
+ : public FastSmiOrObjectElementsAccessor<
920
+ FastHoleyObjectElementsAccessor,
921
+ ElementsKindTraits<FAST_HOLEY_ELEMENTS> > {
922
+ public:
923
+ explicit FastHoleyObjectElementsAccessor(const char* name)
924
+ : FastSmiOrObjectElementsAccessor<
925
+ FastHoleyObjectElementsAccessor,
926
+ ElementsKindTraits<FAST_HOLEY_ELEMENTS> >(name) {}
927
+ };
928
+
929
+
930
+ template<typename FastElementsAccessorSubclass,
931
+ typename KindTraits>
784
932
  class FastDoubleElementsAccessor
785
- : public FastElementsAccessor<FastDoubleElementsAccessor,
786
- ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
933
+ : public FastElementsAccessor<FastElementsAccessorSubclass,
934
+ KindTraits,
787
935
  kDoubleSize> {
788
936
  public:
789
937
  explicit FastDoubleElementsAccessor(const char* name)
790
- : FastElementsAccessor<FastDoubleElementsAccessor,
791
- ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
938
+ : FastElementsAccessor<FastElementsAccessorSubclass,
939
+ KindTraits,
792
940
  kDoubleSize>(name) {}
793
941
 
794
942
  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
795
943
  uint32_t capacity,
796
944
  uint32_t length) {
797
- return obj->SetFastDoubleElementsCapacityAndLength(capacity, length);
945
+ return obj->SetFastDoubleElementsCapacityAndLength(capacity,
946
+ length);
798
947
  }
799
948
 
800
949
  protected:
801
- friend class ElementsAccessorBase<FastDoubleElementsAccessor,
802
- ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
803
- friend class FastElementsAccessor<FastDoubleElementsAccessor,
804
- ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
805
- kDoubleSize>;
806
-
807
950
  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
808
951
  uint32_t from_start,
809
952
  FixedArrayBase* to,
@@ -811,12 +954,15 @@ class FastDoubleElementsAccessor
811
954
  uint32_t to_start,
812
955
  int copy_size) {
813
956
  switch (to_kind) {
814
- case FAST_SMI_ONLY_ELEMENTS:
957
+ case FAST_SMI_ELEMENTS:
815
958
  case FAST_ELEMENTS:
959
+ case FAST_HOLEY_SMI_ELEMENTS:
960
+ case FAST_HOLEY_ELEMENTS:
816
961
  return CopyDoubleToObjectElements(
817
962
  FixedDoubleArray::cast(from), from_start, FixedArray::cast(to),
818
963
  to_kind, to_start, copy_size);
819
964
  case FAST_DOUBLE_ELEMENTS:
965
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
820
966
  CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start,
821
967
  FixedDoubleArray::cast(to),
822
968
  to_start, copy_size);
@@ -826,26 +972,35 @@ class FastDoubleElementsAccessor
826
972
  }
827
973
  return to->GetHeap()->undefined_value();
828
974
  }
975
+ };
829
976
 
830
- virtual MaybeObject* Delete(JSObject* obj,
831
- uint32_t key,
832
- JSReceiver::DeleteMode mode) {
833
- int length = obj->IsJSArray()
834
- ? Smi::cast(JSArray::cast(obj)->length())->value()
835
- : FixedDoubleArray::cast(obj->elements())->length();
836
- if (key < static_cast<uint32_t>(length)) {
837
- FixedDoubleArray::cast(obj->elements())->set_the_hole(key);
838
- }
839
- return obj->GetHeap()->true_value();
840
- }
841
977
 
842
- static bool HasElementImpl(Object* receiver,
843
- JSObject* holder,
844
- uint32_t key,
845
- FixedDoubleArray* backing_store) {
846
- return key < static_cast<uint32_t>(backing_store->length()) &&
847
- !backing_store->is_the_hole(key);
848
- }
978
+ class FastPackedDoubleElementsAccessor
979
+ : public FastDoubleElementsAccessor<
980
+ FastPackedDoubleElementsAccessor,
981
+ ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
982
+ public:
983
+ friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor,
984
+ ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
985
+ explicit FastPackedDoubleElementsAccessor(const char* name)
986
+ : FastDoubleElementsAccessor<
987
+ FastPackedDoubleElementsAccessor,
988
+ ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >(name) {}
989
+ };
990
+
991
+
992
+ class FastHoleyDoubleElementsAccessor
993
+ : public FastDoubleElementsAccessor<
994
+ FastHoleyDoubleElementsAccessor,
995
+ ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
996
+ public:
997
+ friend class ElementsAccessorBase<
998
+ FastHoleyDoubleElementsAccessor,
999
+ ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >;
1000
+ explicit FastHoleyDoubleElementsAccessor(const char* name)
1001
+ : FastDoubleElementsAccessor<
1002
+ FastHoleyDoubleElementsAccessor,
1003
+ ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {}
849
1004
  };
850
1005
 
851
1006
 
@@ -866,27 +1021,28 @@ class ExternalElementsAccessor
866
1021
  friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
867
1022
  ElementsKindTraits<Kind> >;
868
1023
 
869
- static MaybeObject* GetImpl(Object* receiver,
870
- JSObject* obj,
871
- uint32_t key,
872
- BackingStore* backing_store) {
1024
+ MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1025
+ JSObject* obj,
1026
+ uint32_t key,
1027
+ BackingStore* backing_store) {
873
1028
  return
874
1029
  key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
875
1030
  ? backing_store->get(key)
876
1031
  : backing_store->GetHeap()->undefined_value();
877
1032
  }
878
1033
 
879
- static MaybeObject* SetLengthImpl(JSObject* obj,
880
- Object* length,
881
- BackingStore* backing_store) {
1034
+ MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1035
+ JSObject* obj,
1036
+ Object* length,
1037
+ BackingStore* backing_store) {
882
1038
  // External arrays do not support changing their length.
883
1039
  UNREACHABLE();
884
1040
  return obj;
885
1041
  }
886
1042
 
887
- virtual MaybeObject* Delete(JSObject* obj,
888
- uint32_t key,
889
- JSReceiver::DeleteMode mode) {
1043
+ MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1044
+ uint32_t key,
1045
+ JSReceiver::DeleteMode mode) {
890
1046
  // External arrays always ignore deletes.
891
1047
  return obj->GetHeap()->true_value();
892
1048
  }
@@ -1002,10 +1158,11 @@ class DictionaryElementsAccessor
1002
1158
 
1003
1159
  // Adjusts the length of the dictionary backing store and returns the new
1004
1160
  // length according to ES5 section 15.4.5.2 behavior.
1005
- static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
1006
- JSArray* array,
1007
- Object* length_object,
1008
- uint32_t length) {
1161
+ MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
1162
+ SeededNumberDictionary* dict,
1163
+ JSArray* array,
1164
+ Object* length_object,
1165
+ uint32_t length) {
1009
1166
  if (length == 0) {
1010
1167
  // If the length of a slow array is reset to zero, we clear
1011
1168
  // the array and flush backing storage. This has the added
@@ -1057,9 +1214,10 @@ class DictionaryElementsAccessor
1057
1214
  return length_object;
1058
1215
  }
1059
1216
 
1060
- static MaybeObject* DeleteCommon(JSObject* obj,
1061
- uint32_t key,
1062
- JSReceiver::DeleteMode mode) {
1217
+ MUST_USE_RESULT static MaybeObject* DeleteCommon(
1218
+ JSObject* obj,
1219
+ uint32_t key,
1220
+ JSReceiver::DeleteMode mode) {
1063
1221
  Isolate* isolate = obj->GetIsolate();
1064
1222
  Heap* heap = isolate->heap();
1065
1223
  FixedArray* backing_store = FixedArray::cast(obj->elements());
@@ -1102,20 +1260,23 @@ class DictionaryElementsAccessor
1102
1260
  return heap->true_value();
1103
1261
  }
1104
1262
 
1105
- static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1106
- uint32_t from_start,
1107
- FixedArrayBase* to,
1108
- ElementsKind to_kind,
1109
- uint32_t to_start,
1110
- int copy_size) {
1263
+ MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1264
+ uint32_t from_start,
1265
+ FixedArrayBase* to,
1266
+ ElementsKind to_kind,
1267
+ uint32_t to_start,
1268
+ int copy_size) {
1111
1269
  switch (to_kind) {
1112
- case FAST_SMI_ONLY_ELEMENTS:
1270
+ case FAST_SMI_ELEMENTS:
1113
1271
  case FAST_ELEMENTS:
1272
+ case FAST_HOLEY_SMI_ELEMENTS:
1273
+ case FAST_HOLEY_ELEMENTS:
1114
1274
  CopyDictionaryToObjectElements(
1115
1275
  SeededNumberDictionary::cast(from), from_start,
1116
1276
  FixedArray::cast(to), to_kind, to_start, copy_size);
1117
1277
  return from;
1118
1278
  case FAST_DOUBLE_ELEMENTS:
1279
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
1119
1280
  CopyDictionaryToDoubleElements(
1120
1281
  SeededNumberDictionary::cast(from), from_start,
1121
1282
  FixedDoubleArray::cast(to), to_start, copy_size);
@@ -1131,16 +1292,17 @@ class DictionaryElementsAccessor
1131
1292
  friend class ElementsAccessorBase<DictionaryElementsAccessor,
1132
1293
  ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1133
1294
 
1134
- virtual MaybeObject* Delete(JSObject* obj,
1135
- uint32_t key,
1136
- JSReceiver::DeleteMode mode) {
1295
+ MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1296
+ uint32_t key,
1297
+ JSReceiver::DeleteMode mode) {
1137
1298
  return DeleteCommon(obj, key, mode);
1138
1299
  }
1139
1300
 
1140
- static MaybeObject* GetImpl(Object* receiver,
1141
- JSObject* obj,
1142
- uint32_t key,
1143
- SeededNumberDictionary* backing_store) {
1301
+ MUST_USE_RESULT static MaybeObject* GetImpl(
1302
+ Object* receiver,
1303
+ JSObject* obj,
1304
+ uint32_t key,
1305
+ SeededNumberDictionary* backing_store) {
1144
1306
  int entry = backing_store->FindEntry(key);
1145
1307
  if (entry != SeededNumberDictionary::kNotFound) {
1146
1308
  Object* element = backing_store->ValueAt(entry);
@@ -1186,10 +1348,10 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
1186
1348
  NonStrictArgumentsElementsAccessor,
1187
1349
  ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
1188
1350
 
1189
- static MaybeObject* GetImpl(Object* receiver,
1190
- JSObject* obj,
1191
- uint32_t key,
1192
- FixedArray* parameter_map) {
1351
+ MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1352
+ JSObject* obj,
1353
+ uint32_t key,
1354
+ FixedArray* parameter_map) {
1193
1355
  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1194
1356
  if (!probe->IsTheHole()) {
1195
1357
  Context* context = Context::cast(parameter_map->get(0));
@@ -1216,18 +1378,19 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
1216
1378
  }
1217
1379
  }
1218
1380
 
1219
- static MaybeObject* SetLengthImpl(JSObject* obj,
1220
- Object* length,
1221
- FixedArray* parameter_map) {
1381
+ MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1382
+ JSObject* obj,
1383
+ Object* length,
1384
+ FixedArray* parameter_map) {
1222
1385
  // TODO(mstarzinger): This was never implemented but will be used once we
1223
1386
  // correctly implement [[DefineOwnProperty]] on arrays.
1224
1387
  UNIMPLEMENTED();
1225
1388
  return obj;
1226
1389
  }
1227
1390
 
1228
- virtual MaybeObject* Delete(JSObject* obj,
1229
- uint32_t key,
1230
- JSReceiver::DeleteMode mode) {
1391
+ MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1392
+ uint32_t key,
1393
+ JSReceiver::DeleteMode mode) {
1231
1394
  FixedArray* parameter_map = FixedArray::cast(obj->elements());
1232
1395
  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1233
1396
  if (!probe->IsTheHole()) {
@@ -1240,18 +1403,21 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
1240
1403
  if (arguments->IsDictionary()) {
1241
1404
  return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
1242
1405
  } else {
1243
- return FastObjectElementsAccessor::DeleteCommon(obj, key);
1406
+ // It's difficult to access the version of DeleteCommon that is declared
1407
+ // in the templatized super class, call the concrete implementation in
1408
+ // the class for the most generalized ElementsKind subclass.
1409
+ return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode);
1244
1410
  }
1245
1411
  }
1246
1412
  return obj->GetHeap()->true_value();
1247
1413
  }
1248
1414
 
1249
- static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1250
- uint32_t from_start,
1251
- FixedArrayBase* to,
1252
- ElementsKind to_kind,
1253
- uint32_t to_start,
1254
- int copy_size) {
1415
+ MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1416
+ uint32_t from_start,
1417
+ FixedArrayBase* to,
1418
+ ElementsKind to_kind,
1419
+ uint32_t to_start,
1420
+ int copy_size) {
1255
1421
  FixedArray* parameter_map = FixedArray::cast(from);
1256
1422
  FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1257
1423
  ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
@@ -1304,7 +1470,7 @@ ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1304
1470
  if (array->IsDictionary()) {
1305
1471
  return elements_accessors_[DICTIONARY_ELEMENTS];
1306
1472
  } else {
1307
- return elements_accessors_[FAST_ELEMENTS];
1473
+ return elements_accessors_[FAST_HOLEY_ELEMENTS];
1308
1474
  }
1309
1475
  case EXTERNAL_BYTE_ARRAY_TYPE:
1310
1476
  return elements_accessors_[EXTERNAL_BYTE_ELEMENTS];
@@ -1354,8 +1520,8 @@ void ElementsAccessor::TearDown() {
1354
1520
 
1355
1521
 
1356
1522
  template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1357
- MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
1358
- ElementsKindTraits>::
1523
+ MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
1524
+ ElementsKindTraits>::
1359
1525
  SetLengthImpl(JSObject* obj,
1360
1526
  Object* length,
1361
1527
  typename ElementsKindTraits::BackingStore* backing_store) {