| 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 #ifndef V8_OBJECTS_H_ | 5 #ifndef V8_OBJECTS_H_ |
| 6 #define V8_OBJECTS_H_ | 6 #define V8_OBJECTS_H_ |
| 7 | 7 |
| 8 #include <iosfwd> | 8 #include <iosfwd> |
| 9 | 9 |
| 10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
| (...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 // Filler objects (fillers and free space objects). | 1052 // Filler objects (fillers and free space objects). |
| 1053 INLINE(bool IsFiller() const); | 1053 INLINE(bool IsFiller() const); |
| 1054 | 1054 |
| 1055 // Extract the number. | 1055 // Extract the number. |
| 1056 inline double Number(); | 1056 inline double Number(); |
| 1057 INLINE(bool IsNaN() const); | 1057 INLINE(bool IsNaN() const); |
| 1058 INLINE(bool IsMinusZero() const); | 1058 INLINE(bool IsMinusZero() const); |
| 1059 bool ToInt32(int32_t* value); | 1059 bool ToInt32(int32_t* value); |
| 1060 bool ToUint32(uint32_t* value); | 1060 bool ToUint32(uint32_t* value); |
| 1061 | 1061 |
| 1062 inline Representation OptimalRepresentation() { | 1062 inline Representation OptimalRepresentation(); |
| 1063 if (!FLAG_track_fields) return Representation::Tagged(); | |
| 1064 if (IsSmi()) { | |
| 1065 return Representation::Smi(); | |
| 1066 } else if (FLAG_track_double_fields && IsHeapNumber()) { | |
| 1067 return Representation::Double(); | |
| 1068 } else if (FLAG_track_computed_fields && IsUninitialized()) { | |
| 1069 return Representation::None(); | |
| 1070 } else if (FLAG_track_heap_object_fields) { | |
| 1071 DCHECK(IsHeapObject()); | |
| 1072 return Representation::HeapObject(); | |
| 1073 } else { | |
| 1074 return Representation::Tagged(); | |
| 1075 } | |
| 1076 } | |
| 1077 | 1063 |
| 1078 inline ElementsKind OptimalElementsKind() { | 1064 inline ElementsKind OptimalElementsKind(); |
| 1079 if (IsSmi()) return FAST_SMI_ELEMENTS; | |
| 1080 if (IsNumber()) return FAST_DOUBLE_ELEMENTS; | |
| 1081 return FAST_ELEMENTS; | |
| 1082 } | |
| 1083 | 1065 |
| 1084 inline bool FitsRepresentation(Representation representation) { | 1066 inline bool FitsRepresentation(Representation representation); |
| 1085 if (FLAG_track_fields && representation.IsNone()) { | |
| 1086 return false; | |
| 1087 } else if (FLAG_track_fields && representation.IsSmi()) { | |
| 1088 return IsSmi(); | |
| 1089 } else if (FLAG_track_double_fields && representation.IsDouble()) { | |
| 1090 return IsMutableHeapNumber() || IsNumber(); | |
| 1091 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | |
| 1092 return IsHeapObject(); | |
| 1093 } | |
| 1094 return true; | |
| 1095 } | |
| 1096 | 1067 |
| 1097 // Checks whether two valid primitive encodings of a property name resolve to | 1068 // Checks whether two valid primitive encodings of a property name resolve to |
| 1098 // the same logical property. E.g., the smi 1, the string "1" and the double | 1069 // the same logical property. E.g., the smi 1, the string "1" and the double |
| 1099 // 1 all refer to the same property, so this helper will return true. | 1070 // 1 all refer to the same property, so this helper will return true. |
| 1100 inline bool KeyEquals(Object* other); | 1071 inline bool KeyEquals(Object* other); |
| 1101 | 1072 |
| 1102 Handle<HeapType> OptimalType(Isolate* isolate, Representation representation); | 1073 Handle<HeapType> OptimalType(Isolate* isolate, Representation representation); |
| 1103 | 1074 |
| 1104 inline static Handle<Object> NewStorageFor(Isolate* isolate, | 1075 inline static Handle<Object> NewStorageFor(Isolate* isolate, |
| 1105 Handle<Object> object, | 1076 Handle<Object> object, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 | 1262 |
| 1292 // Smi represents integer Numbers that can be stored in 31 bits. | 1263 // Smi represents integer Numbers that can be stored in 31 bits. |
| 1293 // Smis are immediate which means they are NOT allocated in the heap. | 1264 // Smis are immediate which means they are NOT allocated in the heap. |
| 1294 // The this pointer has the following format: [31 bit signed int] 0 | 1265 // The this pointer has the following format: [31 bit signed int] 0 |
| 1295 // For long smis it has the following format: | 1266 // For long smis it has the following format: |
| 1296 // [32 bit signed int] [31 bits zero padding] 0 | 1267 // [32 bit signed int] [31 bits zero padding] 0 |
| 1297 // Smi stands for small integer. | 1268 // Smi stands for small integer. |
| 1298 class Smi: public Object { | 1269 class Smi: public Object { |
| 1299 public: | 1270 public: |
| 1300 // Returns the integer value. | 1271 // Returns the integer value. |
| 1301 inline int value() const; | 1272 inline int value() const { return Internals::SmiValue(this); } |
| 1302 | 1273 |
| 1303 // Convert a value to a Smi object. | 1274 // Convert a value to a Smi object. |
| 1304 static inline Smi* FromInt(int value); | 1275 static inline Smi* FromInt(int value) { |
| 1276 DCHECK(Smi::IsValid(value)); |
| 1277 return reinterpret_cast<Smi*>(Internals::IntToSmi(value)); |
| 1278 } |
| 1305 | 1279 |
| 1306 static inline Smi* FromIntptr(intptr_t value); | 1280 static inline Smi* FromIntptr(intptr_t value) { |
| 1281 DCHECK(Smi::IsValid(value)); |
| 1282 int smi_shift_bits = kSmiTagSize + kSmiShiftSize; |
| 1283 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag); |
| 1284 } |
| 1307 | 1285 |
| 1308 // Returns whether value can be represented in a Smi. | 1286 // Returns whether value can be represented in a Smi. |
| 1309 static inline bool IsValid(intptr_t value); | 1287 static inline bool IsValid(intptr_t value) { |
| 1288 bool result = Internals::IsValidSmi(value); |
| 1289 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue); |
| 1290 return result; |
| 1291 } |
| 1310 | 1292 |
| 1311 DECLARE_CAST(Smi) | 1293 DECLARE_CAST(Smi) |
| 1312 | 1294 |
| 1313 // Dispatched behavior. | 1295 // Dispatched behavior. |
| 1314 void SmiPrint(std::ostream& os) const; // NOLINT | 1296 void SmiPrint(std::ostream& os) const; // NOLINT |
| 1315 DECLARE_VERIFIER(Smi) | 1297 DECLARE_VERIFIER(Smi) |
| 1316 | 1298 |
| 1317 static const int kMinValue = | 1299 static const int kMinValue = |
| 1318 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1); | 1300 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1); |
| 1319 static const int kMaxValue = -(kMinValue + 1); | 1301 static const int kMaxValue = -(kMinValue + 1); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 inline MapWord map_word() const; | 1386 inline MapWord map_word() const; |
| 1405 inline void set_map_word(MapWord map_word); | 1387 inline void set_map_word(MapWord map_word); |
| 1406 | 1388 |
| 1407 // The Heap the object was allocated in. Used also to access Isolate. | 1389 // The Heap the object was allocated in. Used also to access Isolate. |
| 1408 inline Heap* GetHeap() const; | 1390 inline Heap* GetHeap() const; |
| 1409 | 1391 |
| 1410 // Convenience method to get current isolate. | 1392 // Convenience method to get current isolate. |
| 1411 inline Isolate* GetIsolate() const; | 1393 inline Isolate* GetIsolate() const; |
| 1412 | 1394 |
| 1413 // Converts an address to a HeapObject pointer. | 1395 // Converts an address to a HeapObject pointer. |
| 1414 static inline HeapObject* FromAddress(Address address); | 1396 static inline HeapObject* FromAddress(Address address) { |
| 1397 DCHECK_TAG_ALIGNED(address); |
| 1398 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag); |
| 1399 } |
| 1415 | 1400 |
| 1416 // Returns the address of this HeapObject. | 1401 // Returns the address of this HeapObject. |
| 1417 inline Address address(); | 1402 inline Address address() { |
| 1403 return reinterpret_cast<Address>(this) - kHeapObjectTag; |
| 1404 } |
| 1418 | 1405 |
| 1419 // Iterates over pointers contained in the object (including the Map) | 1406 // Iterates over pointers contained in the object (including the Map) |
| 1420 void Iterate(ObjectVisitor* v); | 1407 void Iterate(ObjectVisitor* v); |
| 1421 | 1408 |
| 1422 // Iterates over all pointers contained in the object except the | 1409 // Iterates over all pointers contained in the object except the |
| 1423 // first map pointer. The object type is given in the first | 1410 // first map pointer. The object type is given in the first |
| 1424 // parameter. This function does not access the map pointer in the | 1411 // parameter. This function does not access the map pointer in the |
| 1425 // object, and so is safe to call while the map pointer is modified. | 1412 // object, and so is safe to call while the map pointer is modified. |
| 1426 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v); | 1413 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v); |
| 1427 | 1414 |
| (...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2410 // Copy a sub array from the receiver to dest. | 2397 // Copy a sub array from the receiver to dest. |
| 2411 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); | 2398 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); |
| 2412 | 2399 |
| 2413 // Garbage collection support. | 2400 // Garbage collection support. |
| 2414 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; } | 2401 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; } |
| 2415 | 2402 |
| 2416 // Code Generation support. | 2403 // Code Generation support. |
| 2417 static int OffsetOfElementAt(int index) { return SizeFor(index); } | 2404 static int OffsetOfElementAt(int index) { return SizeFor(index); } |
| 2418 | 2405 |
| 2419 // Garbage collection support. | 2406 // Garbage collection support. |
| 2420 Object** RawFieldOfElementAt(int index) { | 2407 inline Object** RawFieldOfElementAt(int index); |
| 2421 return HeapObject::RawField(this, OffsetOfElementAt(index)); | |
| 2422 } | |
| 2423 | 2408 |
| 2424 DECLARE_CAST(FixedArray) | 2409 DECLARE_CAST(FixedArray) |
| 2425 | 2410 |
| 2426 // Maximal allowed size, in bytes, of a single FixedArray. | 2411 // Maximal allowed size, in bytes, of a single FixedArray. |
| 2427 // Prevents overflowing size computations, as well as extreme memory | 2412 // Prevents overflowing size computations, as well as extreme memory |
| 2428 // consumption. | 2413 // consumption. |
| 2429 static const int kMaxSize = 128 * MB * kPointerSize; | 2414 static const int kMaxSize = 128 * MB * kPointerSize; |
| 2430 // Maximally allowed length of a FixedArray. | 2415 // Maximally allowed length of a FixedArray. |
| 2431 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; | 2416 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; |
| 2432 | 2417 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2443 // once. | 2428 // once. |
| 2444 void SwapPairs(FixedArray* numbers, int i, int j); | 2429 void SwapPairs(FixedArray* numbers, int i, int j); |
| 2445 | 2430 |
| 2446 // Sort prefix of this array and the numbers array as pairs wrt. the | 2431 // Sort prefix of this array and the numbers array as pairs wrt. the |
| 2447 // numbers. If the numbers array and the this array are the same | 2432 // numbers. If the numbers array and the this array are the same |
| 2448 // object, the prefix of this array is sorted. | 2433 // object, the prefix of this array is sorted. |
| 2449 void SortPairs(FixedArray* numbers, uint32_t len); | 2434 void SortPairs(FixedArray* numbers, uint32_t len); |
| 2450 | 2435 |
| 2451 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { | 2436 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { |
| 2452 public: | 2437 public: |
| 2453 static inline int SizeOf(Map* map, HeapObject* object) { | 2438 static inline int SizeOf(Map* map, HeapObject* object); |
| 2454 return SizeFor( | |
| 2455 reinterpret_cast<FixedArray*>(object)->synchronized_length()); | |
| 2456 } | |
| 2457 }; | 2439 }; |
| 2458 | 2440 |
| 2459 protected: | 2441 protected: |
| 2460 // Set operation on FixedArray without using write barriers. Can | 2442 // Set operation on FixedArray without using write barriers. Can |
| 2461 // only be used for storing old space objects or smis. | 2443 // only be used for storing old space objects or smis. |
| 2462 static inline void NoWriteBarrierSet(FixedArray* array, | 2444 static inline void NoWriteBarrierSet(FixedArray* array, |
| 2463 int index, | 2445 int index, |
| 2464 Object* value); | 2446 Object* value); |
| 2465 | 2447 |
| 2466 // Set operation on FixedArray without incremental write barrier. Can | 2448 // Set operation on FixedArray without incremental write barrier. Can |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2611 // [2]: first key | 2593 // [2]: first key |
| 2612 // [2 + number of descriptors * kDescriptorSize]: start of slack | 2594 // [2 + number of descriptors * kDescriptorSize]: start of slack |
| 2613 class DescriptorArray: public FixedArray { | 2595 class DescriptorArray: public FixedArray { |
| 2614 public: | 2596 public: |
| 2615 // Returns true for both shared empty_descriptor_array and for smis, which the | 2597 // Returns true for both shared empty_descriptor_array and for smis, which the |
| 2616 // map uses to encode additional bit fields when the descriptor array is not | 2598 // map uses to encode additional bit fields when the descriptor array is not |
| 2617 // yet used. | 2599 // yet used. |
| 2618 inline bool IsEmpty(); | 2600 inline bool IsEmpty(); |
| 2619 | 2601 |
| 2620 // Returns the number of descriptors in the array. | 2602 // Returns the number of descriptors in the array. |
| 2621 int number_of_descriptors() { | 2603 inline int number_of_descriptors(); |
| 2622 DCHECK(length() >= kFirstIndex || IsEmpty()); | |
| 2623 int len = length(); | |
| 2624 return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value(); | |
| 2625 } | |
| 2626 | 2604 |
| 2627 int number_of_descriptors_storage() { | 2605 inline int number_of_descriptors_storage(); |
| 2628 int len = length(); | |
| 2629 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize; | |
| 2630 } | |
| 2631 | 2606 |
| 2632 int NumberOfSlackDescriptors() { | 2607 inline int NumberOfSlackDescriptors(); |
| 2633 return number_of_descriptors_storage() - number_of_descriptors(); | |
| 2634 } | |
| 2635 | 2608 |
| 2636 inline void SetNumberOfDescriptors(int number_of_descriptors); | 2609 inline void SetNumberOfDescriptors(int number_of_descriptors); |
| 2637 inline int number_of_entries() { return number_of_descriptors(); } | 2610 inline int number_of_entries(); |
| 2638 | 2611 |
| 2639 bool HasEnumCache() { | 2612 inline bool HasEnumCache(); |
| 2640 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); | |
| 2641 } | |
| 2642 | 2613 |
| 2643 void CopyEnumCacheFrom(DescriptorArray* array) { | 2614 inline void CopyEnumCacheFrom(DescriptorArray* array); |
| 2644 set(kEnumCacheIndex, array->get(kEnumCacheIndex)); | |
| 2645 } | |
| 2646 | 2615 |
| 2647 FixedArray* GetEnumCache() { | 2616 inline FixedArray* GetEnumCache(); |
| 2648 DCHECK(HasEnumCache()); | |
| 2649 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | |
| 2650 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex)); | |
| 2651 } | |
| 2652 | 2617 |
| 2653 bool HasEnumIndicesCache() { | 2618 inline bool HasEnumIndicesCache(); |
| 2654 if (IsEmpty()) return false; | |
| 2655 Object* object = get(kEnumCacheIndex); | |
| 2656 if (object->IsSmi()) return false; | |
| 2657 FixedArray* bridge = FixedArray::cast(object); | |
| 2658 return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi(); | |
| 2659 } | |
| 2660 | 2619 |
| 2661 FixedArray* GetEnumIndicesCache() { | 2620 inline FixedArray* GetEnumIndicesCache(); |
| 2662 DCHECK(HasEnumIndicesCache()); | |
| 2663 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | |
| 2664 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex)); | |
| 2665 } | |
| 2666 | 2621 |
| 2667 Object** GetEnumCacheSlot() { | 2622 inline Object** GetEnumCacheSlot(); |
| 2668 DCHECK(HasEnumCache()); | |
| 2669 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | |
| 2670 kEnumCacheOffset); | |
| 2671 } | |
| 2672 | 2623 |
| 2673 void ClearEnumCache(); | 2624 void ClearEnumCache(); |
| 2674 | 2625 |
| 2675 // Initialize or change the enum cache, | 2626 // Initialize or change the enum cache, |
| 2676 // using the supplied storage for the small "bridge". | 2627 // using the supplied storage for the small "bridge". |
| 2677 void SetEnumCache(FixedArray* bridge_storage, | 2628 void SetEnumCache(FixedArray* bridge_storage, |
| 2678 FixedArray* new_cache, | 2629 FixedArray* new_cache, |
| 2679 Object* new_index_cache); | 2630 Object* new_index_cache); |
| 2680 | 2631 |
| 2681 bool CanHoldValue(int descriptor, Object* value); | 2632 bool CanHoldValue(int descriptor, Object* value); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2809 private: | 2760 private: |
| 2810 IncrementalMarking* marking_; | 2761 IncrementalMarking* marking_; |
| 2811 }; | 2762 }; |
| 2812 | 2763 |
| 2813 // An entry in a DescriptorArray, represented as an (array, index) pair. | 2764 // An entry in a DescriptorArray, represented as an (array, index) pair. |
| 2814 class Entry { | 2765 class Entry { |
| 2815 public: | 2766 public: |
| 2816 inline explicit Entry(DescriptorArray* descs, int index) : | 2767 inline explicit Entry(DescriptorArray* descs, int index) : |
| 2817 descs_(descs), index_(index) { } | 2768 descs_(descs), index_(index) { } |
| 2818 | 2769 |
| 2819 inline PropertyType type() { return descs_->GetType(index_); } | 2770 inline PropertyType type(); |
| 2820 inline Object* GetCallbackObject() { return descs_->GetValue(index_); } | 2771 inline Object* GetCallbackObject(); |
| 2821 | 2772 |
| 2822 private: | 2773 private: |
| 2823 DescriptorArray* descs_; | 2774 DescriptorArray* descs_; |
| 2824 int index_; | 2775 int index_; |
| 2825 }; | 2776 }; |
| 2826 | 2777 |
| 2827 // Conversion from descriptor number to array indices. | 2778 // Conversion from descriptor number to array indices. |
| 2828 static int ToKeyIndex(int descriptor_number) { | 2779 static int ToKeyIndex(int descriptor_number) { |
| 2829 return kFirstIndex + | 2780 return kFirstIndex + |
| 2830 (descriptor_number * kDescriptorSize) + | 2781 (descriptor_number * kDescriptorSize) + |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2911 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) { | 2862 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) { |
| 2912 DCHECK(UsesSeed); | 2863 DCHECK(UsesSeed); |
| 2913 return HashForObject(key, object); | 2864 return HashForObject(key, object); |
| 2914 } | 2865 } |
| 2915 }; | 2866 }; |
| 2916 | 2867 |
| 2917 | 2868 |
| 2918 class HashTableBase : public FixedArray { | 2869 class HashTableBase : public FixedArray { |
| 2919 public: | 2870 public: |
| 2920 // Returns the number of elements in the hash table. | 2871 // Returns the number of elements in the hash table. |
| 2921 int NumberOfElements() { | 2872 inline int NumberOfElements(); |
| 2922 return Smi::cast(get(kNumberOfElementsIndex))->value(); | |
| 2923 } | |
| 2924 | 2873 |
| 2925 // Returns the number of deleted elements in the hash table. | 2874 // Returns the number of deleted elements in the hash table. |
| 2926 int NumberOfDeletedElements() { | 2875 inline int NumberOfDeletedElements(); |
| 2927 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); | |
| 2928 } | |
| 2929 | 2876 |
| 2930 // Returns the capacity of the hash table. | 2877 // Returns the capacity of the hash table. |
| 2931 int Capacity() { | 2878 inline int Capacity(); |
| 2932 return Smi::cast(get(kCapacityIndex))->value(); | |
| 2933 } | |
| 2934 | 2879 |
| 2935 // ElementAdded should be called whenever an element is added to a | 2880 // ElementAdded should be called whenever an element is added to a |
| 2936 // hash table. | 2881 // hash table. |
| 2937 void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); } | 2882 inline void ElementAdded(); |
| 2938 | 2883 |
| 2939 // ElementRemoved should be called whenever an element is removed from | 2884 // ElementRemoved should be called whenever an element is removed from |
| 2940 // a hash table. | 2885 // a hash table. |
| 2941 void ElementRemoved() { | 2886 inline void ElementRemoved(); |
| 2942 SetNumberOfElements(NumberOfElements() - 1); | 2887 inline void ElementsRemoved(int n); |
| 2943 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); | |
| 2944 } | |
| 2945 void ElementsRemoved(int n) { | |
| 2946 SetNumberOfElements(NumberOfElements() - n); | |
| 2947 SetNumberOfDeletedElements(NumberOfDeletedElements() + n); | |
| 2948 } | |
| 2949 | 2888 |
| 2950 // Computes the required capacity for a table holding the given | 2889 // Computes the required capacity for a table holding the given |
| 2951 // number of elements. May be more than HashTable::kMaxCapacity. | 2890 // number of elements. May be more than HashTable::kMaxCapacity. |
| 2952 static inline int ComputeCapacity(int at_least_space_for); | 2891 static inline int ComputeCapacity(int at_least_space_for); |
| 2953 | 2892 |
| 2954 // Tells whether k is a real key. The hole and undefined are not allowed | 2893 // Tells whether k is a real key. The hole and undefined are not allowed |
| 2955 // as keys and can be used to indicate missing or deleted elements. | 2894 // as keys and can be used to indicate missing or deleted elements. |
| 2956 bool IsKey(Object* k) { | 2895 inline bool IsKey(Object* k); |
| 2957 return !k->IsTheHole() && !k->IsUndefined(); | |
| 2958 } | |
| 2959 | 2896 |
| 2960 // Compute the probe offset (quadratic probing). | 2897 // Compute the probe offset (quadratic probing). |
| 2961 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { | 2898 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { |
| 2962 return (n + n * n) >> 1; | 2899 return (n + n * n) >> 1; |
| 2963 } | 2900 } |
| 2964 | 2901 |
| 2965 static const int kNumberOfElementsIndex = 0; | 2902 static const int kNumberOfElementsIndex = 0; |
| 2966 static const int kNumberOfDeletedElementsIndex = 1; | 2903 static const int kNumberOfDeletedElementsIndex = 1; |
| 2967 static const int kCapacityIndex = 2; | 2904 static const int kCapacityIndex = 2; |
| 2968 static const int kPrefixStartIndex = 3; | 2905 static const int kPrefixStartIndex = 3; |
| 2969 | 2906 |
| 2970 // Constant used for denoting a absent entry. | 2907 // Constant used for denoting a absent entry. |
| 2971 static const int kNotFound = -1; | 2908 static const int kNotFound = -1; |
| 2972 | 2909 |
| 2973 protected: | 2910 protected: |
| 2974 // Update the number of elements in the hash table. | 2911 // Update the number of elements in the hash table. |
| 2975 void SetNumberOfElements(int nof) { | 2912 inline void SetNumberOfElements(int nof); |
| 2976 set(kNumberOfElementsIndex, Smi::FromInt(nof)); | |
| 2977 } | |
| 2978 | 2913 |
| 2979 // Update the number of deleted elements in the hash table. | 2914 // Update the number of deleted elements in the hash table. |
| 2980 void SetNumberOfDeletedElements(int nod) { | 2915 inline void SetNumberOfDeletedElements(int nod); |
| 2981 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); | |
| 2982 } | |
| 2983 | 2916 |
| 2984 // Returns probe entry. | 2917 // Returns probe entry. |
| 2985 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { | 2918 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { |
| 2986 DCHECK(base::bits::IsPowerOfTwo32(size)); | 2919 DCHECK(base::bits::IsPowerOfTwo32(size)); |
| 2987 return (hash + GetProbeOffset(number)) & (size - 1); | 2920 return (hash + GetProbeOffset(number)) & (size - 1); |
| 2988 } | 2921 } |
| 2989 | 2922 |
| 2990 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) { | 2923 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) { |
| 2991 return hash & (size - 1); | 2924 return hash & (size - 1); |
| 2992 } | 2925 } |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3734 | 3667 |
| 3735 | 3668 |
| 3736 class JSMapIterator; | 3669 class JSMapIterator; |
| 3737 | 3670 |
| 3738 | 3671 |
| 3739 class OrderedHashMap | 3672 class OrderedHashMap |
| 3740 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> { | 3673 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> { |
| 3741 public: | 3674 public: |
| 3742 DECLARE_CAST(OrderedHashMap) | 3675 DECLARE_CAST(OrderedHashMap) |
| 3743 | 3676 |
| 3744 Object* ValueAt(int entry) { | 3677 inline Object* ValueAt(int entry); |
| 3745 return get(EntryToIndex(entry) + kValueOffset); | |
| 3746 } | |
| 3747 | 3678 |
| 3748 static const int kValueOffset = 1; | 3679 static const int kValueOffset = 1; |
| 3749 }; | 3680 }; |
| 3750 | 3681 |
| 3751 | 3682 |
| 3752 template <int entrysize> | 3683 template <int entrysize> |
| 3753 class WeakHashTableShape : public BaseShape<Handle<Object> > { | 3684 class WeakHashTableShape : public BaseShape<Handle<Object> > { |
| 3754 public: | 3685 public: |
| 3755 static inline bool IsMatch(Handle<Object> key, Object* other); | 3686 static inline bool IsMatch(Handle<Object> key, Object* other); |
| 3756 static inline uint32_t Hash(Handle<Object> key); | 3687 static inline uint32_t Hash(Handle<Object> key); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3868 // Is this scope the scope of a named function expression? | 3799 // Is this scope the scope of a named function expression? |
| 3869 bool HasFunctionName(); | 3800 bool HasFunctionName(); |
| 3870 | 3801 |
| 3871 // Return if this has context allocated locals. | 3802 // Return if this has context allocated locals. |
| 3872 bool HasHeapAllocatedLocals(); | 3803 bool HasHeapAllocatedLocals(); |
| 3873 | 3804 |
| 3874 // Return if contexts are allocated for this scope. | 3805 // Return if contexts are allocated for this scope. |
| 3875 bool HasContext(); | 3806 bool HasContext(); |
| 3876 | 3807 |
| 3877 // Return if this is a function scope with "use asm". | 3808 // Return if this is a function scope with "use asm". |
| 3878 bool IsAsmModule() { return AsmModuleField::decode(Flags()); } | 3809 inline bool IsAsmModule(); |
| 3879 | 3810 |
| 3880 // Return if this is a nested function within an asm module scope. | 3811 // Return if this is a nested function within an asm module scope. |
| 3881 bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); } | 3812 inline bool IsAsmFunction(); |
| 3882 | 3813 |
| 3883 bool HasSimpleParameters() { | 3814 inline bool HasSimpleParameters(); |
| 3884 return HasSimpleParametersField::decode(Flags()); | |
| 3885 } | |
| 3886 | 3815 |
| 3887 // Return the function_name if present. | 3816 // Return the function_name if present. |
| 3888 String* FunctionName(); | 3817 String* FunctionName(); |
| 3889 | 3818 |
| 3890 // Return the name of the given parameter. | 3819 // Return the name of the given parameter. |
| 3891 String* ParameterName(int var); | 3820 String* ParameterName(int var); |
| 3892 | 3821 |
| 3893 // Return the name of the given local. | 3822 // Return the name of the given local. |
| 3894 String* LocalName(int var); | 3823 String* LocalName(int var); |
| 3895 | 3824 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3967 #endif | 3896 #endif |
| 3968 | 3897 |
| 3969 // The layout of the static part of a ScopeInfo is as follows. Each entry is | 3898 // The layout of the static part of a ScopeInfo is as follows. Each entry is |
| 3970 // numeric and occupies one array slot. | 3899 // numeric and occupies one array slot. |
| 3971 // 1. A set of properties of the scope | 3900 // 1. A set of properties of the scope |
| 3972 // 2. The number of parameters. This only applies to function scopes. For | 3901 // 2. The number of parameters. This only applies to function scopes. For |
| 3973 // non-function scopes this is 0. | 3902 // non-function scopes this is 0. |
| 3974 // 3. The number of non-parameter variables allocated on the stack. | 3903 // 3. The number of non-parameter variables allocated on the stack. |
| 3975 // 4. The number of non-parameter and parameter variables allocated in the | 3904 // 4. The number of non-parameter and parameter variables allocated in the |
| 3976 // context. | 3905 // context. |
| 3977 #define FOR_EACH_NUMERIC_FIELD(V) \ | 3906 #define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \ |
| 3978 V(Flags) \ | 3907 V(Flags) \ |
| 3979 V(ParameterCount) \ | 3908 V(ParameterCount) \ |
| 3980 V(StackLocalCount) \ | 3909 V(StackLocalCount) \ |
| 3981 V(ContextLocalCount) \ | 3910 V(ContextLocalCount) \ |
| 3982 V(ContextGlobalCount) \ | 3911 V(ContextGlobalCount) \ |
| 3983 V(StrongModeFreeVariableCount) | 3912 V(StrongModeFreeVariableCount) |
| 3984 | 3913 |
| 3985 #define FIELD_ACCESSORS(name) \ | 3914 #define FIELD_ACCESSORS(name) \ |
| 3986 void Set##name(int value) { \ | 3915 inline void Set##name(int value); \ |
| 3987 set(k##name, Smi::FromInt(value)); \ | 3916 inline int name(); |
| 3988 } \ | 3917 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS) |
| 3989 int name() { \ | |
| 3990 if (length() > 0) { \ | |
| 3991 return Smi::cast(get(k##name))->value(); \ | |
| 3992 } else { \ | |
| 3993 return 0; \ | |
| 3994 } \ | |
| 3995 } | |
| 3996 FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS) | |
| 3997 #undef FIELD_ACCESSORS | 3918 #undef FIELD_ACCESSORS |
| 3998 | 3919 |
| 3999 private: | 3920 private: |
| 4000 enum { | 3921 enum { |
| 4001 #define DECL_INDEX(name) k##name, | 3922 #define DECL_INDEX(name) k##name, |
| 4002 FOR_EACH_NUMERIC_FIELD(DECL_INDEX) | 3923 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX) |
| 4003 #undef DECL_INDEX | 3924 #undef DECL_INDEX |
| 4004 #undef FOR_EACH_NUMERIC_FIELD | |
| 4005 kVariablePartIndex | 3925 kVariablePartIndex |
| 4006 }; | 3926 }; |
| 4007 | 3927 |
| 4008 // The layout of the variable part of a ScopeInfo is as follows: | 3928 // The layout of the variable part of a ScopeInfo is as follows: |
| 4009 // 1. ParameterEntries: | 3929 // 1. ParameterEntries: |
| 4010 // This part stores the names of the parameters for function scopes. One | 3930 // This part stores the names of the parameters for function scopes. One |
| 4011 // slot is used per parameter, so in total this part occupies | 3931 // slot is used per parameter, so in total this part occupies |
| 4012 // ParameterCount() slots in the array. For other scopes than function | 3932 // ParameterCount() slots in the array. For other scopes than function |
| 4013 // scopes ParameterCount() is 0. | 3933 // scopes ParameterCount() is 0. |
| 4014 // 2. StackLocalFirstSlot: | 3934 // 2. StackLocalFirstSlot: |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4122 // The following declarations hide base class methods. | 4042 // The following declarations hide base class methods. |
| 4123 Object* get(int index); | 4043 Object* get(int index); |
| 4124 void set(int index, Object* value); | 4044 void set(int index, Object* value); |
| 4125 }; | 4045 }; |
| 4126 | 4046 |
| 4127 | 4047 |
| 4128 // ByteArray represents fixed sized byte arrays. Used for the relocation info | 4048 // ByteArray represents fixed sized byte arrays. Used for the relocation info |
| 4129 // that is attached to code objects. | 4049 // that is attached to code objects. |
| 4130 class ByteArray: public FixedArrayBase { | 4050 class ByteArray: public FixedArrayBase { |
| 4131 public: | 4051 public: |
| 4132 inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); } | 4052 inline int Size(); |
| 4133 | 4053 |
| 4134 // Setter and getter. | 4054 // Setter and getter. |
| 4135 inline byte get(int index); | 4055 inline byte get(int index); |
| 4136 inline void set(int index, byte value); | 4056 inline void set(int index, byte value); |
| 4137 | 4057 |
| 4138 // Treat contents as an int array. | 4058 // Treat contents as an int array. |
| 4139 inline int get_int(int index); | 4059 inline int get_int(int index); |
| 4140 | 4060 |
| 4141 static int SizeFor(int length) { | 4061 static int SizeFor(int length) { |
| 4142 return OBJECT_POINTER_ALIGN(kHeaderSize + length); | 4062 return OBJECT_POINTER_ALIGN(kHeaderSize + length); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4153 | 4073 |
| 4154 // Returns data start address. | 4074 // Returns data start address. |
| 4155 inline Address GetDataStartAddress(); | 4075 inline Address GetDataStartAddress(); |
| 4156 | 4076 |
| 4157 // Returns a pointer to the ByteArray object for a given data start address. | 4077 // Returns a pointer to the ByteArray object for a given data start address. |
| 4158 static inline ByteArray* FromDataStartAddress(Address address); | 4078 static inline ByteArray* FromDataStartAddress(Address address); |
| 4159 | 4079 |
| 4160 DECLARE_CAST(ByteArray) | 4080 DECLARE_CAST(ByteArray) |
| 4161 | 4081 |
| 4162 // Dispatched behavior. | 4082 // Dispatched behavior. |
| 4163 inline int ByteArraySize() { | 4083 inline int ByteArraySize(); |
| 4164 return SizeFor(this->length()); | |
| 4165 } | |
| 4166 DECLARE_PRINTER(ByteArray) | 4084 DECLARE_PRINTER(ByteArray) |
| 4167 DECLARE_VERIFIER(ByteArray) | 4085 DECLARE_VERIFIER(ByteArray) |
| 4168 | 4086 |
| 4169 // Layout description. | 4087 // Layout description. |
| 4170 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); | 4088 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); |
| 4171 | 4089 |
| 4172 // Maximal memory consumption for a single ByteArray. | 4090 // Maximal memory consumption for a single ByteArray. |
| 4173 static const int kMaxSize = 512 * MB; | 4091 static const int kMaxSize = 512 * MB; |
| 4174 // Maximal length of a single ByteArray. | 4092 // Maximal length of a single ByteArray. |
| 4175 static const int kMaxLength = kMaxSize - kHeaderSize; | 4093 static const int kMaxLength = kMaxSize - kHeaderSize; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4193 // Returns data start address. | 4111 // Returns data start address. |
| 4194 inline Address GetFirstBytecodeAddress(); | 4112 inline Address GetFirstBytecodeAddress(); |
| 4195 | 4113 |
| 4196 // Accessors for frame size and the number of locals | 4114 // Accessors for frame size and the number of locals |
| 4197 inline int frame_size() const; | 4115 inline int frame_size() const; |
| 4198 inline void set_frame_size(int value); | 4116 inline void set_frame_size(int value); |
| 4199 | 4117 |
| 4200 DECLARE_CAST(BytecodeArray) | 4118 DECLARE_CAST(BytecodeArray) |
| 4201 | 4119 |
| 4202 // Dispatched behavior. | 4120 // Dispatched behavior. |
| 4203 inline int BytecodeArraySize() { return SizeFor(this->length()); } | 4121 inline int BytecodeArraySize(); |
| 4204 | 4122 |
| 4205 DECLARE_PRINTER(BytecodeArray) | 4123 DECLARE_PRINTER(BytecodeArray) |
| 4206 DECLARE_VERIFIER(BytecodeArray) | 4124 DECLARE_VERIFIER(BytecodeArray) |
| 4207 | 4125 |
| 4208 void Disassemble(std::ostream& os); | 4126 void Disassemble(std::ostream& os); |
| 4209 | 4127 |
| 4210 // Layout description. | 4128 // Layout description. |
| 4211 static const int kFrameSizeOffset = FixedArrayBase::kHeaderSize; | 4129 static const int kFrameSizeOffset = FixedArrayBase::kHeaderSize; |
| 4212 static const int kHeaderSize = kFrameSizeOffset + kIntSize; | 4130 static const int kHeaderSize = kFrameSizeOffset + kIntSize; |
| 4213 | 4131 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4230 // in the free list. | 4148 // in the free list. |
| 4231 class FreeSpace: public HeapObject { | 4149 class FreeSpace: public HeapObject { |
| 4232 public: | 4150 public: |
| 4233 // [size]: size of the free space including the header. | 4151 // [size]: size of the free space including the header. |
| 4234 inline int size() const; | 4152 inline int size() const; |
| 4235 inline void set_size(int value); | 4153 inline void set_size(int value); |
| 4236 | 4154 |
| 4237 inline int nobarrier_size() const; | 4155 inline int nobarrier_size() const; |
| 4238 inline void nobarrier_set_size(int value); | 4156 inline void nobarrier_set_size(int value); |
| 4239 | 4157 |
| 4240 inline int Size() { return size(); } | 4158 inline int Size(); |
| 4241 | 4159 |
| 4242 // Accessors for the next field. | 4160 // Accessors for the next field. |
| 4243 inline FreeSpace* next(); | 4161 inline FreeSpace* next(); |
| 4244 inline FreeSpace** next_address(); | 4162 inline FreeSpace** next_address(); |
| 4245 inline void set_next(FreeSpace* next); | 4163 inline void set_next(FreeSpace* next); |
| 4246 | 4164 |
| 4247 inline static FreeSpace* cast(HeapObject* obj); | 4165 inline static FreeSpace* cast(HeapObject* obj); |
| 4248 | 4166 |
| 4249 // Dispatched behavior. | 4167 // Dispatched behavior. |
| 4250 DECLARE_PRINTER(FreeSpace) | 4168 DECLARE_PRINTER(FreeSpace) |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 static const int kFirstDeoptEntryIndex = 8; | 4300 static const int kFirstDeoptEntryIndex = 8; |
| 4383 | 4301 |
| 4384 // Offsets of deopt entry elements relative to the start of the entry. | 4302 // Offsets of deopt entry elements relative to the start of the entry. |
| 4385 static const int kAstIdRawOffset = 0; | 4303 static const int kAstIdRawOffset = 0; |
| 4386 static const int kTranslationIndexOffset = 1; | 4304 static const int kTranslationIndexOffset = 1; |
| 4387 static const int kArgumentsStackHeightOffset = 2; | 4305 static const int kArgumentsStackHeightOffset = 2; |
| 4388 static const int kPcOffset = 3; | 4306 static const int kPcOffset = 3; |
| 4389 static const int kDeoptEntrySize = 4; | 4307 static const int kDeoptEntrySize = 4; |
| 4390 | 4308 |
| 4391 // Simple element accessors. | 4309 // Simple element accessors. |
| 4392 #define DEFINE_ELEMENT_ACCESSORS(name, type) \ | 4310 #define DECLARE_ELEMENT_ACCESSORS(name, type) \ |
| 4393 type* name() { \ | 4311 inline type* name(); \ |
| 4394 return type::cast(get(k##name##Index)); \ | 4312 inline void Set##name(type* value); |
| 4395 } \ | |
| 4396 void Set##name(type* value) { \ | |
| 4397 set(k##name##Index, value); \ | |
| 4398 } | |
| 4399 | 4313 |
| 4400 DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) | 4314 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) |
| 4401 DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) | 4315 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) |
| 4402 DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray) | 4316 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray) |
| 4403 DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi) | 4317 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi) |
| 4404 DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi) | 4318 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi) |
| 4405 DEFINE_ELEMENT_ACCESSORS(OptimizationId, Smi) | 4319 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi) |
| 4406 DEFINE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) | 4320 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) |
| 4407 DEFINE_ELEMENT_ACCESSORS(WeakCellCache, Object) | 4321 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object) |
| 4408 | 4322 |
| 4409 #undef DEFINE_ELEMENT_ACCESSORS | 4323 #undef DECLARE_ELEMENT_ACCESSORS |
| 4410 | 4324 |
| 4411 // Accessors for elements of the ith deoptimization entry. | 4325 // Accessors for elements of the ith deoptimization entry. |
| 4412 #define DEFINE_ENTRY_ACCESSORS(name, type) \ | 4326 #define DECLARE_ENTRY_ACCESSORS(name, type) \ |
| 4413 type* name(int i) { \ | 4327 inline type* name(int i); \ |
| 4414 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \ | 4328 inline void Set##name(int i, type* value); |
| 4415 } \ | |
| 4416 void Set##name(int i, type* value) { \ | |
| 4417 set(IndexForEntry(i) + k##name##Offset, value); \ | |
| 4418 } | |
| 4419 | 4329 |
| 4420 DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi) | 4330 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi) |
| 4421 DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi) | 4331 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi) |
| 4422 DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) | 4332 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) |
| 4423 DEFINE_ENTRY_ACCESSORS(Pc, Smi) | 4333 DECLARE_ENTRY_ACCESSORS(Pc, Smi) |
| 4424 | 4334 |
| 4425 #undef DEFINE_DEOPT_ENTRY_ACCESSORS | 4335 #undef DECLARE_ENTRY_ACCESSORS |
| 4426 | 4336 |
| 4427 BailoutId AstId(int i) { | 4337 inline BailoutId AstId(int i); |
| 4428 return BailoutId(AstIdRaw(i)->value()); | |
| 4429 } | |
| 4430 | 4338 |
| 4431 void SetAstId(int i, BailoutId value) { | 4339 inline void SetAstId(int i, BailoutId value); |
| 4432 SetAstIdRaw(i, Smi::FromInt(value.ToInt())); | |
| 4433 } | |
| 4434 | 4340 |
| 4435 int DeoptCount() { | 4341 inline int DeoptCount(); |
| 4436 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; | |
| 4437 } | |
| 4438 | 4342 |
| 4439 // Allocates a DeoptimizationInputData. | 4343 // Allocates a DeoptimizationInputData. |
| 4440 static Handle<DeoptimizationInputData> New(Isolate* isolate, | 4344 static Handle<DeoptimizationInputData> New(Isolate* isolate, |
| 4441 int deopt_entry_count, | 4345 int deopt_entry_count, |
| 4442 PretenureFlag pretenure); | 4346 PretenureFlag pretenure); |
| 4443 | 4347 |
| 4444 DECLARE_CAST(DeoptimizationInputData) | 4348 DECLARE_CAST(DeoptimizationInputData) |
| 4445 | 4349 |
| 4446 #ifdef ENABLE_DISASSEMBLER | 4350 #ifdef ENABLE_DISASSEMBLER |
| 4447 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT | 4351 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT |
| 4448 #endif | 4352 #endif |
| 4449 | 4353 |
| 4450 private: | 4354 private: |
| 4451 static int IndexForEntry(int i) { | 4355 static int IndexForEntry(int i) { |
| 4452 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); | 4356 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); |
| 4453 } | 4357 } |
| 4454 | 4358 |
| 4455 | 4359 |
| 4456 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); } | 4360 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); } |
| 4457 }; | 4361 }; |
| 4458 | 4362 |
| 4459 | 4363 |
| 4460 // DeoptimizationOutputData is a fixed array used to hold the deoptimization | 4364 // DeoptimizationOutputData is a fixed array used to hold the deoptimization |
| 4461 // data for code generated by the full compiler. | 4365 // data for code generated by the full compiler. |
| 4462 // The format of the these objects is | 4366 // The format of the these objects is |
| 4463 // [i * 2]: Ast ID for ith deoptimization. | 4367 // [i * 2]: Ast ID for ith deoptimization. |
| 4464 // [i * 2 + 1]: PC and state of ith deoptimization | 4368 // [i * 2 + 1]: PC and state of ith deoptimization |
| 4465 class DeoptimizationOutputData: public FixedArray { | 4369 class DeoptimizationOutputData: public FixedArray { |
| 4466 public: | 4370 public: |
| 4467 int DeoptPoints() { return length() / 2; } | 4371 inline int DeoptPoints(); |
| 4468 | 4372 |
| 4469 BailoutId AstId(int index) { | 4373 inline BailoutId AstId(int index); |
| 4470 return BailoutId(Smi::cast(get(index * 2))->value()); | |
| 4471 } | |
| 4472 | 4374 |
| 4473 void SetAstId(int index, BailoutId id) { | 4375 inline void SetAstId(int index, BailoutId id); |
| 4474 set(index * 2, Smi::FromInt(id.ToInt())); | |
| 4475 } | |
| 4476 | 4376 |
| 4477 Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); } | 4377 inline Smi* PcAndState(int index); |
| 4478 void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); } | 4378 inline void SetPcAndState(int index, Smi* offset); |
| 4479 | 4379 |
| 4480 static int LengthOfFixedArray(int deopt_points) { | 4380 static int LengthOfFixedArray(int deopt_points) { |
| 4481 return deopt_points * 2; | 4381 return deopt_points * 2; |
| 4482 } | 4382 } |
| 4483 | 4383 |
| 4484 // Allocates a DeoptimizationOutputData. | 4384 // Allocates a DeoptimizationOutputData. |
| 4485 static Handle<DeoptimizationOutputData> New(Isolate* isolate, | 4385 static Handle<DeoptimizationOutputData> New(Isolate* isolate, |
| 4486 int number_of_deopt_points, | 4386 int number_of_deopt_points, |
| 4487 PretenureFlag pretenure); | 4387 PretenureFlag pretenure); |
| 4488 | 4388 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4504 // per call-site that could throw an exception. Layout looks as follows: | 4404 // per call-site that could throw an exception. Layout looks as follows: |
| 4505 // [ return-address-offset , handler-offset ] | 4405 // [ return-address-offset , handler-offset ] |
| 4506 class HandlerTable : public FixedArray { | 4406 class HandlerTable : public FixedArray { |
| 4507 public: | 4407 public: |
| 4508 // Conservative prediction whether a given handler will locally catch an | 4408 // Conservative prediction whether a given handler will locally catch an |
| 4509 // exception or cause a re-throw to outside the code boundary. Since this is | 4409 // exception or cause a re-throw to outside the code boundary. Since this is |
| 4510 // undecidable it is merely an approximation (e.g. useful for debugger). | 4410 // undecidable it is merely an approximation (e.g. useful for debugger). |
| 4511 enum CatchPrediction { UNCAUGHT, CAUGHT }; | 4411 enum CatchPrediction { UNCAUGHT, CAUGHT }; |
| 4512 | 4412 |
| 4513 // Accessors for handler table based on ranges. | 4413 // Accessors for handler table based on ranges. |
| 4514 void SetRangeStart(int index, int value) { | 4414 inline void SetRangeStart(int index, int value); |
| 4515 set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value)); | 4415 inline void SetRangeEnd(int index, int value); |
| 4516 } | 4416 inline void SetRangeHandler(int index, int offset, CatchPrediction pred); |
| 4517 void SetRangeEnd(int index, int value) { | 4417 inline void SetRangeDepth(int index, int value); |
| 4518 set(index * kRangeEntrySize + kRangeEndIndex, Smi::FromInt(value)); | |
| 4519 } | |
| 4520 void SetRangeHandler(int index, int offset, CatchPrediction prediction) { | |
| 4521 int value = HandlerOffsetField::encode(offset) | | |
| 4522 HandlerPredictionField::encode(prediction); | |
| 4523 set(index * kRangeEntrySize + kRangeHandlerIndex, Smi::FromInt(value)); | |
| 4524 } | |
| 4525 void SetRangeDepth(int index, int value) { | |
| 4526 set(index * kRangeEntrySize + kRangeDepthIndex, Smi::FromInt(value)); | |
| 4527 } | |
| 4528 | 4418 |
| 4529 // Accessors for handler table based on return addresses. | 4419 // Accessors for handler table based on return addresses. |
| 4530 void SetReturnOffset(int index, int value) { | 4420 inline void SetReturnOffset(int index, int value); |
| 4531 set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value)); | 4421 inline void SetReturnHandler(int index, int offset, CatchPrediction pred); |
| 4532 } | |
| 4533 void SetReturnHandler(int index, int offset, CatchPrediction prediction) { | |
| 4534 int value = HandlerOffsetField::encode(offset) | | |
| 4535 HandlerPredictionField::encode(prediction); | |
| 4536 set(index * kReturnEntrySize + kReturnHandlerIndex, Smi::FromInt(value)); | |
| 4537 } | |
| 4538 | 4422 |
| 4539 // Lookup handler in a table based on ranges. | 4423 // Lookup handler in a table based on ranges. |
| 4540 int LookupRange(int pc_offset, int* stack_depth, CatchPrediction* prediction); | 4424 int LookupRange(int pc_offset, int* stack_depth, CatchPrediction* prediction); |
| 4541 | 4425 |
| 4542 // Lookup handler in a table based on return addresses. | 4426 // Lookup handler in a table based on return addresses. |
| 4543 int LookupReturn(int pc_offset, CatchPrediction* prediction); | 4427 int LookupReturn(int pc_offset, CatchPrediction* prediction); |
| 4544 | 4428 |
| 4545 // Returns the required length of the underlying fixed array. | 4429 // Returns the required length of the underlying fixed array. |
| 4546 static int LengthForRange(int entries) { return entries * kRangeEntrySize; } | 4430 static int LengthForRange(int entries) { return entries * kRangeEntrySize; } |
| 4547 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; } | 4431 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4694 // [flags]: Access to specific code flags. | 4578 // [flags]: Access to specific code flags. |
| 4695 inline Kind kind(); | 4579 inline Kind kind(); |
| 4696 inline InlineCacheState ic_state(); // Only valid for IC stubs. | 4580 inline InlineCacheState ic_state(); // Only valid for IC stubs. |
| 4697 inline ExtraICState extra_ic_state(); // Only valid for IC stubs. | 4581 inline ExtraICState extra_ic_state(); // Only valid for IC stubs. |
| 4698 | 4582 |
| 4699 inline StubType type(); // Only valid for monomorphic IC stubs. | 4583 inline StubType type(); // Only valid for monomorphic IC stubs. |
| 4700 | 4584 |
| 4701 // Testers for IC stub kinds. | 4585 // Testers for IC stub kinds. |
| 4702 inline bool is_inline_cache_stub(); | 4586 inline bool is_inline_cache_stub(); |
| 4703 inline bool is_debug_stub(); | 4587 inline bool is_debug_stub(); |
| 4704 inline bool is_handler() { return kind() == HANDLER; } | 4588 inline bool is_handler(); |
| 4705 inline bool is_load_stub() { return kind() == LOAD_IC; } | 4589 inline bool is_load_stub(); |
| 4706 inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } | 4590 inline bool is_keyed_load_stub(); |
| 4707 inline bool is_store_stub() { return kind() == STORE_IC; } | 4591 inline bool is_store_stub(); |
| 4708 inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } | 4592 inline bool is_keyed_store_stub(); |
| 4709 inline bool is_call_stub() { return kind() == CALL_IC; } | 4593 inline bool is_call_stub(); |
| 4710 inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; } | 4594 inline bool is_binary_op_stub(); |
| 4711 inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; } | 4595 inline bool is_compare_ic_stub(); |
| 4712 inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; } | 4596 inline bool is_compare_nil_ic_stub(); |
| 4713 inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; } | 4597 inline bool is_to_boolean_ic_stub(); |
| 4714 inline bool is_keyed_stub(); | 4598 inline bool is_keyed_stub(); |
| 4715 inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; } | 4599 inline bool is_optimized_code(); |
| 4716 inline bool embeds_maps_weakly() { | 4600 inline bool embeds_maps_weakly(); |
| 4717 Kind k = kind(); | |
| 4718 return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC || | |
| 4719 k == KEYED_STORE_IC || k == COMPARE_NIL_IC) && | |
| 4720 ic_state() == MONOMORPHIC; | |
| 4721 } | |
| 4722 | 4601 |
| 4723 inline bool IsCodeStubOrIC(); | 4602 inline bool IsCodeStubOrIC(); |
| 4724 | 4603 |
| 4725 inline void set_raw_kind_specific_flags1(int value); | 4604 inline void set_raw_kind_specific_flags1(int value); |
| 4726 inline void set_raw_kind_specific_flags2(int value); | 4605 inline void set_raw_kind_specific_flags2(int value); |
| 4727 | 4606 |
| 4728 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code | 4607 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code |
| 4729 // object was generated by either the hydrogen or the TurboFan optimizing | 4608 // object was generated by either the hydrogen or the TurboFan optimizing |
| 4730 // compiler (but it may not be an optimized function). | 4609 // compiler (but it may not be an optimized function). |
| 4731 inline bool is_crankshafted(); | 4610 inline bool is_crankshafted(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4911 void CopyFrom(const CodeDesc& desc); | 4790 void CopyFrom(const CodeDesc& desc); |
| 4912 | 4791 |
| 4913 // Returns the object size for a given body (used for allocation). | 4792 // Returns the object size for a given body (used for allocation). |
| 4914 static int SizeFor(int body_size) { | 4793 static int SizeFor(int body_size) { |
| 4915 DCHECK_SIZE_TAG_ALIGNED(body_size); | 4794 DCHECK_SIZE_TAG_ALIGNED(body_size); |
| 4916 return RoundUp(kHeaderSize + body_size, kCodeAlignment); | 4795 return RoundUp(kHeaderSize + body_size, kCodeAlignment); |
| 4917 } | 4796 } |
| 4918 | 4797 |
| 4919 // Calculate the size of the code object to report for log events. This takes | 4798 // Calculate the size of the code object to report for log events. This takes |
| 4920 // the layout of the code object into account. | 4799 // the layout of the code object into account. |
| 4921 int ExecutableSize() { | 4800 inline int ExecutableSize(); |
| 4922 // Check that the assumptions about the layout of the code object holds. | |
| 4923 DCHECK_EQ(static_cast<int>(instruction_start() - address()), | |
| 4924 Code::kHeaderSize); | |
| 4925 return instruction_size() + Code::kHeaderSize; | |
| 4926 } | |
| 4927 | 4801 |
| 4928 // Locating source position. | 4802 // Locating source position. |
| 4929 int SourcePosition(Address pc); | 4803 int SourcePosition(Address pc); |
| 4930 int SourceStatementPosition(Address pc); | 4804 int SourceStatementPosition(Address pc); |
| 4931 | 4805 |
| 4932 DECLARE_CAST(Code) | 4806 DECLARE_CAST(Code) |
| 4933 | 4807 |
| 4934 // Dispatched behavior. | 4808 // Dispatched behavior. |
| 4935 int CodeSize() { return SizeFor(body_size()); } | 4809 inline int CodeSize(); |
| 4936 inline void CodeIterateBody(ObjectVisitor* v); | 4810 inline void CodeIterateBody(ObjectVisitor* v); |
| 4937 | 4811 |
| 4938 template<typename StaticVisitor> | 4812 template<typename StaticVisitor> |
| 4939 inline void CodeIterateBody(Heap* heap); | 4813 inline void CodeIterateBody(Heap* heap); |
| 4940 | 4814 |
| 4941 DECLARE_PRINTER(Code) | 4815 DECLARE_PRINTER(Code) |
| 4942 DECLARE_VERIFIER(Code) | 4816 DECLARE_VERIFIER(Code) |
| 4943 | 4817 |
| 4944 void ClearInlineCaches(); | 4818 void ClearInlineCaches(); |
| 4945 void ClearInlineCaches(Kind kind); | 4819 void ClearInlineCaches(Kind kind); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4985 #ifdef VERIFY_HEAP | 4859 #ifdef VERIFY_HEAP |
| 4986 void VerifyEmbeddedObjectsDependency(); | 4860 void VerifyEmbeddedObjectsDependency(); |
| 4987 #endif | 4861 #endif |
| 4988 | 4862 |
| 4989 #ifdef DEBUG | 4863 #ifdef DEBUG |
| 4990 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers }; | 4864 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers }; |
| 4991 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers); | 4865 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers); |
| 4992 static void VerifyRecompiledCode(Code* old_code, Code* new_code); | 4866 static void VerifyRecompiledCode(Code* old_code, Code* new_code); |
| 4993 #endif // DEBUG | 4867 #endif // DEBUG |
| 4994 | 4868 |
| 4995 inline bool CanContainWeakObjects() { | 4869 inline bool CanContainWeakObjects(); |
| 4996 // is_turbofanned() implies !can_have_weak_objects(). | |
| 4997 DCHECK(!is_optimized_code() || !is_turbofanned() || | |
| 4998 !can_have_weak_objects()); | |
| 4999 return is_optimized_code() && can_have_weak_objects(); | |
| 5000 } | |
| 5001 | 4870 |
| 5002 inline bool IsWeakObject(Object* object) { | 4871 inline bool IsWeakObject(Object* object); |
| 5003 return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object)); | |
| 5004 } | |
| 5005 | 4872 |
| 5006 static inline bool IsWeakObjectInOptimizedCode(Object* object); | 4873 static inline bool IsWeakObjectInOptimizedCode(Object* object); |
| 5007 | 4874 |
| 5008 static Handle<WeakCell> WeakCellFor(Handle<Code> code); | 4875 static Handle<WeakCell> WeakCellFor(Handle<Code> code); |
| 5009 WeakCell* CachedWeakCell(); | 4876 WeakCell* CachedWeakCell(); |
| 5010 | 4877 |
| 5011 // Max loop nesting marker used to postpose OSR. We don't take loop | 4878 // Max loop nesting marker used to postpose OSR. We don't take loop |
| 5012 // nesting that is deeper than 5 levels into account. | 4879 // nesting that is deeper than 5 levels into account. |
| 5013 static const int kMaxLoopNestingMarker = 6; | 4880 static const int kMaxLoopNestingMarker = 6; |
| 5014 | 4881 |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5343 inline bool has_non_instance_prototype(); | 5210 inline bool has_non_instance_prototype(); |
| 5344 | 5211 |
| 5345 // Tells whether function has special prototype property. If not, prototype | 5212 // Tells whether function has special prototype property. If not, prototype |
| 5346 // property will not be created when accessed (will return undefined), | 5213 // property will not be created when accessed (will return undefined), |
| 5347 // and construction from this function will not be allowed. | 5214 // and construction from this function will not be allowed. |
| 5348 inline void set_function_with_prototype(bool value); | 5215 inline void set_function_with_prototype(bool value); |
| 5349 inline bool function_with_prototype(); | 5216 inline bool function_with_prototype(); |
| 5350 | 5217 |
| 5351 // Tells whether the instance with this map should be ignored by the | 5218 // Tells whether the instance with this map should be ignored by the |
| 5352 // Object.getPrototypeOf() function and the __proto__ accessor. | 5219 // Object.getPrototypeOf() function and the __proto__ accessor. |
| 5353 inline void set_is_hidden_prototype() { | 5220 inline void set_is_hidden_prototype(); |
| 5354 set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); | 5221 inline bool is_hidden_prototype(); |
| 5355 } | |
| 5356 | |
| 5357 inline bool is_hidden_prototype() { | |
| 5358 return ((1 << kIsHiddenPrototype) & bit_field()) != 0; | |
| 5359 } | |
| 5360 | 5222 |
| 5361 // Records and queries whether the instance has a named interceptor. | 5223 // Records and queries whether the instance has a named interceptor. |
| 5362 inline void set_has_named_interceptor() { | 5224 inline void set_has_named_interceptor(); |
| 5363 set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); | 5225 inline bool has_named_interceptor(); |
| 5364 } | |
| 5365 | |
| 5366 inline bool has_named_interceptor() { | |
| 5367 return ((1 << kHasNamedInterceptor) & bit_field()) != 0; | |
| 5368 } | |
| 5369 | 5226 |
| 5370 // Records and queries whether the instance has an indexed interceptor. | 5227 // Records and queries whether the instance has an indexed interceptor. |
| 5371 inline void set_has_indexed_interceptor() { | 5228 inline void set_has_indexed_interceptor(); |
| 5372 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); | 5229 inline bool has_indexed_interceptor(); |
| 5373 } | |
| 5374 | |
| 5375 inline bool has_indexed_interceptor() { | |
| 5376 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; | |
| 5377 } | |
| 5378 | 5230 |
| 5379 // Tells whether the instance is undetectable. | 5231 // Tells whether the instance is undetectable. |
| 5380 // An undetectable object is a special class of JSObject: 'typeof' operator | 5232 // An undetectable object is a special class of JSObject: 'typeof' operator |
| 5381 // returns undefined, ToBoolean returns false. Otherwise it behaves like | 5233 // returns undefined, ToBoolean returns false. Otherwise it behaves like |
| 5382 // a normal JS object. It is useful for implementing undetectable | 5234 // a normal JS object. It is useful for implementing undetectable |
| 5383 // document.all in Firefox & Safari. | 5235 // document.all in Firefox & Safari. |
| 5384 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. | 5236 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. |
| 5385 inline void set_is_undetectable() { | 5237 inline void set_is_undetectable(); |
| 5386 set_bit_field(bit_field() | (1 << kIsUndetectable)); | 5238 inline bool is_undetectable(); |
| 5387 } | |
| 5388 | |
| 5389 inline bool is_undetectable() { | |
| 5390 return ((1 << kIsUndetectable) & bit_field()) != 0; | |
| 5391 } | |
| 5392 | 5239 |
| 5393 // Tells whether the instance has a call-as-function handler. | 5240 // Tells whether the instance has a call-as-function handler. |
| 5394 inline void set_is_observed() { | 5241 inline void set_is_observed(); |
| 5395 set_bit_field(bit_field() | (1 << kIsObserved)); | 5242 inline bool is_observed(); |
| 5396 } | |
| 5397 | |
| 5398 inline bool is_observed() { | |
| 5399 return ((1 << kIsObserved) & bit_field()) != 0; | |
| 5400 } | |
| 5401 | 5243 |
| 5402 inline void set_is_strong(); | 5244 inline void set_is_strong(); |
| 5403 inline bool is_strong(); | 5245 inline bool is_strong(); |
| 5404 inline void set_is_extensible(bool value); | 5246 inline void set_is_extensible(bool value); |
| 5405 inline bool is_extensible(); | 5247 inline bool is_extensible(); |
| 5406 inline void set_is_prototype_map(bool value); | 5248 inline void set_is_prototype_map(bool value); |
| 5407 inline bool is_prototype_map() const; | 5249 inline bool is_prototype_map() const; |
| 5408 | 5250 |
| 5409 inline void set_elements_kind(ElementsKind elements_kind) { | 5251 inline void set_elements_kind(ElementsKind elements_kind); |
| 5410 DCHECK(static_cast<int>(elements_kind) < kElementsKindCount); | 5252 inline ElementsKind elements_kind(); |
| 5411 DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize)); | |
| 5412 set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind)); | |
| 5413 DCHECK(this->elements_kind() == elements_kind); | |
| 5414 } | |
| 5415 | |
| 5416 inline ElementsKind elements_kind() { | |
| 5417 return Map::ElementsKindBits::decode(bit_field2()); | |
| 5418 } | |
| 5419 | 5253 |
| 5420 // Tells whether the instance has fast elements that are only Smis. | 5254 // Tells whether the instance has fast elements that are only Smis. |
| 5421 inline bool has_fast_smi_elements() { | 5255 inline bool has_fast_smi_elements(); |
| 5422 return IsFastSmiElementsKind(elements_kind()); | |
| 5423 } | |
| 5424 | 5256 |
| 5425 // Tells whether the instance has fast elements. | 5257 // Tells whether the instance has fast elements. |
| 5426 inline bool has_fast_object_elements() { | 5258 inline bool has_fast_object_elements(); |
| 5427 return IsFastObjectElementsKind(elements_kind()); | 5259 inline bool has_fast_smi_or_object_elements(); |
| 5428 } | 5260 inline bool has_fast_double_elements(); |
| 5429 | 5261 inline bool has_fast_elements(); |
| 5430 inline bool has_fast_smi_or_object_elements() { | 5262 inline bool has_sloppy_arguments_elements(); |
| 5431 return IsFastSmiOrObjectElementsKind(elements_kind()); | 5263 inline bool has_fixed_typed_array_elements(); |
| 5432 } | 5264 inline bool has_dictionary_elements(); |
| 5433 | |
| 5434 inline bool has_fast_double_elements() { | |
| 5435 return IsFastDoubleElementsKind(elements_kind()); | |
| 5436 } | |
| 5437 | |
| 5438 inline bool has_fast_elements() { | |
| 5439 return IsFastElementsKind(elements_kind()); | |
| 5440 } | |
| 5441 | |
| 5442 inline bool has_sloppy_arguments_elements() { | |
| 5443 return IsSloppyArgumentsElements(elements_kind()); | |
| 5444 } | |
| 5445 | |
| 5446 inline bool has_fixed_typed_array_elements() { | |
| 5447 return IsFixedTypedArrayElementsKind(elements_kind()); | |
| 5448 } | |
| 5449 | |
| 5450 inline bool has_dictionary_elements() { | |
| 5451 return IsDictionaryElementsKind(elements_kind()); | |
| 5452 } | |
| 5453 | 5265 |
| 5454 static bool IsValidElementsTransition(ElementsKind from_kind, | 5266 static bool IsValidElementsTransition(ElementsKind from_kind, |
| 5455 ElementsKind to_kind); | 5267 ElementsKind to_kind); |
| 5456 | 5268 |
| 5457 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a | 5269 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a |
| 5458 // map with DICTIONARY_ELEMENTS was found in the prototype chain. | 5270 // map with DICTIONARY_ELEMENTS was found in the prototype chain. |
| 5459 bool DictionaryElementsInPrototypeChainOnly(); | 5271 bool DictionaryElementsInPrototypeChainOnly(); |
| 5460 | 5272 |
| 5461 inline Map* ElementsTransitionMap(); | 5273 inline Map* ElementsTransitionMap(); |
| 5462 | 5274 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5585 DECL_ACCESSORS(code_cache, Object) | 5397 DECL_ACCESSORS(code_cache, Object) |
| 5586 | 5398 |
| 5587 // [dependent code]: list of optimized codes that weakly embed this map. | 5399 // [dependent code]: list of optimized codes that weakly embed this map. |
| 5588 DECL_ACCESSORS(dependent_code, DependentCode) | 5400 DECL_ACCESSORS(dependent_code, DependentCode) |
| 5589 | 5401 |
| 5590 // [weak cell cache]: cache that stores a weak cell pointing to this map. | 5402 // [weak cell cache]: cache that stores a weak cell pointing to this map. |
| 5591 DECL_ACCESSORS(weak_cell_cache, Object) | 5403 DECL_ACCESSORS(weak_cell_cache, Object) |
| 5592 | 5404 |
| 5593 inline PropertyDetails GetLastDescriptorDetails(); | 5405 inline PropertyDetails GetLastDescriptorDetails(); |
| 5594 | 5406 |
| 5595 int LastAdded() { | 5407 inline int LastAdded(); |
| 5596 int number_of_own_descriptors = NumberOfOwnDescriptors(); | |
| 5597 DCHECK(number_of_own_descriptors > 0); | |
| 5598 return number_of_own_descriptors - 1; | |
| 5599 } | |
| 5600 | 5408 |
| 5601 int NumberOfOwnDescriptors() { | 5409 inline int NumberOfOwnDescriptors(); |
| 5602 return NumberOfOwnDescriptorsBits::decode(bit_field3()); | 5410 inline void SetNumberOfOwnDescriptors(int number); |
| 5603 } | |
| 5604 | |
| 5605 void SetNumberOfOwnDescriptors(int number) { | |
| 5606 DCHECK(number <= instance_descriptors()->number_of_descriptors()); | |
| 5607 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); | |
| 5608 } | |
| 5609 | 5411 |
| 5610 inline Cell* RetrieveDescriptorsPointer(); | 5412 inline Cell* RetrieveDescriptorsPointer(); |
| 5611 | 5413 |
| 5612 int EnumLength() { | 5414 inline int EnumLength(); |
| 5613 return EnumLengthBits::decode(bit_field3()); | 5415 inline void SetEnumLength(int length); |
| 5614 } | |
| 5615 | |
| 5616 void SetEnumLength(int length) { | |
| 5617 if (length != kInvalidEnumCacheSentinel) { | |
| 5618 DCHECK(length >= 0); | |
| 5619 DCHECK(length == 0 || instance_descriptors()->HasEnumCache()); | |
| 5620 DCHECK(length <= NumberOfOwnDescriptors()); | |
| 5621 } | |
| 5622 set_bit_field3(EnumLengthBits::update(bit_field3(), length)); | |
| 5623 } | |
| 5624 | 5416 |
| 5625 inline bool owns_descriptors(); | 5417 inline bool owns_descriptors(); |
| 5626 inline void set_owns_descriptors(bool owns_descriptors); | 5418 inline void set_owns_descriptors(bool owns_descriptors); |
| 5627 inline bool has_instance_call_handler(); | 5419 inline bool has_instance_call_handler(); |
| 5628 inline void set_has_instance_call_handler(); | 5420 inline void set_has_instance_call_handler(); |
| 5629 inline void mark_unstable(); | 5421 inline void mark_unstable(); |
| 5630 inline bool is_stable(); | 5422 inline bool is_stable(); |
| 5631 inline void set_migration_target(bool value); | 5423 inline void set_migration_target(bool value); |
| 5632 inline bool is_migration_target(); | 5424 inline bool is_migration_target(); |
| 5633 inline void set_counter(int value); | 5425 inline void set_counter(int value); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5764 // |safe_to_add_transitions| is set to false if adding transitions is not | 5556 // |safe_to_add_transitions| is set to false if adding transitions is not |
| 5765 // allowed. | 5557 // allowed. |
| 5766 Map* LookupElementsTransitionMap(ElementsKind elements_kind); | 5558 Map* LookupElementsTransitionMap(ElementsKind elements_kind); |
| 5767 | 5559 |
| 5768 // Returns the transitioned map for this map with the most generic | 5560 // Returns the transitioned map for this map with the most generic |
| 5769 // elements_kind that's found in |candidates|, or null handle if no match is | 5561 // elements_kind that's found in |candidates|, or null handle if no match is |
| 5770 // found at all. | 5562 // found at all. |
| 5771 static Handle<Map> FindTransitionedMap(Handle<Map> map, | 5563 static Handle<Map> FindTransitionedMap(Handle<Map> map, |
| 5772 MapHandleList* candidates); | 5564 MapHandleList* candidates); |
| 5773 | 5565 |
| 5774 bool CanTransition() { | 5566 inline bool CanTransition(); |
| 5775 // Only JSObject and subtypes have map transitions and back pointers. | |
| 5776 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE); | |
| 5777 return instance_type() >= FIRST_JS_OBJECT_TYPE; | |
| 5778 } | |
| 5779 | 5567 |
| 5780 bool IsPrimitiveMap() { | 5568 inline bool IsPrimitiveMap(); |
| 5781 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | 5569 inline bool IsJSObjectMap(); |
| 5782 return instance_type() <= LAST_PRIMITIVE_TYPE; | 5570 inline bool IsJSArrayMap(); |
| 5783 } | 5571 inline bool IsStringMap(); |
| 5784 bool IsJSObjectMap() { | 5572 inline bool IsJSProxyMap(); |
| 5785 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 5573 inline bool IsJSGlobalProxyMap(); |
| 5786 return instance_type() >= FIRST_JS_OBJECT_TYPE; | 5574 inline bool IsJSGlobalObjectMap(); |
| 5787 } | 5575 inline bool IsGlobalObjectMap(); |
| 5788 bool IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; } | |
| 5789 bool IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; } | |
| 5790 bool IsJSProxyMap() { | |
| 5791 InstanceType type = instance_type(); | |
| 5792 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE; | |
| 5793 } | |
| 5794 bool IsJSGlobalProxyMap() { | |
| 5795 return instance_type() == JS_GLOBAL_PROXY_TYPE; | |
| 5796 } | |
| 5797 bool IsJSGlobalObjectMap() { | |
| 5798 return instance_type() == JS_GLOBAL_OBJECT_TYPE; | |
| 5799 } | |
| 5800 bool IsGlobalObjectMap() { | |
| 5801 const InstanceType type = instance_type(); | |
| 5802 return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE; | |
| 5803 } | |
| 5804 | 5576 |
| 5805 inline bool CanOmitMapChecks(); | 5577 inline bool CanOmitMapChecks(); |
| 5806 | 5578 |
| 5807 static void AddDependentCode(Handle<Map> map, | 5579 static void AddDependentCode(Handle<Map> map, |
| 5808 DependentCode::DependencyGroup group, | 5580 DependentCode::DependencyGroup group, |
| 5809 Handle<Code> code); | 5581 Handle<Code> code); |
| 5810 | 5582 |
| 5811 bool IsMapInArrayPrototypeChain(); | 5583 bool IsMapInArrayPrototypeChain(); |
| 5812 | 5584 |
| 5813 static Handle<WeakCell> WeakCellForMap(Handle<Map> map); | 5585 static Handle<WeakCell> WeakCellForMap(Handle<Map> map); |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6621 inline void TryReenableOptimization(); | 6393 inline void TryReenableOptimization(); |
| 6622 | 6394 |
| 6623 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields. | 6395 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields. |
| 6624 inline void set_counters(int value); | 6396 inline void set_counters(int value); |
| 6625 inline int counters() const; | 6397 inline int counters() const; |
| 6626 | 6398 |
| 6627 // Stores opt_count and bailout_reason as bit-fields. | 6399 // Stores opt_count and bailout_reason as bit-fields. |
| 6628 inline void set_opt_count_and_bailout_reason(int value); | 6400 inline void set_opt_count_and_bailout_reason(int value); |
| 6629 inline int opt_count_and_bailout_reason() const; | 6401 inline int opt_count_and_bailout_reason() const; |
| 6630 | 6402 |
| 6631 void set_disable_optimization_reason(BailoutReason reason) { | 6403 inline void set_disable_optimization_reason(BailoutReason reason); |
| 6632 set_opt_count_and_bailout_reason( | |
| 6633 DisabledOptimizationReasonBits::update(opt_count_and_bailout_reason(), | |
| 6634 reason)); | |
| 6635 } | |
| 6636 | 6404 |
| 6637 // Tells whether this function should be subject to debugging. | 6405 // Tells whether this function should be subject to debugging. |
| 6638 inline bool IsSubjectToDebugging(); | 6406 inline bool IsSubjectToDebugging(); |
| 6639 | 6407 |
| 6640 // Check whether or not this function is inlineable. | 6408 // Check whether or not this function is inlineable. |
| 6641 bool IsInlineable(); | 6409 bool IsInlineable(); |
| 6642 | 6410 |
| 6643 // Source size of this function. | 6411 // Source size of this function. |
| 6644 int SourceSize(); | 6412 int SourceSize(); |
| 6645 | 6413 |
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7957 // Increments the mementos found counter and returns true when the first | 7725 // Increments the mementos found counter and returns true when the first |
| 7958 // memento was found for a given allocation site. | 7726 // memento was found for a given allocation site. |
| 7959 inline bool IncrementMementoFoundCount(); | 7727 inline bool IncrementMementoFoundCount(); |
| 7960 | 7728 |
| 7961 inline void IncrementMementoCreateCount(); | 7729 inline void IncrementMementoCreateCount(); |
| 7962 | 7730 |
| 7963 PretenureFlag GetPretenureMode(); | 7731 PretenureFlag GetPretenureMode(); |
| 7964 | 7732 |
| 7965 void ResetPretenureDecision(); | 7733 void ResetPretenureDecision(); |
| 7966 | 7734 |
| 7967 PretenureDecision pretenure_decision() { | 7735 inline PretenureDecision pretenure_decision(); |
| 7968 int value = pretenure_data()->value(); | 7736 inline void set_pretenure_decision(PretenureDecision decision); |
| 7969 return PretenureDecisionBits::decode(value); | |
| 7970 } | |
| 7971 | 7737 |
| 7972 void set_pretenure_decision(PretenureDecision decision) { | 7738 inline bool deopt_dependent_code(); |
| 7973 int value = pretenure_data()->value(); | 7739 inline void set_deopt_dependent_code(bool deopt); |
| 7974 set_pretenure_data( | |
| 7975 Smi::FromInt(PretenureDecisionBits::update(value, decision)), | |
| 7976 SKIP_WRITE_BARRIER); | |
| 7977 } | |
| 7978 | 7740 |
| 7979 bool deopt_dependent_code() { | 7741 inline int memento_found_count(); |
| 7980 int value = pretenure_data()->value(); | |
| 7981 return DeoptDependentCodeBit::decode(value); | |
| 7982 } | |
| 7983 | |
| 7984 void set_deopt_dependent_code(bool deopt) { | |
| 7985 int value = pretenure_data()->value(); | |
| 7986 set_pretenure_data( | |
| 7987 Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)), | |
| 7988 SKIP_WRITE_BARRIER); | |
| 7989 } | |
| 7990 | |
| 7991 int memento_found_count() { | |
| 7992 int value = pretenure_data()->value(); | |
| 7993 return MementoFoundCountBits::decode(value); | |
| 7994 } | |
| 7995 | |
| 7996 inline void set_memento_found_count(int count); | 7742 inline void set_memento_found_count(int count); |
| 7997 | 7743 |
| 7998 int memento_create_count() { | 7744 inline int memento_create_count(); |
| 7999 return pretenure_create_count()->value(); | 7745 inline void set_memento_create_count(int count); |
| 8000 } | |
| 8001 | |
| 8002 void set_memento_create_count(int count) { | |
| 8003 set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER); | |
| 8004 } | |
| 8005 | 7746 |
| 8006 // The pretenuring decision is made during gc, and the zombie state allows | 7747 // The pretenuring decision is made during gc, and the zombie state allows |
| 8007 // us to recognize when an allocation site is just being kept alive because | 7748 // us to recognize when an allocation site is just being kept alive because |
| 8008 // a later traversal of new space may discover AllocationMementos that point | 7749 // a later traversal of new space may discover AllocationMementos that point |
| 8009 // to this AllocationSite. | 7750 // to this AllocationSite. |
| 8010 bool IsZombie() { | 7751 inline bool IsZombie(); |
| 8011 return pretenure_decision() == kZombie; | |
| 8012 } | |
| 8013 | 7752 |
| 8014 bool IsMaybeTenure() { | 7753 inline bool IsMaybeTenure(); |
| 8015 return pretenure_decision() == kMaybeTenure; | |
| 8016 } | |
| 8017 | 7754 |
| 8018 inline void MarkZombie(); | 7755 inline void MarkZombie(); |
| 8019 | 7756 |
| 8020 inline bool MakePretenureDecision(PretenureDecision current_decision, | 7757 inline bool MakePretenureDecision(PretenureDecision current_decision, |
| 8021 double ratio, | 7758 double ratio, |
| 8022 bool maximum_size_scavenge); | 7759 bool maximum_size_scavenge); |
| 8023 | 7760 |
| 8024 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge); | 7761 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge); |
| 8025 | 7762 |
| 8026 ElementsKind GetElementsKind() { | 7763 inline ElementsKind GetElementsKind(); |
| 8027 DCHECK(!SitePointsToLiteral()); | 7764 inline void SetElementsKind(ElementsKind kind); |
| 8028 int value = Smi::cast(transition_info())->value(); | |
| 8029 return ElementsKindBits::decode(value); | |
| 8030 } | |
| 8031 | 7765 |
| 8032 void SetElementsKind(ElementsKind kind) { | 7766 inline bool CanInlineCall(); |
| 8033 int value = Smi::cast(transition_info())->value(); | 7767 inline void SetDoNotInlineCall(); |
| 8034 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), | |
| 8035 SKIP_WRITE_BARRIER); | |
| 8036 } | |
| 8037 | 7768 |
| 8038 bool CanInlineCall() { | 7769 inline bool SitePointsToLiteral(); |
| 8039 int value = Smi::cast(transition_info())->value(); | |
| 8040 return DoNotInlineBit::decode(value) == 0; | |
| 8041 } | |
| 8042 | |
| 8043 void SetDoNotInlineCall() { | |
| 8044 int value = Smi::cast(transition_info())->value(); | |
| 8045 set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)), | |
| 8046 SKIP_WRITE_BARRIER); | |
| 8047 } | |
| 8048 | |
| 8049 bool SitePointsToLiteral() { | |
| 8050 // If transition_info is a smi, then it represents an ElementsKind | |
| 8051 // for a constructed array. Otherwise, it must be a boilerplate | |
| 8052 // for an object or array literal. | |
| 8053 return transition_info()->IsJSArray() || transition_info()->IsJSObject(); | |
| 8054 } | |
| 8055 | 7770 |
| 8056 static void DigestTransitionFeedback(Handle<AllocationSite> site, | 7771 static void DigestTransitionFeedback(Handle<AllocationSite> site, |
| 8057 ElementsKind to_kind); | 7772 ElementsKind to_kind); |
| 8058 | 7773 |
| 8059 DECLARE_PRINTER(AllocationSite) | 7774 DECLARE_PRINTER(AllocationSite) |
| 8060 DECLARE_VERIFIER(AllocationSite) | 7775 DECLARE_VERIFIER(AllocationSite) |
| 8061 | 7776 |
| 8062 DECLARE_CAST(AllocationSite) | 7777 DECLARE_CAST(AllocationSite) |
| 8063 static inline AllocationSiteMode GetMode( | 7778 static inline AllocationSiteMode GetMode( |
| 8064 ElementsKind boilerplate_elements_kind); | 7779 ElementsKind boilerplate_elements_kind); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 8079 // field. | 7794 // field. |
| 8080 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; | 7795 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; |
| 8081 static const int kPointerFieldsEndOffset = kWeakNextOffset; | 7796 static const int kPointerFieldsEndOffset = kWeakNextOffset; |
| 8082 | 7797 |
| 8083 // For other visitors, use the fixed body descriptor below. | 7798 // For other visitors, use the fixed body descriptor below. |
| 8084 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, | 7799 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, |
| 8085 kDependentCodeOffset + kPointerSize, | 7800 kDependentCodeOffset + kPointerSize, |
| 8086 kSize> BodyDescriptor; | 7801 kSize> BodyDescriptor; |
| 8087 | 7802 |
| 8088 private: | 7803 private: |
| 8089 bool PretenuringDecisionMade() { | 7804 inline bool PretenuringDecisionMade(); |
| 8090 return pretenure_decision() != kUndecided; | |
| 8091 } | |
| 8092 | 7805 |
| 8093 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); | 7806 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); |
| 8094 }; | 7807 }; |
| 8095 | 7808 |
| 8096 | 7809 |
| 8097 class AllocationMemento: public Struct { | 7810 class AllocationMemento: public Struct { |
| 8098 public: | 7811 public: |
| 8099 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; | 7812 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; |
| 8100 static const int kSize = kAllocationSiteOffset + kPointerSize; | 7813 static const int kSize = kAllocationSiteOffset + kPointerSize; |
| 8101 | 7814 |
| 8102 DECL_ACCESSORS(allocation_site, Object) | 7815 DECL_ACCESSORS(allocation_site, Object) |
| 8103 | 7816 |
| 8104 bool IsValid() { | 7817 inline bool IsValid(); |
| 8105 return allocation_site()->IsAllocationSite() && | 7818 inline AllocationSite* GetAllocationSite(); |
| 8106 !AllocationSite::cast(allocation_site())->IsZombie(); | |
| 8107 } | |
| 8108 AllocationSite* GetAllocationSite() { | |
| 8109 DCHECK(IsValid()); | |
| 8110 return AllocationSite::cast(allocation_site()); | |
| 8111 } | |
| 8112 | 7819 |
| 8113 DECLARE_PRINTER(AllocationMemento) | 7820 DECLARE_PRINTER(AllocationMemento) |
| 8114 DECLARE_VERIFIER(AllocationMemento) | 7821 DECLARE_VERIFIER(AllocationMemento) |
| 8115 | 7822 |
| 8116 DECLARE_CAST(AllocationMemento) | 7823 DECLARE_CAST(AllocationMemento) |
| 8117 | 7824 |
| 8118 private: | 7825 private: |
| 8119 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento); | 7826 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento); |
| 8120 }; | 7827 }; |
| 8121 | 7828 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8210 }; | 7917 }; |
| 8211 | 7918 |
| 8212 | 7919 |
| 8213 class IteratingStringHasher : public StringHasher { | 7920 class IteratingStringHasher : public StringHasher { |
| 8214 public: | 7921 public: |
| 8215 static inline uint32_t Hash(String* string, uint32_t seed); | 7922 static inline uint32_t Hash(String* string, uint32_t seed); |
| 8216 inline void VisitOneByteString(const uint8_t* chars, int length); | 7923 inline void VisitOneByteString(const uint8_t* chars, int length); |
| 8217 inline void VisitTwoByteString(const uint16_t* chars, int length); | 7924 inline void VisitTwoByteString(const uint16_t* chars, int length); |
| 8218 | 7925 |
| 8219 private: | 7926 private: |
| 8220 inline IteratingStringHasher(int len, uint32_t seed) | 7927 inline IteratingStringHasher(int len, uint32_t seed); |
| 8221 : StringHasher(len, seed) {} | |
| 8222 void VisitConsString(ConsString* cons_string); | 7928 void VisitConsString(ConsString* cons_string); |
| 8223 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher); | 7929 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher); |
| 8224 }; | 7930 }; |
| 8225 | 7931 |
| 8226 | 7932 |
| 8227 // The characteristics of a string are stored in its map. Retrieving these | 7933 // The characteristics of a string are stored in its map. Retrieving these |
| 8228 // few bits of information is moderately expensive, involving two memory | 7934 // few bits of information is moderately expensive, involving two memory |
| 8229 // loads where the second is dependent on the first. To improve efficiency | 7935 // loads where the second is dependent on the first. To improve efficiency |
| 8230 // the shape of the string is given its own class so that it can be retrieved | 7936 // the shape of the string is given its own class so that it can be retrieved |
| 8231 // once and used for several string operations. A StringShape is small enough | 7937 // once and used for several string operations. A StringShape is small enough |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8452 // kMaxCachedArrayIndexLength. | 8158 // kMaxCachedArrayIndexLength. |
| 8453 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1)); | 8159 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1)); |
| 8454 | 8160 |
| 8455 static const unsigned int kContainsCachedArrayIndexMask = | 8161 static const unsigned int kContainsCachedArrayIndexMask = |
| 8456 (~static_cast<unsigned>(kMaxCachedArrayIndexLength) | 8162 (~static_cast<unsigned>(kMaxCachedArrayIndexLength) |
| 8457 << ArrayIndexLengthBits::kShift) | | 8163 << ArrayIndexLengthBits::kShift) | |
| 8458 kIsNotArrayIndexMask; | 8164 kIsNotArrayIndexMask; |
| 8459 | 8165 |
| 8460 class SubStringRange { | 8166 class SubStringRange { |
| 8461 public: | 8167 public: |
| 8462 explicit SubStringRange(String* string, int first = 0, int length = -1) | 8168 explicit inline SubStringRange(String* string, int first = 0, |
| 8463 : string_(string), | 8169 int length = -1); |
| 8464 first_(first), | |
| 8465 length_(length == -1 ? string->length() : length) {} | |
| 8466 class iterator; | 8170 class iterator; |
| 8467 inline iterator begin(); | 8171 inline iterator begin(); |
| 8468 inline iterator end(); | 8172 inline iterator end(); |
| 8469 | 8173 |
| 8470 private: | 8174 private: |
| 8471 String* string_; | 8175 String* string_; |
| 8472 int first_; | 8176 int first_; |
| 8473 int length_; | 8177 int length_; |
| 8474 }; | 8178 }; |
| 8475 | 8179 |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9302 class PropertyCell : public HeapObject { | 9006 class PropertyCell : public HeapObject { |
| 9303 public: | 9007 public: |
| 9304 // [property_details]: details of the global property. | 9008 // [property_details]: details of the global property. |
| 9305 DECL_ACCESSORS(property_details_raw, Object) | 9009 DECL_ACCESSORS(property_details_raw, Object) |
| 9306 // [value]: value of the global property. | 9010 // [value]: value of the global property. |
| 9307 DECL_ACCESSORS(value, Object) | 9011 DECL_ACCESSORS(value, Object) |
| 9308 // [dependent_code]: dependent code that depends on the type of the global | 9012 // [dependent_code]: dependent code that depends on the type of the global |
| 9309 // property. | 9013 // property. |
| 9310 DECL_ACCESSORS(dependent_code, DependentCode) | 9014 DECL_ACCESSORS(dependent_code, DependentCode) |
| 9311 | 9015 |
| 9312 PropertyDetails property_details() { | 9016 inline PropertyDetails property_details(); |
| 9313 return PropertyDetails(Smi::cast(property_details_raw())); | 9017 inline void set_property_details(PropertyDetails details); |
| 9314 } | |
| 9315 | |
| 9316 void set_property_details(PropertyDetails details) { | |
| 9317 set_property_details_raw(details.AsSmi()); | |
| 9318 } | |
| 9319 | 9018 |
| 9320 PropertyCellConstantType GetConstantType(); | 9019 PropertyCellConstantType GetConstantType(); |
| 9321 | 9020 |
| 9322 // Computes the new type of the cell's contents for the given value, but | 9021 // Computes the new type of the cell's contents for the given value, but |
| 9323 // without actually modifying the details. | 9022 // without actually modifying the details. |
| 9324 static PropertyCellType UpdatedType(Handle<PropertyCell> cell, | 9023 static PropertyCellType UpdatedType(Handle<PropertyCell> cell, |
| 9325 Handle<Object> value, | 9024 Handle<Object> value, |
| 9326 PropertyDetails details); | 9025 PropertyDetails details); |
| 9327 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry, | 9026 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry, |
| 9328 Handle<Object> value, PropertyDetails details); | 9027 Handle<Object> value, PropertyDetails details); |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9991 static int AppendUnique(Handle<Object> descriptors, | 9690 static int AppendUnique(Handle<Object> descriptors, |
| 9992 Handle<FixedArray> array, | 9691 Handle<FixedArray> array, |
| 9993 int valid_descriptors); | 9692 int valid_descriptors); |
| 9994 | 9693 |
| 9995 static const int kNameOffset = HeapObject::kHeaderSize; | 9694 static const int kNameOffset = HeapObject::kHeaderSize; |
| 9996 static const int kFlagOffset = kNameOffset + kPointerSize; | 9695 static const int kFlagOffset = kNameOffset + kPointerSize; |
| 9997 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize; | 9696 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize; |
| 9998 static const int kSize = kExpectedReceiverTypeOffset + kPointerSize; | 9697 static const int kSize = kExpectedReceiverTypeOffset + kPointerSize; |
| 9999 | 9698 |
| 10000 private: | 9699 private: |
| 10001 inline bool HasExpectedReceiverType() { | 9700 inline bool HasExpectedReceiverType(); |
| 10002 return expected_receiver_type()->IsFunctionTemplateInfo(); | 9701 |
| 10003 } | |
| 10004 // Bit positions in flag. | 9702 // Bit positions in flag. |
| 10005 static const int kAllCanReadBit = 0; | 9703 static const int kAllCanReadBit = 0; |
| 10006 static const int kAllCanWriteBit = 1; | 9704 static const int kAllCanWriteBit = 1; |
| 10007 static const int kSpecialDataProperty = 2; | 9705 static const int kSpecialDataProperty = 2; |
| 10008 class AttributesField : public BitField<PropertyAttributes, 3, 3> {}; | 9706 class AttributesField : public BitField<PropertyAttributes, 3, 3> {}; |
| 10009 | 9707 |
| 10010 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); | 9708 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); |
| 10011 }; | 9709 }; |
| 10012 | 9710 |
| 10013 | 9711 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10052 // * a pointer to a map: a transition used to ensure map sharing | 9750 // * a pointer to a map: a transition used to ensure map sharing |
| 10053 class AccessorPair: public Struct { | 9751 class AccessorPair: public Struct { |
| 10054 public: | 9752 public: |
| 10055 DECL_ACCESSORS(getter, Object) | 9753 DECL_ACCESSORS(getter, Object) |
| 10056 DECL_ACCESSORS(setter, Object) | 9754 DECL_ACCESSORS(setter, Object) |
| 10057 | 9755 |
| 10058 DECLARE_CAST(AccessorPair) | 9756 DECLARE_CAST(AccessorPair) |
| 10059 | 9757 |
| 10060 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair); | 9758 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair); |
| 10061 | 9759 |
| 10062 Object* get(AccessorComponent component) { | 9760 inline Object* get(AccessorComponent component); |
| 10063 return component == ACCESSOR_GETTER ? getter() : setter(); | 9761 inline void set(AccessorComponent component, Object* value); |
| 10064 } | |
| 10065 | |
| 10066 void set(AccessorComponent component, Object* value) { | |
| 10067 if (component == ACCESSOR_GETTER) { | |
| 10068 set_getter(value); | |
| 10069 } else { | |
| 10070 set_setter(value); | |
| 10071 } | |
| 10072 } | |
| 10073 | 9762 |
| 10074 // Note: Returns undefined instead in case of a hole. | 9763 // Note: Returns undefined instead in case of a hole. |
| 10075 Object* GetComponent(AccessorComponent component); | 9764 Object* GetComponent(AccessorComponent component); |
| 10076 | 9765 |
| 10077 // Set both components, skipping arguments which are a JavaScript null. | 9766 // Set both components, skipping arguments which are a JavaScript null. |
| 10078 void SetComponents(Object* getter, Object* setter) { | 9767 inline void SetComponents(Object* getter, Object* setter); |
| 10079 if (!getter->IsNull()) set_getter(getter); | |
| 10080 if (!setter->IsNull()) set_setter(setter); | |
| 10081 } | |
| 10082 | 9768 |
| 10083 bool Equals(AccessorPair* pair) { | 9769 inline bool Equals(AccessorPair* pair); |
| 10084 return (this == pair) || pair->Equals(getter(), setter()); | 9770 inline bool Equals(Object* getter_value, Object* setter_value); |
| 10085 } | |
| 10086 | 9771 |
| 10087 bool Equals(Object* getter_value, Object* setter_value) { | 9772 inline bool ContainsAccessor(); |
| 10088 return (getter() == getter_value) && (setter() == setter_value); | |
| 10089 } | |
| 10090 | |
| 10091 bool ContainsAccessor() { | |
| 10092 return IsJSAccessor(getter()) || IsJSAccessor(setter()); | |
| 10093 } | |
| 10094 | 9773 |
| 10095 // Dispatched behavior. | 9774 // Dispatched behavior. |
| 10096 DECLARE_PRINTER(AccessorPair) | 9775 DECLARE_PRINTER(AccessorPair) |
| 10097 DECLARE_VERIFIER(AccessorPair) | 9776 DECLARE_VERIFIER(AccessorPair) |
| 10098 | 9777 |
| 10099 static const int kGetterOffset = HeapObject::kHeaderSize; | 9778 static const int kGetterOffset = HeapObject::kHeaderSize; |
| 10100 static const int kSetterOffset = kGetterOffset + kPointerSize; | 9779 static const int kSetterOffset = kGetterOffset + kPointerSize; |
| 10101 static const int kSize = kSetterOffset + kPointerSize; | 9780 static const int kSize = kSetterOffset + kPointerSize; |
| 10102 | 9781 |
| 10103 private: | 9782 private: |
| 10104 // Strangely enough, in addition to functions and harmony proxies, the spec | 9783 // Strangely enough, in addition to functions and harmony proxies, the spec |
| 10105 // requires us to consider undefined as a kind of accessor, too: | 9784 // requires us to consider undefined as a kind of accessor, too: |
| 10106 // var obj = {}; | 9785 // var obj = {}; |
| 10107 // Object.defineProperty(obj, "foo", {get: undefined}); | 9786 // Object.defineProperty(obj, "foo", {get: undefined}); |
| 10108 // assertTrue("foo" in obj); | 9787 // assertTrue("foo" in obj); |
| 10109 bool IsJSAccessor(Object* obj) { | 9788 inline bool IsJSAccessor(Object* obj); |
| 10110 return obj->IsSpecFunction() || obj->IsUndefined(); | |
| 10111 } | |
| 10112 | 9789 |
| 10113 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair); | 9790 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair); |
| 10114 }; | 9791 }; |
| 10115 | 9792 |
| 10116 | 9793 |
| 10117 class AccessCheckInfo: public Struct { | 9794 class AccessCheckInfo: public Struct { |
| 10118 public: | 9795 public: |
| 10119 DECL_ACCESSORS(named_callback, Object) | 9796 DECL_ACCESSORS(named_callback, Object) |
| 10120 DECL_ACCESSORS(indexed_callback, Object) | 9797 DECL_ACCESSORS(indexed_callback, Object) |
| 10121 DECL_ACCESSORS(data, Object) | 9798 DECL_ACCESSORS(data, Object) |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10530 // Intended for serialization/deserialization checking: insert, or | 10207 // Intended for serialization/deserialization checking: insert, or |
| 10531 // check for the presence of, a tag at this position in the stream. | 10208 // check for the presence of, a tag at this position in the stream. |
| 10532 // Also used for marking up GC roots in heap snapshots. | 10209 // Also used for marking up GC roots in heap snapshots. |
| 10533 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {} | 10210 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {} |
| 10534 }; | 10211 }; |
| 10535 | 10212 |
| 10536 | 10213 |
| 10537 class StructBodyDescriptor : public | 10214 class StructBodyDescriptor : public |
| 10538 FlexibleBodyDescriptor<HeapObject::kHeaderSize> { | 10215 FlexibleBodyDescriptor<HeapObject::kHeaderSize> { |
| 10539 public: | 10216 public: |
| 10540 static inline int SizeOf(Map* map, HeapObject* object) { | 10217 static inline int SizeOf(Map* map, HeapObject* object); |
| 10541 return map->instance_size(); | |
| 10542 } | |
| 10543 }; | 10218 }; |
| 10544 | 10219 |
| 10545 | 10220 |
| 10546 // BooleanBit is a helper class for setting and getting a bit in an | 10221 // BooleanBit is a helper class for setting and getting a bit in an |
| 10547 // integer or Smi. | 10222 // integer or Smi. |
| 10548 class BooleanBit : public AllStatic { | 10223 class BooleanBit : public AllStatic { |
| 10549 public: | 10224 public: |
| 10550 static inline bool get(Smi* smi, int bit_position) { | 10225 static inline bool get(Smi* smi, int bit_position) { |
| 10551 return get(smi->value(), bit_position); | 10226 return get(smi->value(), bit_position); |
| 10552 } | 10227 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 10565 } else { | 10240 } else { |
| 10566 value &= ~(1 << bit_position); | 10241 value &= ~(1 << bit_position); |
| 10567 } | 10242 } |
| 10568 return value; | 10243 return value; |
| 10569 } | 10244 } |
| 10570 }; | 10245 }; |
| 10571 | 10246 |
| 10572 } } // namespace v8::internal | 10247 } } // namespace v8::internal |
| 10573 | 10248 |
| 10574 #endif // V8_OBJECTS_H_ | 10249 #endif // V8_OBJECTS_H_ |
| OLD | NEW |