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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 return line; | 544 return line; |
545 } | 545 } |
546 | 546 |
547 | 547 |
548 void CustomArguments::IterateInstance(ObjectVisitor* v) { | 548 void CustomArguments::IterateInstance(ObjectVisitor* v) { |
549 v->VisitPointers(values_, values_ + ARRAY_SIZE(values_)); | 549 v->VisitPointers(values_, values_ + ARRAY_SIZE(values_)); |
550 } | 550 } |
551 | 551 |
552 | 552 |
553 // Compute the property keys from the interceptor. | 553 // Compute the property keys from the interceptor. |
| 554 // TODO(rossberg): support symbols in API, and filter here if needed. |
554 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSReceiver> receiver, | 555 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSReceiver> receiver, |
555 Handle<JSObject> object) { | 556 Handle<JSObject> object) { |
556 Isolate* isolate = receiver->GetIsolate(); | 557 Isolate* isolate = receiver->GetIsolate(); |
557 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 558 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
558 CustomArguments args(isolate, interceptor->data(), *receiver, *object); | 559 CustomArguments args(isolate, interceptor->data(), *receiver, *object); |
559 v8::AccessorInfo info(args.end()); | 560 v8::AccessorInfo info(args.end()); |
560 v8::Handle<v8::Array> result; | 561 v8::Handle<v8::Array> result; |
561 if (!interceptor->enumerator()->IsUndefined()) { | 562 if (!interceptor->enumerator()->IsUndefined()) { |
562 v8::NamedPropertyEnumerator enum_fun = | 563 v8::NamedPropertyEnumerator enum_fun = |
563 v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator()); | 564 v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 result = isolate->factory()->undefined_value(); | 619 result = isolate->factory()->undefined_value(); |
619 } | 620 } |
620 return result; | 621 return result; |
621 } | 622 } |
622 | 623 |
623 | 624 |
624 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 625 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
625 int len = array->length(); | 626 int len = array->length(); |
626 for (int i = 0; i < len; i++) { | 627 for (int i = 0; i < len; i++) { |
627 Object* e = array->get(i); | 628 Object* e = array->get(i); |
628 if (!(e->IsName() || e->IsNumber())) return false; | 629 if (!(e->IsString() || e->IsNumber())) return false; |
629 } | 630 } |
630 return true; | 631 return true; |
631 } | 632 } |
632 | 633 |
633 | 634 |
634 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object, | 635 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object, |
635 KeyCollectionType type, | 636 KeyCollectionType type, |
636 bool* threw) { | 637 bool* threw) { |
637 USE(ContainsOnlyValidKeys); | 638 USE(ContainsOnlyValidKeys); |
638 Isolate* isolate = object->GetIsolate(); | 639 Isolate* isolate = object->GetIsolate(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, | 748 Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
748 bool cache_result) { | 749 bool cache_result) { |
749 Isolate* isolate = object->GetIsolate(); | 750 Isolate* isolate = object->GetIsolate(); |
750 if (object->HasFastProperties()) { | 751 if (object->HasFastProperties()) { |
751 if (object->map()->instance_descriptors()->HasEnumCache()) { | 752 if (object->map()->instance_descriptors()->HasEnumCache()) { |
752 int own_property_count = object->map()->EnumLength(); | 753 int own_property_count = object->map()->EnumLength(); |
753 // If we have an enum cache, but the enum length of the given map is set | 754 // If we have an enum cache, but the enum length of the given map is set |
754 // to kInvalidEnumCache, this means that the map itself has never used the | 755 // to kInvalidEnumCache, this means that the map itself has never used the |
755 // present enum cache. The first step to using the cache is to set the | 756 // present enum cache. The first step to using the cache is to set the |
756 // enum length of the map by counting the number of own descriptors that | 757 // enum length of the map by counting the number of own descriptors that |
757 // are not DONT_ENUM. | 758 // are not DONT_ENUM or SYMBOLIC. |
758 if (own_property_count == Map::kInvalidEnumCache) { | 759 if (own_property_count == Map::kInvalidEnumCache) { |
759 own_property_count = object->map()->NumberOfDescribedProperties( | 760 own_property_count = object->map()->NumberOfDescribedProperties( |
760 OWN_DESCRIPTORS, DONT_ENUM); | 761 OWN_DESCRIPTORS, DONT_SHOW); |
761 | 762 |
762 if (cache_result) object->map()->SetEnumLength(own_property_count); | 763 if (cache_result) object->map()->SetEnumLength(own_property_count); |
763 } | 764 } |
764 | 765 |
765 DescriptorArray* desc = object->map()->instance_descriptors(); | 766 DescriptorArray* desc = object->map()->instance_descriptors(); |
766 Handle<FixedArray> keys(desc->GetEnumCache(), isolate); | 767 Handle<FixedArray> keys(desc->GetEnumCache(), isolate); |
767 | 768 |
768 // In case the number of properties required in the enum are actually | 769 // In case the number of properties required in the enum are actually |
769 // present, we can reuse the enum cache. Otherwise, this means that the | 770 // present, we can reuse the enum cache. Otherwise, this means that the |
770 // enum cache was generated for a previous (smaller) version of the | 771 // enum cache was generated for a previous (smaller) version of the |
771 // Descriptor Array. In that case we regenerate the enum cache. | 772 // Descriptor Array. In that case we regenerate the enum cache. |
772 if (own_property_count <= keys->length()) { | 773 if (own_property_count <= keys->length()) { |
773 isolate->counters()->enum_cache_hits()->Increment(); | 774 isolate->counters()->enum_cache_hits()->Increment(); |
774 return ReduceFixedArrayTo(keys, own_property_count); | 775 return ReduceFixedArrayTo(keys, own_property_count); |
775 } | 776 } |
776 } | 777 } |
777 | 778 |
778 Handle<Map> map(object->map()); | 779 Handle<Map> map(object->map()); |
779 | 780 |
780 if (map->instance_descriptors()->IsEmpty()) { | 781 if (map->instance_descriptors()->IsEmpty()) { |
781 isolate->counters()->enum_cache_hits()->Increment(); | 782 isolate->counters()->enum_cache_hits()->Increment(); |
782 if (cache_result) map->SetEnumLength(0); | 783 if (cache_result) map->SetEnumLength(0); |
783 return isolate->factory()->empty_fixed_array(); | 784 return isolate->factory()->empty_fixed_array(); |
784 } | 785 } |
785 | 786 |
786 isolate->counters()->enum_cache_misses()->Increment(); | 787 isolate->counters()->enum_cache_misses()->Increment(); |
787 int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_ENUM); | 788 int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_SHOW); |
788 | 789 |
789 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum); | 790 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum); |
790 Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum); | 791 Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum); |
791 | 792 |
792 Handle<DescriptorArray> descs = | 793 Handle<DescriptorArray> descs = |
793 Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate); | 794 Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate); |
794 | 795 |
795 int real_size = map->NumberOfOwnDescriptors(); | 796 int real_size = map->NumberOfOwnDescriptors(); |
796 int enum_size = 0; | 797 int enum_size = 0; |
797 int index = 0; | 798 int index = 0; |
798 | 799 |
799 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 800 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
800 PropertyDetails details = descs->GetDetails(i); | 801 PropertyDetails details = descs->GetDetails(i); |
801 if (!details.IsDontEnum()) { | 802 Object* key = descs->GetKey(i); |
| 803 if (!(details.IsDontEnum() || key->IsSymbol())) { |
802 if (i < real_size) ++enum_size; | 804 if (i < real_size) ++enum_size; |
803 storage->set(index, descs->GetKey(i)); | 805 storage->set(index, key); |
804 if (!indices.is_null()) { | 806 if (!indices.is_null()) { |
805 if (details.type() != FIELD) { | 807 if (details.type() != FIELD) { |
806 indices = Handle<FixedArray>(); | 808 indices = Handle<FixedArray>(); |
807 } else { | 809 } else { |
808 int field_index = Descriptor::IndexFromValue(descs->GetValue(i)); | 810 int field_index = Descriptor::IndexFromValue(descs->GetValue(i)); |
809 if (field_index >= map->inobject_properties()) { | 811 if (field_index >= map->inobject_properties()) { |
810 field_index = -(field_index - map->inobject_properties() + 1); | 812 field_index = -(field_index - map->inobject_properties() + 1); |
811 } | 813 } |
812 indices->set(index, Smi::FromInt(field_index)); | 814 indices->set(index, Smi::FromInt(field_index)); |
813 } | 815 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 int next_enumeration = dictionary->NextEnumerationIndex(); | 855 int next_enumeration = dictionary->NextEnumerationIndex(); |
854 if (!object->IsGlobalObject() && next_enumeration > (length * 3) / 2) { | 856 if (!object->IsGlobalObject() && next_enumeration > (length * 3) / 2) { |
855 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); | 857 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); |
856 next_enumeration = dictionary->NextEnumerationIndex(); | 858 next_enumeration = dictionary->NextEnumerationIndex(); |
857 } | 859 } |
858 | 860 |
859 Handle<FixedArray> storage = | 861 Handle<FixedArray> storage = |
860 isolate->factory()->NewFixedArray(next_enumeration); | 862 isolate->factory()->NewFixedArray(next_enumeration); |
861 | 863 |
862 storage = Handle<FixedArray>(dictionary->CopyEnumKeysTo(*storage)); | 864 storage = Handle<FixedArray>(dictionary->CopyEnumKeysTo(*storage)); |
863 ASSERT(storage->length() == object->NumberOfLocalProperties(DONT_ENUM)); | 865 ASSERT(storage->length() == object->NumberOfLocalProperties(DONT_SHOW)); |
864 return storage; | 866 return storage; |
865 } | 867 } |
866 } | 868 } |
867 | 869 |
868 | 870 |
869 Handle<ObjectHashSet> ObjectHashSetAdd(Handle<ObjectHashSet> table, | 871 Handle<ObjectHashSet> ObjectHashSetAdd(Handle<ObjectHashSet> table, |
870 Handle<Object> key) { | 872 Handle<Object> key) { |
871 CALL_HEAP_FUNCTION(table->GetIsolate(), | 873 CALL_HEAP_FUNCTION(table->GetIsolate(), |
872 table->Add(*key), | 874 table->Add(*key), |
873 ObjectHashSet); | 875 ObjectHashSet); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 data->next = prev_next_; | 928 data->next = prev_next_; |
927 data->limit = prev_limit_; | 929 data->limit = prev_limit_; |
928 #ifdef DEBUG | 930 #ifdef DEBUG |
929 handles_detached_ = true; | 931 handles_detached_ = true; |
930 #endif | 932 #endif |
931 return deferred; | 933 return deferred; |
932 } | 934 } |
933 | 935 |
934 | 936 |
935 } } // namespace v8::internal | 937 } } // namespace v8::internal |
OLD | NEW |