Chromium Code Reviews| 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 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1889 bool DescriptorArray::MayContainTransitions() { | 1889 bool DescriptorArray::MayContainTransitions() { |
| 1890 return !IsEmpty(); | 1890 return !IsEmpty(); |
| 1891 } | 1891 } |
| 1892 | 1892 |
| 1893 | 1893 |
| 1894 bool DescriptorArray::HasTransitionArray() { | 1894 bool DescriptorArray::HasTransitionArray() { |
| 1895 return MayContainTransitions() && !get(kTransitionsIndex)->IsSmi(); | 1895 return MayContainTransitions() && !get(kTransitionsIndex)->IsSmi(); |
| 1896 } | 1896 } |
| 1897 | 1897 |
| 1898 | 1898 |
| 1899 int DescriptorArray::bit_field3_storage() { | 1899 Object* DescriptorArray::back_pointer_storage() { |
| 1900 Object* storage = READ_FIELD(this, kBitField3StorageOffset); | 1900 return READ_FIELD(this, kBackPointerStorageOffset); |
| 1901 return Smi::cast(storage)->value(); | |
| 1902 } | |
| 1903 | |
| 1904 void DescriptorArray::set_bit_field3_storage(int value) { | |
| 1905 ASSERT(length() > kBitField3StorageIndex); | |
| 1906 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value)); | |
| 1907 } | 1901 } |
| 1908 | 1902 |
| 1909 | 1903 |
| 1904 void DescriptorArray::set_back_pointer_storage(Object* value, | |
| 1905 WriteBarrierMode mode) { | |
| 1906 ASSERT(length() > kBackPointerStorageIndex); | |
| 1907 Heap* heap = GetHeap(); | |
| 1908 WRITE_FIELD(this, kBackPointerStorageOffset, value); | |
| 1909 CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerStorageOffset, value, mode); | |
| 1910 } | |
| 1911 | |
| 1912 | |
| 1910 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, | 1913 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, |
| 1911 int first, | 1914 int first, |
| 1912 int second) { | 1915 int second) { |
| 1913 Object* tmp = array->get(first); | 1916 Object* tmp = array->get(first); |
| 1914 NoIncrementalWriteBarrierSet(array, first, array->get(second)); | 1917 NoIncrementalWriteBarrierSet(array, first, array->get(second)); |
| 1915 NoIncrementalWriteBarrierSet(array, second, tmp); | 1918 NoIncrementalWriteBarrierSet(array, second, tmp); |
| 1916 } | 1919 } |
| 1917 | 1920 |
| 1918 | 1921 |
| 1919 // Perform a binary search in a fixed array. Low and high are entry indices. If | 1922 // Perform a binary search in a fixed array. Low and high are entry indices. If |
| (...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3395 | 3398 |
| 3396 | 3399 |
| 3397 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3400 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
| 3398 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3401 ASSERT(value->IsNull() || value->IsJSReceiver()); |
| 3399 WRITE_FIELD(this, kPrototypeOffset, value); | 3402 WRITE_FIELD(this, kPrototypeOffset, value); |
| 3400 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3403 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
| 3401 } | 3404 } |
| 3402 | 3405 |
| 3403 | 3406 |
| 3404 DescriptorArray* Map::instance_descriptors() { | 3407 DescriptorArray* Map::instance_descriptors() { |
| 3405 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); | 3408 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); |
| 3406 if (object->IsSmi()) { | 3409 if (!object->IsDescriptorArray()) { |
| 3410 ASSERT(object->IsMap() || object->IsUndefined()); | |
| 3407 return GetHeap()->empty_descriptor_array(); | 3411 return GetHeap()->empty_descriptor_array(); |
| 3408 } else { | 3412 } else { |
| 3409 return DescriptorArray::cast(object); | 3413 return DescriptorArray::cast(object); |
| 3410 } | 3414 } |
| 3411 } | 3415 } |
| 3412 | 3416 |
| 3413 | 3417 |
| 3414 void Map::init_instance_descriptors() { | |
| 3415 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0)); | |
| 3416 } | |
| 3417 | |
| 3418 | |
| 3419 void Map::clear_instance_descriptors() { | |
| 3420 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); | |
| 3421 if (!object->IsSmi()) { | |
| 3422 WRITE_FIELD( | |
| 3423 this, | |
| 3424 kInstanceDescriptorsOrBitField3Offset, | |
| 3425 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage())); | |
| 3426 } | |
| 3427 } | |
| 3428 | |
| 3429 | |
| 3430 void Map::set_instance_descriptors(DescriptorArray* value, | 3418 void Map::set_instance_descriptors(DescriptorArray* value, |
| 3431 WriteBarrierMode mode) { | 3419 WriteBarrierMode mode) { |
| 3432 Object* object = READ_FIELD(this, | 3420 ASSERT(!value->IsFailure()); |
|
Jakob Kummerow
2012/07/10 12:26:25
Can this happen?
Toon Verwaest
2012/07/10 13:28:28
Removed.
On 2012/07/10 12:26:25, Jakob wrote:
| |
| 3433 kInstanceDescriptorsOrBitField3Offset); | 3421 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); |
|
Jakob Kummerow
2012/07/10 12:26:25
Looks like you can move this into the "else" block
Toon Verwaest
2012/07/10 13:28:28
Done.
| |
| 3434 Heap* heap = GetHeap(); | 3422 Heap* heap = GetHeap(); |
| 3435 if (value == heap->empty_descriptor_array()) { | 3423 if (value == heap->empty_descriptor_array()) { |
| 3436 clear_instance_descriptors(); | 3424 ClearDescriptorArray(heap, mode); |
| 3437 return; | 3425 return; |
| 3438 } else { | 3426 } else { |
| 3439 if (object->IsSmi()) { | 3427 if (object->IsDescriptorArray()) { |
| 3440 value->set_bit_field3_storage(Smi::cast(object)->value()); | 3428 value->set_back_pointer_storage( |
| 3429 DescriptorArray::cast(object)->back_pointer_storage()); | |
| 3441 } else { | 3430 } else { |
| 3442 value->set_bit_field3_storage( | 3431 ASSERT(object->IsMap() || object->IsUndefined()); |
| 3443 DescriptorArray::cast(object)->bit_field3_storage()); | 3432 value->set_back_pointer_storage(object); |
| 3444 } | 3433 } |
| 3445 } | 3434 } |
| 3446 ASSERT(!is_shared()); | 3435 ASSERT(!is_shared()); |
| 3447 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); | 3436 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value); |
| 3448 CONDITIONAL_WRITE_BARRIER( | 3437 CONDITIONAL_WRITE_BARRIER( |
| 3449 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); | 3438 heap, this, kInstanceDescriptorsOrBackPointerOffset, value, mode); |
| 3450 } | 3439 } |
| 3451 | 3440 |
| 3452 | 3441 |
| 3453 int Map::bit_field3() { | 3442 int Map::bit_field3() { |
|
Jakob Kummerow
2012/07/10 12:26:25
SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
s
Toon Verwaest
2012/07/10 13:28:28
Done.
| |
| 3454 Object* object = READ_FIELD(this, | 3443 return Smi::cast(READ_FIELD(this, kBitField3Offset))->value(); |
| 3455 kInstanceDescriptorsOrBitField3Offset); | 3444 } |
| 3456 if (object->IsSmi()) { | 3445 |
| 3457 return Smi::cast(object)->value(); | 3446 |
| 3447 void Map::ClearDescriptorArray(Heap* heap, WriteBarrierMode mode) { | |
| 3448 Object* back_pointer = GetBackPointer(); | |
| 3449 #ifdef DEBUG | |
| 3450 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | |
| 3451 if (object->IsDescriptorArray()) { | |
| 3452 ZapTransitions(); | |
| 3458 } else { | 3453 } else { |
| 3459 return DescriptorArray::cast(object)->bit_field3_storage(); | 3454 ASSERT(object->IsMap() || object->IsUndefined()); |
| 3455 } | |
| 3456 #endif | |
| 3457 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, back_pointer); | |
| 3458 CONDITIONAL_WRITE_BARRIER( | |
| 3459 heap, this, kInstanceDescriptorsOrBackPointerOffset, back_pointer, mode); | |
| 3460 } | |
| 3461 | |
| 3462 | |
| 3463 void Map::set_bit_field3(int value) { | |
| 3464 WRITE_FIELD(this, kBitField3Offset, Smi::FromInt(value)); | |
| 3465 } | |
| 3466 | |
| 3467 | |
| 3468 Object* Map::GetBackPointer() { | |
| 3469 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | |
| 3470 if (object->IsDescriptorArray()) { | |
| 3471 return DescriptorArray::cast(object)->back_pointer_storage(); | |
| 3472 } else { | |
| 3473 ASSERT(object->IsMap() || object->IsUndefined()); | |
| 3474 return object; | |
| 3460 } | 3475 } |
| 3461 } | 3476 } |
| 3462 | 3477 |
| 3463 | 3478 |
| 3464 void Map::ClearDescriptorArray() { | |
| 3465 int bitfield3 = bit_field3(); | |
| 3466 #ifdef DEBUG | |
| 3467 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); | |
| 3468 if (!object->IsSmi()) { | |
| 3469 ZapTransitions(); | |
| 3470 } | |
| 3471 #endif | |
| 3472 WRITE_FIELD(this, | |
| 3473 kInstanceDescriptorsOrBitField3Offset, | |
| 3474 Smi::FromInt(bitfield3)); | |
| 3475 } | |
| 3476 | |
| 3477 | |
| 3478 void Map::set_bit_field3(int value) { | |
| 3479 ASSERT(Smi::IsValid(value)); | |
| 3480 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); | |
| 3481 if (object->IsSmi()) { | |
| 3482 WRITE_FIELD(this, | |
| 3483 kInstanceDescriptorsOrBitField3Offset, | |
| 3484 Smi::FromInt(value)); | |
| 3485 } else { | |
| 3486 DescriptorArray::cast(object)->set_bit_field3_storage(value); | |
| 3487 } | |
| 3488 } | |
| 3489 | |
| 3490 | |
| 3491 Object* Map::GetBackPointer() { | |
| 3492 return READ_FIELD(this, kBackPointerOffset); | |
| 3493 } | |
| 3494 | |
| 3495 | |
| 3496 bool Map::HasElementsTransition() { | 3479 bool Map::HasElementsTransition() { |
| 3497 return HasTransitionArray() && transitions()->HasElementsTransition(); | 3480 return HasTransitionArray() && transitions()->HasElementsTransition(); |
| 3498 } | 3481 } |
| 3499 | 3482 |
| 3500 | 3483 |
| 3501 bool Map::HasTransitionArray() { | 3484 bool Map::HasTransitionArray() { |
| 3502 return instance_descriptors()->HasTransitionArray(); | 3485 return instance_descriptors()->HasTransitionArray(); |
| 3503 } | 3486 } |
| 3504 | 3487 |
| 3505 | 3488 |
| 3506 Map* Map::elements_transition_map() { | 3489 Map* Map::elements_transition_map() { |
| 3507 return transitions()->elements_transition(); | 3490 return transitions()->elements_transition(); |
| 3508 } | 3491 } |
| 3509 | 3492 |
| 3510 | 3493 |
| 3511 MaybeObject* Map::AddTransition(String* key, Object* value) { | 3494 MaybeObject* Map::AddTransition(String* key, Object* value) { |
| 3512 if (HasTransitionArray()) return transitions()->CopyInsert(key, value); | 3495 if (HasTransitionArray()) return transitions()->CopyInsert(key, value); |
| 3513 return TransitionArray::NewWith(key, value); | 3496 return TransitionArray::NewWith(key, value); |
| 3514 } | 3497 } |
| 3515 | 3498 |
| 3516 | 3499 |
| 3517 // If the map does not have a descriptor array, install a new empty | 3500 // If the map is using the empty descriptor array, install a new empty |
| 3518 // descriptor array that has room for a transition array. | 3501 // descriptor array that will contain an element transition. |
|
Jakob Kummerow
2012/07/10 12:26:25
nit: s/element/elements/
Toon Verwaest
2012/07/10 13:28:28
Done.
| |
| 3519 static MaybeObject* AllowTransitions(Map* map) { | 3502 static MaybeObject* AllowTransitions(Map* map) { |
| 3520 if (map->instance_descriptors()->MayContainTransitions()) return map; | 3503 if (map->instance_descriptors()->MayContainTransitions()) return map; |
| 3521 DescriptorArray* descriptors; | 3504 DescriptorArray* descriptors; |
| 3522 MaybeObject* maybe_descriptors = | 3505 MaybeObject* maybe_descriptors = |
| 3523 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED); | 3506 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED); |
| 3524 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 3507 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
| 3525 map->set_instance_descriptors(descriptors); | 3508 map->set_instance_descriptors(descriptors); |
| 3526 return descriptors; | 3509 return descriptors; |
| 3527 } | 3510 } |
| 3528 | 3511 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3577 bool Map::HasPrototypeTransitions() { | 3560 bool Map::HasPrototypeTransitions() { |
| 3578 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); | 3561 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); |
| 3579 } | 3562 } |
| 3580 | 3563 |
| 3581 | 3564 |
| 3582 TransitionArray* Map::transitions() { | 3565 TransitionArray* Map::transitions() { |
| 3583 return instance_descriptors()->transitions(); | 3566 return instance_descriptors()->transitions(); |
| 3584 } | 3567 } |
| 3585 | 3568 |
| 3586 | 3569 |
| 3587 void Map::ClearTransitions() { | 3570 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
| 3588 #ifdef DEBUG | 3571 #ifdef DEBUG |
| 3589 ZapTransitions(); | 3572 ZapTransitions(); |
| 3590 #endif | 3573 #endif |
| 3591 DescriptorArray* descriptors = instance_descriptors(); | 3574 DescriptorArray* descriptors = instance_descriptors(); |
| 3592 if (descriptors->number_of_descriptors() == 0) { | 3575 if (descriptors->number_of_descriptors() == 0) { |
| 3593 ClearDescriptorArray(); | 3576 ClearDescriptorArray(heap, mode); |
| 3594 } else { | 3577 } else { |
| 3595 descriptors->ClearTransitions(); | 3578 descriptors->ClearTransitions(); |
| 3596 } | 3579 } |
| 3597 } | 3580 } |
| 3598 | 3581 |
| 3599 | 3582 |
| 3600 MaybeObject* Map::set_transitions(TransitionArray* transitions_array) { | 3583 MaybeObject* Map::set_transitions(TransitionArray* transitions_array) { |
| 3601 MaybeObject* allow_transitions = AllowTransitions(this); | 3584 MaybeObject* allow_transitions = AllowTransitions(this); |
| 3602 if (allow_transitions->IsFailure()) return allow_transitions; | 3585 if (allow_transitions->IsFailure()) return allow_transitions; |
| 3603 #ifdef DEBUG | 3586 #ifdef DEBUG |
| 3604 if (HasTransitionArray()) { | 3587 if (HasTransitionArray()) { |
| 3605 ASSERT(transitions() != transitions_array); | 3588 ASSERT(transitions() != transitions_array); |
| 3606 ZapTransitions(); | 3589 ZapTransitions(); |
| 3607 } | 3590 } |
| 3608 #endif | 3591 #endif |
| 3609 instance_descriptors()->set_transitions(transitions_array); | 3592 instance_descriptors()->set_transitions(transitions_array); |
| 3610 return this; | 3593 return this; |
| 3611 } | 3594 } |
| 3612 | 3595 |
| 3613 | 3596 |
| 3614 void Map::init_back_pointer(Object* undefined) { | 3597 void Map::init_back_pointer(Object* undefined) { |
| 3615 ASSERT(undefined->IsUndefined()); | 3598 ASSERT(undefined->IsUndefined()); |
| 3616 WRITE_FIELD(this, kBackPointerOffset, undefined); | 3599 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined); |
| 3617 } | 3600 } |
| 3618 | 3601 |
| 3619 | 3602 |
| 3620 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { | 3603 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { |
| 3621 Heap* heap = GetHeap(); | |
| 3622 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); | 3604 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); |
| 3623 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || | 3605 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || |
| 3624 (value->IsMap() && GetBackPointer()->IsUndefined())); | 3606 (value->IsMap() && GetBackPointer()->IsUndefined())); |
| 3625 WRITE_FIELD(this, kBackPointerOffset, value); | 3607 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); |
| 3626 CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerOffset, value, mode); | 3608 if (object->IsMap()) { |
| 3609 ASSERT(!value->IsFailure()); | |
|
Jakob Kummerow
2012/07/10 12:26:25
Can this happen?
Toon Verwaest
2012/07/10 13:28:28
Removed.
On 2012/07/10 12:26:25, Jakob wrote:
| |
| 3610 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value); | |
| 3611 CONDITIONAL_WRITE_BARRIER( | |
| 3612 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode); | |
| 3613 } else { | |
|
Jakob Kummerow
2012/07/10 12:26:25
What if (object->IsUndefined()) ?
Toon Verwaest
2012/07/10 13:28:28
Then we just overwrite it, since it's the default
| |
| 3614 DescriptorArray::cast(object)->set_back_pointer_storage(value); | |
| 3615 } | |
| 3627 } | 3616 } |
| 3628 | 3617 |
| 3629 | 3618 |
| 3630 // Can either be Smi (no transitions), normal transition array, or a transition | 3619 // Can either be Smi (no transitions), normal transition array, or a transition |
| 3631 // array with the header overwritten as a Smi (thus iterating). | 3620 // array with the header overwritten as a Smi (thus iterating). |
| 3632 TransitionArray* Map::unchecked_transition_array() { | 3621 TransitionArray* Map::unchecked_transition_array() { |
| 3633 ASSERT(HasTransitionArray()); | 3622 ASSERT(HasTransitionArray()); |
| 3634 Object* object = *HeapObject::RawField(instance_descriptors(), | 3623 Object* object = *HeapObject::RawField(instance_descriptors(), |
| 3635 DescriptorArray::kTransitionsOffset); | 3624 DescriptorArray::kTransitionsOffset); |
| 3636 ASSERT(!object->IsSmi()); | 3625 ASSERT(!object->IsSmi()); |
| (...skipping 1647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5284 #undef WRITE_UINT32_FIELD | 5273 #undef WRITE_UINT32_FIELD |
| 5285 #undef READ_SHORT_FIELD | 5274 #undef READ_SHORT_FIELD |
| 5286 #undef WRITE_SHORT_FIELD | 5275 #undef WRITE_SHORT_FIELD |
| 5287 #undef READ_BYTE_FIELD | 5276 #undef READ_BYTE_FIELD |
| 5288 #undef WRITE_BYTE_FIELD | 5277 #undef WRITE_BYTE_FIELD |
| 5289 | 5278 |
| 5290 | 5279 |
| 5291 } } // namespace v8::internal | 5280 } } // namespace v8::internal |
| 5292 | 5281 |
| 5293 #endif // V8_OBJECTS_INL_H_ | 5282 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |