Index: src/objects.h |
diff --git a/src/objects.h b/src/objects.h |
index 14f81f89a93534a9c33652ca2f8ae6d7d9b45928..9b33a4326c373b6508d2c097ed97e947b8a0776b 100644 |
--- a/src/objects.h |
+++ b/src/objects.h |
@@ -178,23 +178,6 @@ enum TransitionFlag { |
}; |
-// Indicates whether the transition is simple: the target map of the transition |
-// either extends the current map with a new property, or it modifies the |
-// property that was added last to the current map. |
-enum SimpleTransitionFlag { |
- SIMPLE_TRANSITION, |
- FULL_TRANSITION |
-}; |
- |
- |
-// Indicates whether we are only interested in the descriptors of a particular |
-// map, or in all descriptors in the descriptor array. |
-enum DescriptorFlag { |
- ALL_DESCRIPTORS, |
- OWN_DESCRIPTORS |
-}; |
- |
- |
// Instance size sentinel for objects of variable size. |
const int kVariableSizeSentinel = 0; |
@@ -1697,15 +1680,15 @@ class JSObject: public JSReceiver { |
String* name, |
PropertyAttributes* attributes); |
MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( |
- Object* receiver, |
+ JSReceiver* receiver, |
String* name, |
PropertyAttributes* attributes); |
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( |
- Object* receiver, |
+ JSReceiver* receiver, |
String* name, |
PropertyAttributes* attributes); |
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( |
- Object* receiver, |
+ JSReceiver* receiver, |
String* name, |
PropertyAttributes* attributes); |
@@ -2385,6 +2368,23 @@ class FixedArray: public FixedArrayBase { |
} |
}; |
+ // WhitenessWitness is used to prove that a descriptor array is white |
+ // (unmarked), so incremental write barriers can be skipped because the |
+ // marking invariant cannot be broken and slots pointing into evacuation |
+ // candidates will be discovered when the object is scanned. A witness is |
+ // always stack-allocated right after creating an array. By allocating a |
+ // witness, incremental marking is globally disabled. The witness is then |
+ // passed along wherever needed to statically prove that the array is known to |
+ // be white. |
+ class WhitenessWitness { |
+ public: |
+ inline explicit WhitenessWitness(FixedArray* array); |
+ inline ~WhitenessWitness(); |
+ |
+ private: |
+ IncrementalMarking* marking_; |
+ }; |
+ |
protected: |
// Set operation on FixedArray without using write barriers. Can |
// only be used for storing old space objects or smis. |
@@ -2468,23 +2468,6 @@ class FixedDoubleArray: public FixedArrayBase { |
// [length() - kDescriptorSize]: last key |
class DescriptorArray: public FixedArray { |
public: |
- // WhitenessWitness is used to prove that a descriptor array is white |
- // (unmarked), so incremental write barriers can be skipped because the |
- // marking invariant cannot be broken and slots pointing into evacuation |
- // candidates will be discovered when the object is scanned. A witness is |
- // always stack-allocated right after creating an array. By allocating a |
- // witness, incremental marking is globally disabled. The witness is then |
- // passed along wherever needed to statically prove that the array is known to |
- // be white. |
- class WhitenessWitness { |
- public: |
- inline explicit WhitenessWitness(FixedArray* array); |
- inline ~WhitenessWitness(); |
- |
- private: |
- IncrementalMarking* marking_; |
- }; |
- |
// Returns true for both shared empty_descriptor_array and for smis, which the |
// map uses to encode additional bit fields when the descriptor array is not |
// yet used. |
@@ -2494,47 +2477,20 @@ class DescriptorArray: public FixedArray { |
int number_of_descriptors() { |
ASSERT(length() >= kFirstIndex || IsEmpty()); |
int len = length(); |
- return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value(); |
- } |
- |
- int number_of_descriptors_storage() { |
- int len = length(); |
- return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize; |
- } |
- |
- int NumberOfSlackDescriptors() { |
- return number_of_descriptors_storage() - number_of_descriptors(); |
+ return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
} |
- inline void SetNumberOfDescriptors(int number_of_descriptors); |
inline int number_of_entries() { return number_of_descriptors(); } |
+ inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } |
bool HasEnumCache() { |
return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
} |
- void CopyEnumCacheFrom(DescriptorArray* array) { |
- set(kEnumCacheIndex, array->get(kEnumCacheIndex)); |
- } |
- |
- FixedArray* GetEnumCache() { |
+ Object* GetEnumCache() { |
ASSERT(HasEnumCache()); |
FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
- return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex)); |
- } |
- |
- bool HasEnumIndicesCache() { |
- if (IsEmpty()) return false; |
- Object* object = get(kEnumCacheIndex); |
- if (object->IsSmi()) return false; |
- FixedArray* bridge = FixedArray::cast(object); |
- return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi(); |
- } |
- |
- FixedArray* GetEnumIndicesCache() { |
- ASSERT(HasEnumIndicesCache()); |
- FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
- return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex)); |
+ return bridge->get(kEnumCacheBridgeCacheIndex); |
} |
Object** GetEnumCacheSlot() { |
@@ -2543,8 +2499,6 @@ class DescriptorArray: public FixedArray { |
kEnumCacheOffset); |
} |
- void ClearEnumCache(); |
- |
// Initialize or change the enum cache, |
// using the supplied storage for the small "bridge". |
void SetEnumCache(FixedArray* bridge_storage, |
@@ -2572,14 +2526,13 @@ class DescriptorArray: public FixedArray { |
inline void Set(int descriptor_number, |
Descriptor* desc, |
const WhitenessWitness&); |
- inline void Set(int descriptor_number, Descriptor* desc); |
- inline void EraseDescriptor(Heap* heap, int descriptor_number); |
// Append automatically sets the enumeration index. This should only be used |
// to add descriptors in bulk at the end, followed by sorting the descriptor |
// array. |
- inline void Append(Descriptor* desc, const WhitenessWitness&); |
- inline void Append(Descriptor* desc); |
+ inline void Append(Descriptor* desc, |
+ const WhitenessWitness&, |
+ int number_of_set_descriptors); |
// Transfer a complete descriptor from the src descriptor array to this |
// descriptor array. |
@@ -2588,22 +2541,23 @@ class DescriptorArray: public FixedArray { |
int src_index, |
const WhitenessWitness&); |
- MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index); |
- |
// Sort the instance descriptors by the hash codes of their keys. |
void Sort(); |
+ inline void SwapSortedKeys(int first, int second); |
// Search the instance descriptors for given name. |
- INLINE(int Search(String* name, int number_of_own_descriptors)); |
+ INLINE(int Search(String* name)); |
// As the above, but uses DescriptorLookupCache and updates it when |
// necessary. |
- INLINE(int SearchWithCache(String* name, Map* map)); |
+ INLINE(int SearchWithCache(String* name)); |
+ |
+ // Tells whether the name is present int the array. |
+ bool Contains(String* name) { return kNotFound != Search(name); } |
// Allocates a DescriptorArray, but returns the singleton |
// empty descriptor array object if number_of_descriptors is 0. |
- MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, |
- int slack = 0); |
+ MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
// Casting. |
static inline DescriptorArray* cast(Object* obj); |
@@ -2611,9 +2565,8 @@ class DescriptorArray: public FixedArray { |
// Constant for denoting key was not found. |
static const int kNotFound = -1; |
- static const int kDescriptorLengthIndex = 0; |
- static const int kEnumCacheIndex = 1; |
- static const int kFirstIndex = 2; |
+ static const int kEnumCacheIndex = 0; |
+ static const int kFirstIndex = 1; |
// The length of the "bridge" to the enum cache. |
static const int kEnumCacheBridgeLength = 2; |
@@ -2621,8 +2574,7 @@ class DescriptorArray: public FixedArray { |
static const int kEnumCacheBridgeIndicesCacheIndex = 1; |
// Layout description. |
- static const int kDescriptorLengthOffset = FixedArray::kHeaderSize; |
- static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize; |
+ static const int kEnumCacheOffset = FixedArray::kHeaderSize; |
static const int kFirstOffset = kEnumCacheOffset + kPointerSize; |
// Layout description for the bridge array. |
@@ -2644,7 +2596,7 @@ class DescriptorArray: public FixedArray { |
#ifdef DEBUG |
// Is the descriptor array sorted and without duplicates? |
- bool IsSortedNoDuplicates(int valid_descriptors = -1); |
+ bool IsSortedNoDuplicates(); |
// Is the descriptor array consistent with the back pointers in targets? |
bool IsConsistentWithBackPointers(Map* current_map); |
@@ -2697,21 +2649,24 @@ class DescriptorArray: public FixedArray { |
kDescriptorValue; |
} |
+ // Swap operation on FixedArray without using write barriers. |
+ static inline void NoIncrementalWriteBarrierSwap( |
+ FixedArray* array, int first, int second); |
+ |
// Swap first and second descriptor. |
- inline void SwapSortedKeys(int first, int second); |
+ inline void NoIncrementalWriteBarrierSwapDescriptors( |
+ int first, int second); |
DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); |
}; |
-enum SearchMode { ALL_ENTRIES, VALID_ENTRIES }; |
- |
-template<SearchMode search_mode, typename T> |
-inline int LinearSearch(T* array, String* name, int len, int valid_entries); |
+template<typename T> |
+inline int LinearSearch(T* array, String* name, int len); |
-template<SearchMode search_mode, typename T> |
-inline int Search(T* array, String* name, int valid_entries = 0); |
+template<typename T> |
+inline int Search(T* array, String* name); |
// HashTable is a subclass of FixedArray that implements a hash table |
@@ -2913,12 +2868,11 @@ class HashTable: public FixedArray { |
return (hash + GetProbeOffset(number)) & (size - 1); |
} |
- inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) { |
+ static uint32_t FirstProbe(uint32_t hash, uint32_t size) { |
return hash & (size - 1); |
} |
- inline static uint32_t NextProbe( |
- uint32_t last, uint32_t number, uint32_t size) { |
+ static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) { |
return (last + number) & (size - 1); |
} |
@@ -3005,8 +2959,6 @@ class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { |
private: |
MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s); |
- template <bool seq_ascii> friend class JsonParser; |
- |
DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); |
}; |
@@ -4720,7 +4672,6 @@ class Map: public HeapObject { |
class IsShared: public BitField<bool, 22, 1> {}; |
class FunctionWithPrototype: public BitField<bool, 23, 1> {}; |
class DictionaryMap: public BitField<bool, 24, 1> {}; |
- class OwnsDescriptors: public BitField<bool, 25, 1> {}; |
// Tells whether the object in the prototype property will be used |
// for instances created from this function. If the prototype |
@@ -4841,17 +4792,13 @@ class Map: public HeapObject { |
static bool IsValidElementsTransition(ElementsKind from_kind, |
ElementsKind to_kind); |
- bool StoresOwnDescriptors() { return HasTransitionArray(); } |
inline bool HasTransitionArray(); |
inline bool HasElementsTransition(); |
inline Map* elements_transition_map(); |
MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( |
Map* transitioned_map); |
- inline void SetTransition(int transition_index, Map* target); |
- inline Map* GetTransition(int transition_index); |
- MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, |
- Map* target, |
- SimpleTransitionFlag flag); |
+ inline void SetTransition(int index, Map* target); |
+ MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target); |
DECL_ACCESSORS(transitions, TransitionArray) |
inline void ClearTransitions(Heap* heap, |
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
@@ -4890,9 +4837,9 @@ class Map: public HeapObject { |
// [instance descriptors]: describes the object. |
inline DescriptorArray* instance_descriptors(); |
- inline JSGlobalPropertyCell* descriptors_pointer(); |
MUST_USE_RESULT inline MaybeObject* SetDescriptors( |
- DescriptorArray* descriptors); |
+ DescriptorArray* descriptors, |
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
static void SetDescriptors(Handle<Map> map, |
Handle<DescriptorArray> descriptors); |
MUST_USE_RESULT inline MaybeObject* InitializeDescriptors( |
@@ -4973,38 +4920,24 @@ class Map: public HeapObject { |
} |
void SetNumberOfOwnDescriptors(int number) { |
- ASSERT(number <= instance_descriptors()->number_of_descriptors()); |
set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); |
} |
- inline JSGlobalPropertyCell* RetrieveDescriptorsPointer(); |
- |
int EnumLength() { |
return EnumLengthBits::decode(bit_field3()); |
} |
- void SetEnumLength(int length) { |
- if (length != kInvalidEnumCache) { |
- ASSERT(length >= 0); |
- ASSERT(length == 0 || instance_descriptors()->HasEnumCache()); |
- ASSERT(length <= NumberOfOwnDescriptors()); |
- } |
- set_bit_field3(EnumLengthBits::update(bit_field3(), length)); |
+ void SetEnumLength(int index) { |
+ set_bit_field3(EnumLengthBits::update(bit_field3(), index)); |
} |
- |
- inline bool owns_descriptors(); |
- inline void set_owns_descriptors(bool is_shared); |
- |
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); |
MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); |
MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); |
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( |
DescriptorArray* descriptors, |
String* name, |
- TransitionFlag flag, |
- int descriptor_index); |
- MUST_USE_RESULT MaybeObject* ShareDescriptor(Descriptor* descriptor); |
+ TransitionFlag flag); |
MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, |
TransitionFlag flag); |
MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, |
@@ -5033,8 +4966,7 @@ class Map: public HeapObject { |
// Returns the number of properties described in instance_descriptors |
// filtering out properties with the specified attributes. |
- int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS, |
- PropertyAttributes filter = NONE); |
+ int NumberOfDescribedProperties(PropertyAttributes filter = NONE); |
// Casting. |
static inline Map* cast(Object* obj); |
@@ -5055,10 +4987,8 @@ class Map: public HeapObject { |
// Extend the descriptor array of the map with the list of descriptors. |
// In case of duplicates, the latest descriptor is used. |
- static void AppendCallbackDescriptors(Handle<Map> map, |
- Handle<Object> descriptors); |
- |
- static void EnsureDescriptorSlack(Handle<Map> map, int slack); |
+ static void CopyAppendCallbackDescriptors(Handle<Map> map, |
+ Handle<Object> descriptors); |
// Returns the found code or undefined if absent. |
Object* FindInCodeCache(String* name, Code::Flags flags); |
@@ -5140,7 +5070,7 @@ class Map: public HeapObject { |
static const int kMaxPreAllocatedPropertyFields = 255; |
- // Constant for denoting that the enum cache is not yet initialized. |
+ // Constant for denoting that the Enum Cache field was not yet used. |
static const int kInvalidEnumCache = EnumLengthBits::kMax; |
// Layout description. |
@@ -7057,6 +6987,10 @@ class StringHasher { |
// index. |
bool is_array_index() { return is_array_index_; } |
+ bool is_valid() { return is_valid_; } |
+ |
+ void invalidate() { is_valid_ = false; } |
+ |
// Calculated hash value for a string consisting of 1 to |
// String::kMaxArrayIndexSize digits with no leading zeros (except "0"). |
// value is represented decimal value. |
@@ -7075,33 +7009,13 @@ class StringHasher { |
inline uint32_t GetHash(); |
- // Reusable parts of the hashing algorithm. |
- INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint32_t c)); |
- INLINE(static uint32_t GetHashCore(uint32_t running_hash)); |
- |
int length_; |
uint32_t raw_running_hash_; |
uint32_t array_index_; |
bool is_array_index_; |
bool is_first_char_; |
+ bool is_valid_; |
friend class TwoCharHashTableKey; |
- |
- template <bool seq_ascii> friend class JsonParser; |
-}; |
- |
- |
-class IncrementalAsciiStringHasher { |
- public: |
- explicit inline IncrementalAsciiStringHasher(uint32_t seed, char first_char); |
- inline void AddCharacter(uc32 c); |
- inline uint32_t GetHash(); |
- |
- private: |
- int length_; |
- uint32_t raw_running_hash_; |
- uint32_t array_index_; |
- bool is_array_index_; |
- char first_char_; |
}; |
@@ -7472,7 +7386,7 @@ class String: public HeapObject { |
#ifdef V8_HOST_CAN_READ_UNALIGNED |
ASSERT(kMaxAsciiCharCode == 0x7F); |
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80; |
- while (chars + sizeof(uintptr_t) <= limit) { |
+ while (chars <= limit - sizeof(uintptr_t)) { |
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) { |
return false; |
} |