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 |