OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 4743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4754 object->Print(); | 4754 object->Print(); |
4755 } | 4755 } |
4756 #endif | 4756 #endif |
4757 } | 4757 } |
4758 | 4758 |
4759 | 4759 |
4760 void JSObject::TransformToFastProperties(Handle<JSObject> object, | 4760 void JSObject::TransformToFastProperties(Handle<JSObject> object, |
4761 int unused_property_fields) { | 4761 int unused_property_fields) { |
4762 if (object->HasFastProperties()) return; | 4762 if (object->HasFastProperties()) return; |
4763 ASSERT(!object->IsGlobalObject()); | 4763 ASSERT(!object->IsGlobalObject()); |
4764 CALL_HEAP_FUNCTION_VOID( | 4764 Handle<NameDictionary> dictionary(object->property_dictionary()); |
4765 object->GetIsolate(), | 4765 NameDictionary::TransformPropertiesToFastFor( |
4766 object->property_dictionary()->TransformPropertiesToFastFor( | 4766 dictionary, object, unused_property_fields); |
4767 *object, unused_property_fields)); | |
4768 } | 4767 } |
4769 | 4768 |
4770 | 4769 |
4771 void JSObject::ResetElements(Handle<JSObject> object) { | 4770 void JSObject::ResetElements(Handle<JSObject> object) { |
4772 if (object->map()->is_observed()) { | 4771 if (object->map()->is_observed()) { |
4773 // Maintain invariant that observed elements are always in dictionary mode. | 4772 // Maintain invariant that observed elements are always in dictionary mode. |
4774 Factory* factory = object->GetIsolate()->factory(); | 4773 Factory* factory = object->GetIsolate()->factory(); |
4775 Handle<SeededNumberDictionary> dictionary = | 4774 Handle<SeededNumberDictionary> dictionary = |
4776 factory->NewSeededNumberDictionary(0); | 4775 factory->NewSeededNumberDictionary(0); |
4777 if (object->map() == *factory->sloppy_arguments_elements_map()) { | 4776 if (object->map() == *factory->sloppy_arguments_elements_map()) { |
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6823 if (FLAG_verify_heap && result->is_shared()) { | 6822 if (FLAG_verify_heap && result->is_shared()) { |
6824 result->SharedMapVerify(); | 6823 result->SharedMapVerify(); |
6825 } | 6824 } |
6826 #endif | 6825 #endif |
6827 | 6826 |
6828 return result; | 6827 return result; |
6829 } | 6828 } |
6830 | 6829 |
6831 | 6830 |
6832 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { | 6831 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { |
6833 CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map); | 6832 Handle<Map> result = RawCopy(map, map->instance_size()); |
6834 } | |
6835 | |
6836 | |
6837 MaybeObject* Map::CopyDropDescriptors() { | |
6838 Map* result; | |
6839 MaybeObject* maybe_result = RawCopy(instance_size()); | |
6840 if (!maybe_result->To(&result)) return maybe_result; | |
6841 | 6833 |
6842 // Please note instance_type and instance_size are set when allocated. | 6834 // Please note instance_type and instance_size are set when allocated. |
6843 result->set_inobject_properties(inobject_properties()); | 6835 result->set_inobject_properties(map->inobject_properties()); |
6844 result->set_unused_property_fields(unused_property_fields()); | 6836 result->set_unused_property_fields(map->unused_property_fields()); |
6845 | 6837 |
6846 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 6838 result->set_pre_allocated_property_fields( |
6839 map->pre_allocated_property_fields()); | |
6847 result->set_is_shared(false); | 6840 result->set_is_shared(false); |
6848 result->ClearCodeCache(GetHeap()); | 6841 result->ClearCodeCache(map->GetHeap()); |
6849 NotifyLeafMapLayoutChange(); | 6842 map->NotifyLeafMapLayoutChange(); |
6850 return result; | 6843 return result; |
6851 } | 6844 } |
6852 | 6845 |
6853 | 6846 |
6854 Handle<Map> Map::ShareDescriptor(Handle<Map> map, | 6847 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
6855 Handle<DescriptorArray> descriptors, | 6848 Handle<DescriptorArray> descriptors, |
6856 Descriptor* descriptor) { | 6849 Descriptor* descriptor) { |
6857 // Sanity check. This path is only to be taken if the map owns its descriptor | 6850 // Sanity check. This path is only to be taken if the map owns its descriptor |
6858 // array, implying that its NumberOfOwnDescriptors equals the number of | 6851 // array, implying that its NumberOfOwnDescriptors equals the number of |
6859 // descriptors in the descriptor array. | 6852 // descriptors in the descriptor array. |
(...skipping 8724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15584 e = PropertyCell::cast(e)->value(); | 15577 e = PropertyCell::cast(e)->value(); |
15585 } | 15578 } |
15586 if (e == value) return k; | 15579 if (e == value) return k; |
15587 } | 15580 } |
15588 } | 15581 } |
15589 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15582 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
15590 return heap->undefined_value(); | 15583 return heap->undefined_value(); |
15591 } | 15584 } |
15592 | 15585 |
15593 | 15586 |
15594 MaybeObject* NameDictionary::TransformPropertiesToFastFor( | 15587 void NameDictionary::TransformPropertiesToFastFor( |
15595 JSObject* obj, int unused_property_fields) { | 15588 Handle<NameDictionary> dictionary, |
15589 Handle<JSObject> obj, | |
15590 int unused_property_fields) { | |
15596 // Make sure we preserve dictionary representation if there are too many | 15591 // Make sure we preserve dictionary representation if there are too many |
15597 // descriptors. | 15592 // descriptors. |
15598 int number_of_elements = NumberOfElements(); | 15593 int number_of_elements = dictionary->NumberOfElements(); |
15599 if (number_of_elements > kMaxNumberOfDescriptors) return obj; | 15594 if (number_of_elements > kMaxNumberOfDescriptors) return; |
15600 | 15595 |
15601 if (number_of_elements != NextEnumerationIndex()) { | 15596 if (number_of_elements != dictionary->NextEnumerationIndex()) { |
15602 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15597 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); |
15603 if (maybe_result->IsFailure()) return maybe_result; | |
15604 } | 15598 } |
15605 | 15599 |
15606 int instance_descriptor_length = 0; | 15600 int instance_descriptor_length = 0; |
15607 int number_of_fields = 0; | 15601 int number_of_fields = 0; |
15608 | 15602 |
15609 Heap* heap = GetHeap(); | 15603 Isolate* isolate = dictionary->GetIsolate(); |
15604 Factory* factory = isolate->factory(); | |
15605 Heap* heap = isolate->heap(); | |
15610 | 15606 |
15611 // Compute the length of the instance descriptor. | 15607 // Compute the length of the instance descriptor. |
15612 int capacity = Capacity(); | 15608 int capacity = dictionary->Capacity(); |
15613 for (int i = 0; i < capacity; i++) { | 15609 for (int i = 0; i < capacity; i++) { |
15614 Object* k = KeyAt(i); | 15610 Object* k = dictionary->KeyAt(i); |
15615 if (IsKey(k)) { | 15611 if (dictionary->IsKey(k)) { |
15616 Object* value = ValueAt(i); | 15612 Object* value = dictionary->ValueAt(i); |
15617 PropertyType type = DetailsAt(i).type(); | 15613 PropertyType type = dictionary->DetailsAt(i).type(); |
15618 ASSERT(type != FIELD); | 15614 ASSERT(type != FIELD); |
15619 instance_descriptor_length++; | 15615 instance_descriptor_length++; |
15620 if (type == NORMAL && !value->IsJSFunction()) { | 15616 if (type == NORMAL && !value->IsJSFunction()) { |
15621 number_of_fields += 1; | 15617 number_of_fields += 1; |
15622 } | 15618 } |
15623 } | 15619 } |
15624 } | 15620 } |
15625 | 15621 |
15626 int inobject_props = obj->map()->inobject_properties(); | 15622 int inobject_props = obj->map()->inobject_properties(); |
15627 | 15623 |
15628 // Allocate new map. | 15624 // Allocate new map. |
15629 Map* new_map; | 15625 Handle<Map> new_map = Map::CopyDropDescriptors(handle(obj->map())); |
15630 MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); | |
15631 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
15632 new_map->set_dictionary_map(false); | 15626 new_map->set_dictionary_map(false); |
15633 | 15627 |
15634 if (instance_descriptor_length == 0) { | 15628 if (instance_descriptor_length == 0) { |
15635 ASSERT_LE(unused_property_fields, inobject_props); | 15629 ASSERT_LE(unused_property_fields, inobject_props); |
Toon Verwaest
2014/04/11 10:37:59
DisallowHeapAllocation no_gc; while committing the
| |
15636 // Transform the object. | 15630 // Transform the object. |
15637 new_map->set_unused_property_fields(inobject_props); | 15631 new_map->set_unused_property_fields(inobject_props); |
15638 obj->set_map(new_map); | 15632 obj->set_map(*new_map); |
15639 obj->set_properties(heap->empty_fixed_array()); | 15633 obj->set_properties(heap->empty_fixed_array()); |
15640 // Check that it really works. | 15634 // Check that it really works. |
15641 ASSERT(obj->HasFastProperties()); | 15635 ASSERT(obj->HasFastProperties()); |
15642 return obj; | 15636 return; |
15643 } | 15637 } |
15644 | 15638 |
15645 // Allocate the instance descriptor. | 15639 // Allocate the instance descriptor. |
15646 DescriptorArray* descriptors; | 15640 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray( |
15647 MaybeObject* maybe_descriptors = | 15641 instance_descriptor_length); |
15648 DescriptorArray::Allocate(GetIsolate(), instance_descriptor_length); | |
15649 if (!maybe_descriptors->To(&descriptors)) { | |
15650 return maybe_descriptors; | |
15651 } | |
15652 | |
15653 DescriptorArray::WhitenessWitness witness(descriptors); | |
15654 | 15642 |
15655 int number_of_allocated_fields = | 15643 int number_of_allocated_fields = |
15656 number_of_fields + unused_property_fields - inobject_props; | 15644 number_of_fields + unused_property_fields - inobject_props; |
15657 if (number_of_allocated_fields < 0) { | 15645 if (number_of_allocated_fields < 0) { |
15658 // There is enough inobject space for all fields (including unused). | 15646 // There is enough inobject space for all fields (including unused). |
15659 number_of_allocated_fields = 0; | 15647 number_of_allocated_fields = 0; |
15660 unused_property_fields = inobject_props - number_of_fields; | 15648 unused_property_fields = inobject_props - number_of_fields; |
15661 } | 15649 } |
15662 | 15650 |
15663 // Allocate the fixed array for the fields. | 15651 // Allocate the fixed array for the fields. |
15664 FixedArray* fields; | 15652 Handle<FixedArray> fields = factory->NewFixedArray( |
15665 MaybeObject* maybe_fields = | 15653 number_of_allocated_fields); |
15666 heap->AllocateFixedArray(number_of_allocated_fields); | |
15667 if (!maybe_fields->To(&fields)) return maybe_fields; | |
15668 | 15654 |
15669 // Fill in the instance descriptor and the fields. | 15655 // Fill in the instance descriptor and the fields. |
15670 int current_offset = 0; | 15656 int current_offset = 0; |
15671 for (int i = 0; i < capacity; i++) { | 15657 for (int i = 0; i < capacity; i++) { |
15672 Object* k = KeyAt(i); | 15658 Object* k = dictionary->KeyAt(i); |
15673 if (IsKey(k)) { | 15659 if (dictionary->IsKey(k)) { |
15674 Object* value = ValueAt(i); | 15660 Object* value = dictionary->ValueAt(i); |
15675 Name* key; | 15661 Handle<Name> key; |
15676 if (k->IsSymbol()) { | 15662 if (k->IsSymbol()) { |
15677 key = Symbol::cast(k); | 15663 key = handle(Symbol::cast(k)); |
15678 } else { | 15664 } else { |
15679 // Ensure the key is a unique name before writing into the | 15665 // Ensure the key is a unique name before writing into the |
15680 // instance descriptor. | 15666 // instance descriptor. |
15681 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); | 15667 key = factory->InternalizeString(handle(String::cast(k))); |
15682 if (!maybe_key->To(&key)) return maybe_key; | |
15683 } | 15668 } |
15684 | 15669 |
15685 PropertyDetails details = DetailsAt(i); | 15670 PropertyDetails details = dictionary->DetailsAt(i); |
15686 int enumeration_index = details.dictionary_index(); | 15671 int enumeration_index = details.dictionary_index(); |
15687 PropertyType type = details.type(); | 15672 PropertyType type = details.type(); |
15688 | 15673 |
15689 if (value->IsJSFunction()) { | 15674 if (value->IsJSFunction()) { |
15690 ConstantDescriptor d(handle(key), | 15675 ConstantDescriptor d(key, |
15691 handle(value, GetIsolate()), | 15676 handle(value, isolate), |
15692 details.attributes()); | 15677 details.attributes()); |
15693 descriptors->Set(enumeration_index - 1, &d, witness); | 15678 descriptors->Set(enumeration_index - 1, &d); |
15694 } else if (type == NORMAL) { | 15679 } else if (type == NORMAL) { |
15695 if (current_offset < inobject_props) { | 15680 if (current_offset < inobject_props) { |
15696 obj->InObjectPropertyAtPut(current_offset, | 15681 obj->InObjectPropertyAtPut(current_offset, |
15697 value, | 15682 value, |
15698 UPDATE_WRITE_BARRIER); | 15683 UPDATE_WRITE_BARRIER); |
15699 } else { | 15684 } else { |
15700 int offset = current_offset - inobject_props; | 15685 int offset = current_offset - inobject_props; |
15701 fields->set(offset, value); | 15686 fields->set(offset, value); |
15702 } | 15687 } |
15703 FieldDescriptor d(handle(key), | 15688 FieldDescriptor d(key, |
15704 current_offset++, | 15689 current_offset++, |
15705 details.attributes(), | 15690 details.attributes(), |
15706 // TODO(verwaest): value->OptimalRepresentation(); | 15691 // TODO(verwaest): value->OptimalRepresentation(); |
15707 Representation::Tagged()); | 15692 Representation::Tagged()); |
15708 descriptors->Set(enumeration_index - 1, &d, witness); | 15693 descriptors->Set(enumeration_index - 1, &d); |
15709 } else if (type == CALLBACKS) { | 15694 } else if (type == CALLBACKS) { |
15710 CallbacksDescriptor d(handle(key), | 15695 CallbacksDescriptor d(key, |
15711 handle(value, GetIsolate()), | 15696 handle(value, isolate), |
15712 details.attributes()); | 15697 details.attributes()); |
15713 descriptors->Set(enumeration_index - 1, &d, witness); | 15698 descriptors->Set(enumeration_index - 1, &d); |
15714 } else { | 15699 } else { |
15715 UNREACHABLE(); | 15700 UNREACHABLE(); |
15716 } | 15701 } |
15717 } | 15702 } |
15718 } | 15703 } |
15719 ASSERT(current_offset == number_of_fields); | 15704 ASSERT(current_offset == number_of_fields); |
15720 | 15705 |
15721 descriptors->Sort(); | 15706 descriptors->Sort(); |
15722 | 15707 |
Toon Verwaest
2014/04/11 10:37:59
DisallowHeapAllocation no_gc while committing stat
mvstanton
2014/04/11 11:25:20
Done.
| |
15723 new_map->InitializeDescriptors(descriptors); | 15708 new_map->InitializeDescriptors(*descriptors); |
15724 new_map->set_unused_property_fields(unused_property_fields); | 15709 new_map->set_unused_property_fields(unused_property_fields); |
15725 | 15710 |
15726 // Transform the object. | 15711 // Transform the object. |
15727 obj->set_map(new_map); | 15712 obj->set_map(*new_map); |
15728 | 15713 |
15729 obj->set_properties(fields); | 15714 obj->set_properties(*fields); |
15730 ASSERT(obj->IsJSObject()); | 15715 ASSERT(obj->IsJSObject()); |
15731 | 15716 |
15732 // Check that it really works. | 15717 // Check that it really works. |
15733 ASSERT(obj->HasFastProperties()); | 15718 ASSERT(obj->HasFastProperties()); |
15734 | |
15735 return obj; | |
15736 } | 15719 } |
15737 | 15720 |
15738 | 15721 |
15739 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15722 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
15740 Handle<ObjectHashTable> table, | 15723 Handle<ObjectHashTable> table, |
15741 int n, | 15724 int n, |
15742 Handle<Object> key, | 15725 Handle<Object> key, |
15743 PretenureFlag pretenure) { | 15726 PretenureFlag pretenure) { |
15744 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | 15727 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; |
15745 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15728 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16629 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16612 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16630 static const char* error_messages_[] = { | 16613 static const char* error_messages_[] = { |
16631 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16614 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16632 }; | 16615 }; |
16633 #undef ERROR_MESSAGES_TEXTS | 16616 #undef ERROR_MESSAGES_TEXTS |
16634 return error_messages_[reason]; | 16617 return error_messages_[reason]; |
16635 } | 16618 } |
16636 | 16619 |
16637 | 16620 |
16638 } } // namespace v8::internal | 16621 } } // namespace v8::internal |
OLD | NEW |