Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Side by Side Diff: src/elements.cc

Issue 11416238: Move CopyElements to the accessor of the target. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 139
140 140
141 static Failure* ThrowArrayLengthRangeError(Heap* heap) { 141 static Failure* ThrowArrayLengthRangeError(Heap* heap) {
142 HandleScope scope(heap->isolate()); 142 HandleScope scope(heap->isolate());
143 return heap->isolate()->Throw( 143 return heap->isolate()->Throw(
144 *heap->isolate()->factory()->NewRangeError("invalid_array_length", 144 *heap->isolate()->factory()->NewRangeError("invalid_array_length",
145 HandleVector<Object>(NULL, 0))); 145 HandleVector<Object>(NULL, 0)));
146 } 146 }
147 147
148 148
149 static void CopyObjectToObjectElements(FixedArray* from, 149 static void CopyObjectToObjectElements(FixedArrayBase* from_base,
150 ElementsKind from_kind, 150 ElementsKind from_kind,
151 uint32_t from_start, 151 uint32_t from_start,
152 FixedArray* to, 152 FixedArrayBase* to_base,
153 ElementsKind to_kind, 153 ElementsKind to_kind,
154 uint32_t to_start, 154 uint32_t to_start,
155 int raw_copy_size) { 155 int raw_copy_size) {
156 ASSERT(to->map() != HEAP->fixed_cow_array_map()); 156 ASSERT(to_base->map() != HEAP->fixed_cow_array_map());
157 AssertNoAllocation no_allocation; 157 AssertNoAllocation no_allocation;
158 int copy_size = raw_copy_size; 158 int copy_size = raw_copy_size;
159 if (raw_copy_size < 0) { 159 if (raw_copy_size < 0) {
160 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 160 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
161 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 161 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
162 copy_size = Min(from->length() - from_start, 162 copy_size = Min(from_base->length() - from_start,
163 to->length() - to_start); 163 to_base->length() - to_start);
164 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 164 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
165 int start = to_start + copy_size; 165 int start = to_start + copy_size;
166 int length = to->length() - start; 166 int length = to_base->length() - start;
167 if (length > 0) { 167 if (length > 0) {
168 Heap* heap = from->GetHeap(); 168 Heap* heap = from_base->GetHeap();
169 MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); 169 MemsetPointer(FixedArray::cast(to_base)->data_start() + start,
170 heap->the_hole_value(), length);
170 } 171 }
171 } 172 }
172 } 173 }
173 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 174 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
174 (copy_size + static_cast<int>(from_start)) <= from->length()); 175 (copy_size + static_cast<int>(from_start)) <= from_base->length());
175 if (copy_size == 0) return; 176 if (copy_size == 0) return;
177 FixedArray* from = FixedArray::cast(from_base);
178 FixedArray* to = FixedArray::cast(to_base);
176 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); 179 ASSERT(IsFastSmiOrObjectElementsKind(from_kind));
177 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); 180 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
178 Address to_address = to->address() + FixedArray::kHeaderSize; 181 Address to_address = to->address() + FixedArray::kHeaderSize;
179 Address from_address = from->address() + FixedArray::kHeaderSize; 182 Address from_address = from->address() + FixedArray::kHeaderSize;
180 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, 183 CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
181 reinterpret_cast<Object**>(from_address) + from_start, 184 reinterpret_cast<Object**>(from_address) + from_start,
182 copy_size); 185 copy_size);
183 if (IsFastObjectElementsKind(from_kind) && 186 if (IsFastObjectElementsKind(from_kind) &&
184 IsFastObjectElementsKind(to_kind)) { 187 IsFastObjectElementsKind(to_kind)) {
185 Heap* heap = from->GetHeap(); 188 Heap* heap = from->GetHeap();
186 if (!heap->InNewSpace(to)) { 189 if (!heap->InNewSpace(to)) {
187 heap->RecordWrites(to->address(), 190 heap->RecordWrites(to->address(),
188 to->OffsetOfElementAt(to_start), 191 to->OffsetOfElementAt(to_start),
189 copy_size); 192 copy_size);
190 } 193 }
191 heap->incremental_marking()->RecordWrites(to); 194 heap->incremental_marking()->RecordWrites(to);
192 } 195 }
193 } 196 }
194 197
195 198
196 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, 199 static void CopyDictionaryToObjectElements(FixedArrayBase* from_base,
197 uint32_t from_start, 200 uint32_t from_start,
198 FixedArray* to, 201 FixedArrayBase* to_base,
199 ElementsKind to_kind, 202 ElementsKind to_kind,
200 uint32_t to_start, 203 uint32_t to_start,
201 int raw_copy_size) { 204 int raw_copy_size) {
205 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base);
202 AssertNoAllocation no_allocation; 206 AssertNoAllocation no_allocation;
203 int copy_size = raw_copy_size; 207 int copy_size = raw_copy_size;
204 Heap* heap = from->GetHeap(); 208 Heap* heap = from->GetHeap();
205 if (raw_copy_size < 0) { 209 if (raw_copy_size < 0) {
206 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 210 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
207 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 211 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
208 copy_size = from->max_number_key() + 1 - from_start; 212 copy_size = from->max_number_key() + 1 - from_start;
209 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 213 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
210 int start = to_start + copy_size; 214 int start = to_start + copy_size;
211 int length = to->length() - start; 215 int length = to_base->length() - start;
212 if (length > 0) { 216 if (length > 0) {
213 Heap* heap = from->GetHeap(); 217 Heap* heap = from->GetHeap();
214 MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); 218 MemsetPointer(FixedArray::cast(to_base)->data_start() + start,
219 heap->the_hole_value(), length);
215 } 220 }
216 } 221 }
217 } 222 }
218 ASSERT(to != from); 223 ASSERT(to_base != from_base);
219 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); 224 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
220 if (copy_size == 0) return; 225 if (copy_size == 0) return;
226 FixedArray* to = FixedArray::cast(to_base);
221 uint32_t to_length = to->length(); 227 uint32_t to_length = to->length();
222 if (to_start + copy_size > to_length) { 228 if (to_start + copy_size > to_length) {
223 copy_size = to_length - to_start; 229 copy_size = to_length - to_start;
224 } 230 }
225 for (int i = 0; i < copy_size; i++) { 231 for (int i = 0; i < copy_size; i++) {
226 int entry = from->FindEntry(i + from_start); 232 int entry = from->FindEntry(i + from_start);
227 if (entry != SeededNumberDictionary::kNotFound) { 233 if (entry != SeededNumberDictionary::kNotFound) {
228 Object* value = from->ValueAt(entry); 234 Object* value = from->ValueAt(entry);
229 ASSERT(!value->IsTheHole()); 235 ASSERT(!value->IsTheHole());
230 to->set(i + to_start, value, SKIP_WRITE_BARRIER); 236 to->set(i + to_start, value, SKIP_WRITE_BARRIER);
231 } else { 237 } else {
232 to->set_the_hole(i + to_start); 238 to->set_the_hole(i + to_start);
233 } 239 }
234 } 240 }
235 if (IsFastObjectElementsKind(to_kind)) { 241 if (IsFastObjectElementsKind(to_kind)) {
236 if (!heap->InNewSpace(to)) { 242 if (!heap->InNewSpace(to)) {
237 heap->RecordWrites(to->address(), 243 heap->RecordWrites(to->address(),
238 to->OffsetOfElementAt(to_start), 244 to->OffsetOfElementAt(to_start),
239 copy_size); 245 copy_size);
240 } 246 }
241 heap->incremental_marking()->RecordWrites(to); 247 heap->incremental_marking()->RecordWrites(to);
242 } 248 }
243 } 249 }
244 250
245 251
246 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( 252 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
247 FixedDoubleArray* from, 253 FixedArrayBase* from_base,
248 uint32_t from_start, 254 uint32_t from_start,
249 FixedArray* to, 255 FixedArrayBase* to_base,
250 ElementsKind to_kind, 256 ElementsKind to_kind,
251 uint32_t to_start, 257 uint32_t to_start,
252 int raw_copy_size) { 258 int raw_copy_size) {
253 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); 259 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
254 int copy_size = raw_copy_size; 260 int copy_size = raw_copy_size;
255 if (raw_copy_size < 0) { 261 if (raw_copy_size < 0) {
256 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 262 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
257 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 263 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
258 copy_size = Min(from->length() - from_start, 264 copy_size = Min(from_base->length() - from_start,
259 to->length() - to_start); 265 to_base->length() - to_start);
260 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 266 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
261 // Also initialize the area that will be copied over since HeapNumber 267 // Also initialize the area that will be copied over since HeapNumber
262 // allocation below can cause an incremental marking step, requiring all 268 // allocation below can cause an incremental marking step, requiring all
263 // existing heap objects to be propertly initialized. 269 // existing heap objects to be propertly initialized.
264 int start = to_start; 270 int start = to_start;
265 int length = to->length() - start; 271 int length = to_base->length() - start;
266 if (length > 0) { 272 if (length > 0) {
267 Heap* heap = from->GetHeap(); 273 Heap* heap = from_base->GetHeap();
268 MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); 274 MemsetPointer(FixedArray::cast(to_base)->data_start() + start,
275 heap->the_hole_value(), length);
269 } 276 }
270 } 277 }
271 } 278 }
272 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 279 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
273 (copy_size + static_cast<int>(from_start)) <= from->length()); 280 (copy_size + static_cast<int>(from_start)) <= from_base->length());
274 if (copy_size == 0) return from; 281 if (copy_size == 0) return from_base;
282 FixedDoubleArray* from = FixedDoubleArray::cast(from_base);
283 FixedArray* to = FixedArray::cast(to_base);
275 for (int i = 0; i < copy_size; ++i) { 284 for (int i = 0; i < copy_size; ++i) {
276 if (IsFastSmiElementsKind(to_kind)) { 285 if (IsFastSmiElementsKind(to_kind)) {
277 UNIMPLEMENTED(); 286 UNIMPLEMENTED();
278 return Failure::Exception(); 287 return Failure::Exception();
279 } else { 288 } else {
280 MaybeObject* maybe_value = from->get(i + from_start); 289 MaybeObject* maybe_value = from->get(i + from_start);
281 Object* value; 290 Object* value;
282 ASSERT(IsFastObjectElementsKind(to_kind)); 291 ASSERT(IsFastObjectElementsKind(to_kind));
283 // Because Double -> Object elements transitions allocate HeapObjects 292 // Because Double -> Object elements transitions allocate HeapObjects
284 // iteratively, the allocate must succeed within a single GC cycle, 293 // iteratively, the allocate must succeed within a single GC cycle,
285 // otherwise the retry after the GC will also fail. In order to ensure 294 // otherwise the retry after the GC will also fail. In order to ensure
286 // that no GC is triggered, allocate HeapNumbers from old space if they 295 // that no GC is triggered, allocate HeapNumbers from old space if they
287 // can't be taken from new space. 296 // can't be taken from new space.
288 if (!maybe_value->ToObject(&value)) { 297 if (!maybe_value->ToObject(&value)) {
289 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); 298 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory());
290 Heap* heap = from->GetHeap(); 299 Heap* heap = from->GetHeap();
291 MaybeObject* maybe_value_object = 300 MaybeObject* maybe_value_object =
292 heap->AllocateHeapNumber(from->get_scalar(i + from_start), 301 heap->AllocateHeapNumber(from->get_scalar(i + from_start),
293 TENURED); 302 TENURED);
294 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 303 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
295 } 304 }
296 to->set(i + to_start, value, UPDATE_WRITE_BARRIER); 305 to->set(i + to_start, value, UPDATE_WRITE_BARRIER);
297 } 306 }
298 } 307 }
299 return to; 308 return to;
300 } 309 }
301 310
302 311
303 static void CopyDoubleToDoubleElements(FixedDoubleArray* from, 312 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base,
304 uint32_t from_start, 313 uint32_t from_start,
305 FixedDoubleArray* to, 314 FixedArrayBase* to_base,
306 uint32_t to_start, 315 uint32_t to_start,
307 int raw_copy_size) { 316 int raw_copy_size) {
308 int copy_size = raw_copy_size; 317 int copy_size = raw_copy_size;
309 if (raw_copy_size < 0) { 318 if (raw_copy_size < 0) {
310 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 319 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
311 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 320 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
312 copy_size = Min(from->length() - from_start, 321 copy_size = Min(from_base->length() - from_start,
313 to->length() - to_start); 322 to_base->length() - to_start);
314 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 323 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
315 for (int i = to_start + copy_size; i < to->length(); ++i) { 324 for (int i = to_start + copy_size; i < to_base->length(); ++i) {
316 to->set_the_hole(i); 325 FixedDoubleArray::cast(to_base)->set_the_hole(i);
317 } 326 }
318 } 327 }
319 } 328 }
320 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 329 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
321 (copy_size + static_cast<int>(from_start)) <= from->length()); 330 (copy_size + static_cast<int>(from_start)) <= from_base->length());
322 if (copy_size == 0) return; 331 if (copy_size == 0) return;
332 FixedDoubleArray* from = FixedDoubleArray::cast(from_base);
333 FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
323 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; 334 Address to_address = to->address() + FixedDoubleArray::kHeaderSize;
324 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; 335 Address from_address = from->address() + FixedDoubleArray::kHeaderSize;
325 to_address += kDoubleSize * to_start; 336 to_address += kDoubleSize * to_start;
326 from_address += kDoubleSize * from_start; 337 from_address += kDoubleSize * from_start;
327 int words_per_double = (kDoubleSize / kPointerSize); 338 int words_per_double = (kDoubleSize / kPointerSize);
328 CopyWords(reinterpret_cast<Object**>(to_address), 339 CopyWords(reinterpret_cast<Object**>(to_address),
329 reinterpret_cast<Object**>(from_address), 340 reinterpret_cast<Object**>(from_address),
330 words_per_double * copy_size); 341 words_per_double * copy_size);
331 } 342 }
332 343
333 344
334 static void CopySmiToDoubleElements(FixedArray* from, 345 static void CopySmiToDoubleElements(FixedArrayBase* from_base,
335 uint32_t from_start, 346 uint32_t from_start,
336 FixedDoubleArray* to, 347 FixedArrayBase* to_base,
337 uint32_t to_start, 348 uint32_t to_start,
338 int raw_copy_size) { 349 int raw_copy_size) {
339 int copy_size = raw_copy_size; 350 int copy_size = raw_copy_size;
340 if (raw_copy_size < 0) { 351 if (raw_copy_size < 0) {
341 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 352 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
342 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 353 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
343 copy_size = from->length() - from_start; 354 copy_size = from_base->length() - from_start;
344 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 355 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
345 for (int i = to_start + copy_size; i < to->length(); ++i) { 356 for (int i = to_start + copy_size; i < to_base->length(); ++i) {
346 to->set_the_hole(i); 357 FixedDoubleArray::cast(to_base)->set_the_hole(i);
347 } 358 }
348 } 359 }
349 } 360 }
350 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 361 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
351 (copy_size + static_cast<int>(from_start)) <= from->length()); 362 (copy_size + static_cast<int>(from_start)) <= from_base->length());
352 if (copy_size == 0) return; 363 if (copy_size == 0) return;
364 FixedArray* from = FixedArray::cast(from_base);
365 FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
353 Object* the_hole = from->GetHeap()->the_hole_value(); 366 Object* the_hole = from->GetHeap()->the_hole_value();
354 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); 367 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size);
355 from_start < from_end; from_start++, to_start++) { 368 from_start < from_end; from_start++, to_start++) {
356 Object* hole_or_smi = from->get(from_start); 369 Object* hole_or_smi = from->get(from_start);
357 if (hole_or_smi == the_hole) { 370 if (hole_or_smi == the_hole) {
358 to->set_the_hole(to_start); 371 to->set_the_hole(to_start);
359 } else { 372 } else {
360 to->set(to_start, Smi::cast(hole_or_smi)->value()); 373 to->set(to_start, Smi::cast(hole_or_smi)->value());
361 } 374 }
362 } 375 }
363 } 376 }
364 377
365 378
366 static void CopyPackedSmiToDoubleElements(FixedArray* from, 379 static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base,
367 uint32_t from_start, 380 uint32_t from_start,
368 FixedDoubleArray* to, 381 FixedArrayBase* to_base,
369 uint32_t to_start, 382 uint32_t to_start,
370 int packed_size, 383 int packed_size,
371 int raw_copy_size) { 384 int raw_copy_size) {
372 int copy_size = raw_copy_size; 385 int copy_size = raw_copy_size;
373 uint32_t to_end; 386 uint32_t to_end;
374 if (raw_copy_size < 0) { 387 if (raw_copy_size < 0) {
375 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 388 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
376 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 389 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
377 copy_size = from->length() - from_start; 390 copy_size = from_base->length() - from_start;
378 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 391 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
379 to_end = to->length(); 392 to_end = to_base->length();
380 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { 393 for (uint32_t i = to_start + copy_size; i < to_end; ++i) {
381 to->set_the_hole(i); 394 FixedDoubleArray::cast(to_base)->set_the_hole(i);
382 } 395 }
383 } else { 396 } else {
384 to_end = to_start + static_cast<uint32_t>(copy_size); 397 to_end = to_start + static_cast<uint32_t>(copy_size);
385 } 398 }
386 } else { 399 } else {
387 to_end = to_start + static_cast<uint32_t>(copy_size); 400 to_end = to_start + static_cast<uint32_t>(copy_size);
388 } 401 }
389 ASSERT(static_cast<int>(to_end) <= to->length()); 402 ASSERT(static_cast<int>(to_end) <= to_base->length());
390 ASSERT(packed_size >= 0 && packed_size <= copy_size); 403 ASSERT(packed_size >= 0 && packed_size <= copy_size);
391 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 404 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
392 (copy_size + static_cast<int>(from_start)) <= from->length()); 405 (copy_size + static_cast<int>(from_start)) <= from_base->length());
393 if (copy_size == 0) return; 406 if (copy_size == 0) return;
407 FixedArray* from = FixedArray::cast(from_base);
408 FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
394 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); 409 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size);
395 from_start < from_end; from_start++, to_start++) { 410 from_start < from_end; from_start++, to_start++) {
396 Object* smi = from->get(from_start); 411 Object* smi = from->get(from_start);
397 ASSERT(!smi->IsTheHole()); 412 ASSERT(!smi->IsTheHole());
398 to->set(to_start, Smi::cast(smi)->value()); 413 to->set(to_start, Smi::cast(smi)->value());
399 } 414 }
400 } 415 }
401 416
402 417
403 static void CopyObjectToDoubleElements(FixedArray* from, 418 static void CopyObjectToDoubleElements(FixedArrayBase* from_base,
404 uint32_t from_start, 419 uint32_t from_start,
405 FixedDoubleArray* to, 420 FixedArrayBase* to_base,
406 uint32_t to_start, 421 uint32_t to_start,
407 int raw_copy_size) { 422 int raw_copy_size) {
408 int copy_size = raw_copy_size; 423 int copy_size = raw_copy_size;
409 if (raw_copy_size < 0) { 424 if (raw_copy_size < 0) {
410 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 425 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
411 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 426 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
412 copy_size = from->length() - from_start; 427 copy_size = from_base->length() - from_start;
413 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 428 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
414 for (int i = to_start + copy_size; i < to->length(); ++i) { 429 for (int i = to_start + copy_size; i < to_base->length(); ++i) {
415 to->set_the_hole(i); 430 FixedDoubleArray::cast(to_base)->set_the_hole(i);
416 } 431 }
417 } 432 }
418 } 433 }
419 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 434 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
420 (copy_size + static_cast<int>(from_start)) <= from->length()); 435 (copy_size + static_cast<int>(from_start)) <= from_base->length());
421 if (copy_size == 0) return; 436 if (copy_size == 0) return;
437 FixedArray* from = FixedArray::cast(from_base);
438 FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
422 Object* the_hole = from->GetHeap()->the_hole_value(); 439 Object* the_hole = from->GetHeap()->the_hole_value();
423 for (uint32_t from_end = from_start + copy_size; 440 for (uint32_t from_end = from_start + copy_size;
424 from_start < from_end; from_start++, to_start++) { 441 from_start < from_end; from_start++, to_start++) {
425 Object* hole_or_object = from->get(from_start); 442 Object* hole_or_object = from->get(from_start);
426 if (hole_or_object == the_hole) { 443 if (hole_or_object == the_hole) {
427 to->set_the_hole(to_start); 444 to->set_the_hole(to_start);
428 } else { 445 } else {
429 to->set(to_start, hole_or_object->Number()); 446 to->set(to_start, hole_or_object->Number());
430 } 447 }
431 } 448 }
432 } 449 }
433 450
434 451
435 static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, 452 static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base,
436 uint32_t from_start, 453 uint32_t from_start,
437 FixedDoubleArray* to, 454 FixedArrayBase* to_base,
438 uint32_t to_start, 455 uint32_t to_start,
439 int raw_copy_size) { 456 int raw_copy_size) {
457 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base);
440 int copy_size = raw_copy_size; 458 int copy_size = raw_copy_size;
441 if (copy_size < 0) { 459 if (copy_size < 0) {
442 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || 460 ASSERT(copy_size == ElementsAccessor::kCopyToEnd ||
443 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 461 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
444 copy_size = from->max_number_key() + 1 - from_start; 462 copy_size = from->max_number_key() + 1 - from_start;
445 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 463 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
446 for (int i = to_start + copy_size; i < to->length(); ++i) { 464 for (int i = to_start + copy_size; i < to_base->length(); ++i) {
447 to->set_the_hole(i); 465 FixedDoubleArray::cast(to_base)->set_the_hole(i);
448 } 466 }
449 } 467 }
450 } 468 }
451 if (copy_size == 0) return; 469 if (copy_size == 0) return;
470 FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
452 uint32_t to_length = to->length(); 471 uint32_t to_length = to->length();
453 if (to_start + copy_size > to_length) { 472 if (to_start + copy_size > to_length) {
454 copy_size = to_length - to_start; 473 copy_size = to_length - to_start;
455 } 474 }
456 for (int i = 0; i < copy_size; i++) { 475 for (int i = 0; i < copy_size; i++) {
457 int entry = from->FindEntry(i + from_start); 476 int entry = from->FindEntry(i + from_start);
458 if (entry != SeededNumberDictionary::kNotFound) { 477 if (entry != SeededNumberDictionary::kNotFound) {
459 to->set(i + to_start, from->ValueAt(entry)->Number()); 478 to->set(i + to_start, from->ValueAt(entry)->Number());
460 } else { 479 } else {
461 to->set_the_hole(i + to_start); 480 to->set_the_hole(i + to_start);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 553 }
535 554
536 virtual bool HasElement(Object* receiver, 555 virtual bool HasElement(Object* receiver,
537 JSObject* holder, 556 JSObject* holder,
538 uint32_t key, 557 uint32_t key,
539 FixedArrayBase* backing_store) { 558 FixedArrayBase* backing_store) {
540 if (backing_store == NULL) { 559 if (backing_store == NULL) {
541 backing_store = holder->elements(); 560 backing_store = holder->elements();
542 } 561 }
543 return ElementsAccessorSubclass::HasElementImpl( 562 return ElementsAccessorSubclass::HasElementImpl(
544 receiver, holder, key, BackingStore::cast(backing_store)); 563 receiver, holder, key, backing_store);
545 } 564 }
546 565
547 MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, 566 MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver,
548 JSObject* holder, 567 JSObject* holder,
549 uint32_t key, 568 uint32_t key,
550 FixedArrayBase* backing_store) { 569 FixedArrayBase* backing_store) {
551 if (backing_store == NULL) { 570 if (backing_store == NULL) {
552 backing_store = holder->elements(); 571 backing_store = holder->elements();
553 } 572 }
554 return ElementsAccessorSubclass::GetImpl( 573 return ElementsAccessorSubclass::GetImpl(
555 receiver, holder, key, BackingStore::cast(backing_store)); 574 receiver, holder, key, backing_store);
556 } 575 }
557 576
558 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, 577 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
559 JSObject* obj, 578 JSObject* obj,
560 uint32_t key, 579 uint32_t key,
561 BackingStore* backing_store) { 580 FixedArrayBase* backing_store) {
562 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) 581 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
563 ? backing_store->get(key) 582 ? BackingStore::cast(backing_store)->get(key)
564 : backing_store->GetHeap()->the_hole_value(); 583 : backing_store->GetHeap()->the_hole_value();
565 } 584 }
566 585
567 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( 586 MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
568 Object* receiver, 587 Object* receiver,
569 JSObject* holder, 588 JSObject* holder,
570 uint32_t key, 589 uint32_t key,
571 FixedArrayBase* backing_store) { 590 FixedArrayBase* backing_store) {
572 if (backing_store == NULL) { 591 if (backing_store == NULL) {
573 backing_store = holder->elements(); 592 backing_store = holder->elements();
(...skipping 15 matching lines...) Expand all
589 608
590 MUST_USE_RESULT virtual PropertyType GetType( 609 MUST_USE_RESULT virtual PropertyType GetType(
591 Object* receiver, 610 Object* receiver,
592 JSObject* holder, 611 JSObject* holder,
593 uint32_t key, 612 uint32_t key,
594 FixedArrayBase* backing_store) { 613 FixedArrayBase* backing_store) {
595 if (backing_store == NULL) { 614 if (backing_store == NULL) {
596 backing_store = holder->elements(); 615 backing_store = holder->elements();
597 } 616 }
598 return ElementsAccessorSubclass::GetTypeImpl( 617 return ElementsAccessorSubclass::GetTypeImpl(
599 receiver, holder, key, BackingStore::cast(backing_store)); 618 receiver, holder, key, backing_store);
600 } 619 }
601 620
602 MUST_USE_RESULT static PropertyType GetTypeImpl( 621 MUST_USE_RESULT static PropertyType GetTypeImpl(
603 Object* receiver, 622 Object* receiver,
604 JSObject* obj, 623 JSObject* obj,
605 uint32_t key, 624 uint32_t key,
606 BackingStore* backing_store) { 625 FixedArrayBase* backing_store) {
607 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { 626 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
608 return NONEXISTENT; 627 return NONEXISTENT;
609 } 628 }
610 return backing_store->is_the_hole(key) ? NONEXISTENT : FIELD; 629 return BackingStore::cast(backing_store)->is_the_hole(key)
630 ? NONEXISTENT : FIELD;
611 } 631 }
612 632
613 MUST_USE_RESULT virtual AccessorPair* GetAccessorPair( 633 MUST_USE_RESULT virtual AccessorPair* GetAccessorPair(
614 Object* receiver, 634 Object* receiver,
615 JSObject* holder, 635 JSObject* holder,
616 uint32_t key, 636 uint32_t key,
617 FixedArrayBase* backing_store) { 637 FixedArrayBase* backing_store) {
618 if (backing_store == NULL) { 638 if (backing_store == NULL) {
619 backing_store = holder->elements(); 639 backing_store = holder->elements();
620 } 640 }
621 return ElementsAccessorSubclass::GetAccessorPairImpl( 641 return ElementsAccessorSubclass::GetAccessorPairImpl(
622 receiver, holder, key, BackingStore::cast(backing_store)); 642 receiver, holder, key, backing_store);
623 } 643 }
624 644
625 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( 645 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
626 Object* receiver, 646 Object* receiver,
627 JSObject* obj, 647 JSObject* obj,
628 uint32_t key, 648 uint32_t key,
629 BackingStore* backing_store) { 649 FixedArrayBase* backing_store) {
630 return NULL; 650 return NULL;
631 } 651 }
632 652
633 MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array, 653 MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array,
634 Object* length) { 654 Object* length) {
635 return ElementsAccessorSubclass::SetLengthImpl( 655 return ElementsAccessorSubclass::SetLengthImpl(
636 array, length, BackingStore::cast(array->elements())); 656 array, length, array->elements());
637 } 657 }
638 658
639 MUST_USE_RESULT static MaybeObject* SetLengthImpl( 659 MUST_USE_RESULT static MaybeObject* SetLengthImpl(
640 JSObject* obj, 660 JSObject* obj,
641 Object* length, 661 Object* length,
642 BackingStore* backing_store); 662 FixedArrayBase* backing_store);
643 663
644 MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength( 664 MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength(
645 JSArray* array, 665 JSArray* array,
646 int capacity, 666 int capacity,
647 int length) { 667 int length) {
648 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( 668 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
649 array, 669 array,
650 capacity, 670 capacity,
651 length); 671 length);
652 } 672 }
653 673
654 MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength( 674 MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength(
655 JSObject* obj, 675 JSObject* obj,
656 int capacity, 676 int capacity,
657 int length) { 677 int length) {
658 UNIMPLEMENTED(); 678 UNIMPLEMENTED();
659 return obj; 679 return obj;
660 } 680 }
661 681
662 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 682 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
663 uint32_t key, 683 uint32_t key,
664 JSReceiver::DeleteMode mode) = 0; 684 JSReceiver::DeleteMode mode) = 0;
665 685
666 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 686 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
667 uint32_t from_start, 687 uint32_t from_start,
668 FixedArrayBase* to, 688 FixedArrayBase* to,
669 ElementsKind to_kind, 689 ElementsKind from_kind,
670 uint32_t to_start, 690 uint32_t to_start,
671 int packed_size, 691 int packed_size,
672 int copy_size) { 692 int copy_size) {
673 UNREACHABLE(); 693 UNREACHABLE();
674 return NULL; 694 return NULL;
675 } 695 }
676 696
677 MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder, 697 MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
678 uint32_t from_start, 698 uint32_t from_start,
679 FixedArrayBase* to, 699 FixedArrayBase* to,
680 ElementsKind to_kind, 700 ElementsKind from_kind,
681 uint32_t to_start, 701 uint32_t to_start,
682 int copy_size, 702 int copy_size,
683 FixedArrayBase* from) { 703 FixedArrayBase* from) {
684 int packed_size = kPackedSizeNotKnown; 704 int packed_size = kPackedSizeNotKnown;
685 if (from == NULL) { 705 if (from == NULL) {
686 from = from_holder->elements(); 706 from = from_holder->elements();
687 } 707 }
688 708
689 if (from_holder) { 709 if (from_holder) {
690 ElementsKind elements_kind = from_holder->GetElementsKind(); 710 bool is_packed = IsFastPackedElementsKind(from_kind) &&
691 bool is_packed = IsFastPackedElementsKind(elements_kind) &&
692 from_holder->IsJSArray(); 711 from_holder->IsJSArray();
693 if (is_packed) { 712 if (is_packed) {
694 packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value(); 713 packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value();
695 if (copy_size >= 0 && packed_size > copy_size) { 714 if (copy_size >= 0 && packed_size > copy_size) {
696 packed_size = copy_size; 715 packed_size = copy_size;
697 } 716 }
698 } 717 }
699 } 718 }
700 return ElementsAccessorSubclass::CopyElementsImpl( 719 return ElementsAccessorSubclass::CopyElementsImpl(
701 from, from_start, to, to_kind, to_start, packed_size, copy_size); 720 from, from_start, to, from_kind, to_start, packed_size, copy_size);
702 } 721 }
703 722
704 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( 723 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
705 Object* receiver, 724 Object* receiver,
706 JSObject* holder, 725 JSObject* holder,
707 FixedArray* to, 726 FixedArray* to,
708 FixedArrayBase* from) { 727 FixedArrayBase* from) {
709 int len0 = to->length(); 728 int len0 = to->length();
710 #ifdef DEBUG 729 #ifdef DEBUG
711 if (FLAG_enable_slow_asserts) { 730 if (FLAG_enable_slow_asserts) {
712 for (int i = 0; i < len0; i++) { 731 for (int i = 0; i < len0; i++) {
713 ASSERT(!to->get(i)->IsTheHole()); 732 ASSERT(!to->get(i)->IsTheHole());
714 } 733 }
715 } 734 }
716 #endif 735 #endif
717 if (from == NULL) { 736 if (from == NULL) {
718 from = holder->elements(); 737 from = holder->elements();
719 } 738 }
720 BackingStore* backing_store = BackingStore::cast(from);
721 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
722 739
723 // Optimize if 'other' is empty. 740 // Optimize if 'other' is empty.
724 // We cannot optimize if 'this' is empty, as other may have holes. 741 // We cannot optimize if 'this' is empty, as other may have holes.
742 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from);
725 if (len1 == 0) return to; 743 if (len1 == 0) return to;
726 744
727 // Compute how many elements are not in other. 745 // Compute how many elements are not in other.
728 uint32_t extra = 0; 746 uint32_t extra = 0;
729 for (uint32_t y = 0; y < len1; y++) { 747 for (uint32_t y = 0; y < len1; y++) {
730 uint32_t key = 748 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
731 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
732 if (ElementsAccessorSubclass::HasElementImpl( 749 if (ElementsAccessorSubclass::HasElementImpl(
733 receiver, holder, key, backing_store)) { 750 receiver, holder, key, from)) {
734 MaybeObject* maybe_value = 751 MaybeObject* maybe_value =
735 ElementsAccessorSubclass::GetImpl(receiver, holder, 752 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
736 key, backing_store);
737 Object* value; 753 Object* value;
738 if (!maybe_value->ToObject(&value)) return maybe_value; 754 if (!maybe_value->To(&value)) return maybe_value;
739 ASSERT(!value->IsTheHole()); 755 ASSERT(!value->IsTheHole());
740 if (!HasKey(to, value)) { 756 if (!HasKey(to, value)) {
741 extra++; 757 extra++;
742 } 758 }
743 } 759 }
744 } 760 }
745 761
746 if (extra == 0) return to; 762 if (extra == 0) return to;
747 763
748 // Allocate the result 764 // Allocate the result
749 FixedArray* result; 765 FixedArray* result;
750 MaybeObject* maybe_obj = 766 MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra);
751 backing_store->GetHeap()->AllocateFixedArray(len0 + extra); 767 if (!maybe_obj->To(&result)) return maybe_obj;
752 if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj;
753 768
754 // Fill in the content 769 // Fill in the content
755 { 770 {
756 AssertNoAllocation no_gc; 771 AssertNoAllocation no_gc;
757 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 772 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
758 for (int i = 0; i < len0; i++) { 773 for (int i = 0; i < len0; i++) {
759 Object* e = to->get(i); 774 Object* e = to->get(i);
760 ASSERT(e->IsString() || e->IsNumber()); 775 ASSERT(e->IsString() || e->IsNumber());
761 result->set(i, e, mode); 776 result->set(i, e, mode);
762 } 777 }
763 } 778 }
764 // Fill in the extra values. 779 // Fill in the extra values.
765 uint32_t index = 0; 780 uint32_t index = 0;
766 for (uint32_t y = 0; y < len1; y++) { 781 for (uint32_t y = 0; y < len1; y++) {
767 uint32_t key = 782 uint32_t key =
768 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 783 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
769 if (ElementsAccessorSubclass::HasElementImpl( 784 if (ElementsAccessorSubclass::HasElementImpl(
770 receiver, holder, key, backing_store)) { 785 receiver, holder, key, from)) {
771 MaybeObject* maybe_value = 786 MaybeObject* maybe_value =
772 ElementsAccessorSubclass::GetImpl(receiver, holder, 787 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
773 key, backing_store);
774 Object* value; 788 Object* value;
775 if (!maybe_value->ToObject(&value)) return maybe_value; 789 if (!maybe_value->To(&value)) return maybe_value;
776 if (!value->IsTheHole() && !HasKey(to, value)) { 790 if (!value->IsTheHole() && !HasKey(to, value)) {
777 result->set(len0 + index, value); 791 result->set(len0 + index, value);
778 index++; 792 index++;
779 } 793 }
780 } 794 }
781 } 795 }
782 ASSERT(extra == index); 796 ASSERT(extra == index);
783 return result; 797 return result;
784 } 798 }
785 799
786 protected: 800 protected:
787 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { 801 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
788 return backing_store->length(); 802 return backing_store->length();
789 } 803 }
790 804
791 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 805 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
792 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); 806 return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
793 } 807 }
794 808
795 static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, 809 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
796 uint32_t index) { 810 uint32_t index) {
797 return index; 811 return index;
798 } 812 }
799 813
800 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 814 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
801 uint32_t index) { 815 uint32_t index) {
802 return ElementsAccessorSubclass::GetKeyForIndexImpl( 816 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
803 BackingStore::cast(backing_store), index);
804 } 817 }
805 818
806 private: 819 private:
807 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 820 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
808 }; 821 };
809 822
810 823
811 // Super class for all fast element arrays. 824 // Super class for all fast element arrays.
812 template<typename FastElementsAccessorSubclass, 825 template<typename FastElementsAccessorSubclass,
813 typename KindTraits, 826 typename KindTraits,
814 int ElementSize> 827 int ElementSize>
815 class FastElementsAccessor 828 class FastElementsAccessor
816 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 829 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
817 public: 830 public:
818 explicit FastElementsAccessor(const char* name) 831 explicit FastElementsAccessor(const char* name)
819 : ElementsAccessorBase<FastElementsAccessorSubclass, 832 : ElementsAccessorBase<FastElementsAccessorSubclass,
820 KindTraits>(name) {} 833 KindTraits>(name) {}
821 protected: 834 protected:
822 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 835 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
823 friend class NonStrictArgumentsElementsAccessor; 836 friend class NonStrictArgumentsElementsAccessor;
824 837
825 typedef typename KindTraits::BackingStore BackingStore; 838 typedef typename KindTraits::BackingStore BackingStore;
826 839
827 // Adjusts the length of the fast backing store or returns the new length or 840 // Adjusts the length of the fast backing store or returns the new length or
828 // undefined in case conversion to a slow backing store should be performed. 841 // undefined in case conversion to a slow backing store should be performed.
829 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 842 static MaybeObject* SetLengthWithoutNormalize(FixedArrayBase* backing_store,
830 JSArray* array, 843 JSArray* array,
831 Object* length_object, 844 Object* length_object,
832 uint32_t length) { 845 uint32_t length) {
833 uint32_t old_capacity = backing_store->length(); 846 uint32_t old_capacity = backing_store->length();
834 Object* old_length = array->length(); 847 Object* old_length = array->length();
835 bool same_or_smaller_size = old_length->IsSmi() && 848 bool same_or_smaller_size = old_length->IsSmi() &&
836 static_cast<uint32_t>(Smi::cast(old_length)->value()) >= length; 849 static_cast<uint32_t>(Smi::cast(old_length)->value()) >= length;
837 ElementsKind kind = array->GetElementsKind(); 850 ElementsKind kind = array->GetElementsKind();
838 851
839 if (!same_or_smaller_size && IsFastElementsKind(kind) && 852 if (!same_or_smaller_size && IsFastElementsKind(kind) &&
(...skipping 17 matching lines...) Expand all
857 backing_store->set_length(length); 870 backing_store->set_length(length);
858 Address filler_start = backing_store->address() + 871 Address filler_start = backing_store->address() +
859 BackingStore::OffsetOfElementAt(length); 872 BackingStore::OffsetOfElementAt(length);
860 int filler_size = (old_capacity - length) * ElementSize; 873 int filler_size = (old_capacity - length) * ElementSize;
861 array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 874 array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
862 } 875 }
863 } else { 876 } else {
864 // Otherwise, fill the unused tail with holes. 877 // Otherwise, fill the unused tail with holes.
865 int old_length = FastD2IChecked(array->length()->Number()); 878 int old_length = FastD2IChecked(array->length()->Number());
866 for (int i = length; i < old_length; i++) { 879 for (int i = length; i < old_length; i++) {
867 backing_store->set_the_hole(i); 880 BackingStore::cast(backing_store)->set_the_hole(i);
868 } 881 }
869 } 882 }
870 return length_object; 883 return length_object;
871 } 884 }
872 885
873 // Check whether the backing store should be expanded. 886 // Check whether the backing store should be expanded.
874 uint32_t min = JSObject::NewElementsCapacity(old_capacity); 887 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
875 uint32_t new_capacity = length > min ? length : min; 888 uint32_t new_capacity = length > min ? length : min;
876 if (!array->ShouldConvertToSlowElements(new_capacity)) { 889 if (!array->ShouldConvertToSlowElements(new_capacity)) {
877 MaybeObject* result = FastElementsAccessorSubclass:: 890 MaybeObject* result = FastElementsAccessorSubclass::
(...skipping 16 matching lines...) Expand all
894 Heap* heap = obj->GetHeap(); 907 Heap* heap = obj->GetHeap();
895 Object* elements = obj->elements(); 908 Object* elements = obj->elements();
896 if (elements == heap->empty_fixed_array()) { 909 if (elements == heap->empty_fixed_array()) {
897 return heap->true_value(); 910 return heap->true_value();
898 } 911 }
899 typename KindTraits::BackingStore* backing_store = 912 typename KindTraits::BackingStore* backing_store =
900 KindTraits::BackingStore::cast(elements); 913 KindTraits::BackingStore::cast(elements);
901 bool is_non_strict_arguments_elements_map = 914 bool is_non_strict_arguments_elements_map =
902 backing_store->map() == heap->non_strict_arguments_elements_map(); 915 backing_store->map() == heap->non_strict_arguments_elements_map();
903 if (is_non_strict_arguments_elements_map) { 916 if (is_non_strict_arguments_elements_map) {
904 backing_store = 917 backing_store = KindTraits::BackingStore::cast(
905 KindTraits::BackingStore::cast( 918 FixedArray::cast(backing_store)->get(1));
906 FixedArray::cast(backing_store)->get(1));
907 } 919 }
908 uint32_t length = static_cast<uint32_t>( 920 uint32_t length = static_cast<uint32_t>(
909 obj->IsJSArray() 921 obj->IsJSArray()
910 ? Smi::cast(JSArray::cast(obj)->length())->value() 922 ? Smi::cast(JSArray::cast(obj)->length())->value()
911 : backing_store->length()); 923 : backing_store->length());
912 if (key < length) { 924 if (key < length) {
913 if (!is_non_strict_arguments_elements_map) { 925 if (!is_non_strict_arguments_elements_map) {
914 ElementsKind kind = KindTraits::Kind; 926 ElementsKind kind = KindTraits::Kind;
915 if (IsFastPackedElementsKind(kind)) { 927 if (IsFastPackedElementsKind(kind)) {
916 MaybeObject* transitioned = 928 MaybeObject* transitioned =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 virtual MaybeObject* Delete(JSObject* obj, 964 virtual MaybeObject* Delete(JSObject* obj,
953 uint32_t key, 965 uint32_t key,
954 JSReceiver::DeleteMode mode) { 966 JSReceiver::DeleteMode mode) {
955 return DeleteCommon(obj, key, mode); 967 return DeleteCommon(obj, key, mode);
956 } 968 }
957 969
958 static bool HasElementImpl( 970 static bool HasElementImpl(
959 Object* receiver, 971 Object* receiver,
960 JSObject* holder, 972 JSObject* holder,
961 uint32_t key, 973 uint32_t key,
962 typename KindTraits::BackingStore* backing_store) { 974 FixedArrayBase* backing_store) {
963 if (key >= static_cast<uint32_t>(backing_store->length())) { 975 if (key >= static_cast<uint32_t>(backing_store->length())) {
964 return false; 976 return false;
965 } 977 }
966 return !backing_store->is_the_hole(key); 978 return !BackingStore::cast(backing_store)->is_the_hole(key);
967 } 979 }
968 980
969 static void ValidateContents(JSObject* holder, int length) { 981 static void ValidateContents(JSObject* holder, int length) {
970 #if DEBUG 982 #if DEBUG
971 FixedArrayBase* elements = holder->elements(); 983 FixedArrayBase* elements = holder->elements();
972 Heap* heap = elements->GetHeap(); 984 Heap* heap = elements->GetHeap();
973 Map* map = elements->map(); 985 Map* map = elements->map();
974 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 986 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
975 (map == heap->fixed_array_map() || 987 (map == heap->fixed_array_map() ||
976 map == heap->fixed_cow_array_map())) || 988 map == heap->fixed_cow_array_map())) ||
977 (IsFastDoubleElementsKind(KindTraits::Kind) == 989 (IsFastDoubleElementsKind(KindTraits::Kind) ==
978 ((map == heap->fixed_array_map() && length == 0) || 990 ((map == heap->fixed_array_map() && length == 0) ||
979 map == heap->fixed_double_array_map()))); 991 map == heap->fixed_double_array_map())));
980 for (int i = 0; i < length; i++) { 992 for (int i = 0; i < length; i++) {
981 typename KindTraits::BackingStore* backing_store = 993 typename KindTraits::BackingStore* backing_store =
982 KindTraits::BackingStore::cast(elements); 994 KindTraits::BackingStore::cast(elements);
983 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || 995 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) ||
984 static_cast<Object*>(backing_store->get(i))->IsSmi()) || 996 static_cast<Object*>(backing_store->get(i))->IsSmi()) ||
985 (IsFastHoleyElementsKind(KindTraits::Kind) == 997 (IsFastHoleyElementsKind(KindTraits::Kind) ==
986 backing_store->is_the_hole(i))); 998 backing_store->is_the_hole(i)));
987 } 999 }
988 #endif 1000 #endif
989 } 1001 }
990 }; 1002 };
991 1003
992 1004
1005 static ElementsKind ElementsKindForArray(FixedArrayBase* array) {
1006 switch (array->map()->instance_type()) {
1007 case FIXED_ARRAY_TYPE:
1008 if (array->IsDictionary()) {
1009 return DICTIONARY_ELEMENTS;
1010 } else {
1011 return FAST_HOLEY_ELEMENTS;
1012 }
1013 case FIXED_DOUBLE_ARRAY_TYPE:
1014 return FAST_HOLEY_DOUBLE_ELEMENTS;
1015 case EXTERNAL_BYTE_ARRAY_TYPE:
1016 return EXTERNAL_BYTE_ELEMENTS;
1017 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
1018 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
1019 case EXTERNAL_SHORT_ARRAY_TYPE:
1020 return EXTERNAL_SHORT_ELEMENTS;
1021 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
1022 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
1023 case EXTERNAL_INT_ARRAY_TYPE:
1024 return EXTERNAL_INT_ELEMENTS;
1025 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
1026 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
1027 case EXTERNAL_FLOAT_ARRAY_TYPE:
1028 return EXTERNAL_FLOAT_ELEMENTS;
1029 case EXTERNAL_DOUBLE_ARRAY_TYPE:
1030 return EXTERNAL_DOUBLE_ELEMENTS;
1031 case EXTERNAL_PIXEL_ARRAY_TYPE:
1032 return EXTERNAL_PIXEL_ELEMENTS;
1033 default:
1034 UNREACHABLE();
1035 }
1036 return FAST_HOLEY_ELEMENTS;
1037 }
1038
1039
993 template<typename FastElementsAccessorSubclass, 1040 template<typename FastElementsAccessorSubclass,
994 typename KindTraits> 1041 typename KindTraits>
995 class FastSmiOrObjectElementsAccessor 1042 class FastSmiOrObjectElementsAccessor
996 : public FastElementsAccessor<FastElementsAccessorSubclass, 1043 : public FastElementsAccessor<FastElementsAccessorSubclass,
997 KindTraits, 1044 KindTraits,
998 kPointerSize> { 1045 kPointerSize> {
999 public: 1046 public:
1000 explicit FastSmiOrObjectElementsAccessor(const char* name) 1047 explicit FastSmiOrObjectElementsAccessor(const char* name)
1001 : FastElementsAccessor<FastElementsAccessorSubclass, 1048 : FastElementsAccessor<FastElementsAccessorSubclass,
1002 KindTraits, 1049 KindTraits,
1003 kPointerSize>(name) {} 1050 kPointerSize>(name) {}
1004 1051
1005 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1052 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1006 uint32_t from_start, 1053 uint32_t from_start,
1007 FixedArrayBase* to, 1054 FixedArrayBase* to,
1008 ElementsKind to_kind, 1055 ElementsKind from_kind,
1009 uint32_t to_start, 1056 uint32_t to_start,
1010 int packed_size, 1057 int packed_size,
1011 int copy_size) { 1058 int copy_size) {
1012 if (IsFastSmiOrObjectElementsKind(to_kind)) { 1059 ElementsKind to_kind = KindTraits::Kind;
1013 CopyObjectToObjectElements( 1060 switch (from_kind) {
1014 FixedArray::cast(from), KindTraits::Kind, from_start, 1061 case FAST_SMI_ELEMENTS:
1015 FixedArray::cast(to), to_kind, to_start, copy_size); 1062 case FAST_HOLEY_SMI_ELEMENTS:
1016 } else if (IsFastDoubleElementsKind(to_kind)) { 1063 case FAST_ELEMENTS:
1017 if (IsFastSmiElementsKind(KindTraits::Kind)) { 1064 case FAST_HOLEY_ELEMENTS:
1018 if (IsFastPackedElementsKind(KindTraits::Kind) && 1065 CopyObjectToObjectElements(
1019 packed_size != kPackedSizeNotKnown) { 1066 from, from_kind, from_start, to, to_kind, to_start, copy_size);
1020 CopyPackedSmiToDoubleElements( 1067 return to->GetHeap()->undefined_value();
1021 FixedArray::cast(from), from_start, 1068 case FAST_DOUBLE_ELEMENTS:
1022 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, 1069 case FAST_HOLEY_DOUBLE_ELEMENTS:
1023 packed_size, copy_size); 1070 return CopyDoubleToObjectElements(
1024 } else { 1071 from, from_start, to, to_kind, to_start, copy_size);
1025 CopySmiToDoubleElements( 1072 case DICTIONARY_ELEMENTS:
1026 FixedArray::cast(from), from_start, 1073 CopyDictionaryToObjectElements(
1027 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); 1074 from, from_start, to, to_kind, to_start, copy_size);
1028 } 1075 return to->GetHeap()->undefined_value();
1029 } else { 1076 case NON_STRICT_ARGUMENTS_ELEMENTS: {
1030 CopyObjectToDoubleElements( 1077 // TODO(verwaest): This is a temporary hack to support extending
1031 FixedArray::cast(from), from_start, 1078 // NON_STRICT_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
1032 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); 1079 // This case should be UNREACHABLE().
1080 FixedArray* parameter_map = FixedArray::cast(from);
1081 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1082 ElementsKind from_kind = ElementsKindForArray(arguments);
1083 return CopyElementsImpl(arguments, from_start, to, from_kind,
1084 to_start, packed_size, copy_size);
1033 } 1085 }
1034 } else { 1086 case EXTERNAL_BYTE_ELEMENTS:
1035 UNREACHABLE(); 1087 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1088 case EXTERNAL_SHORT_ELEMENTS:
1089 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
1090 case EXTERNAL_INT_ELEMENTS:
1091 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
1092 case EXTERNAL_FLOAT_ELEMENTS:
1093 case EXTERNAL_DOUBLE_ELEMENTS:
1094 case EXTERNAL_PIXEL_ELEMENTS:
1095 UNREACHABLE();
1036 } 1096 }
1037 return to->GetHeap()->undefined_value(); 1097 return NULL;
1038 } 1098 }
1039 1099
1040 1100
1041 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 1101 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
1042 uint32_t capacity, 1102 uint32_t capacity,
1043 uint32_t length) { 1103 uint32_t length) {
1044 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = 1104 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode =
1045 obj->HasFastSmiElements() 1105 obj->HasFastSmiElements()
1046 ? JSObject::kAllowSmiElements 1106 ? JSObject::kAllowSmiElements
1047 : JSObject::kDontAllowSmiElements; 1107 : JSObject::kDontAllowSmiElements;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 uint32_t capacity, 1176 uint32_t capacity,
1117 uint32_t length) { 1177 uint32_t length) {
1118 return obj->SetFastDoubleElementsCapacityAndLength(capacity, 1178 return obj->SetFastDoubleElementsCapacityAndLength(capacity,
1119 length); 1179 length);
1120 } 1180 }
1121 1181
1122 protected: 1182 protected:
1123 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1183 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1124 uint32_t from_start, 1184 uint32_t from_start,
1125 FixedArrayBase* to, 1185 FixedArrayBase* to,
1126 ElementsKind to_kind, 1186 ElementsKind from_kind,
1127 uint32_t to_start, 1187 uint32_t to_start,
1128 int packed_size, 1188 int packed_size,
1129 int copy_size) { 1189 int copy_size) {
1130 switch (to_kind) { 1190 switch (from_kind) {
1131 case FAST_SMI_ELEMENTS: 1191 case FAST_SMI_ELEMENTS:
1132 case FAST_ELEMENTS: 1192 CopyPackedSmiToDoubleElements(
1193 from, from_start, to, to_start, packed_size, copy_size);
1194 break;
1133 case FAST_HOLEY_SMI_ELEMENTS: 1195 case FAST_HOLEY_SMI_ELEMENTS:
1134 case FAST_HOLEY_ELEMENTS: 1196 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
1135 return CopyDoubleToObjectElements( 1197 break;
1136 FixedDoubleArray::castOrEmptyFixedArray(from), from_start,
1137 FixedArray::cast(to), to_kind, to_start, copy_size);
1138 case FAST_DOUBLE_ELEMENTS: 1198 case FAST_DOUBLE_ELEMENTS:
1139 case FAST_HOLEY_DOUBLE_ELEMENTS: 1199 case FAST_HOLEY_DOUBLE_ELEMENTS:
1140 CopyDoubleToDoubleElements( 1200 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
1141 FixedDoubleArray::castOrEmptyFixedArray(from), from_start, 1201 break;
1142 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); 1202 case FAST_ELEMENTS:
1143 return from; 1203 case FAST_HOLEY_ELEMENTS:
1144 default: 1204 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1205 break;
1206 case DICTIONARY_ELEMENTS:
1207 CopyDictionaryToDoubleElements(
1208 from, from_start, to, to_start, copy_size);
1209 break;
1210 case NON_STRICT_ARGUMENTS_ELEMENTS:
1211 case EXTERNAL_BYTE_ELEMENTS:
1212 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1213 case EXTERNAL_SHORT_ELEMENTS:
1214 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
1215 case EXTERNAL_INT_ELEMENTS:
1216 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
1217 case EXTERNAL_FLOAT_ELEMENTS:
1218 case EXTERNAL_DOUBLE_ELEMENTS:
1219 case EXTERNAL_PIXEL_ELEMENTS:
1145 UNREACHABLE(); 1220 UNREACHABLE();
1146 } 1221 }
1147 return to->GetHeap()->undefined_value(); 1222 return to->GetHeap()->undefined_value();
1148 } 1223 }
1149 }; 1224 };
1150 1225
1151 1226
1152 class FastPackedDoubleElementsAccessor 1227 class FastPackedDoubleElementsAccessor
1153 : public FastDoubleElementsAccessor< 1228 : public FastDoubleElementsAccessor<
1154 FastPackedDoubleElementsAccessor, 1229 FastPackedDoubleElementsAccessor,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 1266
1192 protected: 1267 protected:
1193 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1268 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1194 1269
1195 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 1270 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
1196 ElementsKindTraits<Kind> >; 1271 ElementsKindTraits<Kind> >;
1197 1272
1198 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, 1273 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1199 JSObject* obj, 1274 JSObject* obj,
1200 uint32_t key, 1275 uint32_t key,
1201 BackingStore* backing_store) { 1276 FixedArrayBase* backing_store) {
1202 return 1277 return
1203 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1278 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1204 ? backing_store->get(key) 1279 ? BackingStore::cast(backing_store)->get(key)
1205 : backing_store->GetHeap()->undefined_value(); 1280 : backing_store->GetHeap()->undefined_value();
1206 } 1281 }
1207 1282
1208 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1283 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
1209 Object* receiver, 1284 Object* receiver,
1210 JSObject* obj, 1285 JSObject* obj,
1211 uint32_t key, 1286 uint32_t key,
1212 FixedArrayBase* backing_store) { 1287 FixedArrayBase* backing_store) {
1213 return 1288 return
1214 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1289 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1215 ? NONE : ABSENT; 1290 ? NONE : ABSENT;
1216 } 1291 }
1217 1292
1218 MUST_USE_RESULT static PropertyType GetTypeImpl( 1293 MUST_USE_RESULT static PropertyType GetTypeImpl(
1219 Object* receiver, 1294 Object* receiver,
1220 JSObject* obj, 1295 JSObject* obj,
1221 uint32_t key, 1296 uint32_t key,
1222 BackingStore* backing_store) { 1297 FixedArrayBase* backing_store) {
1223 return 1298 return
1224 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1299 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1225 ? FIELD : NONEXISTENT; 1300 ? FIELD : NONEXISTENT;
1226 } 1301 }
1227 1302
1228 MUST_USE_RESULT static MaybeObject* SetLengthImpl( 1303 MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1229 JSObject* obj, 1304 JSObject* obj,
1230 Object* length, 1305 Object* length,
1231 BackingStore* backing_store) { 1306 FixedArrayBase* backing_store) {
1232 // External arrays do not support changing their length. 1307 // External arrays do not support changing their length.
1233 UNREACHABLE(); 1308 UNREACHABLE();
1234 return obj; 1309 return obj;
1235 } 1310 }
1236 1311
1237 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1312 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1238 uint32_t key, 1313 uint32_t key,
1239 JSReceiver::DeleteMode mode) { 1314 JSReceiver::DeleteMode mode) {
1240 // External arrays always ignore deletes. 1315 // External arrays always ignore deletes.
1241 return obj->GetHeap()->true_value(); 1316 return obj->GetHeap()->true_value();
1242 } 1317 }
1243 1318
1244 static bool HasElementImpl(Object* receiver, 1319 static bool HasElementImpl(Object* receiver,
1245 JSObject* holder, 1320 JSObject* holder,
1246 uint32_t key, 1321 uint32_t key,
1247 BackingStore* backing_store) { 1322 FixedArrayBase* backing_store) {
1248 uint32_t capacity = 1323 uint32_t capacity =
1249 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); 1324 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
1250 return key < capacity; 1325 return key < capacity;
1251 } 1326 }
1252 }; 1327 };
1253 1328
1254 1329
1255 class ExternalByteElementsAccessor 1330 class ExternalByteElementsAccessor
1256 : public ExternalElementsAccessor<ExternalByteElementsAccessor, 1331 : public ExternalElementsAccessor<ExternalByteElementsAccessor,
1257 EXTERNAL_BYTE_ELEMENTS> { 1332 EXTERNAL_BYTE_ELEMENTS> {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 : public ElementsAccessorBase<DictionaryElementsAccessor, 1421 : public ElementsAccessorBase<DictionaryElementsAccessor,
1347 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1422 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1348 public: 1423 public:
1349 explicit DictionaryElementsAccessor(const char* name) 1424 explicit DictionaryElementsAccessor(const char* name)
1350 : ElementsAccessorBase<DictionaryElementsAccessor, 1425 : ElementsAccessorBase<DictionaryElementsAccessor,
1351 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1426 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1352 1427
1353 // Adjusts the length of the dictionary backing store and returns the new 1428 // Adjusts the length of the dictionary backing store and returns the new
1354 // length according to ES5 section 15.4.5.2 behavior. 1429 // length according to ES5 section 15.4.5.2 behavior.
1355 MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( 1430 MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
1356 SeededNumberDictionary* dict, 1431 FixedArrayBase* store,
1357 JSArray* array, 1432 JSArray* array,
1358 Object* length_object, 1433 Object* length_object,
1359 uint32_t length) { 1434 uint32_t length) {
1435 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1360 Heap* heap = array->GetHeap(); 1436 Heap* heap = array->GetHeap();
1361 int capacity = dict->Capacity(); 1437 int capacity = dict->Capacity();
1362 uint32_t new_length = length; 1438 uint32_t new_length = length;
1363 uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); 1439 uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
1364 if (new_length < old_length) { 1440 if (new_length < old_length) {
1365 // Find last non-deletable element in range of elements to be 1441 // Find last non-deletable element in range of elements to be
1366 // deleted and adjust range accordingly. 1442 // deleted and adjust range accordingly.
1367 for (int i = 0; i < capacity; i++) { 1443 for (int i = 0; i < capacity; i++) {
1368 Object* key = dict->KeyAt(i); 1444 Object* key = dict->KeyAt(i);
1369 if (key->IsNumber()) { 1445 if (key->IsNumber()) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 } else { 1525 } else {
1450 obj->set_elements(new_elements); 1526 obj->set_elements(new_elements);
1451 } 1527 }
1452 } 1528 }
1453 return heap->true_value(); 1529 return heap->true_value();
1454 } 1530 }
1455 1531
1456 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1532 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1457 uint32_t from_start, 1533 uint32_t from_start,
1458 FixedArrayBase* to, 1534 FixedArrayBase* to,
1459 ElementsKind to_kind, 1535 ElementsKind from_kind,
1460 uint32_t to_start, 1536 uint32_t to_start,
1461 int packed_size, 1537 int packed_size,
1462 int copy_size) { 1538 int copy_size) {
1463 switch (to_kind) { 1539 UNREACHABLE();
1464 case FAST_SMI_ELEMENTS: 1540 return NULL;
1465 case FAST_ELEMENTS:
1466 case FAST_HOLEY_SMI_ELEMENTS:
1467 case FAST_HOLEY_ELEMENTS:
1468 CopyDictionaryToObjectElements(
1469 SeededNumberDictionary::cast(from), from_start,
1470 FixedArray::cast(to), to_kind, to_start, copy_size);
1471 return from;
1472 case FAST_DOUBLE_ELEMENTS:
1473 case FAST_HOLEY_DOUBLE_ELEMENTS:
1474 CopyDictionaryToDoubleElements(
1475 SeededNumberDictionary::cast(from), from_start,
1476 FixedDoubleArray::castOrEmptyFixedArray(to), to_start,
1477 copy_size);
1478 return from;
1479 default:
1480 UNREACHABLE();
1481 }
1482 return to->GetHeap()->undefined_value();
1483 } 1541 }
1484 1542
1485 1543
1486 protected: 1544 protected:
1487 friend class ElementsAccessorBase<DictionaryElementsAccessor, 1545 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1488 ElementsKindTraits<DICTIONARY_ELEMENTS> >; 1546 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1489 1547
1490 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1548 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1491 uint32_t key, 1549 uint32_t key,
1492 JSReceiver::DeleteMode mode) { 1550 JSReceiver::DeleteMode mode) {
1493 return DeleteCommon(obj, key, mode); 1551 return DeleteCommon(obj, key, mode);
1494 } 1552 }
1495 1553
1496 MUST_USE_RESULT static MaybeObject* GetImpl( 1554 MUST_USE_RESULT static MaybeObject* GetImpl(
1497 Object* receiver, 1555 Object* receiver,
1498 JSObject* obj, 1556 JSObject* obj,
1499 uint32_t key, 1557 uint32_t key,
1500 SeededNumberDictionary* backing_store) { 1558 FixedArrayBase* store) {
1559 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1501 int entry = backing_store->FindEntry(key); 1560 int entry = backing_store->FindEntry(key);
1502 if (entry != SeededNumberDictionary::kNotFound) { 1561 if (entry != SeededNumberDictionary::kNotFound) {
1503 Object* element = backing_store->ValueAt(entry); 1562 Object* element = backing_store->ValueAt(entry);
1504 PropertyDetails details = backing_store->DetailsAt(entry); 1563 PropertyDetails details = backing_store->DetailsAt(entry);
1505 if (details.type() == CALLBACKS) { 1564 if (details.type() == CALLBACKS) {
1506 return obj->GetElementWithCallback(receiver, 1565 return obj->GetElementWithCallback(receiver,
1507 element, 1566 element,
1508 key, 1567 key,
1509 obj); 1568 obj);
1510 } else { 1569 } else {
(...skipping 14 matching lines...) Expand all
1525 if (entry != SeededNumberDictionary::kNotFound) { 1584 if (entry != SeededNumberDictionary::kNotFound) {
1526 return dictionary->DetailsAt(entry).attributes(); 1585 return dictionary->DetailsAt(entry).attributes();
1527 } 1586 }
1528 return ABSENT; 1587 return ABSENT;
1529 } 1588 }
1530 1589
1531 MUST_USE_RESULT static PropertyType GetTypeImpl( 1590 MUST_USE_RESULT static PropertyType GetTypeImpl(
1532 Object* receiver, 1591 Object* receiver,
1533 JSObject* obj, 1592 JSObject* obj,
1534 uint32_t key, 1593 uint32_t key,
1535 SeededNumberDictionary* backing_store) { 1594 FixedArrayBase* store) {
1595 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1536 int entry = backing_store->FindEntry(key); 1596 int entry = backing_store->FindEntry(key);
1537 if (entry != SeededNumberDictionary::kNotFound) { 1597 if (entry != SeededNumberDictionary::kNotFound) {
1538 return backing_store->DetailsAt(entry).type(); 1598 return backing_store->DetailsAt(entry).type();
1539 } 1599 }
1540 return NONEXISTENT; 1600 return NONEXISTENT;
1541 } 1601 }
1542 1602
1543 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( 1603 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
1544 Object* receiver, 1604 Object* receiver,
1545 JSObject* obj, 1605 JSObject* obj,
1546 uint32_t key, 1606 uint32_t key,
1547 BackingStore* backing_store) { 1607 FixedArrayBase* store) {
1608 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1548 int entry = backing_store->FindEntry(key); 1609 int entry = backing_store->FindEntry(key);
1549 if (entry != SeededNumberDictionary::kNotFound && 1610 if (entry != SeededNumberDictionary::kNotFound &&
1550 backing_store->DetailsAt(entry).type() == CALLBACKS && 1611 backing_store->DetailsAt(entry).type() == CALLBACKS &&
1551 backing_store->ValueAt(entry)->IsAccessorPair()) { 1612 backing_store->ValueAt(entry)->IsAccessorPair()) {
1552 return AccessorPair::cast(backing_store->ValueAt(entry)); 1613 return AccessorPair::cast(backing_store->ValueAt(entry));
1553 } 1614 }
1554 return NULL; 1615 return NULL;
1555 } 1616 }
1556 1617
1557 static bool HasElementImpl(Object* receiver, 1618 static bool HasElementImpl(Object* receiver,
1558 JSObject* holder, 1619 JSObject* holder,
1559 uint32_t key, 1620 uint32_t key,
1560 SeededNumberDictionary* backing_store) { 1621 FixedArrayBase* backing_store) {
1561 return backing_store->FindEntry(key) != 1622 return SeededNumberDictionary::cast(backing_store)->FindEntry(key) !=
1562 SeededNumberDictionary::kNotFound; 1623 SeededNumberDictionary::kNotFound;
1563 } 1624 }
1564 1625
1565 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 1626 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store,
1566 uint32_t index) { 1627 uint32_t index) {
1628 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1567 Object* key = dict->KeyAt(index); 1629 Object* key = dict->KeyAt(index);
1568 return Smi::cast(key)->value(); 1630 return Smi::cast(key)->value();
1569 } 1631 }
1570 }; 1632 };
1571 1633
1572 1634
1573 class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< 1635 class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
1574 NonStrictArgumentsElementsAccessor, 1636 NonStrictArgumentsElementsAccessor,
1575 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > { 1637 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > {
1576 public: 1638 public:
1577 explicit NonStrictArgumentsElementsAccessor(const char* name) 1639 explicit NonStrictArgumentsElementsAccessor(const char* name)
1578 : ElementsAccessorBase< 1640 : ElementsAccessorBase<
1579 NonStrictArgumentsElementsAccessor, 1641 NonStrictArgumentsElementsAccessor,
1580 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {} 1642 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {}
1581 protected: 1643 protected:
1582 friend class ElementsAccessorBase< 1644 friend class ElementsAccessorBase<
1583 NonStrictArgumentsElementsAccessor, 1645 NonStrictArgumentsElementsAccessor,
1584 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >; 1646 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
1585 1647
1586 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, 1648 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1587 JSObject* obj, 1649 JSObject* obj,
1588 uint32_t key, 1650 uint32_t key,
1589 FixedArray* parameter_map) { 1651 FixedArrayBase* parameters) {
1652 FixedArray* parameter_map = FixedArray::cast(parameters);
1590 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1653 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1591 if (!probe->IsTheHole()) { 1654 if (!probe->IsTheHole()) {
1592 Context* context = Context::cast(parameter_map->get(0)); 1655 Context* context = Context::cast(parameter_map->get(0));
1593 int context_index = Smi::cast(probe)->value(); 1656 int context_index = Smi::cast(probe)->value();
1594 ASSERT(!context->get(context_index)->IsTheHole()); 1657 ASSERT(!context->get(context_index)->IsTheHole());
1595 return context->get(context_index); 1658 return context->get(context_index);
1596 } else { 1659 } else {
1597 // Object is not mapped, defer to the arguments. 1660 // Object is not mapped, defer to the arguments.
1598 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1661 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1599 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( 1662 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
(...skipping 27 matching lines...) Expand all
1627 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1690 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1628 return ElementsAccessor::ForArray(arguments)->GetAttributes( 1691 return ElementsAccessor::ForArray(arguments)->GetAttributes(
1629 receiver, obj, key, arguments); 1692 receiver, obj, key, arguments);
1630 } 1693 }
1631 } 1694 }
1632 1695
1633 MUST_USE_RESULT static PropertyType GetTypeImpl( 1696 MUST_USE_RESULT static PropertyType GetTypeImpl(
1634 Object* receiver, 1697 Object* receiver,
1635 JSObject* obj, 1698 JSObject* obj,
1636 uint32_t key, 1699 uint32_t key,
1637 FixedArray* parameter_map) { 1700 FixedArrayBase* parameters) {
1701 FixedArray* parameter_map = FixedArray::cast(parameters);
1638 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1702 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1639 if (!probe->IsTheHole()) { 1703 if (!probe->IsTheHole()) {
1640 return FIELD; 1704 return FIELD;
1641 } else { 1705 } else {
1642 // If not aliased, check the arguments. 1706 // If not aliased, check the arguments.
1643 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1707 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1644 return ElementsAccessor::ForArray(arguments)->GetType( 1708 return ElementsAccessor::ForArray(arguments)->GetType(
1645 receiver, obj, key, arguments); 1709 receiver, obj, key, arguments);
1646 } 1710 }
1647 } 1711 }
1648 1712
1649 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( 1713 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
1650 Object* receiver, 1714 Object* receiver,
1651 JSObject* obj, 1715 JSObject* obj,
1652 uint32_t key, 1716 uint32_t key,
1653 FixedArray* parameter_map) { 1717 FixedArrayBase* parameters) {
1718 FixedArray* parameter_map = FixedArray::cast(parameters);
1654 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1719 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1655 if (!probe->IsTheHole()) { 1720 if (!probe->IsTheHole()) {
1656 return NULL; 1721 return NULL;
1657 } else { 1722 } else {
1658 // If not aliased, check the arguments. 1723 // If not aliased, check the arguments.
1659 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1724 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1660 return ElementsAccessor::ForArray(arguments)->GetAccessorPair( 1725 return ElementsAccessor::ForArray(arguments)->GetAccessorPair(
1661 receiver, obj, key, arguments); 1726 receiver, obj, key, arguments);
1662 } 1727 }
1663 } 1728 }
1664 1729
1665 MUST_USE_RESULT static MaybeObject* SetLengthImpl( 1730 MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1666 JSObject* obj, 1731 JSObject* obj,
1667 Object* length, 1732 Object* length,
1668 FixedArray* parameter_map) { 1733 FixedArrayBase* parameter_map) {
1669 // TODO(mstarzinger): This was never implemented but will be used once we 1734 // TODO(mstarzinger): This was never implemented but will be used once we
1670 // correctly implement [[DefineOwnProperty]] on arrays. 1735 // correctly implement [[DefineOwnProperty]] on arrays.
1671 UNIMPLEMENTED(); 1736 UNIMPLEMENTED();
1672 return obj; 1737 return obj;
1673 } 1738 }
1674 1739
1675 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1740 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1676 uint32_t key, 1741 uint32_t key,
1677 JSReceiver::DeleteMode mode) { 1742 JSReceiver::DeleteMode mode) {
1678 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1743 FixedArray* parameter_map = FixedArray::cast(obj->elements());
(...skipping 13 matching lines...) Expand all
1692 // the class for the most generalized ElementsKind subclass. 1757 // the class for the most generalized ElementsKind subclass.
1693 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); 1758 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode);
1694 } 1759 }
1695 } 1760 }
1696 return obj->GetHeap()->true_value(); 1761 return obj->GetHeap()->true_value();
1697 } 1762 }
1698 1763
1699 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1764 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1700 uint32_t from_start, 1765 uint32_t from_start,
1701 FixedArrayBase* to, 1766 FixedArrayBase* to,
1702 ElementsKind to_kind, 1767 ElementsKind from_kind,
1703 uint32_t to_start, 1768 uint32_t to_start,
1704 int packed_size, 1769 int packed_size,
1705 int copy_size) { 1770 int copy_size) {
1706 FixedArray* parameter_map = FixedArray::cast(from); 1771 UNREACHABLE();
1707 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1772 return NULL;
1708 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1709 return accessor->CopyElements(NULL, from_start, to, to_kind,
1710 to_start, copy_size, arguments);
1711 } 1773 }
1712 1774
1713 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { 1775 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
1714 FixedArray* parameter_map = FixedArray::cast(backing_store); 1776 FixedArray* parameter_map = FixedArray::cast(backing_store);
1715 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1777 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1716 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 1778 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
1717 ForArray(arguments)->GetCapacity(arguments)); 1779 ForArray(arguments)->GetCapacity(arguments));
1718 } 1780 }
1719 1781
1720 static uint32_t GetKeyForIndexImpl(FixedArray* dict, 1782 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict,
1721 uint32_t index) { 1783 uint32_t index) {
1722 return index; 1784 return index;
1723 } 1785 }
1724 1786
1725 static bool HasElementImpl(Object* receiver, 1787 static bool HasElementImpl(Object* receiver,
1726 JSObject* holder, 1788 JSObject* holder,
1727 uint32_t key, 1789 uint32_t key,
1728 FixedArray* parameter_map) { 1790 FixedArrayBase* parameters) {
1791 FixedArray* parameter_map = FixedArray::cast(parameters);
1729 Object* probe = GetParameterMapArg(holder, parameter_map, key); 1792 Object* probe = GetParameterMapArg(holder, parameter_map, key);
1730 if (!probe->IsTheHole()) { 1793 if (!probe->IsTheHole()) {
1731 return true; 1794 return true;
1732 } else { 1795 } else {
1733 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1796 FixedArrayBase* arguments =
1797 FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1));
1734 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 1798 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1735 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); 1799 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
1736 } 1800 }
1737 } 1801 }
1738 1802
1739 private: 1803 private:
1740 static Object* GetParameterMapArg(JSObject* holder, 1804 static Object* GetParameterMapArg(JSObject* holder,
1741 FixedArray* parameter_map, 1805 FixedArray* parameter_map,
1742 uint32_t key) { 1806 uint32_t key) {
1743 uint32_t length = holder->IsJSArray() 1807 uint32_t length = holder->IsJSArray()
1744 ? Smi::cast(JSArray::cast(holder)->length())->value() 1808 ? Smi::cast(JSArray::cast(holder)->length())->value()
1745 : parameter_map->length(); 1809 : parameter_map->length();
1746 return key < (length - 2 ) 1810 return key < (length - 2)
1747 ? parameter_map->get(key + 2) 1811 ? parameter_map->get(key + 2)
1748 : parameter_map->GetHeap()->the_hole_value(); 1812 : parameter_map->GetHeap()->the_hole_value();
1749 } 1813 }
1750 }; 1814 };
1751 1815
1752 1816
1753 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1817 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1754 switch (array->map()->instance_type()) { 1818 return elements_accessors_[ElementsKindForArray(array)];
1755 case FIXED_ARRAY_TYPE:
1756 if (array->IsDictionary()) {
1757 return elements_accessors_[DICTIONARY_ELEMENTS];
1758 } else {
1759 return elements_accessors_[FAST_HOLEY_ELEMENTS];
1760 }
1761 case EXTERNAL_BYTE_ARRAY_TYPE:
1762 return elements_accessors_[EXTERNAL_BYTE_ELEMENTS];
1763 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
1764 return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS];
1765 case EXTERNAL_SHORT_ARRAY_TYPE:
1766 return elements_accessors_[EXTERNAL_SHORT_ELEMENTS];
1767 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
1768 return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS];
1769 case EXTERNAL_INT_ARRAY_TYPE:
1770 return elements_accessors_[EXTERNAL_INT_ELEMENTS];
1771 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
1772 return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS];
1773 case EXTERNAL_FLOAT_ARRAY_TYPE:
1774 return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS];
1775 case EXTERNAL_DOUBLE_ARRAY_TYPE:
1776 return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS];
1777 case EXTERNAL_PIXEL_ARRAY_TYPE:
1778 return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS];
1779 default:
1780 UNREACHABLE();
1781 return NULL;
1782 }
1783 } 1819 }
1784 1820
1785 1821
1786 void ElementsAccessor::InitializeOncePerProcess() { 1822 void ElementsAccessor::InitializeOncePerProcess() {
1787 static ElementsAccessor* accessor_array[] = { 1823 static ElementsAccessor* accessor_array[] = {
1788 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), 1824 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
1789 ELEMENTS_LIST(ACCESSOR_ARRAY) 1825 ELEMENTS_LIST(ACCESSOR_ARRAY)
1790 #undef ACCESSOR_ARRAY 1826 #undef ACCESSOR_ARRAY
1791 }; 1827 };
1792 1828
(...skipping 10 matching lines...) Expand all
1803 #undef ACCESSOR_DELETE 1839 #undef ACCESSOR_DELETE
1804 elements_accessors_ = NULL; 1840 elements_accessors_ = NULL;
1805 } 1841 }
1806 1842
1807 1843
1808 template <typename ElementsAccessorSubclass, typename ElementsKindTraits> 1844 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1809 MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, 1845 MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
1810 ElementsKindTraits>:: 1846 ElementsKindTraits>::
1811 SetLengthImpl(JSObject* obj, 1847 SetLengthImpl(JSObject* obj,
1812 Object* length, 1848 Object* length,
1813 typename ElementsKindTraits::BackingStore* backing_store) { 1849 FixedArrayBase* backing_store) {
1814 JSArray* array = JSArray::cast(obj); 1850 JSArray* array = JSArray::cast(obj);
1815 1851
1816 // Fast case: The new length fits into a Smi. 1852 // Fast case: The new length fits into a Smi.
1817 MaybeObject* maybe_smi_length = length->ToSmi(); 1853 MaybeObject* maybe_smi_length = length->ToSmi();
1818 Object* smi_length = Smi::FromInt(0); 1854 Object* smi_length = Smi::FromInt(0);
1819 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 1855 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
1820 const int value = Smi::cast(smi_length)->value(); 1856 const int value = Smi::cast(smi_length)->value();
1821 if (value >= 0) { 1857 if (value >= 0) {
1822 Object* new_length; 1858 Object* new_length;
1823 MaybeObject* result = ElementsAccessorSubclass:: 1859 MaybeObject* result = ElementsAccessorSubclass::
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 1896 if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
1861 new_backing_store->set(0, length); 1897 new_backing_store->set(0, length);
1862 { MaybeObject* result = array->SetContent(new_backing_store); 1898 { MaybeObject* result = array->SetContent(new_backing_store);
1863 if (result->IsFailure()) return result; 1899 if (result->IsFailure()) return result;
1864 } 1900 }
1865 return array; 1901 return array;
1866 } 1902 }
1867 1903
1868 1904
1869 } } // namespace v8::internal 1905 } } // namespace v8::internal
OLDNEW
« src/elements.h ('K') | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698