OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 uint32_t end) final { | 511 uint32_t end) final { |
512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, | 512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, |
513 end); | 513 end); |
514 } | 514 } |
515 | 515 |
516 static bool IsPackedImpl(Handle<JSObject> holder, | 516 static bool IsPackedImpl(Handle<JSObject> holder, |
517 Handle<FixedArrayBase> backing_store, uint32_t start, | 517 Handle<FixedArrayBase> backing_store, uint32_t start, |
518 uint32_t end) { | 518 uint32_t end) { |
519 if (IsFastPackedElementsKind(kind())) return true; | 519 if (IsFastPackedElementsKind(kind())) return true; |
520 for (uint32_t i = start; i < end; i++) { | 520 for (uint32_t i = start; i < end; i++) { |
521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store)) { | 521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store, |
| 522 NONE)) { |
522 return false; | 523 return false; |
523 } | 524 } |
524 } | 525 } |
525 return true; | 526 return true; |
526 } | 527 } |
527 | 528 |
528 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { | 529 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { |
529 if (!IsHoleyElementsKind(kind())) return; | 530 if (!IsHoleyElementsKind(kind())) return; |
530 int length = Smi::cast(array->length())->value(); | 531 int length = Smi::cast(array->length())->value(); |
531 Handle<FixedArrayBase> backing_store(array->elements()); | 532 Handle<FixedArrayBase> backing_store(array->elements()); |
532 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, | 533 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, |
533 length)) { | 534 length)) { |
534 return; | 535 return; |
535 } | 536 } |
536 ElementsKind packed_kind = GetPackedElementsKind(kind()); | 537 ElementsKind packed_kind = GetPackedElementsKind(kind()); |
537 Handle<Map> new_map = | 538 Handle<Map> new_map = |
538 JSObject::GetElementsTransitionMap(array, packed_kind); | 539 JSObject::GetElementsTransitionMap(array, packed_kind); |
539 JSObject::MigrateToMap(array, new_map); | 540 JSObject::MigrateToMap(array, new_map); |
540 if (FLAG_trace_elements_transitions) { | 541 if (FLAG_trace_elements_transitions) { |
541 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, | 542 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, |
542 packed_kind, backing_store); | 543 packed_kind, backing_store); |
543 } | 544 } |
544 } | 545 } |
545 | 546 |
546 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, | 547 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, |
547 Handle<FixedArrayBase> backing_store) final { | 548 Handle<FixedArrayBase> backing_store, |
| 549 PropertyAttributes filter) final { |
548 return ElementsAccessorSubclass::HasElementImpl(holder, index, | 550 return ElementsAccessorSubclass::HasElementImpl(holder, index, |
549 backing_store); | 551 backing_store, filter); |
550 } | 552 } |
551 | 553 |
552 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, | 554 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, |
553 Handle<FixedArrayBase> backing_store) { | 555 Handle<FixedArrayBase> backing_store, |
| 556 PropertyAttributes filter) { |
554 return ElementsAccessorSubclass::GetEntryForIndexImpl( | 557 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
555 *holder, *backing_store, index) != kMaxUInt32; | 558 *holder, *backing_store, index, filter) != kMaxUInt32; |
556 } | 559 } |
557 | 560 |
558 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store, | 561 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store, |
559 uint32_t entry) final { | 562 uint32_t entry) final { |
560 return ElementsAccessorSubclass::GetImpl(backing_store, entry); | 563 return ElementsAccessorSubclass::GetImpl(backing_store, entry); |
561 } | 564 } |
562 | 565 |
563 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, | 566 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, |
564 uint32_t entry) { | 567 uint32_t entry) { |
565 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 568 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 // intentionally to avoid ArrayConcat() builtin performance degradation. | 864 // intentionally to avoid ArrayConcat() builtin performance degradation. |
862 // | 865 // |
863 // Details: The idea is that allocations actually happen only in case of | 866 // Details: The idea is that allocations actually happen only in case of |
864 // copying from object with fast double elements to object with object | 867 // copying from object with fast double elements to object with object |
865 // elements. In all the other cases there are no allocations performed and | 868 // elements. In all the other cases there are no allocations performed and |
866 // handle creation causes noticeable performance degradation of the builtin. | 869 // handle creation causes noticeable performance degradation of the builtin. |
867 ElementsAccessorSubclass::CopyElementsImpl( | 870 ElementsAccessorSubclass::CopyElementsImpl( |
868 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 871 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
869 } | 872 } |
870 | 873 |
| 874 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 875 Handle<FixedArrayBase> backing_store, |
| 876 KeyAccumulator* keys, uint32_t range, |
| 877 PropertyAttributes filter, |
| 878 uint32_t offset) { |
| 879 uint32_t length = 0; |
| 880 if (object->IsJSArray()) { |
| 881 length = Smi::cast(JSArray::cast(*object)->length())->value(); |
| 882 } else { |
| 883 length = |
| 884 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
| 885 } |
| 886 if (range < length) length = range; |
| 887 for (uint32_t i = offset; i < length; i++) { |
| 888 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
| 889 filter)) |
| 890 continue; |
| 891 keys->AddKey(i); |
| 892 } |
| 893 } |
| 894 |
| 895 virtual void CollectElementIndices(Handle<JSObject> object, |
| 896 Handle<FixedArrayBase> backing_store, |
| 897 KeyAccumulator* keys, uint32_t range, |
| 898 PropertyAttributes filter, |
| 899 uint32_t offset) final { |
| 900 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 901 object, backing_store, keys, range, filter, offset); |
| 902 }; |
| 903 |
871 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 904 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
872 KeyAccumulator* accumulator, | 905 KeyAccumulator* accumulator, |
873 KeyFilter filter) final { | 906 AddKeyConversion convert) final { |
874 Handle<FixedArrayBase> from(receiver->elements()); | 907 Handle<FixedArrayBase> from(receiver->elements()); |
875 uint32_t add_length = | 908 uint32_t add_length = |
876 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); | 909 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); |
877 if (add_length == 0) return; | 910 if (add_length == 0) return; |
878 accumulator->PrepareForComparisons(add_length); | 911 |
879 int prev_key_count = accumulator->GetLength(); | |
880 for (uint32_t i = 0; i < add_length; i++) { | 912 for (uint32_t i = 0; i < add_length; i++) { |
881 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue; | 913 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue; |
882 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i); | 914 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i); |
883 DCHECK(!value->IsTheHole()); | 915 DCHECK(!value->IsTheHole()); |
884 DCHECK(!value->IsAccessorPair()); | 916 DCHECK(!value->IsAccessorPair()); |
885 DCHECK(!value->IsExecutableAccessorInfo()); | 917 DCHECK(!value->IsExecutableAccessorInfo()); |
886 if (filter == SKIP_SYMBOLS && value->IsSymbol()) { | 918 accumulator->AddKey(value, convert); |
887 continue; | |
888 } | |
889 accumulator->AddKey(value, prev_key_count); | |
890 } | 919 } |
891 } | 920 } |
892 | 921 |
893 static uint32_t GetCapacityImpl(JSObject* holder, | 922 static uint32_t GetCapacityImpl(JSObject* holder, |
894 FixedArrayBase* backing_store) { | 923 FixedArrayBase* backing_store) { |
895 return backing_store->length(); | 924 return backing_store->length(); |
896 } | 925 } |
897 | 926 |
898 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { | 927 virtual uint32_t GetCapacity(JSObject* holder, |
| 928 FixedArrayBase* backing_store) final { |
899 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); | 929 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); |
900 } | 930 } |
901 | 931 |
902 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 932 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
903 return true; | 933 return true; |
904 } | 934 } |
905 | 935 |
906 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 936 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
907 uint32_t entry) { | 937 uint32_t entry) { |
908 return entry; | 938 return entry; |
909 } | 939 } |
910 | 940 |
911 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 941 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
912 FixedArrayBase* backing_store, | 942 FixedArrayBase* backing_store, |
913 uint32_t index) { | 943 uint32_t index, |
| 944 PropertyAttributes filter) { |
914 if (IsHoleyElementsKind(kind())) { | 945 if (IsHoleyElementsKind(kind())) { |
915 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, | 946 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, |
916 backing_store) && | 947 backing_store) && |
917 !BackingStore::cast(backing_store)->is_the_hole(index) | 948 !BackingStore::cast(backing_store)->is_the_hole(index) |
918 ? index | 949 ? index |
919 : kMaxUInt32; | 950 : kMaxUInt32; |
920 } else { | 951 } else { |
921 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length()); | 952 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length()); |
922 uint32_t length = static_cast<uint32_t>(smi_length->value()); | 953 uint32_t length = static_cast<uint32_t>(smi_length->value()); |
923 return index < length ? index : kMaxUInt32; | 954 return index < length ? index : kMaxUInt32; |
924 } | 955 } |
925 } | 956 } |
926 | 957 |
927 virtual uint32_t GetEntryForIndex(JSObject* holder, | 958 virtual uint32_t GetEntryForIndex(JSObject* holder, |
928 FixedArrayBase* backing_store, | 959 FixedArrayBase* backing_store, |
929 uint32_t index) final { | 960 uint32_t index) final { |
930 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, | 961 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, |
931 index); | 962 index, NONE); |
932 } | 963 } |
933 | 964 |
934 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 965 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
935 uint32_t entry) { | 966 uint32_t entry) { |
936 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 967 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
937 } | 968 } |
938 | 969 |
939 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, | 970 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, |
940 uint32_t entry) final { | 971 uint32_t entry) final { |
941 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); | 972 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 | 1114 |
1084 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1115 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
1085 DisallowHeapAllocation no_gc; | 1116 DisallowHeapAllocation no_gc; |
1086 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1117 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1087 uint32_t result = 0; | 1118 uint32_t result = 0; |
1088 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); | 1119 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); |
1089 return result; | 1120 return result; |
1090 } | 1121 } |
1091 | 1122 |
1092 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, | 1123 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, |
1093 uint32_t index) { | 1124 uint32_t index, |
| 1125 PropertyAttributes filter) { |
1094 DisallowHeapAllocation no_gc; | 1126 DisallowHeapAllocation no_gc; |
1095 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1127 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
1096 int entry = dict->FindEntry(index); | 1128 int entry = dictionary->FindEntry(index); |
1097 return entry == SeededNumberDictionary::kNotFound | 1129 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; |
1098 ? kMaxUInt32 | 1130 if (filter != NONE) { |
1099 : static_cast<uint32_t>(entry); | 1131 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1132 PropertyAttributes attr = details.attributes(); |
| 1133 if ((attr & filter) != 0) return kMaxUInt32; |
| 1134 } |
| 1135 return static_cast<uint32_t>(entry); |
1100 } | 1136 } |
1101 | 1137 |
1102 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1138 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1103 uint32_t entry) { | 1139 uint32_t entry) { |
1104 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1140 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
1105 } | 1141 } |
| 1142 |
| 1143 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 1144 Handle<FixedArrayBase> backing_store, |
| 1145 KeyAccumulator* keys, uint32_t range, |
| 1146 PropertyAttributes filter, |
| 1147 uint32_t offset) { |
| 1148 Handle<SeededNumberDictionary> dictionary = |
| 1149 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1150 int capacity = dictionary->Capacity(); |
| 1151 for (int i = 0; i < capacity; i++) { |
| 1152 Object* k = dictionary->KeyAt(i); |
| 1153 if (!dictionary->IsKey(k)) continue; |
| 1154 if (k->FilterKey(filter)) continue; |
| 1155 if (dictionary->IsDeleted(i)) continue; |
| 1156 DCHECK(k->IsNumber()); |
| 1157 DCHECK_LE(k->Number(), kMaxUInt32); |
| 1158 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 1159 if (index < offset) continue; |
| 1160 PropertyDetails details = dictionary->DetailsAt(i); |
| 1161 PropertyAttributes attr = details.attributes(); |
| 1162 if ((attr & filter) != 0) continue; |
| 1163 keys->AddKey(index); |
| 1164 } |
| 1165 |
| 1166 keys->SortCurrentElementsList(); |
| 1167 } |
1106 }; | 1168 }; |
1107 | 1169 |
1108 | 1170 |
1109 // Super class for all fast element arrays. | 1171 // Super class for all fast element arrays. |
1110 template<typename FastElementsAccessorSubclass, | 1172 template<typename FastElementsAccessorSubclass, |
1111 typename KindTraits> | 1173 typename KindTraits> |
1112 class FastElementsAccessor | 1174 class FastElementsAccessor |
1113 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { | 1175 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { |
1114 public: | 1176 public: |
1115 explicit FastElementsAccessor(const char* name) | 1177 explicit FastElementsAccessor(const char* name) |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 UNREACHABLE(); | 1814 UNREACHABLE(); |
1753 } | 1815 } |
1754 | 1816 |
1755 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1817 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
1756 uint32_t entry) { | 1818 uint32_t entry) { |
1757 return entry; | 1819 return entry; |
1758 } | 1820 } |
1759 | 1821 |
1760 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1822 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1761 FixedArrayBase* backing_store, | 1823 FixedArrayBase* backing_store, |
1762 uint32_t index) { | 1824 uint32_t index, |
| 1825 PropertyAttributes filter) { |
1763 return index < AccessorClass::GetCapacityImpl(holder, backing_store) | 1826 return index < AccessorClass::GetCapacityImpl(holder, backing_store) |
1764 ? index | 1827 ? index |
1765 : kMaxUInt32; | 1828 : kMaxUInt32; |
1766 } | 1829 } |
1767 | 1830 |
1768 static uint32_t GetCapacityImpl(JSObject* holder, | 1831 static uint32_t GetCapacityImpl(JSObject* holder, |
1769 FixedArrayBase* backing_store) { | 1832 FixedArrayBase* backing_store) { |
1770 JSArrayBufferView* view = JSArrayBufferView::cast(holder); | 1833 JSArrayBufferView* view = JSArrayBufferView::cast(holder); |
1771 if (view->WasNeutered()) return 0; | 1834 if (view->WasNeutered()) return 0; |
1772 return backing_store->length(); | 1835 return backing_store->length(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 FixedArray* parameter_map = FixedArray::cast(parameters); | 1949 FixedArray* parameter_map = FixedArray::cast(parameters); |
1887 uint32_t length = parameter_map->length() - 2; | 1950 uint32_t length = parameter_map->length() - 2; |
1888 if (entry < length) return entry; | 1951 if (entry < length) return entry; |
1889 | 1952 |
1890 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1953 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1891 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); | 1954 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
1892 } | 1955 } |
1893 | 1956 |
1894 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1957 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1895 FixedArrayBase* parameters, | 1958 FixedArrayBase* parameters, |
1896 uint32_t index) { | 1959 uint32_t index, |
| 1960 PropertyAttributes filter) { |
1897 FixedArray* parameter_map = FixedArray::cast(parameters); | 1961 FixedArray* parameter_map = FixedArray::cast(parameters); |
1898 Object* probe = GetParameterMapArg(parameter_map, index); | 1962 Object* probe = GetParameterMapArg(parameter_map, index); |
1899 if (!probe->IsTheHole()) return index; | 1963 if (!probe->IsTheHole()) return index; |
1900 | 1964 |
1901 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1965 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1902 uint32_t entry = | 1966 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, |
1903 ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, index); | 1967 index, filter); |
1904 if (entry == kMaxUInt32) return entry; | 1968 if (entry == kMaxUInt32) return entry; |
1905 return (parameter_map->length() - 2) + entry; | 1969 return (parameter_map->length() - 2) + entry; |
1906 } | 1970 } |
1907 | 1971 |
1908 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, | 1972 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, |
1909 uint32_t entry) { | 1973 uint32_t entry) { |
1910 FixedArray* parameter_map = FixedArray::cast(parameters); | 1974 FixedArray* parameter_map = FixedArray::cast(parameters); |
1911 uint32_t length = parameter_map->length() - 2; | 1975 uint32_t length = parameter_map->length() - 2; |
1912 if (entry < length) { | 1976 if (entry < length) { |
1913 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 1977 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2326 } | 2390 } |
2327 } | 2391 } |
2328 | 2392 |
2329 DCHECK(j == result_len); | 2393 DCHECK(j == result_len); |
2330 return result_array; | 2394 return result_array; |
2331 } | 2395 } |
2332 | 2396 |
2333 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2397 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2334 } // namespace internal | 2398 } // namespace internal |
2335 } // namespace v8 | 2399 } // namespace v8 |
OLD | NEW |