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

Side by Side Diff: src/elements.cc

Issue 11299226: Pass FixedArrayBase in elements.cc. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove castOrEmptyFixedArray 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
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 #ifdef DEBUG 730 #ifdef DEBUG
711 if (FLAG_enable_slow_asserts) { 731 if (FLAG_enable_slow_asserts) {
712 for (int i = 0; i < len0; i++) { 732 for (int i = 0; i < len0; i++) {
713 ASSERT(!to->get(i)->IsTheHole()); 733 ASSERT(!to->get(i)->IsTheHole());
714 } 734 }
715 } 735 }
716 #endif 736 #endif
717 if (from == NULL) { 737 if (from == NULL) {
718 from = holder->elements(); 738 from = holder->elements();
719 } 739 }
720 BackingStore* backing_store = BackingStore::cast(from);
721 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
722 740
723 // Optimize if 'other' is empty. 741 // Optimize if 'other' is empty.
724 // We cannot optimize if 'this' is empty, as other may have holes. 742 // We cannot optimize if 'this' is empty, as other may have holes.
743 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from);
725 if (len1 == 0) return to; 744 if (len1 == 0) return to;
726 745
727 // Compute how many elements are not in other. 746 // Compute how many elements are not in other.
728 uint32_t extra = 0; 747 uint32_t extra = 0;
729 for (uint32_t y = 0; y < len1; y++) { 748 for (uint32_t y = 0; y < len1; y++) {
730 uint32_t key = 749 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
731 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
732 if (ElementsAccessorSubclass::HasElementImpl( 750 if (ElementsAccessorSubclass::HasElementImpl(
733 receiver, holder, key, backing_store)) { 751 receiver, holder, key, from)) {
734 MaybeObject* maybe_value = 752 MaybeObject* maybe_value =
735 ElementsAccessorSubclass::GetImpl(receiver, holder, 753 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
736 key, backing_store);
737 Object* value; 754 Object* value;
738 if (!maybe_value->ToObject(&value)) return maybe_value; 755 if (!maybe_value->To(&value)) return maybe_value;
739 ASSERT(!value->IsTheHole()); 756 ASSERT(!value->IsTheHole());
740 if (!HasKey(to, value)) { 757 if (!HasKey(to, value)) {
741 extra++; 758 extra++;
742 } 759 }
743 } 760 }
744 } 761 }
745 762
746 if (extra == 0) return to; 763 if (extra == 0) return to;
747 764
748 // Allocate the result 765 // Allocate the result
749 FixedArray* result; 766 FixedArray* result;
750 MaybeObject* maybe_obj = 767 MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra);
751 backing_store->GetHeap()->AllocateFixedArray(len0 + extra); 768 if (!maybe_obj->To(&result)) return maybe_obj;
752 if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj;
753 769
754 // Fill in the content 770 // Fill in the content
755 { 771 {
756 AssertNoAllocation no_gc; 772 AssertNoAllocation no_gc;
757 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 773 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
758 for (int i = 0; i < len0; i++) { 774 for (int i = 0; i < len0; i++) {
759 Object* e = to->get(i); 775 Object* e = to->get(i);
760 ASSERT(e->IsString() || e->IsNumber()); 776 ASSERT(e->IsString() || e->IsNumber());
761 result->set(i, e, mode); 777 result->set(i, e, mode);
762 } 778 }
763 } 779 }
764 // Fill in the extra values. 780 // Fill in the extra values.
765 uint32_t index = 0; 781 uint32_t index = 0;
766 for (uint32_t y = 0; y < len1; y++) { 782 for (uint32_t y = 0; y < len1; y++) {
767 uint32_t key = 783 uint32_t key =
768 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 784 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
769 if (ElementsAccessorSubclass::HasElementImpl( 785 if (ElementsAccessorSubclass::HasElementImpl(
770 receiver, holder, key, backing_store)) { 786 receiver, holder, key, from)) {
771 MaybeObject* maybe_value = 787 MaybeObject* maybe_value =
772 ElementsAccessorSubclass::GetImpl(receiver, holder, 788 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
773 key, backing_store);
774 Object* value; 789 Object* value;
775 if (!maybe_value->ToObject(&value)) return maybe_value; 790 if (!maybe_value->To(&value)) return maybe_value;
776 if (!value->IsTheHole() && !HasKey(to, value)) { 791 if (!value->IsTheHole() && !HasKey(to, value)) {
777 result->set(len0 + index, value); 792 result->set(len0 + index, value);
778 index++; 793 index++;
779 } 794 }
780 } 795 }
781 } 796 }
782 ASSERT(extra == index); 797 ASSERT(extra == index);
783 return result; 798 return result;
784 } 799 }
785 800
786 protected: 801 protected:
787 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { 802 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
788 return backing_store->length(); 803 return backing_store->length();
789 } 804 }
790 805
791 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 806 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
792 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); 807 return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
793 } 808 }
794 809
795 static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, 810 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
796 uint32_t index) { 811 uint32_t index) {
797 return index; 812 return index;
798 } 813 }
799 814
800 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 815 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
801 uint32_t index) { 816 uint32_t index) {
802 return ElementsAccessorSubclass::GetKeyForIndexImpl( 817 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
803 BackingStore::cast(backing_store), index);
804 } 818 }
805 819
806 private: 820 private:
807 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 821 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
808 }; 822 };
809 823
810 824
811 // Super class for all fast element arrays. 825 // Super class for all fast element arrays.
812 template<typename FastElementsAccessorSubclass, 826 template<typename FastElementsAccessorSubclass,
813 typename KindTraits, 827 typename KindTraits,
814 int ElementSize> 828 int ElementSize>
815 class FastElementsAccessor 829 class FastElementsAccessor
816 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 830 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
817 public: 831 public:
818 explicit FastElementsAccessor(const char* name) 832 explicit FastElementsAccessor(const char* name)
819 : ElementsAccessorBase<FastElementsAccessorSubclass, 833 : ElementsAccessorBase<FastElementsAccessorSubclass,
820 KindTraits>(name) {} 834 KindTraits>(name) {}
821 protected: 835 protected:
822 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 836 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
823 friend class NonStrictArgumentsElementsAccessor; 837 friend class NonStrictArgumentsElementsAccessor;
824 838
825 typedef typename KindTraits::BackingStore BackingStore; 839 typedef typename KindTraits::BackingStore BackingStore;
826 840
827 // Adjusts the length of the fast backing store or returns the new length or 841 // 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. 842 // undefined in case conversion to a slow backing store should be performed.
829 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 843 static MaybeObject* SetLengthWithoutNormalize(FixedArrayBase* backing_store,
830 JSArray* array, 844 JSArray* array,
831 Object* length_object, 845 Object* length_object,
832 uint32_t length) { 846 uint32_t length) {
833 uint32_t old_capacity = backing_store->length(); 847 uint32_t old_capacity = backing_store->length();
834 Object* old_length = array->length(); 848 Object* old_length = array->length();
835 bool same_or_smaller_size = old_length->IsSmi() && 849 bool same_or_smaller_size = old_length->IsSmi() &&
836 static_cast<uint32_t>(Smi::cast(old_length)->value()) >= length; 850 static_cast<uint32_t>(Smi::cast(old_length)->value()) >= length;
837 ElementsKind kind = array->GetElementsKind(); 851 ElementsKind kind = array->GetElementsKind();
838 852
839 if (!same_or_smaller_size && IsFastElementsKind(kind) && 853 if (!same_or_smaller_size && IsFastElementsKind(kind) &&
(...skipping 17 matching lines...) Expand all
857 backing_store->set_length(length); 871 backing_store->set_length(length);
858 Address filler_start = backing_store->address() + 872 Address filler_start = backing_store->address() +
859 BackingStore::OffsetOfElementAt(length); 873 BackingStore::OffsetOfElementAt(length);
860 int filler_size = (old_capacity - length) * ElementSize; 874 int filler_size = (old_capacity - length) * ElementSize;
861 array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 875 array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
862 } 876 }
863 } else { 877 } else {
864 // Otherwise, fill the unused tail with holes. 878 // Otherwise, fill the unused tail with holes.
865 int old_length = FastD2IChecked(array->length()->Number()); 879 int old_length = FastD2IChecked(array->length()->Number());
866 for (int i = length; i < old_length; i++) { 880 for (int i = length; i < old_length; i++) {
867 backing_store->set_the_hole(i); 881 BackingStore::cast(backing_store)->set_the_hole(i);
868 } 882 }
869 } 883 }
870 return length_object; 884 return length_object;
871 } 885 }
872 886
873 // Check whether the backing store should be expanded. 887 // Check whether the backing store should be expanded.
874 uint32_t min = JSObject::NewElementsCapacity(old_capacity); 888 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
875 uint32_t new_capacity = length > min ? length : min; 889 uint32_t new_capacity = length > min ? length : min;
876 if (!array->ShouldConvertToSlowElements(new_capacity)) { 890 if (!array->ShouldConvertToSlowElements(new_capacity)) {
877 MaybeObject* result = FastElementsAccessorSubclass:: 891 MaybeObject* result = FastElementsAccessorSubclass::
(...skipping 16 matching lines...) Expand all
894 Heap* heap = obj->GetHeap(); 908 Heap* heap = obj->GetHeap();
895 Object* elements = obj->elements(); 909 Object* elements = obj->elements();
896 if (elements == heap->empty_fixed_array()) { 910 if (elements == heap->empty_fixed_array()) {
897 return heap->true_value(); 911 return heap->true_value();
898 } 912 }
899 typename KindTraits::BackingStore* backing_store = 913 typename KindTraits::BackingStore* backing_store =
900 KindTraits::BackingStore::cast(elements); 914 KindTraits::BackingStore::cast(elements);
901 bool is_non_strict_arguments_elements_map = 915 bool is_non_strict_arguments_elements_map =
902 backing_store->map() == heap->non_strict_arguments_elements_map(); 916 backing_store->map() == heap->non_strict_arguments_elements_map();
903 if (is_non_strict_arguments_elements_map) { 917 if (is_non_strict_arguments_elements_map) {
904 backing_store = 918 backing_store = KindTraits::BackingStore::cast(
905 KindTraits::BackingStore::cast( 919 FixedArray::cast(backing_store)->get(1));
906 FixedArray::cast(backing_store)->get(1));
907 } 920 }
908 uint32_t length = static_cast<uint32_t>( 921 uint32_t length = static_cast<uint32_t>(
909 obj->IsJSArray() 922 obj->IsJSArray()
910 ? Smi::cast(JSArray::cast(obj)->length())->value() 923 ? Smi::cast(JSArray::cast(obj)->length())->value()
911 : backing_store->length()); 924 : backing_store->length());
912 if (key < length) { 925 if (key < length) {
913 if (!is_non_strict_arguments_elements_map) { 926 if (!is_non_strict_arguments_elements_map) {
914 ElementsKind kind = KindTraits::Kind; 927 ElementsKind kind = KindTraits::Kind;
915 if (IsFastPackedElementsKind(kind)) { 928 if (IsFastPackedElementsKind(kind)) {
916 MaybeObject* transitioned = 929 MaybeObject* transitioned =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 virtual MaybeObject* Delete(JSObject* obj, 965 virtual MaybeObject* Delete(JSObject* obj,
953 uint32_t key, 966 uint32_t key,
954 JSReceiver::DeleteMode mode) { 967 JSReceiver::DeleteMode mode) {
955 return DeleteCommon(obj, key, mode); 968 return DeleteCommon(obj, key, mode);
956 } 969 }
957 970
958 static bool HasElementImpl( 971 static bool HasElementImpl(
959 Object* receiver, 972 Object* receiver,
960 JSObject* holder, 973 JSObject* holder,
961 uint32_t key, 974 uint32_t key,
962 typename KindTraits::BackingStore* backing_store) { 975 FixedArrayBase* backing_store) {
963 if (key >= static_cast<uint32_t>(backing_store->length())) { 976 if (key >= static_cast<uint32_t>(backing_store->length())) {
964 return false; 977 return false;
965 } 978 }
966 return !backing_store->is_the_hole(key); 979 return !BackingStore::cast(backing_store)->is_the_hole(key);
967 } 980 }
968 981
969 static void ValidateContents(JSObject* holder, int length) { 982 static void ValidateContents(JSObject* holder, int length) {
970 #if DEBUG 983 #if DEBUG
971 FixedArrayBase* elements = holder->elements(); 984 FixedArrayBase* elements = holder->elements();
972 Heap* heap = elements->GetHeap(); 985 Heap* heap = elements->GetHeap();
973 Map* map = elements->map(); 986 Map* map = elements->map();
974 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 987 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
975 (map == heap->fixed_array_map() || 988 (map == heap->fixed_array_map() ||
976 map == heap->fixed_cow_array_map())) || 989 map == heap->fixed_cow_array_map())) ||
(...skipping 27 matching lines...) Expand all
1004 1017
1005 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1018 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1006 uint32_t from_start, 1019 uint32_t from_start,
1007 FixedArrayBase* to, 1020 FixedArrayBase* to,
1008 ElementsKind to_kind, 1021 ElementsKind to_kind,
1009 uint32_t to_start, 1022 uint32_t to_start,
1010 int packed_size, 1023 int packed_size,
1011 int copy_size) { 1024 int copy_size) {
1012 if (IsFastSmiOrObjectElementsKind(to_kind)) { 1025 if (IsFastSmiOrObjectElementsKind(to_kind)) {
1013 CopyObjectToObjectElements( 1026 CopyObjectToObjectElements(
1014 FixedArray::cast(from), KindTraits::Kind, from_start, 1027 from, KindTraits::Kind, from_start, to, to_kind, to_start, copy_size);
1015 FixedArray::cast(to), to_kind, to_start, copy_size);
1016 } else if (IsFastDoubleElementsKind(to_kind)) { 1028 } else if (IsFastDoubleElementsKind(to_kind)) {
1017 if (IsFastSmiElementsKind(KindTraits::Kind)) { 1029 if (IsFastSmiElementsKind(KindTraits::Kind)) {
1018 if (IsFastPackedElementsKind(KindTraits::Kind) && 1030 if (IsFastPackedElementsKind(KindTraits::Kind) &&
1019 packed_size != kPackedSizeNotKnown) { 1031 packed_size != kPackedSizeNotKnown) {
1020 CopyPackedSmiToDoubleElements( 1032 CopyPackedSmiToDoubleElements(
1021 FixedArray::cast(from), from_start, 1033 from, from_start, to, to_start, packed_size, copy_size);
1022 FixedDoubleArray::castOrEmptyFixedArray(to), to_start,
1023 packed_size, copy_size);
1024 } else { 1034 } else {
1025 CopySmiToDoubleElements( 1035 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
1026 FixedArray::cast(from), from_start,
1027 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size);
1028 } 1036 }
1029 } else { 1037 } else {
1030 CopyObjectToDoubleElements( 1038 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1031 FixedArray::cast(from), from_start,
1032 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size);
1033 } 1039 }
1034 } else { 1040 } else {
1035 UNREACHABLE(); 1041 UNREACHABLE();
1036 } 1042 }
1037 return to->GetHeap()->undefined_value(); 1043 return to->GetHeap()->undefined_value();
1038 } 1044 }
1039 1045
1040 1046
1041 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 1047 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
1042 uint32_t capacity, 1048 uint32_t capacity,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 ElementsKind to_kind, 1132 ElementsKind to_kind,
1127 uint32_t to_start, 1133 uint32_t to_start,
1128 int packed_size, 1134 int packed_size,
1129 int copy_size) { 1135 int copy_size) {
1130 switch (to_kind) { 1136 switch (to_kind) {
1131 case FAST_SMI_ELEMENTS: 1137 case FAST_SMI_ELEMENTS:
1132 case FAST_ELEMENTS: 1138 case FAST_ELEMENTS:
1133 case FAST_HOLEY_SMI_ELEMENTS: 1139 case FAST_HOLEY_SMI_ELEMENTS:
1134 case FAST_HOLEY_ELEMENTS: 1140 case FAST_HOLEY_ELEMENTS:
1135 return CopyDoubleToObjectElements( 1141 return CopyDoubleToObjectElements(
1136 FixedDoubleArray::castOrEmptyFixedArray(from), from_start, 1142 from, from_start, to, to_kind, to_start, copy_size);
1137 FixedArray::cast(to), to_kind, to_start, copy_size);
1138 case FAST_DOUBLE_ELEMENTS: 1143 case FAST_DOUBLE_ELEMENTS:
1139 case FAST_HOLEY_DOUBLE_ELEMENTS: 1144 case FAST_HOLEY_DOUBLE_ELEMENTS:
1140 CopyDoubleToDoubleElements( 1145 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
1141 FixedDoubleArray::castOrEmptyFixedArray(from), from_start,
1142 FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size);
1143 return from; 1146 return from;
1144 default: 1147 default:
1145 UNREACHABLE(); 1148 UNREACHABLE();
1146 } 1149 }
1147 return to->GetHeap()->undefined_value(); 1150 return to->GetHeap()->undefined_value();
1148 } 1151 }
1149 }; 1152 };
1150 1153
1151 1154
1152 class FastPackedDoubleElementsAccessor 1155 class FastPackedDoubleElementsAccessor
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 1194
1192 protected: 1195 protected:
1193 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1196 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1194 1197
1195 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 1198 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
1196 ElementsKindTraits<Kind> >; 1199 ElementsKindTraits<Kind> >;
1197 1200
1198 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, 1201 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1199 JSObject* obj, 1202 JSObject* obj,
1200 uint32_t key, 1203 uint32_t key,
1201 BackingStore* backing_store) { 1204 FixedArrayBase* backing_store) {
1202 return 1205 return
1203 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1206 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1204 ? backing_store->get(key) 1207 ? BackingStore::cast(backing_store)->get(key)
1205 : backing_store->GetHeap()->undefined_value(); 1208 : backing_store->GetHeap()->undefined_value();
1206 } 1209 }
1207 1210
1208 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1211 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
1209 Object* receiver, 1212 Object* receiver,
1210 JSObject* obj, 1213 JSObject* obj,
1211 uint32_t key, 1214 uint32_t key,
1212 FixedArrayBase* backing_store) { 1215 FixedArrayBase* backing_store) {
1213 return 1216 return
1214 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1217 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1215 ? NONE : ABSENT; 1218 ? NONE : ABSENT;
1216 } 1219 }
1217 1220
1218 MUST_USE_RESULT static PropertyType GetTypeImpl( 1221 MUST_USE_RESULT static PropertyType GetTypeImpl(
1219 Object* receiver, 1222 Object* receiver,
1220 JSObject* obj, 1223 JSObject* obj,
1221 uint32_t key, 1224 uint32_t key,
1222 BackingStore* backing_store) { 1225 FixedArrayBase* backing_store) {
1223 return 1226 return
1224 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 1227 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
1225 ? FIELD : NONEXISTENT; 1228 ? FIELD : NONEXISTENT;
1226 } 1229 }
1227 1230
1228 MUST_USE_RESULT static MaybeObject* SetLengthImpl( 1231 MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1229 JSObject* obj, 1232 JSObject* obj,
1230 Object* length, 1233 Object* length,
1231 BackingStore* backing_store) { 1234 FixedArrayBase* backing_store) {
1232 // External arrays do not support changing their length. 1235 // External arrays do not support changing their length.
1233 UNREACHABLE(); 1236 UNREACHABLE();
1234 return obj; 1237 return obj;
1235 } 1238 }
1236 1239
1237 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1240 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1238 uint32_t key, 1241 uint32_t key,
1239 JSReceiver::DeleteMode mode) { 1242 JSReceiver::DeleteMode mode) {
1240 // External arrays always ignore deletes. 1243 // External arrays always ignore deletes.
1241 return obj->GetHeap()->true_value(); 1244 return obj->GetHeap()->true_value();
1242 } 1245 }
1243 1246
1244 static bool HasElementImpl(Object* receiver, 1247 static bool HasElementImpl(Object* receiver,
1245 JSObject* holder, 1248 JSObject* holder,
1246 uint32_t key, 1249 uint32_t key,
1247 BackingStore* backing_store) { 1250 FixedArrayBase* backing_store) {
1248 uint32_t capacity = 1251 uint32_t capacity =
1249 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); 1252 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
1250 return key < capacity; 1253 return key < capacity;
1251 } 1254 }
1252 }; 1255 };
1253 1256
1254 1257
1255 class ExternalByteElementsAccessor 1258 class ExternalByteElementsAccessor
1256 : public ExternalElementsAccessor<ExternalByteElementsAccessor, 1259 : public ExternalElementsAccessor<ExternalByteElementsAccessor,
1257 EXTERNAL_BYTE_ELEMENTS> { 1260 EXTERNAL_BYTE_ELEMENTS> {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 : public ElementsAccessorBase<DictionaryElementsAccessor, 1349 : public ElementsAccessorBase<DictionaryElementsAccessor,
1347 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1350 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1348 public: 1351 public:
1349 explicit DictionaryElementsAccessor(const char* name) 1352 explicit DictionaryElementsAccessor(const char* name)
1350 : ElementsAccessorBase<DictionaryElementsAccessor, 1353 : ElementsAccessorBase<DictionaryElementsAccessor,
1351 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1354 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1352 1355
1353 // Adjusts the length of the dictionary backing store and returns the new 1356 // Adjusts the length of the dictionary backing store and returns the new
1354 // length according to ES5 section 15.4.5.2 behavior. 1357 // length according to ES5 section 15.4.5.2 behavior.
1355 MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( 1358 MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
1356 SeededNumberDictionary* dict, 1359 FixedArrayBase* store,
1357 JSArray* array, 1360 JSArray* array,
1358 Object* length_object, 1361 Object* length_object,
1359 uint32_t length) { 1362 uint32_t length) {
1363 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1360 Heap* heap = array->GetHeap(); 1364 Heap* heap = array->GetHeap();
1361 int capacity = dict->Capacity(); 1365 int capacity = dict->Capacity();
1362 uint32_t new_length = length; 1366 uint32_t new_length = length;
1363 uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); 1367 uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
1364 if (new_length < old_length) { 1368 if (new_length < old_length) {
1365 // Find last non-deletable element in range of elements to be 1369 // Find last non-deletable element in range of elements to be
1366 // deleted and adjust range accordingly. 1370 // deleted and adjust range accordingly.
1367 for (int i = 0; i < capacity; i++) { 1371 for (int i = 0; i < capacity; i++) {
1368 Object* key = dict->KeyAt(i); 1372 Object* key = dict->KeyAt(i);
1369 if (key->IsNumber()) { 1373 if (key->IsNumber()) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 ElementsKind to_kind, 1463 ElementsKind to_kind,
1460 uint32_t to_start, 1464 uint32_t to_start,
1461 int packed_size, 1465 int packed_size,
1462 int copy_size) { 1466 int copy_size) {
1463 switch (to_kind) { 1467 switch (to_kind) {
1464 case FAST_SMI_ELEMENTS: 1468 case FAST_SMI_ELEMENTS:
1465 case FAST_ELEMENTS: 1469 case FAST_ELEMENTS:
1466 case FAST_HOLEY_SMI_ELEMENTS: 1470 case FAST_HOLEY_SMI_ELEMENTS:
1467 case FAST_HOLEY_ELEMENTS: 1471 case FAST_HOLEY_ELEMENTS:
1468 CopyDictionaryToObjectElements( 1472 CopyDictionaryToObjectElements(
1469 SeededNumberDictionary::cast(from), from_start, 1473 from, from_start, to, to_kind, to_start, copy_size);
1470 FixedArray::cast(to), to_kind, to_start, copy_size);
1471 return from; 1474 return from;
1472 case FAST_DOUBLE_ELEMENTS: 1475 case FAST_DOUBLE_ELEMENTS:
1473 case FAST_HOLEY_DOUBLE_ELEMENTS: 1476 case FAST_HOLEY_DOUBLE_ELEMENTS:
1474 CopyDictionaryToDoubleElements( 1477 CopyDictionaryToDoubleElements(
1475 SeededNumberDictionary::cast(from), from_start, 1478 from, from_start, to, to_start, copy_size);
1476 FixedDoubleArray::castOrEmptyFixedArray(to), to_start,
1477 copy_size);
1478 return from; 1479 return from;
1479 default: 1480 default:
1480 UNREACHABLE(); 1481 UNREACHABLE();
1481 } 1482 }
1482 return to->GetHeap()->undefined_value(); 1483 return to->GetHeap()->undefined_value();
1483 } 1484 }
1484 1485
1485 1486
1486 protected: 1487 protected:
1487 friend class ElementsAccessorBase<DictionaryElementsAccessor, 1488 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1488 ElementsKindTraits<DICTIONARY_ELEMENTS> >; 1489 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1489 1490
1490 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1491 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1491 uint32_t key, 1492 uint32_t key,
1492 JSReceiver::DeleteMode mode) { 1493 JSReceiver::DeleteMode mode) {
1493 return DeleteCommon(obj, key, mode); 1494 return DeleteCommon(obj, key, mode);
1494 } 1495 }
1495 1496
1496 MUST_USE_RESULT static MaybeObject* GetImpl( 1497 MUST_USE_RESULT static MaybeObject* GetImpl(
1497 Object* receiver, 1498 Object* receiver,
1498 JSObject* obj, 1499 JSObject* obj,
1499 uint32_t key, 1500 uint32_t key,
1500 SeededNumberDictionary* backing_store) { 1501 FixedArrayBase* store) {
1502 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1501 int entry = backing_store->FindEntry(key); 1503 int entry = backing_store->FindEntry(key);
1502 if (entry != SeededNumberDictionary::kNotFound) { 1504 if (entry != SeededNumberDictionary::kNotFound) {
1503 Object* element = backing_store->ValueAt(entry); 1505 Object* element = backing_store->ValueAt(entry);
1504 PropertyDetails details = backing_store->DetailsAt(entry); 1506 PropertyDetails details = backing_store->DetailsAt(entry);
1505 if (details.type() == CALLBACKS) { 1507 if (details.type() == CALLBACKS) {
1506 return obj->GetElementWithCallback(receiver, 1508 return obj->GetElementWithCallback(receiver,
1507 element, 1509 element,
1508 key, 1510 key,
1509 obj); 1511 obj);
1510 } else { 1512 } else {
(...skipping 14 matching lines...) Expand all
1525 if (entry != SeededNumberDictionary::kNotFound) { 1527 if (entry != SeededNumberDictionary::kNotFound) {
1526 return dictionary->DetailsAt(entry).attributes(); 1528 return dictionary->DetailsAt(entry).attributes();
1527 } 1529 }
1528 return ABSENT; 1530 return ABSENT;
1529 } 1531 }
1530 1532
1531 MUST_USE_RESULT static PropertyType GetTypeImpl( 1533 MUST_USE_RESULT static PropertyType GetTypeImpl(
1532 Object* receiver, 1534 Object* receiver,
1533 JSObject* obj, 1535 JSObject* obj,
1534 uint32_t key, 1536 uint32_t key,
1535 SeededNumberDictionary* backing_store) { 1537 FixedArrayBase* store) {
1538 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1536 int entry = backing_store->FindEntry(key); 1539 int entry = backing_store->FindEntry(key);
1537 if (entry != SeededNumberDictionary::kNotFound) { 1540 if (entry != SeededNumberDictionary::kNotFound) {
1538 return backing_store->DetailsAt(entry).type(); 1541 return backing_store->DetailsAt(entry).type();
1539 } 1542 }
1540 return NONEXISTENT; 1543 return NONEXISTENT;
1541 } 1544 }
1542 1545
1543 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( 1546 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
1544 Object* receiver, 1547 Object* receiver,
1545 JSObject* obj, 1548 JSObject* obj,
1546 uint32_t key, 1549 uint32_t key,
1547 BackingStore* backing_store) { 1550 FixedArrayBase* store) {
1551 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1548 int entry = backing_store->FindEntry(key); 1552 int entry = backing_store->FindEntry(key);
1549 if (entry != SeededNumberDictionary::kNotFound && 1553 if (entry != SeededNumberDictionary::kNotFound &&
1550 backing_store->DetailsAt(entry).type() == CALLBACKS && 1554 backing_store->DetailsAt(entry).type() == CALLBACKS &&
1551 backing_store->ValueAt(entry)->IsAccessorPair()) { 1555 backing_store->ValueAt(entry)->IsAccessorPair()) {
1552 return AccessorPair::cast(backing_store->ValueAt(entry)); 1556 return AccessorPair::cast(backing_store->ValueAt(entry));
1553 } 1557 }
1554 return NULL; 1558 return NULL;
1555 } 1559 }
1556 1560
1557 static bool HasElementImpl(Object* receiver, 1561 static bool HasElementImpl(Object* receiver,
1558 JSObject* holder, 1562 JSObject* holder,
1559 uint32_t key, 1563 uint32_t key,
1560 SeededNumberDictionary* backing_store) { 1564 FixedArrayBase* backing_store) {
1561 return backing_store->FindEntry(key) != 1565 return SeededNumberDictionary::cast(backing_store)->FindEntry(key) !=
1562 SeededNumberDictionary::kNotFound; 1566 SeededNumberDictionary::kNotFound;
1563 } 1567 }
1564 1568
1565 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 1569 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store,
1566 uint32_t index) { 1570 uint32_t index) {
1571 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1567 Object* key = dict->KeyAt(index); 1572 Object* key = dict->KeyAt(index);
1568 return Smi::cast(key)->value(); 1573 return Smi::cast(key)->value();
1569 } 1574 }
1570 }; 1575 };
1571 1576
1572 1577
1573 class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< 1578 class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
1574 NonStrictArgumentsElementsAccessor, 1579 NonStrictArgumentsElementsAccessor,
1575 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > { 1580 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > {
1576 public: 1581 public:
1577 explicit NonStrictArgumentsElementsAccessor(const char* name) 1582 explicit NonStrictArgumentsElementsAccessor(const char* name)
1578 : ElementsAccessorBase< 1583 : ElementsAccessorBase<
1579 NonStrictArgumentsElementsAccessor, 1584 NonStrictArgumentsElementsAccessor,
1580 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {} 1585 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {}
1581 protected: 1586 protected:
1582 friend class ElementsAccessorBase< 1587 friend class ElementsAccessorBase<
1583 NonStrictArgumentsElementsAccessor, 1588 NonStrictArgumentsElementsAccessor,
1584 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >; 1589 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
1585 1590
1586 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, 1591 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1587 JSObject* obj, 1592 JSObject* obj,
1588 uint32_t key, 1593 uint32_t key,
1589 FixedArray* parameter_map) { 1594 FixedArrayBase* parameters) {
1595 FixedArray* parameter_map = FixedArray::cast(parameters);
1590 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1596 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1591 if (!probe->IsTheHole()) { 1597 if (!probe->IsTheHole()) {
1592 Context* context = Context::cast(parameter_map->get(0)); 1598 Context* context = Context::cast(parameter_map->get(0));
1593 int context_index = Smi::cast(probe)->value(); 1599 int context_index = Smi::cast(probe)->value();
1594 ASSERT(!context->get(context_index)->IsTheHole()); 1600 ASSERT(!context->get(context_index)->IsTheHole());
1595 return context->get(context_index); 1601 return context->get(context_index);
1596 } else { 1602 } else {
1597 // Object is not mapped, defer to the arguments. 1603 // Object is not mapped, defer to the arguments.
1598 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1604 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1599 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( 1605 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
(...skipping 27 matching lines...) Expand all
1627 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1633 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1628 return ElementsAccessor::ForArray(arguments)->GetAttributes( 1634 return ElementsAccessor::ForArray(arguments)->GetAttributes(
1629 receiver, obj, key, arguments); 1635 receiver, obj, key, arguments);
1630 } 1636 }
1631 } 1637 }
1632 1638
1633 MUST_USE_RESULT static PropertyType GetTypeImpl( 1639 MUST_USE_RESULT static PropertyType GetTypeImpl(
1634 Object* receiver, 1640 Object* receiver,
1635 JSObject* obj, 1641 JSObject* obj,
1636 uint32_t key, 1642 uint32_t key,
1637 FixedArray* parameter_map) { 1643 FixedArrayBase* parameters) {
1644 FixedArray* parameter_map = FixedArray::cast(parameters);
1638 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1645 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1639 if (!probe->IsTheHole()) { 1646 if (!probe->IsTheHole()) {
1640 return FIELD; 1647 return FIELD;
1641 } else { 1648 } else {
1642 // If not aliased, check the arguments. 1649 // If not aliased, check the arguments.
1643 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1650 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1644 return ElementsAccessor::ForArray(arguments)->GetType( 1651 return ElementsAccessor::ForArray(arguments)->GetType(
1645 receiver, obj, key, arguments); 1652 receiver, obj, key, arguments);
1646 } 1653 }
1647 } 1654 }
1648 1655
1649 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( 1656 MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
1650 Object* receiver, 1657 Object* receiver,
1651 JSObject* obj, 1658 JSObject* obj,
1652 uint32_t key, 1659 uint32_t key,
1653 FixedArray* parameter_map) { 1660 FixedArrayBase* parameters) {
1661 FixedArray* parameter_map = FixedArray::cast(parameters);
1654 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1662 Object* probe = GetParameterMapArg(obj, parameter_map, key);
1655 if (!probe->IsTheHole()) { 1663 if (!probe->IsTheHole()) {
1656 return NULL; 1664 return NULL;
1657 } else { 1665 } else {
1658 // If not aliased, check the arguments. 1666 // If not aliased, check the arguments.
1659 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1667 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1660 return ElementsAccessor::ForArray(arguments)->GetAccessorPair( 1668 return ElementsAccessor::ForArray(arguments)->GetAccessorPair(
1661 receiver, obj, key, arguments); 1669 receiver, obj, key, arguments);
1662 } 1670 }
1663 } 1671 }
1664 1672
1665 MUST_USE_RESULT static MaybeObject* SetLengthImpl( 1673 MUST_USE_RESULT static MaybeObject* SetLengthImpl(
1666 JSObject* obj, 1674 JSObject* obj,
1667 Object* length, 1675 Object* length,
1668 FixedArray* parameter_map) { 1676 FixedArrayBase* parameter_map) {
1669 // TODO(mstarzinger): This was never implemented but will be used once we 1677 // TODO(mstarzinger): This was never implemented but will be used once we
1670 // correctly implement [[DefineOwnProperty]] on arrays. 1678 // correctly implement [[DefineOwnProperty]] on arrays.
1671 UNIMPLEMENTED(); 1679 UNIMPLEMENTED();
1672 return obj; 1680 return obj;
1673 } 1681 }
1674 1682
1675 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, 1683 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
1676 uint32_t key, 1684 uint32_t key,
1677 JSReceiver::DeleteMode mode) { 1685 JSReceiver::DeleteMode mode) {
1678 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1686 FixedArray* parameter_map = FixedArray::cast(obj->elements());
(...skipping 18 matching lines...) Expand all
1697 } 1705 }
1698 1706
1699 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1707 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1700 uint32_t from_start, 1708 uint32_t from_start,
1701 FixedArrayBase* to, 1709 FixedArrayBase* to,
1702 ElementsKind to_kind, 1710 ElementsKind to_kind,
1703 uint32_t to_start, 1711 uint32_t to_start,
1704 int packed_size, 1712 int packed_size,
1705 int copy_size) { 1713 int copy_size) {
1706 FixedArray* parameter_map = FixedArray::cast(from); 1714 FixedArray* parameter_map = FixedArray::cast(from);
1707 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1715 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1708 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 1716 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1709 return accessor->CopyElements(NULL, from_start, to, to_kind, 1717 return accessor->CopyElements(NULL, from_start, to, to_kind,
1710 to_start, copy_size, arguments); 1718 to_start, copy_size, arguments);
1711 } 1719 }
1712 1720
1713 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { 1721 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
1714 FixedArray* parameter_map = FixedArray::cast(backing_store); 1722 FixedArray* parameter_map = FixedArray::cast(backing_store);
1715 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1723 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1716 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 1724 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
1717 ForArray(arguments)->GetCapacity(arguments)); 1725 ForArray(arguments)->GetCapacity(arguments));
1718 } 1726 }
1719 1727
1720 static uint32_t GetKeyForIndexImpl(FixedArray* dict, 1728 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict,
1721 uint32_t index) { 1729 uint32_t index) {
1722 return index; 1730 return index;
1723 } 1731 }
1724 1732
1725 static bool HasElementImpl(Object* receiver, 1733 static bool HasElementImpl(Object* receiver,
1726 JSObject* holder, 1734 JSObject* holder,
1727 uint32_t key, 1735 uint32_t key,
1728 FixedArray* parameter_map) { 1736 FixedArrayBase* parameters) {
1737 FixedArray* parameter_map = FixedArray::cast(parameters);
1729 Object* probe = GetParameterMapArg(holder, parameter_map, key); 1738 Object* probe = GetParameterMapArg(holder, parameter_map, key);
1730 if (!probe->IsTheHole()) { 1739 if (!probe->IsTheHole()) {
1731 return true; 1740 return true;
1732 } else { 1741 } else {
1733 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1742 FixedArrayBase* arguments =
1743 FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1));
1734 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 1744 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1735 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); 1745 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
1736 } 1746 }
1737 } 1747 }
1738 1748
1739 private: 1749 private:
1740 static Object* GetParameterMapArg(JSObject* holder, 1750 static Object* GetParameterMapArg(JSObject* holder,
1741 FixedArray* parameter_map, 1751 FixedArray* parameter_map,
1742 uint32_t key) { 1752 uint32_t key) {
1743 uint32_t length = holder->IsJSArray() 1753 uint32_t length = holder->IsJSArray()
1744 ? Smi::cast(JSArray::cast(holder)->length())->value() 1754 ? Smi::cast(JSArray::cast(holder)->length())->value()
1745 : parameter_map->length(); 1755 : parameter_map->length();
1746 return key < (length - 2 ) 1756 return key < (length - 2)
1747 ? parameter_map->get(key + 2) 1757 ? parameter_map->get(key + 2)
1748 : parameter_map->GetHeap()->the_hole_value(); 1758 : parameter_map->GetHeap()->the_hole_value();
1749 } 1759 }
1750 }; 1760 };
1751 1761
1752 1762
1753 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1763 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1754 switch (array->map()->instance_type()) { 1764 switch (array->map()->instance_type()) {
1755 case FIXED_ARRAY_TYPE: 1765 case FIXED_ARRAY_TYPE:
1756 if (array->IsDictionary()) { 1766 if (array->IsDictionary()) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1803 #undef ACCESSOR_DELETE 1813 #undef ACCESSOR_DELETE
1804 elements_accessors_ = NULL; 1814 elements_accessors_ = NULL;
1805 } 1815 }
1806 1816
1807 1817
1808 template <typename ElementsAccessorSubclass, typename ElementsKindTraits> 1818 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1809 MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, 1819 MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
1810 ElementsKindTraits>:: 1820 ElementsKindTraits>::
1811 SetLengthImpl(JSObject* obj, 1821 SetLengthImpl(JSObject* obj,
1812 Object* length, 1822 Object* length,
1813 typename ElementsKindTraits::BackingStore* backing_store) { 1823 FixedArrayBase* backing_store) {
1814 JSArray* array = JSArray::cast(obj); 1824 JSArray* array = JSArray::cast(obj);
1815 1825
1816 // Fast case: The new length fits into a Smi. 1826 // Fast case: The new length fits into a Smi.
1817 MaybeObject* maybe_smi_length = length->ToSmi(); 1827 MaybeObject* maybe_smi_length = length->ToSmi();
1818 Object* smi_length = Smi::FromInt(0); 1828 Object* smi_length = Smi::FromInt(0);
1819 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 1829 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
1820 const int value = Smi::cast(smi_length)->value(); 1830 const int value = Smi::cast(smi_length)->value();
1821 if (value >= 0) { 1831 if (value >= 0) {
1822 Object* new_length; 1832 Object* new_length;
1823 MaybeObject* result = ElementsAccessorSubclass:: 1833 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; 1870 if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
1861 new_backing_store->set(0, length); 1871 new_backing_store->set(0, length);
1862 { MaybeObject* result = array->SetContent(new_backing_store); 1872 { MaybeObject* result = array->SetContent(new_backing_store);
1863 if (result->IsFailure()) return result; 1873 if (result->IsFailure()) return result;
1864 } 1874 }
1865 return array; 1875 return array;
1866 } 1876 }
1867 1877
1868 1878
1869 } } // namespace v8::internal 1879 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698