Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1025)

Side by Side Diff: src/objects.cc

Issue 234783002: Handlify Map::CopyDropDescriptors(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more refactoring. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 Isolate* isolate = object->GetIsolate();
4765 object->GetIsolate(), 4765 Factory* factory = isolate->factory();
4766 object->property_dictionary()->TransformPropertiesToFastFor( 4766 Handle<NameDictionary> dictionary(object->property_dictionary());
4767 *object, unused_property_fields)); 4767
4768 // Make sure we preserve dictionary representation if there are too many
4769 // descriptors.
4770 int number_of_elements = dictionary->NumberOfElements();
4771 if (number_of_elements > kMaxNumberOfDescriptors) return;
4772
4773 if (number_of_elements != dictionary->NextEnumerationIndex()) {
4774 NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
4775 }
4776
4777 int instance_descriptor_length = 0;
4778 int number_of_fields = 0;
4779
4780 // Compute the length of the instance descriptor.
4781 int capacity = dictionary->Capacity();
4782 for (int i = 0; i < capacity; i++) {
4783 Object* k = dictionary->KeyAt(i);
4784 if (dictionary->IsKey(k)) {
4785 Object* value = dictionary->ValueAt(i);
4786 PropertyType type = dictionary->DetailsAt(i).type();
4787 ASSERT(type != FIELD);
4788 instance_descriptor_length++;
4789 if (type == NORMAL && !value->IsJSFunction()) {
4790 number_of_fields += 1;
4791 }
4792 }
4793 }
4794
4795 int inobject_props = object->map()->inobject_properties();
4796
4797 // Allocate new map.
4798 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
4799 new_map->set_dictionary_map(false);
4800
4801 if (instance_descriptor_length == 0) {
4802 DisallowHeapAllocation no_gc;
4803 ASSERT_LE(unused_property_fields, inobject_props);
4804 // Transform the object.
4805 new_map->set_unused_property_fields(inobject_props);
4806 object->set_map(*new_map);
4807 object->set_properties(isolate->heap()->empty_fixed_array());
4808 // Check that it really works.
4809 ASSERT(object->HasFastProperties());
4810 return;
4811 }
4812
4813 // Allocate the instance descriptor.
4814 Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
4815 isolate, instance_descriptor_length);
4816
4817 int number_of_allocated_fields =
4818 number_of_fields + unused_property_fields - inobject_props;
4819 if (number_of_allocated_fields < 0) {
4820 // There is enough inobject space for all fields (including unused).
4821 number_of_allocated_fields = 0;
4822 unused_property_fields = inobject_props - number_of_fields;
4823 }
4824
4825 // Allocate the fixed array for the fields.
4826 Handle<FixedArray> fields = factory->NewFixedArray(
4827 number_of_allocated_fields);
4828
4829 // Fill in the instance descriptor and the fields.
4830 int current_offset = 0;
4831 for (int i = 0; i < capacity; i++) {
4832 Object* k = dictionary->KeyAt(i);
4833 if (dictionary->IsKey(k)) {
4834 Object* value = dictionary->ValueAt(i);
4835 Handle<Name> key;
4836 if (k->IsSymbol()) {
4837 key = handle(Symbol::cast(k));
4838 } else {
4839 // Ensure the key is a unique name before writing into the
4840 // instance descriptor.
4841 key = factory->InternalizeString(handle(String::cast(k)));
4842 }
4843
4844 PropertyDetails details = dictionary->DetailsAt(i);
4845 int enumeration_index = details.dictionary_index();
4846 PropertyType type = details.type();
4847
4848 if (value->IsJSFunction()) {
4849 ConstantDescriptor d(key,
4850 handle(value, isolate),
4851 details.attributes());
4852 descriptors->Set(enumeration_index - 1, &d);
4853 } else if (type == NORMAL) {
4854 if (current_offset < inobject_props) {
4855 object->InObjectPropertyAtPut(current_offset,
4856 value,
4857 UPDATE_WRITE_BARRIER);
4858 } else {
4859 int offset = current_offset - inobject_props;
4860 fields->set(offset, value);
4861 }
4862 FieldDescriptor d(key,
4863 current_offset++,
4864 details.attributes(),
4865 // TODO(verwaest): value->OptimalRepresentation();
4866 Representation::Tagged());
4867 descriptors->Set(enumeration_index - 1, &d);
4868 } else if (type == CALLBACKS) {
4869 CallbacksDescriptor d(key,
4870 handle(value, isolate),
4871 details.attributes());
4872 descriptors->Set(enumeration_index - 1, &d);
4873 } else {
4874 UNREACHABLE();
4875 }
4876 }
4877 }
4878 ASSERT(current_offset == number_of_fields);
4879
4880 descriptors->Sort();
4881
4882 DisallowHeapAllocation no_gc;
4883 new_map->InitializeDescriptors(*descriptors);
4884 new_map->set_unused_property_fields(unused_property_fields);
4885
4886 // Transform the object.
4887 object->set_map(*new_map);
4888
4889 object->set_properties(*fields);
4890 ASSERT(object->IsJSObject());
4891
4892 // Check that it really works.
4893 ASSERT(object->HasFastProperties());
4768 } 4894 }
4769 4895
4770 4896
4771 void JSObject::ResetElements(Handle<JSObject> object) { 4897 void JSObject::ResetElements(Handle<JSObject> object) {
4772 if (object->map()->is_observed()) { 4898 if (object->map()->is_observed()) {
4773 // Maintain invariant that observed elements are always in dictionary mode. 4899 // Maintain invariant that observed elements are always in dictionary mode.
4774 Factory* factory = object->GetIsolate()->factory(); 4900 Factory* factory = object->GetIsolate()->factory();
4775 Handle<SeededNumberDictionary> dictionary = 4901 Handle<SeededNumberDictionary> dictionary =
4776 factory->NewSeededNumberDictionary(0); 4902 factory->NewSeededNumberDictionary(0);
4777 if (object->map() == *factory->sloppy_arguments_elements_map()) { 4903 if (object->map() == *factory->sloppy_arguments_elements_map()) {
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after
6823 if (FLAG_verify_heap && result->is_shared()) { 6949 if (FLAG_verify_heap && result->is_shared()) {
6824 result->SharedMapVerify(); 6950 result->SharedMapVerify();
6825 } 6951 }
6826 #endif 6952 #endif
6827 6953
6828 return result; 6954 return result;
6829 } 6955 }
6830 6956
6831 6957
6832 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { 6958 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
6833 CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map); 6959 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 6960
6842 // Please note instance_type and instance_size are set when allocated. 6961 // Please note instance_type and instance_size are set when allocated.
6843 result->set_inobject_properties(inobject_properties()); 6962 result->set_inobject_properties(map->inobject_properties());
6844 result->set_unused_property_fields(unused_property_fields()); 6963 result->set_unused_property_fields(map->unused_property_fields());
6845 6964
6846 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); 6965 result->set_pre_allocated_property_fields(
6966 map->pre_allocated_property_fields());
6847 result->set_is_shared(false); 6967 result->set_is_shared(false);
6848 result->ClearCodeCache(GetHeap()); 6968 result->ClearCodeCache(map->GetHeap());
6849 NotifyLeafMapLayoutChange(); 6969 map->NotifyLeafMapLayoutChange();
6850 return result; 6970 return result;
6851 } 6971 }
6852 6972
6853 6973
6854 Handle<Map> Map::ShareDescriptor(Handle<Map> map, 6974 Handle<Map> Map::ShareDescriptor(Handle<Map> map,
6855 Handle<DescriptorArray> descriptors, 6975 Handle<DescriptorArray> descriptors,
6856 Descriptor* descriptor) { 6976 Descriptor* descriptor) {
6857 // Sanity check. This path is only to be taken if the map owns its descriptor 6977 // 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 6978 // array, implying that its NumberOfOwnDescriptors equals the number of
6859 // descriptors in the descriptor array. 6979 // descriptors in the descriptor array.
6860 ASSERT(map->NumberOfOwnDescriptors() == 6980 ASSERT(map->NumberOfOwnDescriptors() ==
6861 map->instance_descriptors()->number_of_descriptors()); 6981 map->instance_descriptors()->number_of_descriptors());
6862 6982
6863 Handle<Map> result = Map::CopyDropDescriptors(map); 6983 Handle<Map> result = Map::CopyDropDescriptors(map);
6864 Handle<Name> name = descriptor->GetKey(); 6984 Handle<Name> name = descriptor->GetKey();
6865 Handle<TransitionArray> transitions = 6985 Handle<TransitionArray> transitions =
6866 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); 6986 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION);
6867 6987
6868 // Ensure there's space for the new descriptor in the shared descriptor array. 6988 // Ensure there's space for the new descriptor in the shared descriptor array.
6869 if (descriptors->NumberOfSlackDescriptors() == 0) { 6989 if (descriptors->NumberOfSlackDescriptors() == 0) {
6870 int old_size = descriptors->number_of_descriptors(); 6990 int old_size = descriptors->number_of_descriptors();
6871 if (old_size == 0) { 6991 if (old_size == 0) {
6872 descriptors = map->GetIsolate()->factory()->NewDescriptorArray(0, 1); 6992 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
6873 } else { 6993 } else {
6874 Map::EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); 6994 Map::EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
6875 descriptors = handle(map->instance_descriptors()); 6995 descriptors = handle(map->instance_descriptors());
6876 } 6996 }
6877 } 6997 }
6878 6998
6879 // Commit the state atomically. 6999 // Commit the state atomically.
6880 DisallowHeapAllocation no_gc; 7000 DisallowHeapAllocation no_gc;
6881 7001
6882 descriptors->Append(descriptor); 7002 descriptors->Append(descriptor);
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
7130 int enumeration_index, 7250 int enumeration_index,
7131 PropertyAttributes attributes, 7251 PropertyAttributes attributes,
7132 int slack) { 7252 int slack) {
7133 if (enumeration_index + slack == 0) { 7253 if (enumeration_index + slack == 0) {
7134 return desc->GetIsolate()->factory()->empty_descriptor_array(); 7254 return desc->GetIsolate()->factory()->empty_descriptor_array();
7135 } 7255 }
7136 7256
7137 int size = enumeration_index; 7257 int size = enumeration_index;
7138 7258
7139 Handle<DescriptorArray> descriptors = 7259 Handle<DescriptorArray> descriptors =
7140 desc->GetIsolate()->factory()->NewDescriptorArray(size, slack); 7260 DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
7141 DescriptorArray::WhitenessWitness witness(*descriptors); 7261 DescriptorArray::WhitenessWitness witness(*descriptors);
7142 7262
7143 if (attributes != NONE) { 7263 if (attributes != NONE) {
7144 for (int i = 0; i < size; ++i) { 7264 for (int i = 0; i < size; ++i) {
7145 Object* value = desc->GetValue(i); 7265 Object* value = desc->GetValue(i);
7146 PropertyDetails details = desc->GetDetails(i); 7266 PropertyDetails details = desc->GetDetails(i);
7147 int mask = DONT_DELETE | DONT_ENUM; 7267 int mask = DONT_DELETE | DONT_ENUM;
7148 // READ_ONLY is an invalid attribute for JS setters/getters. 7268 // READ_ONLY is an invalid attribute for JS setters/getters.
7149 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { 7269 if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
7150 mask |= READ_ONLY; 7270 mask |= READ_ONLY;
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
7989 bool FixedArray::IsEqualTo(FixedArray* other) { 8109 bool FixedArray::IsEqualTo(FixedArray* other) {
7990 if (length() != other->length()) return false; 8110 if (length() != other->length()) return false;
7991 for (int i = 0 ; i < length(); ++i) { 8111 for (int i = 0 ; i < length(); ++i) {
7992 if (get(i) != other->get(i)) return false; 8112 if (get(i) != other->get(i)) return false;
7993 } 8113 }
7994 return true; 8114 return true;
7995 } 8115 }
7996 #endif 8116 #endif
7997 8117
7998 8118
7999 MaybeObject* DescriptorArray::Allocate(Isolate* isolate, 8119 Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
8000 int number_of_descriptors, 8120 int number_of_descriptors,
8001 int slack) { 8121 int slack) {
8002 Heap* heap = isolate->heap(); 8122 ASSERT(0 <= number_of_descriptors);
8123 Factory* factory = isolate->factory();
8003 // Do not use DescriptorArray::cast on incomplete object. 8124 // Do not use DescriptorArray::cast on incomplete object.
8004 int size = number_of_descriptors + slack; 8125 int size = number_of_descriptors + slack;
8005 if (size == 0) return heap->empty_descriptor_array(); 8126 if (size == 0) return factory->empty_descriptor_array();
8006 FixedArray* result;
8007 // Allocate the array of keys. 8127 // Allocate the array of keys.
8008 MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size)); 8128 Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size));
8009 if (!maybe_array->To(&result)) return maybe_array;
8010 8129
8011 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors)); 8130 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
8012 result->set(kEnumCacheIndex, Smi::FromInt(0)); 8131 result->set(kEnumCacheIndex, Smi::FromInt(0));
8013 return result; 8132 return Handle<DescriptorArray>::cast(result);
8014 } 8133 }
8015 8134
8016 8135
8017 void DescriptorArray::ClearEnumCache() { 8136 void DescriptorArray::ClearEnumCache() {
8018 set(kEnumCacheIndex, Smi::FromInt(0)); 8137 set(kEnumCacheIndex, Smi::FromInt(0));
8019 } 8138 }
8020 8139
8021 8140
8022 void DescriptorArray::Replace(int index, Descriptor* descriptor) { 8141 void DescriptorArray::Replace(int index, Descriptor* descriptor) {
8023 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index)); 8142 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
8067 int valid, 8186 int valid,
8068 int new_size, 8187 int new_size,
8069 int modify_index, 8188 int modify_index,
8070 StoreMode store_mode, 8189 StoreMode store_mode,
8071 Handle<Map> right_map) { 8190 Handle<Map> right_map) {
8072 ASSERT(verbatim <= valid); 8191 ASSERT(verbatim <= valid);
8073 ASSERT(valid <= new_size); 8192 ASSERT(valid <= new_size);
8074 8193
8075 // Allocate a new descriptor array large enough to hold the required 8194 // Allocate a new descriptor array large enough to hold the required
8076 // descriptors, with minimally the exact same size as this descriptor array. 8195 // descriptors, with minimally the exact same size as this descriptor array.
8077 Factory* factory = left_map->GetIsolate()->factory(); 8196 Isolate* isolate = left_map->GetIsolate();
8078 Handle<DescriptorArray> left(left_map->instance_descriptors()); 8197 Handle<DescriptorArray> left(left_map->instance_descriptors());
8079 Handle<DescriptorArray> right(right_map->instance_descriptors()); 8198 Handle<DescriptorArray> right(right_map->instance_descriptors());
8080 Handle<DescriptorArray> result = factory->NewDescriptorArray( 8199 Handle<DescriptorArray> result = DescriptorArray::Allocate(
8081 new_size, Max(new_size, right->number_of_descriptors()) - new_size); 8200 isolate,
8201 new_size,
8202 Max(new_size, right->number_of_descriptors()) - new_size);
8082 ASSERT(result->length() > left->length() || 8203 ASSERT(result->length() > left->length() ||
8083 result->NumberOfSlackDescriptors() > 0 || 8204 result->NumberOfSlackDescriptors() > 0 ||
8084 result->number_of_descriptors() == right->number_of_descriptors()); 8205 result->number_of_descriptors() == right->number_of_descriptors());
8085 ASSERT(result->number_of_descriptors() == new_size); 8206 ASSERT(result->number_of_descriptors() == new_size);
8086 8207
8087 int descriptor; 8208 int descriptor;
8088 8209
8089 // 0 -> |verbatim| 8210 // 0 -> |verbatim|
8090 int current_offset = 0; 8211 int current_offset = 0;
8091 for (descriptor = 0; descriptor < verbatim; descriptor++) { 8212 for (descriptor = 0; descriptor < verbatim; descriptor++) {
(...skipping 3410 matching lines...) Expand 10 before | Expand all | Expand 10 after
11502 int capacity = (cache->length() - header) / step; 11623 int capacity = (cache->length() - header) / step;
11503 int transitions = map->NumberOfProtoTransitions() + 1; 11624 int transitions = map->NumberOfProtoTransitions() + 1;
11504 11625
11505 if (transitions > capacity) { 11626 if (transitions > capacity) {
11506 if (capacity > kMaxCachedPrototypeTransitions) return map; 11627 if (capacity > kMaxCachedPrototypeTransitions) return map;
11507 11628
11508 // Grow array by factor 2 over and above what we need. 11629 // Grow array by factor 2 over and above what we need.
11509 Factory* factory = map->GetIsolate()->factory(); 11630 Factory* factory = map->GetIsolate()->factory();
11510 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header); 11631 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header);
11511 11632
11512 CALL_AND_RETRY_OR_DIE(map->GetIsolate(), 11633 Map::SetPrototypeTransitions(map, cache);
11513 map->SetPrototypeTransitions(*cache),
11514 break,
11515 return Handle<Map>());
11516 } 11634 }
11517 11635
11518 // Reload number of transitions as GC might shrink them. 11636 // Reload number of transitions as GC might shrink them.
11519 int last = map->NumberOfProtoTransitions(); 11637 int last = map->NumberOfProtoTransitions();
11520 int entry = header + last * step; 11638 int entry = header + last * step;
11521 11639
11522 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); 11640 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype);
11523 cache->set(entry + kProtoTransitionMapOffset, *target_map); 11641 cache->set(entry + kProtoTransitionMapOffset, *target_map);
11524 map->SetNumberOfProtoTransitions(last + 1); 11642 map->SetNumberOfProtoTransitions(last + 1);
11525 11643
(...skipping 4058 matching lines...) Expand 10 before | Expand all | Expand 10 after
15584 e = PropertyCell::cast(e)->value(); 15702 e = PropertyCell::cast(e)->value();
15585 } 15703 }
15586 if (e == value) return k; 15704 if (e == value) return k;
15587 } 15705 }
15588 } 15706 }
15589 Heap* heap = Dictionary<Shape, Key>::GetHeap(); 15707 Heap* heap = Dictionary<Shape, Key>::GetHeap();
15590 return heap->undefined_value(); 15708 return heap->undefined_value();
15591 } 15709 }
15592 15710
15593 15711
15594 MaybeObject* NameDictionary::TransformPropertiesToFastFor(
15595 JSObject* obj, int unused_property_fields) {
15596 // Make sure we preserve dictionary representation if there are too many
15597 // descriptors.
15598 int number_of_elements = NumberOfElements();
15599 if (number_of_elements > kMaxNumberOfDescriptors) return obj;
15600
15601 if (number_of_elements != NextEnumerationIndex()) {
15602 MaybeObject* maybe_result = GenerateNewEnumerationIndices();
15603 if (maybe_result->IsFailure()) return maybe_result;
15604 }
15605
15606 int instance_descriptor_length = 0;
15607 int number_of_fields = 0;
15608
15609 Heap* heap = GetHeap();
15610
15611 // Compute the length of the instance descriptor.
15612 int capacity = Capacity();
15613 for (int i = 0; i < capacity; i++) {
15614 Object* k = KeyAt(i);
15615 if (IsKey(k)) {
15616 Object* value = ValueAt(i);
15617 PropertyType type = DetailsAt(i).type();
15618 ASSERT(type != FIELD);
15619 instance_descriptor_length++;
15620 if (type == NORMAL && !value->IsJSFunction()) {
15621 number_of_fields += 1;
15622 }
15623 }
15624 }
15625
15626 int inobject_props = obj->map()->inobject_properties();
15627
15628 // Allocate new map.
15629 Map* new_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);
15633
15634 if (instance_descriptor_length == 0) {
15635 ASSERT_LE(unused_property_fields, inobject_props);
15636 // Transform the object.
15637 new_map->set_unused_property_fields(inobject_props);
15638 obj->set_map(new_map);
15639 obj->set_properties(heap->empty_fixed_array());
15640 // Check that it really works.
15641 ASSERT(obj->HasFastProperties());
15642 return obj;
15643 }
15644
15645 // Allocate the instance descriptor.
15646 DescriptorArray* descriptors;
15647 MaybeObject* maybe_descriptors =
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
15655 int number_of_allocated_fields =
15656 number_of_fields + unused_property_fields - inobject_props;
15657 if (number_of_allocated_fields < 0) {
15658 // There is enough inobject space for all fields (including unused).
15659 number_of_allocated_fields = 0;
15660 unused_property_fields = inobject_props - number_of_fields;
15661 }
15662
15663 // Allocate the fixed array for the fields.
15664 FixedArray* fields;
15665 MaybeObject* maybe_fields =
15666 heap->AllocateFixedArray(number_of_allocated_fields);
15667 if (!maybe_fields->To(&fields)) return maybe_fields;
15668
15669 // Fill in the instance descriptor and the fields.
15670 int current_offset = 0;
15671 for (int i = 0; i < capacity; i++) {
15672 Object* k = KeyAt(i);
15673 if (IsKey(k)) {
15674 Object* value = ValueAt(i);
15675 Name* key;
15676 if (k->IsSymbol()) {
15677 key = Symbol::cast(k);
15678 } else {
15679 // Ensure the key is a unique name before writing into the
15680 // instance descriptor.
15681 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
15682 if (!maybe_key->To(&key)) return maybe_key;
15683 }
15684
15685 PropertyDetails details = DetailsAt(i);
15686 int enumeration_index = details.dictionary_index();
15687 PropertyType type = details.type();
15688
15689 if (value->IsJSFunction()) {
15690 ConstantDescriptor d(handle(key),
15691 handle(value, GetIsolate()),
15692 details.attributes());
15693 descriptors->Set(enumeration_index - 1, &d, witness);
15694 } else if (type == NORMAL) {
15695 if (current_offset < inobject_props) {
15696 obj->InObjectPropertyAtPut(current_offset,
15697 value,
15698 UPDATE_WRITE_BARRIER);
15699 } else {
15700 int offset = current_offset - inobject_props;
15701 fields->set(offset, value);
15702 }
15703 FieldDescriptor d(handle(key),
15704 current_offset++,
15705 details.attributes(),
15706 // TODO(verwaest): value->OptimalRepresentation();
15707 Representation::Tagged());
15708 descriptors->Set(enumeration_index - 1, &d, witness);
15709 } else if (type == CALLBACKS) {
15710 CallbacksDescriptor d(handle(key),
15711 handle(value, GetIsolate()),
15712 details.attributes());
15713 descriptors->Set(enumeration_index - 1, &d, witness);
15714 } else {
15715 UNREACHABLE();
15716 }
15717 }
15718 }
15719 ASSERT(current_offset == number_of_fields);
15720
15721 descriptors->Sort();
15722
15723 new_map->InitializeDescriptors(descriptors);
15724 new_map->set_unused_property_fields(unused_property_fields);
15725
15726 // Transform the object.
15727 obj->set_map(new_map);
15728
15729 obj->set_properties(fields);
15730 ASSERT(obj->IsJSObject());
15731
15732 // Check that it really works.
15733 ASSERT(obj->HasFastProperties());
15734
15735 return obj;
15736 }
15737
15738
15739 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( 15712 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity(
15740 Handle<ObjectHashTable> table, 15713 Handle<ObjectHashTable> table,
15741 int n, 15714 int n,
15742 Handle<Object> key, 15715 Handle<Object> key,
15743 PretenureFlag pretenure) { 15716 PretenureFlag pretenure) {
15744 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; 15717 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table;
15745 CALL_HEAP_FUNCTION(table_base->GetIsolate(), 15718 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15746 table_base->EnsureCapacity(n, *key, pretenure), 15719 table_base->EnsureCapacity(n, *key, pretenure),
15747 ObjectHashTable); 15720 ObjectHashTable);
15748 } 15721 }
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
16629 #define ERROR_MESSAGES_TEXTS(C, T) T, 16602 #define ERROR_MESSAGES_TEXTS(C, T) T,
16630 static const char* error_messages_[] = { 16603 static const char* error_messages_[] = {
16631 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16604 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16632 }; 16605 };
16633 #undef ERROR_MESSAGES_TEXTS 16606 #undef ERROR_MESSAGES_TEXTS
16634 return error_messages_[reason]; 16607 return error_messages_[reason];
16635 } 16608 }
16636 16609
16637 16610
16638 } } // namespace v8::internal 16611 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698