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 |