OLD | NEW |
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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 161 |
162 | 162 |
163 static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { | 163 static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { |
164 isolate->Throw( | 164 isolate->Throw( |
165 *isolate->factory()->NewRangeError("invalid_array_length", | 165 *isolate->factory()->NewRangeError("invalid_array_length", |
166 HandleVector<Object>(NULL, 0))); | 166 HandleVector<Object>(NULL, 0))); |
167 return Handle<Object>(); | 167 return Handle<Object>(); |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 static void CopyObjectToObjectElements(FixedArrayBase* from_base, | 171 static void CopyObjectToObjectElements(Handle<FixedArrayBase> from_base, |
172 ElementsKind from_kind, | 172 ElementsKind from_kind, |
173 uint32_t from_start, | 173 uint32_t from_start, |
174 FixedArrayBase* to_base, | 174 Handle<FixedArrayBase> to_base, |
175 ElementsKind to_kind, | 175 ElementsKind to_kind, |
176 uint32_t to_start, | 176 uint32_t to_start, |
177 int raw_copy_size) { | 177 int raw_copy_size) { |
178 ASSERT(to_base->map() != | 178 ASSERT(to_base->map() != |
179 from_base->GetIsolate()->heap()->fixed_cow_array_map()); | 179 from_base->GetIsolate()->heap()->fixed_cow_array_map()); |
180 DisallowHeapAllocation no_allocation; | 180 DisallowHeapAllocation no_allocation; |
181 int copy_size = raw_copy_size; | 181 int copy_size = raw_copy_size; |
182 if (raw_copy_size < 0) { | 182 if (raw_copy_size < 0) { |
183 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 183 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
184 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 184 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
185 copy_size = Min(from_base->length() - from_start, | 185 copy_size = Min(from_base->length() - from_start, |
186 to_base->length() - to_start); | 186 to_base->length() - to_start); |
187 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 187 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
188 int start = to_start + copy_size; | 188 int start = to_start + copy_size; |
189 int length = to_base->length() - start; | 189 int length = to_base->length() - start; |
190 if (length > 0) { | 190 if (length > 0) { |
191 Heap* heap = from_base->GetHeap(); | 191 Heap* heap = from_base->GetHeap(); |
192 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 192 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
193 heap->the_hole_value(), length); | 193 heap->the_hole_value(), length); |
194 } | 194 } |
195 } | 195 } |
196 } | 196 } |
197 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 197 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
198 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 198 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
199 if (copy_size == 0) return; | 199 if (copy_size == 0) return; |
200 FixedArray* from = FixedArray::cast(from_base); | 200 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
201 FixedArray* to = FixedArray::cast(to_base); | 201 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
202 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); | 202 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
203 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 203 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
204 Address to_address = to->address() + FixedArray::kHeaderSize; | 204 Address to_address = to->address() + FixedArray::kHeaderSize; |
205 Address from_address = from->address() + FixedArray::kHeaderSize; | 205 Address from_address = from->address() + FixedArray::kHeaderSize; |
206 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, | 206 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, |
207 reinterpret_cast<Object**>(from_address) + from_start, | 207 reinterpret_cast<Object**>(from_address) + from_start, |
208 static_cast<size_t>(copy_size)); | 208 static_cast<size_t>(copy_size)); |
209 if (IsFastObjectElementsKind(from_kind) && | 209 if (IsFastObjectElementsKind(from_kind) && |
210 IsFastObjectElementsKind(to_kind)) { | 210 IsFastObjectElementsKind(to_kind)) { |
211 Heap* heap = from->GetHeap(); | 211 Heap* heap = from->GetHeap(); |
212 if (!heap->InNewSpace(to)) { | 212 if (!heap->InNewSpace(*to)) { |
213 heap->RecordWrites(to->address(), | 213 heap->RecordWrites(to->address(), |
214 to->OffsetOfElementAt(to_start), | 214 to->OffsetOfElementAt(to_start), |
215 copy_size); | 215 copy_size); |
216 } | 216 } |
217 heap->incremental_marking()->RecordWrites(to); | 217 heap->incremental_marking()->RecordWrites(*to); |
218 } | 218 } |
219 } | 219 } |
220 | 220 |
221 | 221 |
222 static void CopyDictionaryToObjectElements(FixedArrayBase* from_base, | 222 static void CopyDictionaryToObjectElements(Handle<FixedArrayBase> from_base, |
223 uint32_t from_start, | 223 uint32_t from_start, |
224 FixedArrayBase* to_base, | 224 Handle<FixedArrayBase> to_base, |
225 ElementsKind to_kind, | 225 ElementsKind to_kind, |
226 uint32_t to_start, | 226 uint32_t to_start, |
227 int raw_copy_size) { | 227 int raw_copy_size) { |
228 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); | 228 Handle<SeededNumberDictionary> from = |
| 229 Handle<SeededNumberDictionary>::cast(from_base); |
229 DisallowHeapAllocation no_allocation; | 230 DisallowHeapAllocation no_allocation; |
230 int copy_size = raw_copy_size; | 231 int copy_size = raw_copy_size; |
231 Heap* heap = from->GetHeap(); | 232 Heap* heap = from->GetHeap(); |
232 if (raw_copy_size < 0) { | 233 if (raw_copy_size < 0) { |
233 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 234 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
234 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 235 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
235 copy_size = from->max_number_key() + 1 - from_start; | 236 copy_size = from->max_number_key() + 1 - from_start; |
236 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 237 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
237 int start = to_start + copy_size; | 238 int start = to_start + copy_size; |
238 int length = to_base->length() - start; | 239 int length = to_base->length() - start; |
239 if (length > 0) { | 240 if (length > 0) { |
240 Heap* heap = from->GetHeap(); | 241 Heap* heap = from->GetHeap(); |
241 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 242 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
242 heap->the_hole_value(), length); | 243 heap->the_hole_value(), length); |
243 } | 244 } |
244 } | 245 } |
245 } | 246 } |
246 ASSERT(to_base != from_base); | 247 ASSERT(*to_base != *from_base); |
247 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 248 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
248 if (copy_size == 0) return; | 249 if (copy_size == 0) return; |
249 FixedArray* to = FixedArray::cast(to_base); | 250 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
250 uint32_t to_length = to->length(); | 251 uint32_t to_length = to->length(); |
251 if (to_start + copy_size > to_length) { | 252 if (to_start + copy_size > to_length) { |
252 copy_size = to_length - to_start; | 253 copy_size = to_length - to_start; |
253 } | 254 } |
254 for (int i = 0; i < copy_size; i++) { | 255 for (int i = 0; i < copy_size; i++) { |
255 int entry = from->FindEntry(i + from_start); | 256 int entry = from->FindEntry(i + from_start); |
256 if (entry != SeededNumberDictionary::kNotFound) { | 257 if (entry != SeededNumberDictionary::kNotFound) { |
257 Object* value = from->ValueAt(entry); | 258 Object* value = from->ValueAt(entry); |
258 ASSERT(!value->IsTheHole()); | 259 ASSERT(!value->IsTheHole()); |
259 to->set(i + to_start, value, SKIP_WRITE_BARRIER); | 260 to->set(i + to_start, value, SKIP_WRITE_BARRIER); |
260 } else { | 261 } else { |
261 to->set_the_hole(i + to_start); | 262 to->set_the_hole(i + to_start); |
262 } | 263 } |
263 } | 264 } |
264 if (IsFastObjectElementsKind(to_kind)) { | 265 if (IsFastObjectElementsKind(to_kind)) { |
265 if (!heap->InNewSpace(to)) { | 266 if (!heap->InNewSpace(*to)) { |
266 heap->RecordWrites(to->address(), | 267 heap->RecordWrites(to->address(), |
267 to->OffsetOfElementAt(to_start), | 268 to->OffsetOfElementAt(to_start), |
268 copy_size); | 269 copy_size); |
269 } | 270 } |
270 heap->incremental_marking()->RecordWrites(to); | 271 heap->incremental_marking()->RecordWrites(*to); |
271 } | 272 } |
272 } | 273 } |
273 | 274 |
274 | 275 |
275 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( | 276 static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base, |
276 FixedArrayBase* from_base, | 277 uint32_t from_start, |
277 uint32_t from_start, | 278 Handle<FixedArrayBase> to_base, |
278 FixedArrayBase* to_base, | 279 ElementsKind to_kind, |
279 ElementsKind to_kind, | 280 uint32_t to_start, |
280 uint32_t to_start, | 281 int raw_copy_size) { |
281 int raw_copy_size) { | |
282 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 282 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
283 int copy_size = raw_copy_size; | 283 int copy_size = raw_copy_size; |
284 if (raw_copy_size < 0) { | 284 if (raw_copy_size < 0) { |
285 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 285 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
286 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 286 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
287 copy_size = Min(from_base->length() - from_start, | 287 copy_size = Min(from_base->length() - from_start, |
288 to_base->length() - to_start); | 288 to_base->length() - to_start); |
289 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 289 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
290 // Also initialize the area that will be copied over since HeapNumber | 290 // Also initialize the area that will be copied over since HeapNumber |
291 // allocation below can cause an incremental marking step, requiring all | 291 // allocation below can cause an incremental marking step, requiring all |
292 // existing heap objects to be propertly initialized. | 292 // existing heap objects to be propertly initialized. |
293 int start = to_start; | 293 int start = to_start; |
294 int length = to_base->length() - start; | 294 int length = to_base->length() - start; |
295 if (length > 0) { | 295 if (length > 0) { |
296 Heap* heap = from_base->GetHeap(); | 296 Heap* heap = from_base->GetHeap(); |
297 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 297 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
298 heap->the_hole_value(), length); | 298 heap->the_hole_value(), length); |
299 } | 299 } |
300 } | 300 } |
301 } | 301 } |
302 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 302 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
303 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 303 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
304 if (copy_size == 0) return from_base; | 304 if (copy_size == 0) return; |
305 FixedDoubleArray* from = FixedDoubleArray::cast(from_base); | 305 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
306 FixedArray* to = FixedArray::cast(to_base); | 306 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
307 for (int i = 0; i < copy_size; ++i) { | 307 for (int i = 0; i < copy_size; ++i) { |
| 308 HandleScope scope(from_base->GetIsolate()); |
308 if (IsFastSmiElementsKind(to_kind)) { | 309 if (IsFastSmiElementsKind(to_kind)) { |
309 UNIMPLEMENTED(); | 310 UNIMPLEMENTED(); |
310 return Failure::Exception(); | |
311 } else { | 311 } else { |
312 MaybeObject* maybe_value = from->get(i + from_start); | |
313 Object* value; | |
314 ASSERT(IsFastObjectElementsKind(to_kind)); | 312 ASSERT(IsFastObjectElementsKind(to_kind)); |
315 // Because Double -> Object elements transitions allocate HeapObjects | 313 Handle<Object> value = from->get_as_handle(i + from_start); |
316 // iteratively, the allocate must succeed within a single GC cycle, | 314 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); |
317 // otherwise the retry after the GC will also fail. In order to ensure | |
318 // that no GC is triggered, allocate HeapNumbers from old space if they | |
319 // can't be taken from new space. | |
320 if (!maybe_value->ToObject(&value)) { | |
321 ASSERT(maybe_value->IsRetryAfterGC()); | |
322 Heap* heap = from->GetHeap(); | |
323 MaybeObject* maybe_value_object = | |
324 heap->AllocateHeapNumber(from->get_scalar(i + from_start), | |
325 TENURED); | |
326 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; | |
327 } | |
328 to->set(i + to_start, value, UPDATE_WRITE_BARRIER); | |
329 } | 315 } |
330 } | 316 } |
331 return to; | |
332 } | 317 } |
333 | 318 |
334 | 319 |
335 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, | 320 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base, |
336 uint32_t from_start, | 321 uint32_t from_start, |
337 FixedArrayBase* to_base, | 322 Handle<FixedArrayBase> to_base, |
338 uint32_t to_start, | 323 uint32_t to_start, |
339 int raw_copy_size) { | 324 int raw_copy_size) { |
| 325 DisallowHeapAllocation no_allocation; |
340 int copy_size = raw_copy_size; | 326 int copy_size = raw_copy_size; |
341 if (raw_copy_size < 0) { | 327 if (raw_copy_size < 0) { |
342 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 328 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
343 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 329 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
344 copy_size = Min(from_base->length() - from_start, | 330 copy_size = Min(from_base->length() - from_start, |
345 to_base->length() - to_start); | 331 to_base->length() - to_start); |
346 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 332 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
347 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 333 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
348 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 334 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
349 } | 335 } |
350 } | 336 } |
351 } | 337 } |
352 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 338 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
353 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 339 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
354 if (copy_size == 0) return; | 340 if (copy_size == 0) return; |
355 FixedDoubleArray* from = FixedDoubleArray::cast(from_base); | 341 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
356 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 342 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
357 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; | 343 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
358 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; | 344 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
359 to_address += kDoubleSize * to_start; | 345 to_address += kDoubleSize * to_start; |
360 from_address += kDoubleSize * from_start; | 346 from_address += kDoubleSize * from_start; |
361 int words_per_double = (kDoubleSize / kPointerSize); | 347 int words_per_double = (kDoubleSize / kPointerSize); |
362 CopyWords(reinterpret_cast<Object**>(to_address), | 348 CopyWords(reinterpret_cast<Object**>(to_address), |
363 reinterpret_cast<Object**>(from_address), | 349 reinterpret_cast<Object**>(from_address), |
364 static_cast<size_t>(words_per_double * copy_size)); | 350 static_cast<size_t>(words_per_double * copy_size)); |
365 } | 351 } |
366 | 352 |
367 | 353 |
368 static void CopySmiToDoubleElements(FixedArrayBase* from_base, | 354 static void CopySmiToDoubleElements(Handle<FixedArrayBase> from_base, |
369 uint32_t from_start, | 355 uint32_t from_start, |
370 FixedArrayBase* to_base, | 356 Handle<FixedArrayBase> to_base, |
371 uint32_t to_start, | 357 uint32_t to_start, |
372 int raw_copy_size) { | 358 int raw_copy_size) { |
| 359 DisallowHeapAllocation no_allocation; |
373 int copy_size = raw_copy_size; | 360 int copy_size = raw_copy_size; |
374 if (raw_copy_size < 0) { | 361 if (raw_copy_size < 0) { |
375 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 362 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
376 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 363 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
377 copy_size = from_base->length() - from_start; | 364 copy_size = from_base->length() - from_start; |
378 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 365 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
379 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 366 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
380 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 367 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
381 } | 368 } |
382 } | 369 } |
383 } | 370 } |
384 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 371 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
385 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 372 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
386 if (copy_size == 0) return; | 373 if (copy_size == 0) return; |
387 FixedArray* from = FixedArray::cast(from_base); | 374 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
388 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 375 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
389 Object* the_hole = from->GetHeap()->the_hole_value(); | 376 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); |
390 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); | 377 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
391 from_start < from_end; from_start++, to_start++) { | 378 from_start < from_end; from_start++, to_start++) { |
392 Object* hole_or_smi = from->get(from_start); | 379 Object* hole_or_smi = from->get(from_start); |
393 if (hole_or_smi == the_hole) { | 380 if (hole_or_smi == *the_hole) { |
394 to->set_the_hole(to_start); | 381 to->set_the_hole(to_start); |
395 } else { | 382 } else { |
396 to->set(to_start, Smi::cast(hole_or_smi)->value()); | 383 to->set(to_start, Smi::cast(hole_or_smi)->value()); |
397 } | 384 } |
398 } | 385 } |
399 } | 386 } |
400 | 387 |
401 | 388 |
402 static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, | 389 static void CopyPackedSmiToDoubleElements(Handle<FixedArrayBase> from_base, |
403 uint32_t from_start, | 390 uint32_t from_start, |
404 FixedArrayBase* to_base, | 391 Handle<FixedArrayBase> to_base, |
405 uint32_t to_start, | 392 uint32_t to_start, |
406 int packed_size, | 393 int packed_size, |
407 int raw_copy_size) { | 394 int raw_copy_size) { |
| 395 DisallowHeapAllocation no_allocation; |
408 int copy_size = raw_copy_size; | 396 int copy_size = raw_copy_size; |
409 uint32_t to_end; | 397 uint32_t to_end; |
410 if (raw_copy_size < 0) { | 398 if (raw_copy_size < 0) { |
411 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 399 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
412 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 400 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
413 copy_size = packed_size - from_start; | 401 copy_size = packed_size - from_start; |
414 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 402 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
415 to_end = to_base->length(); | 403 to_end = to_base->length(); |
416 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { | 404 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { |
417 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 405 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
418 } | 406 } |
419 } else { | 407 } else { |
420 to_end = to_start + static_cast<uint32_t>(copy_size); | 408 to_end = to_start + static_cast<uint32_t>(copy_size); |
421 } | 409 } |
422 } else { | 410 } else { |
423 to_end = to_start + static_cast<uint32_t>(copy_size); | 411 to_end = to_start + static_cast<uint32_t>(copy_size); |
424 } | 412 } |
425 ASSERT(static_cast<int>(to_end) <= to_base->length()); | 413 ASSERT(static_cast<int>(to_end) <= to_base->length()); |
426 ASSERT(packed_size >= 0 && packed_size <= copy_size); | 414 ASSERT(packed_size >= 0 && packed_size <= copy_size); |
427 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 415 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
428 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 416 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
429 if (copy_size == 0) return; | 417 if (copy_size == 0) return; |
430 FixedArray* from = FixedArray::cast(from_base); | 418 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
431 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 419 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
432 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); | 420 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
433 from_start < from_end; from_start++, to_start++) { | 421 from_start < from_end; from_start++, to_start++) { |
434 Object* smi = from->get(from_start); | 422 Object* smi = from->get(from_start); |
435 ASSERT(!smi->IsTheHole()); | 423 ASSERT(!smi->IsTheHole()); |
436 to->set(to_start, Smi::cast(smi)->value()); | 424 to->set(to_start, Smi::cast(smi)->value()); |
437 } | 425 } |
438 } | 426 } |
439 | 427 |
440 | 428 |
441 static void CopyObjectToDoubleElements(FixedArrayBase* from_base, | 429 static void CopyObjectToDoubleElements(Handle<FixedArrayBase> from_base, |
442 uint32_t from_start, | 430 uint32_t from_start, |
443 FixedArrayBase* to_base, | 431 Handle<FixedArrayBase> to_base, |
444 uint32_t to_start, | 432 uint32_t to_start, |
445 int raw_copy_size) { | 433 int raw_copy_size) { |
| 434 DisallowHeapAllocation no_allocation; |
446 int copy_size = raw_copy_size; | 435 int copy_size = raw_copy_size; |
447 if (raw_copy_size < 0) { | 436 if (raw_copy_size < 0) { |
448 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 437 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
449 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 438 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
450 copy_size = from_base->length() - from_start; | 439 copy_size = from_base->length() - from_start; |
451 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 440 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
452 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 441 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
453 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 442 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
454 } | 443 } |
455 } | 444 } |
456 } | 445 } |
457 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 446 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
458 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 447 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
459 if (copy_size == 0) return; | 448 if (copy_size == 0) return; |
460 FixedArray* from = FixedArray::cast(from_base); | 449 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
461 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 450 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
462 Object* the_hole = from->GetHeap()->the_hole_value(); | 451 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); |
463 for (uint32_t from_end = from_start + copy_size; | 452 for (uint32_t from_end = from_start + copy_size; |
464 from_start < from_end; from_start++, to_start++) { | 453 from_start < from_end; from_start++, to_start++) { |
465 Object* hole_or_object = from->get(from_start); | 454 Object* hole_or_object = from->get(from_start); |
466 if (hole_or_object == the_hole) { | 455 if (hole_or_object == *the_hole) { |
467 to->set_the_hole(to_start); | 456 to->set_the_hole(to_start); |
468 } else { | 457 } else { |
469 to->set(to_start, hole_or_object->Number()); | 458 to->set(to_start, hole_or_object->Number()); |
470 } | 459 } |
471 } | 460 } |
472 } | 461 } |
473 | 462 |
474 | 463 |
475 static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, | 464 static void CopyDictionaryToDoubleElements(Handle<FixedArrayBase> from_base, |
476 uint32_t from_start, | 465 uint32_t from_start, |
477 FixedArrayBase* to_base, | 466 Handle<FixedArrayBase> to_base, |
478 uint32_t to_start, | 467 uint32_t to_start, |
479 int raw_copy_size) { | 468 int raw_copy_size) { |
480 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); | 469 Handle<SeededNumberDictionary> from = |
| 470 Handle<SeededNumberDictionary>::cast(from_base); |
| 471 DisallowHeapAllocation no_allocation; |
481 int copy_size = raw_copy_size; | 472 int copy_size = raw_copy_size; |
482 if (copy_size < 0) { | 473 if (copy_size < 0) { |
483 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || | 474 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
484 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 475 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
485 copy_size = from->max_number_key() + 1 - from_start; | 476 copy_size = from->max_number_key() + 1 - from_start; |
486 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 477 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
487 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 478 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
488 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 479 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
489 } | 480 } |
490 } | 481 } |
491 } | 482 } |
492 if (copy_size == 0) return; | 483 if (copy_size == 0) return; |
493 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 484 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
494 uint32_t to_length = to->length(); | 485 uint32_t to_length = to->length(); |
495 if (to_start + copy_size > to_length) { | 486 if (to_start + copy_size > to_length) { |
496 copy_size = to_length - to_start; | 487 copy_size = to_length - to_start; |
497 } | 488 } |
498 for (int i = 0; i < copy_size; i++) { | 489 for (int i = 0; i < copy_size; i++) { |
499 int entry = from->FindEntry(i + from_start); | 490 int entry = from->FindEntry(i + from_start); |
500 if (entry != SeededNumberDictionary::kNotFound) { | 491 if (entry != SeededNumberDictionary::kNotFound) { |
501 to->set(i + to_start, from->ValueAt(entry)->Number()); | 492 to->set(i + to_start, from->ValueAt(entry)->Number()); |
502 } else { | 493 } else { |
503 to->set_the_hole(i + to_start); | 494 to->set_the_hole(i + to_start); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 Object* receiver, | 740 Object* receiver, |
750 JSObject* obj, | 741 JSObject* obj, |
751 uint32_t key, | 742 uint32_t key, |
752 FixedArrayBase* backing_store) { | 743 FixedArrayBase* backing_store) { |
753 return NULL; | 744 return NULL; |
754 } | 745 } |
755 | 746 |
756 MUST_USE_RESULT virtual Handle<Object> SetLength( | 747 MUST_USE_RESULT virtual Handle<Object> SetLength( |
757 Handle<JSArray> array, | 748 Handle<JSArray> array, |
758 Handle<Object> length) V8_FINAL V8_OVERRIDE { | 749 Handle<Object> length) V8_FINAL V8_OVERRIDE { |
759 Isolate* isolate = array->GetIsolate(); | |
760 return ElementsAccessorSubclass::SetLengthImpl( | 750 return ElementsAccessorSubclass::SetLengthImpl( |
761 array, length, handle(array->elements(), isolate)); | 751 array, length, handle(array->elements())); |
762 } | 752 } |
763 | 753 |
764 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 754 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
765 Handle<JSObject> obj, | 755 Handle<JSObject> obj, |
766 Handle<Object> length, | 756 Handle<Object> length, |
767 Handle<FixedArrayBase> backing_store); | 757 Handle<FixedArrayBase> backing_store); |
768 | 758 |
769 virtual void SetCapacityAndLength( | 759 virtual void SetCapacityAndLength( |
770 Handle<JSArray> array, | 760 Handle<JSArray> array, |
771 int capacity, | 761 int capacity, |
772 int length) V8_FINAL V8_OVERRIDE { | 762 int length) V8_FINAL V8_OVERRIDE { |
773 ElementsAccessorSubclass:: | 763 ElementsAccessorSubclass:: |
774 SetFastElementsCapacityAndLength(array, capacity, length); | 764 SetFastElementsCapacityAndLength(array, capacity, length); |
775 } | 765 } |
776 | 766 |
777 static void SetFastElementsCapacityAndLength( | 767 static void SetFastElementsCapacityAndLength( |
778 Handle<JSObject> obj, | 768 Handle<JSObject> obj, |
779 int capacity, | 769 int capacity, |
780 int length) { | 770 int length) { |
781 UNIMPLEMENTED(); | 771 UNIMPLEMENTED(); |
782 } | 772 } |
783 | 773 |
784 MUST_USE_RESULT virtual Handle<Object> Delete( | 774 MUST_USE_RESULT virtual Handle<Object> Delete( |
785 Handle<JSObject> obj, | 775 Handle<JSObject> obj, |
786 uint32_t key, | 776 uint32_t key, |
787 JSReceiver::DeleteMode mode) V8_OVERRIDE = 0; | 777 JSReceiver::DeleteMode mode) V8_OVERRIDE = 0; |
788 | 778 |
789 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 779 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
790 uint32_t from_start, | 780 uint32_t from_start, |
791 FixedArrayBase* to, | 781 Handle<FixedArrayBase> to, |
792 ElementsKind from_kind, | 782 ElementsKind from_kind, |
793 uint32_t to_start, | 783 uint32_t to_start, |
794 int packed_size, | 784 int packed_size, |
795 int copy_size) { | 785 int copy_size) { |
796 UNREACHABLE(); | 786 UNREACHABLE(); |
797 return NULL; | |
798 } | |
799 | |
800 // TODO(ishell): Temporary wrapper, remove when CopyElements handlified. | |
801 Handle<Object> CopyElementsHelper( | |
802 Handle<JSObject> from_holder, | |
803 uint32_t from_start, | |
804 ElementsKind from_kind, | |
805 Handle<FixedArrayBase> to, | |
806 uint32_t to_start, | |
807 int copy_size, | |
808 Handle<FixedArrayBase> from) { | |
809 CALL_HEAP_FUNCTION(to->GetIsolate(), | |
810 CopyElements( | |
811 from_holder.is_null() ? NULL : *from_holder, | |
812 from_start, from_kind, *to, to_start, copy_size, | |
813 from.is_null() ? NULL : *from), | |
814 Object); | |
815 } | 787 } |
816 | 788 |
817 virtual void CopyElements( | 789 virtual void CopyElements( |
818 Handle<JSObject> from_holder, | 790 Handle<JSObject> from_holder, |
819 uint32_t from_start, | 791 uint32_t from_start, |
820 ElementsKind from_kind, | 792 ElementsKind from_kind, |
821 Handle<FixedArrayBase> to, | 793 Handle<FixedArrayBase> to, |
822 uint32_t to_start, | 794 uint32_t to_start, |
823 int copy_size, | 795 int copy_size, |
824 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { | 796 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { |
825 Handle<Object> result = CopyElementsHelper( | |
826 from_holder, from_start, from_kind, to, to_start, copy_size, from); | |
827 ASSERT(!result.is_null()); | |
828 USE(result); | |
829 } | |
830 | |
831 MUST_USE_RESULT virtual MaybeObject* CopyElements( | |
832 JSObject* from_holder, | |
833 uint32_t from_start, | |
834 ElementsKind from_kind, | |
835 FixedArrayBase* to, | |
836 uint32_t to_start, | |
837 int copy_size, | |
838 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { | |
839 int packed_size = kPackedSizeNotKnown; | 797 int packed_size = kPackedSizeNotKnown; |
840 if (from == NULL) { | 798 if (from.is_null()) { |
841 from = from_holder->elements(); | 799 from = handle(from_holder->elements()); |
842 } | 800 } |
843 | 801 |
844 if (from_holder) { | 802 if (!from_holder.is_null()) { |
845 bool is_packed = IsFastPackedElementsKind(from_kind) && | 803 bool is_packed = IsFastPackedElementsKind(from_kind) && |
846 from_holder->IsJSArray(); | 804 from_holder->IsJSArray(); |
847 if (is_packed) { | 805 if (is_packed) { |
848 packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value(); | 806 packed_size = |
| 807 Smi::cast(Handle<JSArray>::cast(from_holder)->length())->value(); |
849 if (copy_size >= 0 && packed_size > copy_size) { | 808 if (copy_size >= 0 && packed_size > copy_size) { |
850 packed_size = copy_size; | 809 packed_size = copy_size; |
851 } | 810 } |
852 } | 811 } |
853 } | 812 } |
854 return ElementsAccessorSubclass::CopyElementsImpl( | 813 ElementsAccessorSubclass::CopyElementsImpl( |
855 from, from_start, to, from_kind, to_start, packed_size, copy_size); | 814 from, from_start, to, from_kind, to_start, packed_size, copy_size); |
856 } | 815 } |
857 | 816 |
858 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( | 817 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( |
859 Object* receiver, | 818 Object* receiver, |
860 JSObject* holder, | 819 JSObject* holder, |
861 FixedArray* to, | 820 FixedArray* to, |
862 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { | 821 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { |
863 int len0 = to->length(); | 822 int len0 = to->length(); |
864 #ifdef ENABLE_SLOW_ASSERTS | 823 #ifdef ENABLE_SLOW_ASSERTS |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 } | 993 } |
1035 | 994 |
1036 static Handle<Object> DeleteCommon(Handle<JSObject> obj, | 995 static Handle<Object> DeleteCommon(Handle<JSObject> obj, |
1037 uint32_t key, | 996 uint32_t key, |
1038 JSReceiver::DeleteMode mode) { | 997 JSReceiver::DeleteMode mode) { |
1039 ASSERT(obj->HasFastSmiOrObjectElements() || | 998 ASSERT(obj->HasFastSmiOrObjectElements() || |
1040 obj->HasFastDoubleElements() || | 999 obj->HasFastDoubleElements() || |
1041 obj->HasFastArgumentsElements()); | 1000 obj->HasFastArgumentsElements()); |
1042 Isolate* isolate = obj->GetIsolate(); | 1001 Isolate* isolate = obj->GetIsolate(); |
1043 Heap* heap = obj->GetHeap(); | 1002 Heap* heap = obj->GetHeap(); |
1044 Handle<Object> elements = handle(obj->elements(), isolate); | 1003 Handle<FixedArrayBase> elements(obj->elements()); |
1045 if (*elements == heap->empty_fixed_array()) { | 1004 if (*elements == heap->empty_fixed_array()) { |
1046 return isolate->factory()->true_value(); | 1005 return isolate->factory()->true_value(); |
1047 } | 1006 } |
1048 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1007 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
1049 bool is_sloppy_arguments_elements_map = | 1008 bool is_sloppy_arguments_elements_map = |
1050 backing_store->map() == heap->sloppy_arguments_elements_map(); | 1009 backing_store->map() == heap->sloppy_arguments_elements_map(); |
1051 if (is_sloppy_arguments_elements_map) { | 1010 if (is_sloppy_arguments_elements_map) { |
1052 backing_store = Handle<BackingStore>::cast( | 1011 backing_store = handle( |
1053 handle(Handle<FixedArray>::cast(backing_store)->get(1), isolate)); | 1012 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1))); |
1054 } | 1013 } |
1055 uint32_t length = static_cast<uint32_t>( | 1014 uint32_t length = static_cast<uint32_t>( |
1056 obj->IsJSArray() | 1015 obj->IsJSArray() |
1057 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() | 1016 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() |
1058 : backing_store->length()); | 1017 : backing_store->length()); |
1059 if (key < length) { | 1018 if (key < length) { |
1060 if (!is_sloppy_arguments_elements_map) { | 1019 if (!is_sloppy_arguments_elements_map) { |
1061 ElementsKind kind = KindTraits::Kind; | 1020 ElementsKind kind = KindTraits::Kind; |
1062 if (IsFastPackedElementsKind(kind)) { | 1021 if (IsFastPackedElementsKind(kind)) { |
1063 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | 1022 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 FixedArrayBase* elements = holder->elements(); | 1073 FixedArrayBase* elements = holder->elements(); |
1115 Heap* heap = elements->GetHeap(); | 1074 Heap* heap = elements->GetHeap(); |
1116 Map* map = elements->map(); | 1075 Map* map = elements->map(); |
1117 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 1076 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && |
1118 (map == heap->fixed_array_map() || | 1077 (map == heap->fixed_array_map() || |
1119 map == heap->fixed_cow_array_map())) || | 1078 map == heap->fixed_cow_array_map())) || |
1120 (IsFastDoubleElementsKind(KindTraits::Kind) == | 1079 (IsFastDoubleElementsKind(KindTraits::Kind) == |
1121 ((map == heap->fixed_array_map() && length == 0) || | 1080 ((map == heap->fixed_array_map() && length == 0) || |
1122 map == heap->fixed_double_array_map()))); | 1081 map == heap->fixed_double_array_map()))); |
1123 for (int i = 0; i < length; i++) { | 1082 for (int i = 0; i < length; i++) { |
1124 typename KindTraits::BackingStore* backing_store = | 1083 BackingStore* backing_store = BackingStore::cast(elements); |
1125 KindTraits::BackingStore::cast(elements); | |
1126 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || | 1084 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || |
1127 static_cast<Object*>(backing_store->get(i))->IsSmi()) || | 1085 static_cast<Object*>(backing_store->get(i))->IsSmi()) || |
1128 (IsFastHoleyElementsKind(KindTraits::Kind) == | 1086 (IsFastHoleyElementsKind(KindTraits::Kind) == |
1129 backing_store->is_the_hole(i))); | 1087 backing_store->is_the_hole(i))); |
1130 } | 1088 } |
1131 #endif | 1089 #endif |
1132 } | 1090 } |
1133 }; | 1091 }; |
1134 | 1092 |
1135 | 1093 |
(...skipping 29 matching lines...) Expand all Loading... |
1165 class FastSmiOrObjectElementsAccessor | 1123 class FastSmiOrObjectElementsAccessor |
1166 : public FastElementsAccessor<FastElementsAccessorSubclass, | 1124 : public FastElementsAccessor<FastElementsAccessorSubclass, |
1167 KindTraits, | 1125 KindTraits, |
1168 kPointerSize> { | 1126 kPointerSize> { |
1169 public: | 1127 public: |
1170 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1128 explicit FastSmiOrObjectElementsAccessor(const char* name) |
1171 : FastElementsAccessor<FastElementsAccessorSubclass, | 1129 : FastElementsAccessor<FastElementsAccessorSubclass, |
1172 KindTraits, | 1130 KindTraits, |
1173 kPointerSize>(name) {} | 1131 kPointerSize>(name) {} |
1174 | 1132 |
1175 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1133 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1176 uint32_t from_start, | 1134 uint32_t from_start, |
1177 FixedArrayBase* to, | 1135 Handle<FixedArrayBase> to, |
1178 ElementsKind from_kind, | 1136 ElementsKind from_kind, |
1179 uint32_t to_start, | 1137 uint32_t to_start, |
1180 int packed_size, | 1138 int packed_size, |
1181 int copy_size) { | 1139 int copy_size) { |
1182 ElementsKind to_kind = KindTraits::Kind; | 1140 ElementsKind to_kind = KindTraits::Kind; |
1183 switch (from_kind) { | 1141 switch (from_kind) { |
1184 case FAST_SMI_ELEMENTS: | 1142 case FAST_SMI_ELEMENTS: |
1185 case FAST_HOLEY_SMI_ELEMENTS: | 1143 case FAST_HOLEY_SMI_ELEMENTS: |
1186 case FAST_ELEMENTS: | 1144 case FAST_ELEMENTS: |
1187 case FAST_HOLEY_ELEMENTS: | 1145 case FAST_HOLEY_ELEMENTS: |
1188 CopyObjectToObjectElements( | 1146 CopyObjectToObjectElements( |
1189 from, from_kind, from_start, to, to_kind, to_start, copy_size); | 1147 from, from_kind, from_start, to, to_kind, to_start, copy_size); |
1190 return to->GetHeap()->undefined_value(); | 1148 break; |
1191 case FAST_DOUBLE_ELEMENTS: | 1149 case FAST_DOUBLE_ELEMENTS: |
1192 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1150 case FAST_HOLEY_DOUBLE_ELEMENTS: |
1193 return CopyDoubleToObjectElements( | 1151 CopyDoubleToObjectElements( |
1194 from, from_start, to, to_kind, to_start, copy_size); | 1152 from, from_start, to, to_kind, to_start, copy_size); |
| 1153 break; |
1195 case DICTIONARY_ELEMENTS: | 1154 case DICTIONARY_ELEMENTS: |
1196 CopyDictionaryToObjectElements( | 1155 CopyDictionaryToObjectElements( |
1197 from, from_start, to, to_kind, to_start, copy_size); | 1156 from, from_start, to, to_kind, to_start, copy_size); |
1198 return to->GetHeap()->undefined_value(); | 1157 break; |
1199 case SLOPPY_ARGUMENTS_ELEMENTS: { | 1158 case SLOPPY_ARGUMENTS_ELEMENTS: { |
1200 // TODO(verwaest): This is a temporary hack to support extending | 1159 // TODO(verwaest): This is a temporary hack to support extending |
1201 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. | 1160 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
1202 // This case should be UNREACHABLE(). | 1161 // This case should be UNREACHABLE(). |
1203 FixedArray* parameter_map = FixedArray::cast(from); | 1162 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); |
1204 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1163 Handle<FixedArrayBase> arguments( |
1205 ElementsKind from_kind = ElementsKindForArray(arguments); | 1164 FixedArrayBase::cast(parameter_map->get(1))); |
1206 return CopyElementsImpl(arguments, from_start, to, from_kind, | 1165 ElementsKind from_kind = ElementsKindForArray(*arguments); |
1207 to_start, packed_size, copy_size); | 1166 CopyElementsImpl(arguments, from_start, to, from_kind, |
| 1167 to_start, packed_size, copy_size); |
| 1168 break; |
1208 } | 1169 } |
1209 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1170 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1210 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1171 case EXTERNAL_##TYPE##_ELEMENTS: \ |
1211 case TYPE##_ELEMENTS: \ | 1172 case TYPE##_ELEMENTS: \ |
1212 UNREACHABLE(); | 1173 UNREACHABLE(); |
1213 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1174 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1214 #undef TYPED_ARRAY_CASE | 1175 #undef TYPED_ARRAY_CASE |
1215 } | 1176 } |
1216 return NULL; | |
1217 } | 1177 } |
1218 | 1178 |
1219 | 1179 |
1220 static void SetFastElementsCapacityAndLength( | 1180 static void SetFastElementsCapacityAndLength( |
1221 Handle<JSObject> obj, | 1181 Handle<JSObject> obj, |
1222 uint32_t capacity, | 1182 uint32_t capacity, |
1223 uint32_t length) { | 1183 uint32_t length) { |
1224 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = | 1184 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = |
1225 obj->HasFastSmiElements() | 1185 obj->HasFastSmiElements() |
1226 ? JSObject::kAllowSmiElements | 1186 ? JSObject::kAllowSmiElements |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 KindTraits, | 1251 KindTraits, |
1292 kDoubleSize>(name) {} | 1252 kDoubleSize>(name) {} |
1293 | 1253 |
1294 static void SetFastElementsCapacityAndLength(Handle<JSObject> obj, | 1254 static void SetFastElementsCapacityAndLength(Handle<JSObject> obj, |
1295 uint32_t capacity, | 1255 uint32_t capacity, |
1296 uint32_t length) { | 1256 uint32_t length) { |
1297 JSObject::SetFastDoubleElementsCapacityAndLength(obj, capacity, length); | 1257 JSObject::SetFastDoubleElementsCapacityAndLength(obj, capacity, length); |
1298 } | 1258 } |
1299 | 1259 |
1300 protected: | 1260 protected: |
1301 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1261 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1302 uint32_t from_start, | 1262 uint32_t from_start, |
1303 FixedArrayBase* to, | 1263 Handle<FixedArrayBase> to, |
1304 ElementsKind from_kind, | 1264 ElementsKind from_kind, |
1305 uint32_t to_start, | 1265 uint32_t to_start, |
1306 int packed_size, | 1266 int packed_size, |
1307 int copy_size) { | 1267 int copy_size) { |
1308 switch (from_kind) { | 1268 switch (from_kind) { |
1309 case FAST_SMI_ELEMENTS: | 1269 case FAST_SMI_ELEMENTS: |
1310 CopyPackedSmiToDoubleElements( | 1270 CopyPackedSmiToDoubleElements( |
1311 from, from_start, to, to_start, packed_size, copy_size); | 1271 from, from_start, to, to_start, packed_size, copy_size); |
1312 break; | 1272 break; |
1313 case FAST_HOLEY_SMI_ELEMENTS: | 1273 case FAST_HOLEY_SMI_ELEMENTS: |
1314 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); | 1274 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); |
1315 break; | 1275 break; |
1316 case FAST_DOUBLE_ELEMENTS: | 1276 case FAST_DOUBLE_ELEMENTS: |
1317 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1277 case FAST_HOLEY_DOUBLE_ELEMENTS: |
(...skipping 10 matching lines...) Expand all Loading... |
1328 case SLOPPY_ARGUMENTS_ELEMENTS: | 1288 case SLOPPY_ARGUMENTS_ELEMENTS: |
1329 UNREACHABLE(); | 1289 UNREACHABLE(); |
1330 | 1290 |
1331 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1291 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1332 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1292 case EXTERNAL_##TYPE##_ELEMENTS: \ |
1333 case TYPE##_ELEMENTS: \ | 1293 case TYPE##_ELEMENTS: \ |
1334 UNREACHABLE(); | 1294 UNREACHABLE(); |
1335 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1295 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1336 #undef TYPED_ARRAY_CASE | 1296 #undef TYPED_ARRAY_CASE |
1337 } | 1297 } |
1338 return to->GetHeap()->undefined_value(); | |
1339 } | 1298 } |
1340 }; | 1299 }; |
1341 | 1300 |
1342 | 1301 |
1343 class FastPackedDoubleElementsAccessor | 1302 class FastPackedDoubleElementsAccessor |
1344 : public FastDoubleElementsAccessor< | 1303 : public FastDoubleElementsAccessor< |
1345 FastPackedDoubleElementsAccessor, | 1304 FastPackedDoubleElementsAccessor, |
1346 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { | 1305 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { |
1347 public: | 1306 public: |
1348 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor, | 1307 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor, |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 // TODO(ishell): Temporary wrapper until handlified. | 1547 // TODO(ishell): Temporary wrapper until handlified. |
1589 MUST_USE_RESULT static Handle<Object> DeleteCommon( | 1548 MUST_USE_RESULT static Handle<Object> DeleteCommon( |
1590 Handle<JSObject> obj, | 1549 Handle<JSObject> obj, |
1591 uint32_t key, | 1550 uint32_t key, |
1592 JSReceiver::DeleteMode mode) { | 1551 JSReceiver::DeleteMode mode) { |
1593 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 1552 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
1594 DeleteCommon(*obj, key, mode), | 1553 DeleteCommon(*obj, key, mode), |
1595 Object); | 1554 Object); |
1596 } | 1555 } |
1597 | 1556 |
1598 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1557 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1599 uint32_t from_start, | 1558 uint32_t from_start, |
1600 FixedArrayBase* to, | 1559 Handle<FixedArrayBase> to, |
1601 ElementsKind from_kind, | 1560 ElementsKind from_kind, |
1602 uint32_t to_start, | 1561 uint32_t to_start, |
1603 int packed_size, | 1562 int packed_size, |
1604 int copy_size) { | 1563 int copy_size) { |
1605 UNREACHABLE(); | 1564 UNREACHABLE(); |
1606 return NULL; | |
1607 } | 1565 } |
1608 | 1566 |
1609 | 1567 |
1610 protected: | 1568 protected: |
1611 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1569 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
1612 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1570 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
1613 | 1571 |
1614 MUST_USE_RESULT virtual Handle<Object> Delete( | 1572 MUST_USE_RESULT virtual Handle<Object> Delete( |
1615 Handle<JSObject> obj, | 1573 Handle<JSObject> obj, |
1616 uint32_t key, | 1574 uint32_t key, |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 // correctly implement [[DefineOwnProperty]] on arrays. | 1760 // correctly implement [[DefineOwnProperty]] on arrays. |
1803 UNIMPLEMENTED(); | 1761 UNIMPLEMENTED(); |
1804 return obj; | 1762 return obj; |
1805 } | 1763 } |
1806 | 1764 |
1807 MUST_USE_RESULT virtual Handle<Object> Delete( | 1765 MUST_USE_RESULT virtual Handle<Object> Delete( |
1808 Handle<JSObject> obj, | 1766 Handle<JSObject> obj, |
1809 uint32_t key, | 1767 uint32_t key, |
1810 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1768 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
1811 Isolate* isolate = obj->GetIsolate(); | 1769 Isolate* isolate = obj->GetIsolate(); |
1812 Handle<FixedArray> parameter_map = | 1770 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
1813 handle(FixedArray::cast(obj->elements()), isolate); | |
1814 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1771 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
1815 if (!probe->IsTheHole()) { | 1772 if (!probe->IsTheHole()) { |
1816 // TODO(kmillikin): We could check if this was the last aliased | 1773 // TODO(kmillikin): We could check if this was the last aliased |
1817 // parameter, and revert to normal elements in that case. That | 1774 // parameter, and revert to normal elements in that case. That |
1818 // would enable GC of the context. | 1775 // would enable GC of the context. |
1819 parameter_map->set_the_hole(key + 2); | 1776 parameter_map->set_the_hole(key + 2); |
1820 } else { | 1777 } else { |
1821 Handle<FixedArray> arguments = | 1778 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1822 handle(FixedArray::cast(parameter_map->get(1)), isolate); | |
1823 if (arguments->IsDictionary()) { | 1779 if (arguments->IsDictionary()) { |
1824 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); | 1780 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); |
1825 } else { | 1781 } else { |
1826 // It's difficult to access the version of DeleteCommon that is declared | 1782 // It's difficult to access the version of DeleteCommon that is declared |
1827 // in the templatized super class, call the concrete implementation in | 1783 // in the templatized super class, call the concrete implementation in |
1828 // the class for the most generalized ElementsKind subclass. | 1784 // the class for the most generalized ElementsKind subclass. |
1829 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); | 1785 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); |
1830 } | 1786 } |
1831 } | 1787 } |
1832 return isolate->factory()->true_value(); | 1788 return isolate->factory()->true_value(); |
1833 } | 1789 } |
1834 | 1790 |
1835 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1791 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1836 uint32_t from_start, | 1792 uint32_t from_start, |
1837 FixedArrayBase* to, | 1793 Handle<FixedArrayBase> to, |
1838 ElementsKind from_kind, | 1794 ElementsKind from_kind, |
1839 uint32_t to_start, | 1795 uint32_t to_start, |
1840 int packed_size, | 1796 int packed_size, |
1841 int copy_size) { | 1797 int copy_size) { |
1842 UNREACHABLE(); | 1798 UNREACHABLE(); |
1843 return NULL; | |
1844 } | 1799 } |
1845 | 1800 |
1846 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { | 1801 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
1847 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1802 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1848 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1803 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
1849 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1804 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1850 ForArray(arguments)->GetCapacity(arguments)); | 1805 ForArray(arguments)->GetCapacity(arguments)); |
1851 } | 1806 } |
1852 | 1807 |
1853 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, | 1808 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 UNREACHABLE(); | 2033 UNREACHABLE(); |
2079 break; | 2034 break; |
2080 } | 2035 } |
2081 | 2036 |
2082 array->set_elements(*elms); | 2037 array->set_elements(*elms); |
2083 array->set_length(Smi::FromInt(number_of_elements)); | 2038 array->set_length(Smi::FromInt(number_of_elements)); |
2084 return array; | 2039 return array; |
2085 } | 2040 } |
2086 | 2041 |
2087 } } // namespace v8::internal | 2042 } } // namespace v8::internal |
OLD | NEW |