OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 237 |
238 | 238 |
239 // NormalizedMapSharingMode is used to specify whether a map may be shared | 239 // NormalizedMapSharingMode is used to specify whether a map may be shared |
240 // by different objects with normalized properties. | 240 // by different objects with normalized properties. |
241 enum NormalizedMapSharingMode { | 241 enum NormalizedMapSharingMode { |
242 UNIQUE_NORMALIZED_MAP, | 242 UNIQUE_NORMALIZED_MAP, |
243 SHARED_NORMALIZED_MAP | 243 SHARED_NORMALIZED_MAP |
244 }; | 244 }; |
245 | 245 |
246 | 246 |
| 247 // Indicates whether a get method should implicitly create the object looked up. |
| 248 enum CreationFlag { |
| 249 ALLOW_CREATION, |
| 250 OMIT_CREATION |
| 251 }; |
| 252 |
| 253 |
247 // Instance size sentinel for objects of variable size. | 254 // Instance size sentinel for objects of variable size. |
248 static const int kVariableSizeSentinel = 0; | 255 static const int kVariableSizeSentinel = 0; |
249 | 256 |
250 | 257 |
251 // All Maps have a field instance_type containing a InstanceType. | 258 // All Maps have a field instance_type containing a InstanceType. |
252 // It describes the type of the instances. | 259 // It describes the type of the instances. |
253 // | 260 // |
254 // As an example, a JavaScript object is a heap object and its map | 261 // As an example, a JavaScript object is a heap object and its map |
255 // instance_type is JS_OBJECT_TYPE. | 262 // instance_type is JS_OBJECT_TYPE. |
256 // | 263 // |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 inline bool HasLocalProperty(String* name); | 1430 inline bool HasLocalProperty(String* name); |
1424 inline bool HasElement(uint32_t index); | 1431 inline bool HasElement(uint32_t index); |
1425 | 1432 |
1426 // Return the object's prototype (might be Heap::null_value()). | 1433 // Return the object's prototype (might be Heap::null_value()). |
1427 inline Object* GetPrototype(); | 1434 inline Object* GetPrototype(); |
1428 | 1435 |
1429 // Set the object's prototype (only JSReceiver and null are allowed). | 1436 // Set the object's prototype (only JSReceiver and null are allowed). |
1430 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value, | 1437 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value, |
1431 bool skip_hidden_prototypes); | 1438 bool skip_hidden_prototypes); |
1432 | 1439 |
| 1440 // Retrieves a permanent object identity hash code. The undefined value might |
| 1441 // be returned in case no has been created yet and OMIT_CREATION was used. |
| 1442 inline MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); |
| 1443 |
1433 // Lookup a property. If found, the result is valid and has | 1444 // Lookup a property. If found, the result is valid and has |
1434 // detailed information. | 1445 // detailed information. |
1435 void LocalLookup(String* name, LookupResult* result); | 1446 void LocalLookup(String* name, LookupResult* result); |
1436 void Lookup(String* name, LookupResult* result); | 1447 void Lookup(String* name, LookupResult* result); |
1437 | 1448 |
| 1449 protected: |
| 1450 Smi* GenerateIdentityHash(); |
| 1451 |
1438 private: | 1452 private: |
1439 PropertyAttributes GetPropertyAttribute(JSReceiver* receiver, | 1453 PropertyAttributes GetPropertyAttribute(JSReceiver* receiver, |
1440 LookupResult* result, | 1454 LookupResult* result, |
1441 String* name, | 1455 String* name, |
1442 bool continue_search); | 1456 bool continue_search); |
1443 | 1457 |
1444 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver); | 1458 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver); |
1445 }; | 1459 }; |
1446 | 1460 |
1447 // The JSObject describes real heap allocated JavaScript objects with | 1461 // The JSObject describes real heap allocated JavaScript objects with |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 // Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be | 1673 // Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be |
1660 // a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real | 1674 // a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real |
1661 // holder. | 1675 // holder. |
1662 // | 1676 // |
1663 // These accessors do not touch interceptors or accessors. | 1677 // These accessors do not touch interceptors or accessors. |
1664 inline bool HasHiddenPropertiesObject(); | 1678 inline bool HasHiddenPropertiesObject(); |
1665 inline Object* GetHiddenPropertiesObject(); | 1679 inline Object* GetHiddenPropertiesObject(); |
1666 MUST_USE_RESULT inline MaybeObject* SetHiddenPropertiesObject( | 1680 MUST_USE_RESULT inline MaybeObject* SetHiddenPropertiesObject( |
1667 Object* hidden_obj); | 1681 Object* hidden_obj); |
1668 | 1682 |
1669 // Indicates whether the hidden properties object should be created. | |
1670 enum HiddenPropertiesFlag { ALLOW_CREATION, OMIT_CREATION }; | |
1671 | |
1672 // Retrieves the hidden properties object. | 1683 // Retrieves the hidden properties object. |
1673 // | 1684 // |
1674 // The undefined value might be returned in case no hidden properties object | 1685 // The undefined value might be returned in case no hidden properties object |
1675 // is present and creation was omitted. | 1686 // is present and creation was omitted. |
1676 inline bool HasHiddenProperties(); | 1687 inline bool HasHiddenProperties(); |
1677 MUST_USE_RESULT MaybeObject* GetHiddenProperties(HiddenPropertiesFlag flag); | 1688 MUST_USE_RESULT MaybeObject* GetHiddenProperties(CreationFlag flag); |
1678 | 1689 |
1679 // Retrieves a permanent object identity hash code. | 1690 MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); |
1680 // | 1691 MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag); |
1681 // The identity hash is stored as a hidden property. The undefined value might | |
1682 // be returned in case no hidden properties object is present and creation was | |
1683 // omitted. | |
1684 MUST_USE_RESULT MaybeObject* GetIdentityHash(HiddenPropertiesFlag flag); | |
1685 | 1692 |
1686 MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode); | 1693 MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode); |
1687 MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); | 1694 MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); |
1688 | 1695 |
1689 // Tests for the fast common case for property enumeration. | 1696 // Tests for the fast common case for property enumeration. |
1690 bool IsSimpleEnum(); | 1697 bool IsSimpleEnum(); |
1691 | 1698 |
1692 // Do we want to keep the elements in fast case when increasing the | 1699 // Do we want to keep the elements in fast case when increasing the |
1693 // capacity? | 1700 // capacity? |
1694 bool ShouldConvertToSlowElements(int new_capacity); | 1701 bool ShouldConvertToSlowElements(int new_capacity); |
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2958 | 2965 |
2959 // Bit masks. | 2966 // Bit masks. |
2960 static const int kRequiresSlowElementsMask = 1; | 2967 static const int kRequiresSlowElementsMask = 1; |
2961 static const int kRequiresSlowElementsTagSize = 1; | 2968 static const int kRequiresSlowElementsTagSize = 1; |
2962 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; | 2969 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; |
2963 }; | 2970 }; |
2964 | 2971 |
2965 | 2972 |
2966 class ObjectHashTableShape { | 2973 class ObjectHashTableShape { |
2967 public: | 2974 public: |
2968 static inline bool IsMatch(JSObject* key, Object* other); | 2975 static inline bool IsMatch(JSReceiver* key, Object* other); |
2969 static inline uint32_t Hash(JSObject* key); | 2976 static inline uint32_t Hash(JSReceiver* key); |
2970 static inline uint32_t HashForObject(JSObject* key, Object* object); | 2977 static inline uint32_t HashForObject(JSReceiver* key, Object* object); |
2971 MUST_USE_RESULT static inline MaybeObject* AsObject(JSObject* key); | 2978 MUST_USE_RESULT static inline MaybeObject* AsObject(JSReceiver* key); |
2972 static const int kPrefixSize = 0; | 2979 static const int kPrefixSize = 0; |
2973 static const int kEntrySize = 2; | 2980 static const int kEntrySize = 2; |
2974 }; | 2981 }; |
2975 | 2982 |
2976 | 2983 |
2977 // ObjectHashTable maps keys that are JavaScript objects to object values by | 2984 // ObjectHashTable maps keys that are JavaScript objects to object values by |
2978 // using the identity hash of the key for hashing purposes. | 2985 // using the identity hash of the key for hashing purposes. |
2979 class ObjectHashTable: public HashTable<ObjectHashTableShape, JSObject*> { | 2986 class ObjectHashTable: public HashTable<ObjectHashTableShape, JSReceiver*> { |
2980 public: | 2987 public: |
2981 static inline ObjectHashTable* cast(Object* obj) { | 2988 static inline ObjectHashTable* cast(Object* obj) { |
2982 ASSERT(obj->IsHashTable()); | 2989 ASSERT(obj->IsHashTable()); |
2983 return reinterpret_cast<ObjectHashTable*>(obj); | 2990 return reinterpret_cast<ObjectHashTable*>(obj); |
2984 } | 2991 } |
2985 | 2992 |
2986 // Looks up the value associated with the given key. The undefined value is | 2993 // Looks up the value associated with the given key. The undefined value is |
2987 // returned in case the key is not present. | 2994 // returned in case the key is not present. |
2988 Object* Lookup(JSObject* key); | 2995 Object* Lookup(JSReceiver* key); |
2989 | 2996 |
2990 // Adds (or overwrites) the value associated with the given key. Mapping a | 2997 // Adds (or overwrites) the value associated with the given key. Mapping a |
2991 // key to the undefined value causes removal of the whole entry. | 2998 // key to the undefined value causes removal of the whole entry. |
2992 MUST_USE_RESULT MaybeObject* Put(JSObject* key, Object* value); | 2999 MUST_USE_RESULT MaybeObject* Put(JSReceiver* key, Object* value); |
2993 | 3000 |
2994 private: | 3001 private: |
2995 friend class MarkCompactCollector; | 3002 friend class MarkCompactCollector; |
2996 | 3003 |
2997 void AddEntry(int entry, JSObject* key, Object* value); | 3004 void AddEntry(int entry, JSReceiver* key, Object* value); |
2998 void RemoveEntry(int entry, Heap* heap); | 3005 void RemoveEntry(int entry, Heap* heap); |
2999 inline void RemoveEntry(int entry); | 3006 inline void RemoveEntry(int entry); |
3000 | 3007 |
3001 // Returns the index to the value of an entry. | 3008 // Returns the index to the value of an entry. |
3002 static inline int EntryToValueIndex(int entry) { | 3009 static inline int EntryToValueIndex(int entry) { |
3003 return EntryToIndex(entry) + 1; | 3010 return EntryToIndex(entry) + 1; |
3004 } | 3011 } |
3005 }; | 3012 }; |
3006 | 3013 |
3007 | 3014 |
(...skipping 3583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6591 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); | 6598 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); |
6592 }; | 6599 }; |
6593 | 6600 |
6594 | 6601 |
6595 // The JSProxy describes EcmaScript Harmony proxies | 6602 // The JSProxy describes EcmaScript Harmony proxies |
6596 class JSProxy: public JSReceiver { | 6603 class JSProxy: public JSReceiver { |
6597 public: | 6604 public: |
6598 // [handler]: The handler property. | 6605 // [handler]: The handler property. |
6599 DECL_ACCESSORS(handler, Object) | 6606 DECL_ACCESSORS(handler, Object) |
6600 | 6607 |
| 6608 // [hash]: The hash code property (undefined if not initialized yet). |
| 6609 DECL_ACCESSORS(hash, Object) |
| 6610 |
6601 // Casting. | 6611 // Casting. |
6602 static inline JSProxy* cast(Object* obj); | 6612 static inline JSProxy* cast(Object* obj); |
6603 | 6613 |
6604 bool HasPropertyWithHandler(String* name); | 6614 bool HasPropertyWithHandler(String* name); |
6605 bool HasElementWithHandler(uint32_t index); | 6615 bool HasElementWithHandler(uint32_t index); |
6606 | 6616 |
6607 MUST_USE_RESULT MaybeObject* GetPropertyWithHandler( | 6617 MUST_USE_RESULT MaybeObject* GetPropertyWithHandler( |
6608 Object* receiver, | 6618 Object* receiver, |
6609 String* name); | 6619 String* name); |
6610 MUST_USE_RESULT MaybeObject* GetElementWithHandler( | 6620 MUST_USE_RESULT MaybeObject* GetElementWithHandler( |
(...skipping 24 matching lines...) Expand all Loading... |
6635 uint32_t index, | 6645 uint32_t index, |
6636 DeleteMode mode); | 6646 DeleteMode mode); |
6637 | 6647 |
6638 MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler( | 6648 MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler( |
6639 JSReceiver* receiver, | 6649 JSReceiver* receiver, |
6640 String* name); | 6650 String* name); |
6641 MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler( | 6651 MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler( |
6642 JSReceiver* receiver, | 6652 JSReceiver* receiver, |
6643 uint32_t index); | 6653 uint32_t index); |
6644 | 6654 |
| 6655 MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); |
| 6656 |
6645 // Turn this into an (empty) JSObject. | 6657 // Turn this into an (empty) JSObject. |
6646 void Fix(); | 6658 void Fix(); |
6647 | 6659 |
6648 // Initializes the body after the handler slot. | 6660 // Initializes the body after the handler slot. |
6649 inline void InitializeBody(int object_size, Object* value); | 6661 inline void InitializeBody(int object_size, Object* value); |
6650 | 6662 |
6651 // Invoke a trap by name. If the trap does not exist on this's handler, | 6663 // Invoke a trap by name. If the trap does not exist on this's handler, |
6652 // but derived_trap is non-NULL, invoke that instead. May cause GC. | 6664 // but derived_trap is non-NULL, invoke that instead. May cause GC. |
6653 Handle<Object> CallTrap(const char* name, | 6665 Handle<Object> CallTrap(const char* name, |
6654 Handle<Object> derived_trap, | 6666 Handle<Object> derived_trap, |
6655 int argc, | 6667 int argc, |
6656 Handle<Object> args[]); | 6668 Handle<Object> args[]); |
6657 | 6669 |
6658 // Dispatched behavior. | 6670 // Dispatched behavior. |
6659 #ifdef OBJECT_PRINT | 6671 #ifdef OBJECT_PRINT |
6660 inline void JSProxyPrint() { | 6672 inline void JSProxyPrint() { |
6661 JSProxyPrint(stdout); | 6673 JSProxyPrint(stdout); |
6662 } | 6674 } |
6663 void JSProxyPrint(FILE* out); | 6675 void JSProxyPrint(FILE* out); |
6664 #endif | 6676 #endif |
6665 #ifdef DEBUG | 6677 #ifdef DEBUG |
6666 void JSProxyVerify(); | 6678 void JSProxyVerify(); |
6667 #endif | 6679 #endif |
6668 | 6680 |
6669 // Layout description. We add padding so that a proxy has the same | 6681 // Layout description. We add padding so that a proxy has the same |
6670 // size as a virgin JSObject. This is essential for becoming a JSObject | 6682 // size as a virgin JSObject. This is essential for becoming a JSObject |
6671 // upon freeze. | 6683 // upon freeze. |
6672 static const int kHandlerOffset = HeapObject::kHeaderSize; | 6684 static const int kHandlerOffset = HeapObject::kHeaderSize; |
6673 static const int kPaddingOffset = kHandlerOffset + kPointerSize; | 6685 static const int kHashOffset = kHandlerOffset + kPointerSize; |
| 6686 static const int kPaddingOffset = kHashOffset + kPointerSize; |
6674 static const int kSize = JSObject::kHeaderSize; | 6687 static const int kSize = JSObject::kHeaderSize; |
6675 static const int kHeaderSize = kPaddingOffset; | 6688 static const int kHeaderSize = kPaddingOffset; |
6676 static const int kPaddingSize = kSize - kPaddingOffset; | 6689 static const int kPaddingSize = kSize - kPaddingOffset; |
6677 | 6690 |
6678 STATIC_CHECK(kPaddingSize >= 0); | 6691 STATIC_CHECK(kPaddingSize >= 0); |
6679 | 6692 |
6680 typedef FixedBodyDescriptor<kHandlerOffset, | 6693 typedef FixedBodyDescriptor<kHandlerOffset, |
6681 kHandlerOffset + kPointerSize, | 6694 kPaddingOffset, |
6682 kSize> BodyDescriptor; | 6695 kSize> BodyDescriptor; |
6683 | 6696 |
6684 private: | 6697 private: |
6685 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy); | 6698 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy); |
6686 }; | 6699 }; |
6687 | 6700 |
6688 | 6701 |
6689 class JSFunctionProxy: public JSProxy { | 6702 class JSFunctionProxy: public JSProxy { |
6690 public: | 6703 public: |
6691 // [call_trap]: The call trap. | 6704 // [call_trap]: The call trap. |
(...skipping 10 matching lines...) Expand all Loading... |
6702 inline void JSFunctionProxyPrint() { | 6715 inline void JSFunctionProxyPrint() { |
6703 JSFunctionProxyPrint(stdout); | 6716 JSFunctionProxyPrint(stdout); |
6704 } | 6717 } |
6705 void JSFunctionProxyPrint(FILE* out); | 6718 void JSFunctionProxyPrint(FILE* out); |
6706 #endif | 6719 #endif |
6707 #ifdef DEBUG | 6720 #ifdef DEBUG |
6708 void JSFunctionProxyVerify(); | 6721 void JSFunctionProxyVerify(); |
6709 #endif | 6722 #endif |
6710 | 6723 |
6711 // Layout description. | 6724 // Layout description. |
6712 static const int kCallTrapOffset = kHandlerOffset + kPointerSize; | 6725 static const int kCallTrapOffset = JSProxy::kPaddingOffset; |
6713 static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize; | 6726 static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize; |
6714 static const int kPaddingOffset = kConstructTrapOffset + kPointerSize; | 6727 static const int kPaddingOffset = kConstructTrapOffset + kPointerSize; |
6715 static const int kSize = JSFunction::kSize; | 6728 static const int kSize = JSFunction::kSize; |
6716 static const int kPaddingSize = kSize - kPaddingOffset; | 6729 static const int kPaddingSize = kSize - kPaddingOffset; |
6717 | 6730 |
6718 STATIC_CHECK(kPaddingSize >= 0); | 6731 STATIC_CHECK(kPaddingSize >= 0); |
6719 | 6732 |
6720 typedef FixedBodyDescriptor<kHandlerOffset, | 6733 typedef FixedBodyDescriptor<kHandlerOffset, |
6721 kConstructTrapOffset + kPointerSize, | 6734 kConstructTrapOffset + kPointerSize, |
6722 kSize> BodyDescriptor; | 6735 kSize> BodyDescriptor; |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7396 } else { | 7409 } else { |
7397 value &= ~(1 << bit_position); | 7410 value &= ~(1 << bit_position); |
7398 } | 7411 } |
7399 return value; | 7412 return value; |
7400 } | 7413 } |
7401 }; | 7414 }; |
7402 | 7415 |
7403 } } // namespace v8::internal | 7416 } } // namespace v8::internal |
7404 | 7417 |
7405 #endif // V8_OBJECTS_H_ | 7418 #endif // V8_OBJECTS_H_ |
OLD | NEW |