OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2643 SKIP_WRITE_BARRIER); | 2643 SKIP_WRITE_BARRIER); |
2644 | 2644 |
2645 // Check the state of the object | 2645 // Check the state of the object |
2646 ASSERT(JSObject::cast(result)->HasFastProperties()); | 2646 ASSERT(JSObject::cast(result)->HasFastProperties()); |
2647 ASSERT(JSObject::cast(result)->HasFastElements()); | 2647 ASSERT(JSObject::cast(result)->HasFastElements()); |
2648 | 2648 |
2649 return result; | 2649 return result; |
2650 } | 2650 } |
2651 | 2651 |
2652 | 2652 |
2653 static bool HasDuplicates(DescriptorArray* descriptors) { | |
2654 int count = descriptors->number_of_descriptors(); | |
2655 if (count > 1) { | |
2656 String* prev_key = descriptors->GetKey(0); | |
2657 for (int i = 1; i != count; i++) { | |
2658 String* current_key = descriptors->GetKey(i); | |
2659 if (prev_key == current_key) return true; | |
2660 prev_key = current_key; | |
2661 } | |
2662 } | |
2663 return false; | |
2664 } | |
2665 | |
2666 | |
2653 Object* Heap::AllocateInitialMap(JSFunction* fun) { | 2667 Object* Heap::AllocateInitialMap(JSFunction* fun) { |
2654 ASSERT(!fun->has_initial_map()); | 2668 ASSERT(!fun->has_initial_map()); |
2655 | 2669 |
2656 // First create a new map with the size and number of in-object properties | 2670 // First create a new map with the size and number of in-object properties |
2657 // suggested by the function. | 2671 // suggested by the function. |
2658 int instance_size = fun->shared()->CalculateInstanceSize(); | 2672 int instance_size = fun->shared()->CalculateInstanceSize(); |
2659 int in_object_properties = fun->shared()->CalculateInObjectProperties(); | 2673 int in_object_properties = fun->shared()->CalculateInObjectProperties(); |
2660 Object* map_obj = Heap::AllocateMap(JS_OBJECT_TYPE, instance_size); | 2674 Object* map_obj = Heap::AllocateMap(JS_OBJECT_TYPE, instance_size); |
2661 if (map_obj->IsFailure()) return map_obj; | 2675 if (map_obj->IsFailure()) return map_obj; |
2662 | 2676 |
(...skipping 13 matching lines...) Expand all Loading... | |
2676 | 2690 |
2677 // If the function has only simple this property assignments add | 2691 // If the function has only simple this property assignments add |
2678 // field descriptors for these to the initial map as the object | 2692 // field descriptors for these to the initial map as the object |
2679 // cannot be constructed without having these properties. Guard by | 2693 // cannot be constructed without having these properties. Guard by |
2680 // the inline_new flag so we only change the map if we generate a | 2694 // the inline_new flag so we only change the map if we generate a |
2681 // specialized construct stub. | 2695 // specialized construct stub. |
2682 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); | 2696 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); |
2683 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { | 2697 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { |
2684 int count = fun->shared()->this_property_assignments_count(); | 2698 int count = fun->shared()->this_property_assignments_count(); |
2685 if (count > in_object_properties) { | 2699 if (count > in_object_properties) { |
2686 count = in_object_properties; | 2700 // Inline constructor can only handle inobject properties. |
2701 fun->shared()->ForbidInlineConstructor(); | |
2702 } else { | |
2703 Object* descriptors_obj = DescriptorArray::Allocate(count); | |
2704 if (descriptors_obj->IsFailure()) return descriptors_obj; | |
2705 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_obj); | |
2706 for (int i = 0; i < count; i++) { | |
2707 String* name = fun->shared()->GetThisPropertyAssignmentName(i); | |
2708 ASSERT(name->IsSymbol()); | |
2709 FieldDescriptor field(name, i, NONE); | |
2710 field.SetEnumerationIndex(i); | |
2711 descriptors->Set(i, &field); | |
2712 } | |
2713 descriptors->SetNextEnumerationIndex(count); | |
2714 descriptors->SortUnchecked(); | |
2715 | |
2716 // The descriptors may contain duplicates because the compiler does not | |
2717 // guarantee the uniqueness of property names (it would have required | |
Søren Thygesen Gjesse
2010/09/16 06:43:41
We could do the sorting and checking for duplicate
Vladislav Kaznacheev
2010/09/16 10:50:21
I have considered this and decided against it. If
| |
2718 // quadratic time). Once the descriptors are sorted we can check for | |
2719 // duplicates in linear time. | |
2720 if (HasDuplicates(descriptors)) { | |
2721 fun->shared()->ForbidInlineConstructor(); | |
2722 } else { | |
2723 map->set_instance_descriptors(descriptors); | |
2724 map->set_pre_allocated_property_fields(count); | |
2725 map->set_unused_property_fields(in_object_properties - count); | |
2726 } | |
2687 } | 2727 } |
2688 Object* descriptors_obj = DescriptorArray::Allocate(count); | |
2689 if (descriptors_obj->IsFailure()) return descriptors_obj; | |
2690 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_obj); | |
2691 for (int i = 0; i < count; i++) { | |
2692 String* name = fun->shared()->GetThisPropertyAssignmentName(i); | |
2693 ASSERT(name->IsSymbol()); | |
2694 FieldDescriptor field(name, i, NONE); | |
2695 field.SetEnumerationIndex(i); | |
2696 descriptors->Set(i, &field); | |
2697 } | |
2698 descriptors->SetNextEnumerationIndex(count); | |
2699 descriptors->Sort(); | |
2700 map->set_instance_descriptors(descriptors); | |
2701 map->set_pre_allocated_property_fields(count); | |
2702 map->set_unused_property_fields(in_object_properties - count); | |
2703 } | 2728 } |
2704 return map; | 2729 return map; |
2705 } | 2730 } |
2706 | 2731 |
2707 | 2732 |
2708 void Heap::InitializeJSObjectFromMap(JSObject* obj, | 2733 void Heap::InitializeJSObjectFromMap(JSObject* obj, |
2709 FixedArray* properties, | 2734 FixedArray* properties, |
2710 Map* map) { | 2735 Map* map) { |
2711 obj->set_properties(properties); | 2736 obj->set_properties(properties); |
2712 obj->initialize_elements(); | 2737 obj->initialize_elements(); |
(...skipping 2216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4929 void ExternalStringTable::TearDown() { | 4954 void ExternalStringTable::TearDown() { |
4930 new_space_strings_.Free(); | 4955 new_space_strings_.Free(); |
4931 old_space_strings_.Free(); | 4956 old_space_strings_.Free(); |
4932 } | 4957 } |
4933 | 4958 |
4934 | 4959 |
4935 List<Object*> ExternalStringTable::new_space_strings_; | 4960 List<Object*> ExternalStringTable::new_space_strings_; |
4936 List<Object*> ExternalStringTable::old_space_strings_; | 4961 List<Object*> ExternalStringTable::old_space_strings_; |
4937 | 4962 |
4938 } } // namespace v8::internal | 4963 } } // namespace v8::internal |
OLD | NEW |