| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 752 |
| 753 // CONDITIONAL_WRITE_BARRIER must be issued after the actual | 753 // CONDITIONAL_WRITE_BARRIER must be issued after the actual |
| 754 // write due to the assert validating the written value. | 754 // write due to the assert validating the written value. |
| 755 #define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \ | 755 #define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \ |
| 756 if (mode == UPDATE_WRITE_BARRIER) { \ | 756 if (mode == UPDATE_WRITE_BARRIER) { \ |
| 757 Heap::RecordWrite(object->address(), offset); \ | 757 Heap::RecordWrite(object->address(), offset); \ |
| 758 } else { \ | 758 } else { \ |
| 759 ASSERT(mode == SKIP_WRITE_BARRIER); \ | 759 ASSERT(mode == SKIP_WRITE_BARRIER); \ |
| 760 ASSERT(Heap::InNewSpace(object) || \ | 760 ASSERT(Heap::InNewSpace(object) || \ |
| 761 !Heap::InNewSpace(READ_FIELD(object, offset)) || \ | 761 !Heap::InNewSpace(READ_FIELD(object, offset)) || \ |
| 762 Page::FromAddress(object->address())-> \ | 762 Page::IsRSetSet(object->address(), offset)); \ |
| 763 IsRegionDirty(object->address() + offset)); \ | |
| 764 } | 763 } |
| 765 | 764 |
| 766 #define READ_DOUBLE_FIELD(p, offset) \ | 765 #define READ_DOUBLE_FIELD(p, offset) \ |
| 767 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) | 766 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) |
| 768 | 767 |
| 769 #define WRITE_DOUBLE_FIELD(p, offset, value) \ | 768 #define WRITE_DOUBLE_FIELD(p, offset, value) \ |
| 770 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) | 769 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) |
| 771 | 770 |
| 772 #define READ_INT_FIELD(p, offset) \ | 771 #define READ_INT_FIELD(p, offset) \ |
| 773 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) | 772 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 | 1038 |
| 1040 Address MapWord::ToEncodedAddress() { | 1039 Address MapWord::ToEncodedAddress() { |
| 1041 return reinterpret_cast<Address>(value_); | 1040 return reinterpret_cast<Address>(value_); |
| 1042 } | 1041 } |
| 1043 | 1042 |
| 1044 | 1043 |
| 1045 #ifdef DEBUG | 1044 #ifdef DEBUG |
| 1046 void HeapObject::VerifyObjectField(int offset) { | 1045 void HeapObject::VerifyObjectField(int offset) { |
| 1047 VerifyPointer(READ_FIELD(this, offset)); | 1046 VerifyPointer(READ_FIELD(this, offset)); |
| 1048 } | 1047 } |
| 1049 | |
| 1050 void HeapObject::VerifySmiField(int offset) { | |
| 1051 ASSERT(READ_FIELD(this, offset)->IsSmi()); | |
| 1052 } | |
| 1053 #endif | 1048 #endif |
| 1054 | 1049 |
| 1055 | 1050 |
| 1056 Map* HeapObject::map() { | 1051 Map* HeapObject::map() { |
| 1057 return map_word().ToMap(); | 1052 return map_word().ToMap(); |
| 1058 } | 1053 } |
| 1059 | 1054 |
| 1060 | 1055 |
| 1061 void HeapObject::set_map(Map* value) { | 1056 void HeapObject::set_map(Map* value) { |
| 1062 set_map_word(MapWord::FromMap(value)); | 1057 set_map_word(MapWord::FromMap(value)); |
| 1063 } | 1058 } |
| 1064 | 1059 |
| 1065 | 1060 |
| 1066 MapWord HeapObject::map_word() { | 1061 MapWord HeapObject::map_word() { |
| 1067 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); | 1062 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); |
| 1068 } | 1063 } |
| 1069 | 1064 |
| 1070 | 1065 |
| 1071 void HeapObject::set_map_word(MapWord map_word) { | 1066 void HeapObject::set_map_word(MapWord map_word) { |
| 1072 // WRITE_FIELD does not invoke write barrier, but there is no need | 1067 // WRITE_FIELD does not update the remembered set, but there is no need |
| 1073 // here. | 1068 // here. |
| 1074 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_)); | 1069 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_)); |
| 1075 } | 1070 } |
| 1076 | 1071 |
| 1077 | 1072 |
| 1078 HeapObject* HeapObject::FromAddress(Address address) { | 1073 HeapObject* HeapObject::FromAddress(Address address) { |
| 1079 ASSERT_TAG_ALIGNED(address); | 1074 ASSERT_TAG_ALIGNED(address); |
| 1080 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag); | 1075 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag); |
| 1081 } | 1076 } |
| 1082 | 1077 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 | 1155 |
| 1161 | 1156 |
| 1162 int HeapNumber::get_sign() { | 1157 int HeapNumber::get_sign() { |
| 1163 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; | 1158 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; |
| 1164 } | 1159 } |
| 1165 | 1160 |
| 1166 | 1161 |
| 1167 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) | 1162 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
| 1168 | 1163 |
| 1169 | 1164 |
| 1170 HeapObject* JSObject::elements() { | 1165 Array* JSObject::elements() { |
| 1171 Object* array = READ_FIELD(this, kElementsOffset); | 1166 Object* array = READ_FIELD(this, kElementsOffset); |
| 1172 // In the assert below Dictionary is covered under FixedArray. | 1167 // In the assert below Dictionary is covered under FixedArray. |
| 1173 ASSERT(array->IsFixedArray() || array->IsPixelArray() || | 1168 ASSERT(array->IsFixedArray() || array->IsPixelArray() || |
| 1174 array->IsExternalArray()); | 1169 array->IsExternalArray()); |
| 1175 return reinterpret_cast<HeapObject*>(array); | 1170 return reinterpret_cast<Array*>(array); |
| 1176 } | 1171 } |
| 1177 | 1172 |
| 1178 | 1173 |
| 1179 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { | 1174 void JSObject::set_elements(Array* value, WriteBarrierMode mode) { |
| 1180 // In the assert below Dictionary is covered under FixedArray. | 1175 // In the assert below Dictionary is covered under FixedArray. |
| 1181 ASSERT(value->IsFixedArray() || value->IsPixelArray() || | 1176 ASSERT(value->IsFixedArray() || value->IsPixelArray() || |
| 1182 value->IsExternalArray()); | 1177 value->IsExternalArray()); |
| 1183 WRITE_FIELD(this, kElementsOffset, value); | 1178 WRITE_FIELD(this, kElementsOffset, value); |
| 1184 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode); | 1179 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode); |
| 1185 } | 1180 } |
| 1186 | 1181 |
| 1187 | 1182 |
| 1188 void JSObject::initialize_properties() { | 1183 void JSObject::initialize_properties() { |
| 1189 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); | 1184 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 WRITE_FIELD(this, offset, value); | 1335 WRITE_FIELD(this, offset, value); |
| 1341 } | 1336 } |
| 1342 } | 1337 } |
| 1343 | 1338 |
| 1344 | 1339 |
| 1345 bool JSObject::HasFastProperties() { | 1340 bool JSObject::HasFastProperties() { |
| 1346 return !properties()->IsDictionary(); | 1341 return !properties()->IsDictionary(); |
| 1347 } | 1342 } |
| 1348 | 1343 |
| 1349 | 1344 |
| 1350 bool Object::ToArrayIndex(uint32_t* index) { | 1345 bool Array::IndexFromObject(Object* object, uint32_t* index) { |
| 1351 if (IsSmi()) { | 1346 if (object->IsSmi()) { |
| 1352 int value = Smi::cast(this)->value(); | 1347 int value = Smi::cast(object)->value(); |
| 1353 if (value < 0) return false; | 1348 if (value < 0) return false; |
| 1354 *index = value; | 1349 *index = value; |
| 1355 return true; | 1350 return true; |
| 1356 } | 1351 } |
| 1357 if (IsHeapNumber()) { | 1352 if (object->IsHeapNumber()) { |
| 1358 double value = HeapNumber::cast(this)->value(); | 1353 double value = HeapNumber::cast(object)->value(); |
| 1359 uint32_t uint_value = static_cast<uint32_t>(value); | 1354 uint32_t uint_value = static_cast<uint32_t>(value); |
| 1360 if (value == static_cast<double>(uint_value)) { | 1355 if (value == static_cast<double>(uint_value)) { |
| 1361 *index = uint_value; | 1356 *index = uint_value; |
| 1362 return true; | 1357 return true; |
| 1363 } | 1358 } |
| 1364 } | 1359 } |
| 1365 return false; | 1360 return false; |
| 1366 } | 1361 } |
| 1367 | 1362 |
| 1368 | 1363 |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 #undef MAKE_STRUCT_CAST | 1658 #undef MAKE_STRUCT_CAST |
| 1664 | 1659 |
| 1665 | 1660 |
| 1666 template <typename Shape, typename Key> | 1661 template <typename Shape, typename Key> |
| 1667 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { | 1662 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { |
| 1668 ASSERT(obj->IsHashTable()); | 1663 ASSERT(obj->IsHashTable()); |
| 1669 return reinterpret_cast<HashTable*>(obj); | 1664 return reinterpret_cast<HashTable*>(obj); |
| 1670 } | 1665 } |
| 1671 | 1666 |
| 1672 | 1667 |
| 1673 SMI_ACCESSORS(FixedArray, length, kLengthOffset) | 1668 INT_ACCESSORS(Array, length, kLengthOffset) |
| 1674 SMI_ACCESSORS(ByteArray, length, kLengthOffset) | |
| 1675 | |
| 1676 INT_ACCESSORS(PixelArray, length, kLengthOffset) | |
| 1677 INT_ACCESSORS(ExternalArray, length, kLengthOffset) | |
| 1678 | 1669 |
| 1679 | 1670 |
| 1680 SMI_ACCESSORS(String, length, kLengthOffset) | 1671 SMI_ACCESSORS(String, length, kLengthOffset) |
| 1681 | 1672 |
| 1682 | 1673 |
| 1683 uint32_t String::hash_field() { | 1674 uint32_t String::hash_field() { |
| 1684 return READ_UINT32_FIELD(this, kHashFieldOffset); | 1675 return READ_UINT32_FIELD(this, kHashFieldOffset); |
| 1685 } | 1676 } |
| 1686 | 1677 |
| 1687 | 1678 |
| 1688 void String::set_hash_field(uint32_t value) { | 1679 void String::set_hash_field(uint32_t value) { |
| 1689 WRITE_UINT32_FIELD(this, kHashFieldOffset, value); | 1680 WRITE_UINT32_FIELD(this, kHashFieldOffset, value); |
| 1690 #if V8_HOST_ARCH_64_BIT | |
| 1691 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0); | |
| 1692 #endif | |
| 1693 } | 1681 } |
| 1694 | 1682 |
| 1695 | 1683 |
| 1696 bool String::Equals(String* other) { | 1684 bool String::Equals(String* other) { |
| 1697 if (other == this) return true; | 1685 if (other == this) return true; |
| 1698 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { | 1686 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { |
| 1699 return false; | 1687 return false; |
| 1700 } | 1688 } |
| 1701 return SlowEquals(other); | 1689 return SlowEquals(other); |
| 1702 } | 1690 } |
| (...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel, | 2449 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel, |
| 2462 kIsTopLevelBit) | 2450 kIsTopLevelBit) |
| 2463 BOOL_GETTER(SharedFunctionInfo, compiler_hints, | 2451 BOOL_GETTER(SharedFunctionInfo, compiler_hints, |
| 2464 has_only_simple_this_property_assignments, | 2452 has_only_simple_this_property_assignments, |
| 2465 kHasOnlySimpleThisPropertyAssignments) | 2453 kHasOnlySimpleThisPropertyAssignments) |
| 2466 BOOL_ACCESSORS(SharedFunctionInfo, | 2454 BOOL_ACCESSORS(SharedFunctionInfo, |
| 2467 compiler_hints, | 2455 compiler_hints, |
| 2468 try_full_codegen, | 2456 try_full_codegen, |
| 2469 kTryFullCodegen) | 2457 kTryFullCodegen) |
| 2470 | 2458 |
| 2471 #if V8_HOST_ARCH_32_BIT | 2459 INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset) |
| 2472 SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset) | 2460 INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count, |
| 2473 SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count, | |
| 2474 kFormalParameterCountOffset) | 2461 kFormalParameterCountOffset) |
| 2475 SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties, | 2462 INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties, |
| 2476 kExpectedNofPropertiesOffset) | 2463 kExpectedNofPropertiesOffset) |
| 2477 SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset) | 2464 INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset) |
| 2478 SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type, | 2465 INT_ACCESSORS(SharedFunctionInfo, start_position_and_type, |
| 2479 kStartPositionAndTypeOffset) | 2466 kStartPositionAndTypeOffset) |
| 2480 SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset) | 2467 INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset) |
| 2481 SMI_ACCESSORS(SharedFunctionInfo, function_token_position, | 2468 INT_ACCESSORS(SharedFunctionInfo, function_token_position, |
| 2482 kFunctionTokenPositionOffset) | 2469 kFunctionTokenPositionOffset) |
| 2483 SMI_ACCESSORS(SharedFunctionInfo, compiler_hints, | 2470 INT_ACCESSORS(SharedFunctionInfo, compiler_hints, |
| 2484 kCompilerHintsOffset) | 2471 kCompilerHintsOffset) |
| 2485 SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count, | 2472 INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count, |
| 2486 kThisPropertyAssignmentsCountOffset) | 2473 kThisPropertyAssignmentsCountOffset) |
| 2487 #else | |
| 2488 | 2474 |
| 2489 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \ | |
| 2490 int holder::name() { \ | |
| 2491 int value = READ_INT_FIELD(this, offset); \ | |
| 2492 ASSERT(kHeapObjectTag == 1); \ | |
| 2493 ASSERT((value & kHeapObjectTag) == 0); \ | |
| 2494 return value >> 1; \ | |
| 2495 } \ | |
| 2496 void holder::set_##name(int value) { \ | |
| 2497 ASSERT(kHeapObjectTag == 1); \ | |
| 2498 ASSERT((value & 0xC0000000) == 0xC0000000 || \ | |
| 2499 (value & 0xC0000000) == 0x000000000); \ | |
| 2500 WRITE_INT_FIELD(this, \ | |
| 2501 offset, \ | |
| 2502 (value << 1) & ~kHeapObjectTag); \ | |
| 2503 } | |
| 2504 | |
| 2505 #define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \ | |
| 2506 INT_ACCESSORS(holder, name, offset) | |
| 2507 | |
| 2508 | |
| 2509 | |
| 2510 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset) | |
| 2511 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count, | |
| 2512 kFormalParameterCountOffset) | |
| 2513 | |
| 2514 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties, | |
| 2515 kExpectedNofPropertiesOffset) | |
| 2516 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset) | |
| 2517 | |
| 2518 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type, | |
| 2519 kStartPositionAndTypeOffset) | |
| 2520 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset) | |
| 2521 | |
| 2522 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position, | |
| 2523 kFunctionTokenPositionOffset) | |
| 2524 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints, | |
| 2525 kCompilerHintsOffset) | |
| 2526 | |
| 2527 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count, | |
| 2528 kThisPropertyAssignmentsCountOffset) | |
| 2529 #endif | |
| 2530 | 2475 |
| 2531 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) | 2476 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) |
| 2532 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) | 2477 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) |
| 2533 | 2478 |
| 2534 bool Script::HasValidSource() { | 2479 bool Script::HasValidSource() { |
| 2535 Object* src = this->source(); | 2480 Object* src = this->source(); |
| 2536 if (!src->IsString()) return true; | 2481 if (!src->IsString()) return true; |
| 2537 String* src_str = String::cast(src); | 2482 String* src_str = String::cast(src); |
| 2538 if (!StringShape(src_str).IsExternal()) return true; | 2483 if (!StringShape(src_str).IsExternal()) return true; |
| 2539 if (src_str->IsAsciiRepresentation()) { | 2484 if (src_str->IsAsciiRepresentation()) { |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2833 | 2778 |
| 2834 | 2779 |
| 2835 void JSRegExp::SetDataAt(int index, Object* value) { | 2780 void JSRegExp::SetDataAt(int index, Object* value) { |
| 2836 ASSERT(TypeTag() != NOT_COMPILED); | 2781 ASSERT(TypeTag() != NOT_COMPILED); |
| 2837 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. | 2782 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. |
| 2838 FixedArray::cast(data())->set(index, value); | 2783 FixedArray::cast(data())->set(index, value); |
| 2839 } | 2784 } |
| 2840 | 2785 |
| 2841 | 2786 |
| 2842 JSObject::ElementsKind JSObject::GetElementsKind() { | 2787 JSObject::ElementsKind JSObject::GetElementsKind() { |
| 2843 HeapObject* array = elements(); | 2788 Array* array = elements(); |
| 2844 if (array->IsFixedArray()) { | 2789 if (array->IsFixedArray()) { |
| 2845 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray. | 2790 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray. |
| 2846 if (array->map() == Heap::fixed_array_map()) { | 2791 if (array->map() == Heap::fixed_array_map()) { |
| 2847 return FAST_ELEMENTS; | 2792 return FAST_ELEMENTS; |
| 2848 } | 2793 } |
| 2849 ASSERT(array->IsDictionary()); | 2794 ASSERT(array->IsDictionary()); |
| 2850 return DICTIONARY_ELEMENTS; | 2795 return DICTIONARY_ELEMENTS; |
| 2851 } | 2796 } |
| 2852 if (array->IsExternalArray()) { | 2797 if (array->IsExternalArray()) { |
| 2853 switch (array->map()->instance_type()) { | 2798 switch (array->map()->instance_type()) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2956 return StringDictionary::cast(properties()); | 2901 return StringDictionary::cast(properties()); |
| 2957 } | 2902 } |
| 2958 | 2903 |
| 2959 | 2904 |
| 2960 NumberDictionary* JSObject::element_dictionary() { | 2905 NumberDictionary* JSObject::element_dictionary() { |
| 2961 ASSERT(HasDictionaryElements()); | 2906 ASSERT(HasDictionaryElements()); |
| 2962 return NumberDictionary::cast(elements()); | 2907 return NumberDictionary::cast(elements()); |
| 2963 } | 2908 } |
| 2964 | 2909 |
| 2965 | 2910 |
| 2966 bool String::IsHashFieldComputed(uint32_t field) { | |
| 2967 return (field & kHashNotComputedMask) == 0; | |
| 2968 } | |
| 2969 | |
| 2970 | |
| 2971 bool String::HasHashCode() { | 2911 bool String::HasHashCode() { |
| 2972 return IsHashFieldComputed(hash_field()); | 2912 return (hash_field() & kHashComputedMask) != 0; |
| 2973 } | 2913 } |
| 2974 | 2914 |
| 2975 | 2915 |
| 2976 uint32_t String::Hash() { | 2916 uint32_t String::Hash() { |
| 2977 // Fast case: has hash code already been computed? | 2917 // Fast case: has hash code already been computed? |
| 2978 uint32_t field = hash_field(); | 2918 uint32_t field = hash_field(); |
| 2979 if (IsHashFieldComputed(field)) return field >> kHashShift; | 2919 if (field & kHashComputedMask) return field >> kHashShift; |
| 2980 // Slow case: compute hash code and set it. | 2920 // Slow case: compute hash code and set it. |
| 2981 return ComputeAndSetHash(); | 2921 return ComputeAndSetHash(); |
| 2982 } | 2922 } |
| 2983 | 2923 |
| 2984 | 2924 |
| 2985 StringHasher::StringHasher(int length) | 2925 StringHasher::StringHasher(int length) |
| 2986 : length_(length), | 2926 : length_(length), |
| 2987 raw_running_hash_(0), | 2927 raw_running_hash_(0), |
| 2988 array_index_(0), | 2928 array_index_(0), |
| 2989 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), | 2929 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3042 result += (result << 15); | 2982 result += (result << 15); |
| 3043 if (result == 0) { | 2983 if (result == 0) { |
| 3044 result = 27; | 2984 result = 27; |
| 3045 } | 2985 } |
| 3046 return result; | 2986 return result; |
| 3047 } | 2987 } |
| 3048 | 2988 |
| 3049 | 2989 |
| 3050 bool String::AsArrayIndex(uint32_t* index) { | 2990 bool String::AsArrayIndex(uint32_t* index) { |
| 3051 uint32_t field = hash_field(); | 2991 uint32_t field = hash_field(); |
| 3052 if (IsHashFieldComputed(field) && !(field & kIsArrayIndexMask)) return false; | 2992 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false; |
| 3053 return SlowAsArrayIndex(index); | 2993 return SlowAsArrayIndex(index); |
| 3054 } | 2994 } |
| 3055 | 2995 |
| 3056 | 2996 |
| 3057 Object* JSObject::GetPrototype() { | 2997 Object* JSObject::GetPrototype() { |
| 3058 return JSObject::cast(this)->map()->prototype(); | 2998 return JSObject::cast(this)->map()->prototype(); |
| 3059 } | 2999 } |
| 3060 | 3000 |
| 3061 | 3001 |
| 3062 PropertyAttributes JSObject::GetPropertyAttribute(String* key) { | 3002 PropertyAttributes JSObject::GetPropertyAttribute(String* key) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3166 // No write barrier is needed since empty_fixed_array is not in new space. | 3106 // No write barrier is needed since empty_fixed_array is not in new space. |
| 3167 // Please note this function is used during marking: | 3107 // Please note this function is used during marking: |
| 3168 // - MarkCompactCollector::MarkUnmarkedObject | 3108 // - MarkCompactCollector::MarkUnmarkedObject |
| 3169 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array())); | 3109 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array())); |
| 3170 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array()); | 3110 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array()); |
| 3171 } | 3111 } |
| 3172 | 3112 |
| 3173 | 3113 |
| 3174 void JSArray::EnsureSize(int required_size) { | 3114 void JSArray::EnsureSize(int required_size) { |
| 3175 ASSERT(HasFastElements()); | 3115 ASSERT(HasFastElements()); |
| 3176 FixedArray* elts = FixedArray::cast(elements()); | 3116 Array* elts = elements(); |
| 3177 const int kArraySizeThatFitsComfortablyInNewSpace = 128; | 3117 const int kArraySizeThatFitsComfortablyInNewSpace = 128; |
| 3178 if (elts->length() < required_size) { | 3118 if (elts->length() < required_size) { |
| 3179 // Doubling in size would be overkill, but leave some slack to avoid | 3119 // Doubling in size would be overkill, but leave some slack to avoid |
| 3180 // constantly growing. | 3120 // constantly growing. |
| 3181 Expand(required_size + (required_size >> 3)); | 3121 Expand(required_size + (required_size >> 3)); |
| 3182 // It's a performance benefit to keep a frequently used array in new-space. | 3122 // It's a performance benefit to keep a frequently used array in new-space. |
| 3183 } else if (!Heap::new_space()->Contains(elts) && | 3123 } else if (!Heap::new_space()->Contains(elts) && |
| 3184 required_size < kArraySizeThatFitsComfortablyInNewSpace) { | 3124 required_size < kArraySizeThatFitsComfortablyInNewSpace) { |
| 3185 // Expand will allocate a new backing store in new space even if the size | 3125 // Expand will allocate a new backing store in new space even if the size |
| 3186 // we asked for isn't larger than what we had before. | 3126 // we asked for isn't larger than what we had before. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3223 #undef WRITE_INT_FIELD | 3163 #undef WRITE_INT_FIELD |
| 3224 #undef READ_SHORT_FIELD | 3164 #undef READ_SHORT_FIELD |
| 3225 #undef WRITE_SHORT_FIELD | 3165 #undef WRITE_SHORT_FIELD |
| 3226 #undef READ_BYTE_FIELD | 3166 #undef READ_BYTE_FIELD |
| 3227 #undef WRITE_BYTE_FIELD | 3167 #undef WRITE_BYTE_FIELD |
| 3228 | 3168 |
| 3229 | 3169 |
| 3230 } } // namespace v8::internal | 3170 } } // namespace v8::internal |
| 3231 | 3171 |
| 3232 #endif // V8_OBJECTS_INL_H_ | 3172 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |