| 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 |