OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 // Remember to check the prototype chain. | 436 // Remember to check the prototype chain. |
437 JSFunction* array_function = | 437 JSFunction* array_function = |
438 Top::context()->global_context()->array_function(); | 438 Top::context()->global_context()->array_function(); |
439 JSObject* prototype = JSObject::cast(array_function->prototype()); | 439 JSObject* prototype = JSObject::cast(array_function->prototype()); |
440 top = prototype->GetElement(len - 1); | 440 top = prototype->GetElement(len - 1); |
441 | 441 |
442 return top; | 442 return top; |
443 } | 443 } |
444 | 444 |
445 | 445 |
| 446 static FixedArray* LeftTrimFixedArray(FixedArray* elms) { |
| 447 // For now this trick is only applied to fixed arrays in new space. |
| 448 // In large object space the object's start must coincide with chunk |
| 449 // and thus the trick is just not applicable. |
| 450 // In old space we do not use this trick to avoid dealing with |
| 451 // remembered sets. |
| 452 ASSERT(Heap::new_space()->Contains(elms)); |
| 453 |
| 454 Object** former_map = |
| 455 HeapObject::RawField(elms, FixedArray::kMapOffset); |
| 456 Object** former_length = |
| 457 HeapObject::RawField(elms, FixedArray::kLengthOffset); |
| 458 Object** former_first = |
| 459 HeapObject::RawField(elms, FixedArray::kHeaderSize); |
| 460 // Check that we don't forget to copy all the bits. |
| 461 STATIC_ASSERT(FixedArray::kMapOffset + 2 * kPointerSize |
| 462 == FixedArray::kHeaderSize); |
| 463 |
| 464 int len = elms->length(); |
| 465 |
| 466 *former_first = reinterpret_cast<Object*>(len - 1); |
| 467 *former_length = Heap::fixed_array_map(); |
| 468 // Technically in new space this write might be omitted (except for |
| 469 // debug mode which iterates through the heap), but to play safer |
| 470 // we still do it. |
| 471 *former_map = Heap::raw_unchecked_one_pointer_filler_map(); |
| 472 |
| 473 ASSERT(elms->address() + kPointerSize == (elms + kPointerSize)->address()); |
| 474 return elms + kPointerSize; |
| 475 } |
| 476 |
| 477 |
446 BUILTIN(ArrayShift) { | 478 BUILTIN(ArrayShift) { |
447 Object* receiver = *args.receiver(); | 479 Object* receiver = *args.receiver(); |
448 FixedArray* elms = NULL; | 480 FixedArray* elms = NULL; |
449 if (!IsJSArrayWithFastElements(receiver, &elms) | 481 if (!IsJSArrayWithFastElements(receiver, &elms) |
450 || !ArrayPrototypeHasNoElements()) { | 482 || !ArrayPrototypeHasNoElements()) { |
451 return CallJsBuiltin("ArrayShift", args); | 483 return CallJsBuiltin("ArrayShift", args); |
452 } | 484 } |
453 JSArray* array = JSArray::cast(receiver); | 485 JSArray* array = JSArray::cast(receiver); |
454 ASSERT(array->HasFastElements()); | 486 ASSERT(array->HasFastElements()); |
455 | 487 |
456 int len = Smi::cast(array->length())->value(); | 488 int len = Smi::cast(array->length())->value(); |
457 if (len == 0) return Heap::undefined_value(); | 489 if (len == 0) return Heap::undefined_value(); |
458 | 490 |
459 // Get first element | 491 // Get first element |
460 Object* first = elms->get(0); | 492 Object* first = elms->get(0); |
461 if (first->IsTheHole()) { | 493 if (first->IsTheHole()) { |
462 first = Heap::undefined_value(); | 494 first = Heap::undefined_value(); |
463 } | 495 } |
464 | 496 |
465 // Shift the elements. | 497 if (Heap::new_space()->Contains(elms)) { |
466 AssertNoAllocation no_gc; | 498 array->set_elements(LeftTrimFixedArray(elms)); |
467 MoveElements(&no_gc, elms, 0, elms, 1, len - 1); | 499 } else { |
468 elms->set(len - 1, Heap::the_hole_value()); | 500 // Shift the elements. |
| 501 AssertNoAllocation no_gc; |
| 502 MoveElements(&no_gc, elms, 0, elms, 1, len - 1); |
| 503 elms->set(len - 1, Heap::the_hole_value()); |
| 504 } |
469 | 505 |
470 // Set the length. | 506 // Set the length. |
471 array->set_length(Smi::FromInt(len - 1)); | 507 array->set_length(Smi::FromInt(len - 1)); |
472 | 508 |
473 return first; | 509 return first; |
474 } | 510 } |
475 | 511 |
476 | 512 |
477 BUILTIN(ArrayUnshift) { | 513 BUILTIN(ArrayUnshift) { |
478 Object* receiver = *args.receiver(); | 514 Object* receiver = *args.receiver(); |
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 if (entry->contains(pc)) { | 1468 if (entry->contains(pc)) { |
1433 return names_[i]; | 1469 return names_[i]; |
1434 } | 1470 } |
1435 } | 1471 } |
1436 } | 1472 } |
1437 return NULL; | 1473 return NULL; |
1438 } | 1474 } |
1439 | 1475 |
1440 | 1476 |
1441 } } // namespace v8::internal | 1477 } } // namespace v8::internal |
OLD | NEW |