Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 2321) |
+++ src/objects.cc (working copy) |
@@ -41,6 +41,7 @@ |
#include "disassembler.h" |
#endif |
+ |
namespace v8 { |
namespace internal { |
@@ -428,17 +429,17 @@ |
Object* value, |
PropertyDetails details) { |
ASSERT(!HasFastProperties()); |
- int entry = property_dictionary()->FindStringEntry(name); |
- if (entry == Dictionary::kNotFound) { |
+ int entry = property_dictionary()->FindEntry(name); |
+ if (entry == StringDictionary::kNotFound) { |
Object* store_value = value; |
if (IsGlobalObject()) { |
store_value = Heap::AllocateJSGlobalPropertyCell(value); |
if (store_value->IsFailure()) return store_value; |
} |
Object* dict = |
- property_dictionary()->AddStringEntry(name, store_value, details); |
+ property_dictionary()->Add(name, store_value, details); |
if (dict->IsFailure()) return dict; |
- set_properties(Dictionary::cast(dict)); |
+ set_properties(StringDictionary::cast(dict)); |
return value; |
} |
// Preserve enumeration index. |
@@ -452,7 +453,7 @@ |
// Please note we have to update the property details. |
property_dictionary()->DetailsAtPut(entry, details); |
} else { |
- property_dictionary()->SetStringEntry(entry, name, value, details); |
+ property_dictionary()->SetEntry(entry, name, value, details); |
} |
return value; |
} |
@@ -460,9 +461,9 @@ |
Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
ASSERT(!HasFastProperties()); |
- Dictionary* dictionary = property_dictionary(); |
- int entry = dictionary->FindStringEntry(name); |
- if (entry != Dictionary::kNotFound) { |
+ StringDictionary* dictionary = property_dictionary(); |
+ int entry = dictionary->FindEntry(name); |
+ if (entry != StringDictionary::kNotFound) { |
// If we have a global object set the cell to the hole. |
if (IsGlobalObject()) { |
PropertyDetails details = dictionary->DetailsAt(entry); |
@@ -1340,16 +1341,16 @@ |
Object* value, |
PropertyAttributes attributes) { |
ASSERT(!HasFastProperties()); |
- Dictionary* dict = property_dictionary(); |
+ StringDictionary* dict = property_dictionary(); |
Object* store_value = value; |
if (IsGlobalObject()) { |
// In case name is an orphaned property reuse the cell. |
- int entry = dict->FindStringEntry(name); |
- if (entry != Dictionary::kNotFound) { |
+ int entry = dict->FindEntry(name); |
+ if (entry != StringDictionary::kNotFound) { |
store_value = dict->ValueAt(entry); |
JSGlobalPropertyCell::cast(store_value)->set_value(value); |
PropertyDetails details = PropertyDetails(attributes, NORMAL); |
- dict->SetStringEntry(entry, name, store_value, details); |
+ dict->SetEntry(entry, name, store_value, details); |
return value; |
} |
store_value = Heap::AllocateJSGlobalPropertyCell(value); |
@@ -1357,9 +1358,9 @@ |
JSGlobalPropertyCell::cast(store_value)->set_value(value); |
} |
PropertyDetails details = PropertyDetails(attributes, NORMAL); |
- Object* result = dict->AddStringEntry(name, store_value, details); |
+ Object* result = dict->Add(name, store_value, details); |
if (result->IsFailure()) return result; |
- if (dict != result) set_properties(Dictionary::cast(result)); |
+ if (dict != result) set_properties(StringDictionary::cast(result)); |
return value; |
} |
@@ -1405,8 +1406,8 @@ |
Object* JSObject::ReplaceSlowProperty(String* name, |
Object* value, |
PropertyAttributes attributes) { |
- Dictionary* dictionary = property_dictionary(); |
- int old_index = dictionary->FindStringEntry(name); |
+ StringDictionary* dictionary = property_dictionary(); |
+ int old_index = dictionary->FindEntry(name); |
int new_enumeration_index = 0; // 0 means "Use the next available index." |
if (old_index != -1) { |
// All calls to ReplaceSlowProperty have had all transitions removed. |
@@ -1646,9 +1647,9 @@ |
pt != Heap::null_value(); |
pt = pt->GetPrototype()) { |
if (JSObject::cast(pt)->HasFastElements()) continue; |
- Dictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != StringDictionary::kNotFound) { |
Object* element = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.type() == CALLBACKS) { |
@@ -1698,8 +1699,8 @@ |
return; |
} |
} else { |
- int entry = property_dictionary()->FindStringEntry(name); |
- if (entry != Dictionary::kNotFound) { |
+ int entry = property_dictionary()->FindEntry(name); |
+ if (entry != StringDictionary::kNotFound) { |
// Make sure to disallow caching for uninitialized constants |
// found in the dictionary-mode objects. |
Object* value = property_dictionary()->ValueAt(entry); |
@@ -2101,9 +2102,9 @@ |
// Allocate new content |
Object* obj = |
- Dictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); |
+ StringDictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); |
if (obj->IsFailure()) return obj; |
- Dictionary* dictionary = Dictionary::cast(obj); |
+ StringDictionary* dictionary = StringDictionary::cast(obj); |
for (DescriptorReader r(map()->instance_descriptors()); |
!r.eos(); |
@@ -2118,9 +2119,9 @@ |
value = Heap::AllocateJSGlobalPropertyCell(value); |
if (value->IsFailure()) return value; |
} |
- Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
+ Object* result = dictionary->Add(r.GetKey(), value, d); |
if (result->IsFailure()) return result; |
- dictionary = Dictionary::cast(result); |
+ dictionary = StringDictionary::cast(result); |
break; |
} |
case FIELD: { |
@@ -2131,9 +2132,9 @@ |
value = Heap::AllocateJSGlobalPropertyCell(value); |
if (value->IsFailure()) return value; |
} |
- Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
+ Object* result = dictionary->Add(r.GetKey(), value, d); |
if (result->IsFailure()) return result; |
- dictionary = Dictionary::cast(result); |
+ dictionary = StringDictionary::cast(result); |
break; |
} |
case CALLBACKS: { |
@@ -2144,9 +2145,9 @@ |
value = Heap::AllocateJSGlobalPropertyCell(value); |
if (value->IsFailure()) return value; |
} |
- Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
+ Object* result = dictionary->Add(r.GetKey(), value, d); |
if (result->IsFailure()) return result; |
- dictionary = Dictionary::cast(result); |
+ dictionary = StringDictionary::cast(result); |
break; |
} |
case MAP_TRANSITION: |
@@ -2219,9 +2220,9 @@ |
int length = IsJSArray() ? |
Smi::cast(JSArray::cast(this)->length())->value() : |
array->length(); |
- Object* obj = Dictionary::Allocate(length); |
+ Object* obj = NumberDictionary::Allocate(length); |
if (obj->IsFailure()) return obj; |
- Dictionary* dictionary = Dictionary::cast(obj); |
+ NumberDictionary* dictionary = NumberDictionary::cast(obj); |
// Copy entries. |
for (int i = 0; i < length; i++) { |
Object* value = array->get(i); |
@@ -2229,7 +2230,7 @@ |
PropertyDetails details = PropertyDetails(NONE, NORMAL); |
Object* result = dictionary->AddNumberEntry(i, array->get(i), details); |
if (result->IsFailure()) return result; |
- dictionary = Dictionary::cast(result); |
+ dictionary = NumberDictionary::cast(result); |
} |
} |
// Switch to using the dictionary as the backing storage for elements. |
@@ -2306,9 +2307,9 @@ |
return Heap::true_value(); |
} |
ASSERT(!HasFastElements()); |
- Dictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != StringDictionary::kNotFound) { |
Mads Ager (chromium)
2009/07/01 15:32:49
NumberDictionary::kNotFound
|
return dictionary->DeleteProperty(entry, mode); |
} |
return Heap::true_value(); |
@@ -2380,9 +2381,9 @@ |
} |
return Heap::true_value(); |
} else { |
- Dictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
return dictionary->DeleteProperty(entry, mode); |
} |
} |
@@ -2687,9 +2688,9 @@ |
if (is_element) { |
// Lookup the index. |
if (!HasFastElements()) { |
- Dictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
Object* result = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.IsReadOnly()) return Heap::undefined_value(); |
@@ -2725,14 +2726,14 @@ |
// Update the dictionary with the new CALLBACKS property. |
Object* dict = |
- element_dictionary()->SetOrAddNumberEntry(index, structure, details); |
+ element_dictionary()->Set(index, structure, details); |
if (dict->IsFailure()) return dict; |
// If name is an index we need to stay in slow case. |
- Dictionary* elements = Dictionary::cast(dict); |
+ NumberDictionary* elements = NumberDictionary::cast(dict); |
elements->set_requires_slow_elements(); |
// Set the potential new dictionary on the object. |
- set_elements(Dictionary::cast(dict)); |
+ set_elements(NumberDictionary::cast(dict)); |
} else { |
// Normalize object to make this operation simple. |
Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
@@ -2799,9 +2800,9 @@ |
obj = JSObject::cast(obj)->GetPrototype()) { |
JSObject* jsObject = JSObject::cast(obj); |
if (!jsObject->HasFastElements()) { |
- Dictionary* dictionary = jsObject->element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = jsObject->element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
Object* element = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.type() == CALLBACKS) { |
@@ -3004,7 +3005,7 @@ |
return UnionOfKeys(array->elements()); |
} |
ASSERT(!array->HasFastElements()); |
- Dictionary* dict = array->element_dictionary(); |
+ NumberDictionary* dict = array->element_dictionary(); |
int size = dict->NumberOfElements(); |
// Allocate a temporary fixed array. |
@@ -5075,7 +5076,7 @@ |
elems->set(i, old_elements->get(i), mode); |
} |
} else { |
- Dictionary* dictionary = Dictionary::cast(elements()); |
+ NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
for (int i = 0; i < dictionary->Capacity(); i++) { |
Object* key = dictionary->KeyAt(i); |
if (key->IsNumber()) { |
@@ -5240,7 +5241,8 @@ |
return true; |
} |
} else { |
- if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) { |
+ if (element_dictionary()->FindEntry(index) |
+ != NumberDictionary::kNotFound) { |
return true; |
} |
} |
@@ -5317,8 +5319,8 @@ |
return (index < length) && |
!FixedArray::cast(elements())->get(index)->IsTheHole(); |
} else { |
- return element_dictionary()->FindNumberEntry(index) |
- != Dictionary::kNotFound; |
+ return element_dictionary()->FindEntry(index) |
+ != NumberDictionary::kNotFound; |
} |
} |
@@ -5344,7 +5346,8 @@ |
if ((index < length) && |
!FixedArray::cast(elements())->get(index)->IsTheHole()) return true; |
} else { |
- if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) { |
+ if (element_dictionary()->FindEntry(index) |
+ != NumberDictionary::kNotFound) { |
return true; |
} |
} |
@@ -5479,10 +5482,10 @@ |
// Insert element in the dictionary. |
FixedArray* elms = FixedArray::cast(elements()); |
- Dictionary* dictionary = Dictionary::cast(elms); |
+ NumberDictionary* dictionary = NumberDictionary::cast(elms); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
Object* element = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.type() == CALLBACKS) { |
@@ -5531,7 +5534,7 @@ |
CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), &new_length)); |
JSArray::cast(this)->set_length(Smi::FromInt(new_length)); |
} else { |
- new_length = Dictionary::cast(elements())->max_number_key() + 1; |
+ new_length = NumberDictionary::cast(elements())->max_number_key() + 1; |
} |
Object* obj = Heap::AllocateFixedArrayWithHoles(new_length); |
if (obj->IsFailure()) return obj; |
@@ -5574,9 +5577,9 @@ |
if (!value->IsTheHole()) return value; |
} |
} else { |
- Dictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
Object* element = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.type() == CALLBACKS) { |
@@ -5658,9 +5661,9 @@ |
if (!value->IsTheHole()) return value; |
} |
} else { |
- Dictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindNumberEntry(index); |
- if (entry != Dictionary::kNotFound) { |
+ NumberDictionary* dictionary = element_dictionary(); |
+ int entry = dictionary->FindEntry(index); |
+ if (entry != NumberDictionary::kNotFound) { |
Object* element = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
if (details.type() == CALLBACKS) { |
@@ -5696,7 +5699,7 @@ |
if (!elms->get(i)->IsTheHole()) number_of_elements++; |
} |
} else { |
- Dictionary* dictionary = Dictionary::cast(elements()); |
+ NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
capacity = dictionary->Capacity(); |
number_of_elements = dictionary->NumberOfElements(); |
} |
@@ -5718,7 +5721,7 @@ |
bool JSObject::ShouldConvertToFastElements() { |
ASSERT(!HasFastElements()); |
- Dictionary* dictionary = Dictionary::cast(elements()); |
+ NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
// If the elements are sparse, we should not go back to fast case. |
if (!HasDenseElements()) return false; |
// If an element has been added at a very high index in the elements |
@@ -5737,17 +5740,19 @@ |
length = dictionary->max_number_key(); |
} |
return static_cast<uint32_t>(dictionary->Capacity()) >= |
- (length / (2 * Dictionary::kElementSize)); |
+ (length / (2 * NumberDictionary::kEntrySize)); |
} |
- |
-void Dictionary::CopyValuesTo(FixedArray* elements) { |
+template<typename Shape, typename Key> |
+void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { |
int pos = 0; |
- int capacity = Capacity(); |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
WriteBarrierMode mode = elements->GetWriteBarrierMode(); |
for (int i = 0; i < capacity; i++) { |
- Object* k = KeyAt(i); |
- if (IsKey(k)) elements->set(pos++, ValueAt(i), mode); |
+ Object* k = Dictionary<Shape, Key>::KeyAt(i); |
+ if (Dictionary<Shape, Key>::IsKey(k)) { |
+ elements->set(pos++, ValueAt(i), mode); |
+ } |
} |
ASSERT(pos == elements->length()); |
} |
@@ -5953,8 +5958,8 @@ |
return (index < length) && |
!FixedArray::cast(elements())->get(index)->IsTheHole(); |
} |
- return element_dictionary()->FindNumberEntry(index) |
- != Dictionary::kNotFound; |
+ return element_dictionary()->FindEntry(index) |
+ != NumberDictionary::kNotFound; |
} |
@@ -6187,51 +6192,62 @@ |
} |
-// The NumberKey uses carries the uint32_t as key. |
-// This avoids allocation in HasProperty. |
-class NumberKey : public HashTableKey { |
- public: |
- explicit NumberKey(uint32_t number) : number_(number) { } |
+bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) { |
+ ASSERT(other->IsNumber()); |
+ return key == static_cast<uint32_t>(other->Number()); |
+} |
- bool IsMatch(Object* number) { |
- return number_ == ToUint32(number); |
- } |
- uint32_t Hash() { return ComputeIntegerHash(number_); } |
+uint32_t NumberDictionaryShape::Hash(uint32_t key) { |
+ return ComputeIntegerHash(key); |
+} |
- HashFunction GetHashFunction() { return NumberHash; } |
- Object* GetObject() { |
- return Heap::NumberFromDouble(number_); |
- } |
+uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { |
+ ASSERT(other->IsNumber()); |
+ return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); |
+} |
- bool IsStringKey() { return false; } |
- private: |
- static uint32_t NumberHash(Object* obj) { |
- return ComputeIntegerHash(ToUint32(obj)); |
- } |
+Object* NumberDictionaryShape::AsObject(uint32_t key) { |
+ return Heap::NumberFromUint32(key); |
+} |
- static uint32_t ToUint32(Object* obj) { |
- ASSERT(obj->IsNumber()); |
- return static_cast<uint32_t>(obj->Number()); |
- } |
- uint32_t number_; |
-}; |
+bool StringDictionaryShape::IsMatch(String* key, Object* other) { |
+ // We know that all entries in a hash table had their hash keys created. |
+ // Use that knowledge to have fast failure. |
+ if (key->Hash() != String::cast(other)->Hash()) return false; |
+ return key->Equals(String::cast(other)); |
+} |
+uint32_t StringDictionaryShape::Hash(String* key) { |
+ return key->Hash(); |
+} |
+ |
+ |
+uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { |
+ return String::cast(other)->Hash(); |
+} |
+ |
+ |
+Object* StringDictionaryShape::AsObject(String* key) { |
+ return key; |
+} |
+ |
+ |
// StringKey simply carries a string object as key. |
class StringKey : public HashTableKey { |
public: |
explicit StringKey(String* string) : |
string_(string), |
- hash_(StringHash(string)) { } |
+ hash_(HashForObject(string)) { } |
bool IsMatch(Object* string) { |
// We know that all entries in a hash table had their hash keys created. |
// Use that knowledge to have fast failure. |
- if (hash_ != StringHash(string)) { |
+ if (hash_ != HashForObject(string)) { |
return false; |
} |
return string_->Equals(String::cast(string)); |
@@ -6239,16 +6255,10 @@ |
uint32_t Hash() { return hash_; } |
- HashFunction GetHashFunction() { return StringHash; } |
+ uint32_t HashForObject(Object* other) { return String::cast(other)->Hash(); } |
- Object* GetObject() { return string_; } |
+ Object* AsObject() { return string_; } |
- static uint32_t StringHash(Object* obj) { |
- return String::cast(obj)->Hash(); |
- } |
- |
- bool IsStringKey() { return true; } |
- |
String* string_; |
uint32_t hash_; |
}; |
@@ -6269,10 +6279,6 @@ |
return source->Equals(source_); |
} |
- typedef uint32_t (*HashFunction)(Object* obj); |
- |
- virtual HashFunction GetHashFunction() { return StringSharedHash; } |
- |
static uint32_t StringSharedHashHelper(String* source, |
SharedFunctionInfo* shared) { |
uint32_t hash = source->Hash(); |
@@ -6289,18 +6295,18 @@ |
return hash; |
} |
- static uint32_t StringSharedHash(Object* obj) { |
+ uint32_t Hash() { |
+ return StringSharedHashHelper(source_, shared_); |
+ } |
+ |
+ uint32_t HashForObject(Object* obj) { |
FixedArray* pair = FixedArray::cast(obj); |
SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); |
String* source = String::cast(pair->get(1)); |
return StringSharedHashHelper(source, shared); |
} |
- virtual uint32_t Hash() { |
- return StringSharedHashHelper(source_, shared_); |
- } |
- |
- virtual Object* GetObject() { |
+ Object* AsObject() { |
Object* obj = Heap::AllocateFixedArray(2); |
if (obj->IsFailure()) return obj; |
FixedArray* pair = FixedArray::cast(obj); |
@@ -6309,8 +6315,6 @@ |
return pair; |
} |
- virtual bool IsStringKey() { return false; } |
- |
private: |
String* source_; |
SharedFunctionInfo* shared_; |
@@ -6332,16 +6336,14 @@ |
uint32_t Hash() { return RegExpHash(string_, flags_); } |
- HashFunction GetHashFunction() { return RegExpObjectHash; } |
- |
- Object* GetObject() { |
+ Object* AsObject() { |
// Plain hash maps, which is where regexp keys are used, don't |
// use this function. |
UNREACHABLE(); |
return NULL; |
} |
- static uint32_t RegExpObjectHash(Object* obj) { |
+ uint32_t HashForObject(Object* obj) { |
FixedArray* val = FixedArray::cast(obj); |
return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)), |
Smi::cast(val->get(JSRegExp::kFlagsIndex))); |
@@ -6351,8 +6353,6 @@ |
return string->Hash() + flags->value(); |
} |
- bool IsStringKey() { return false; } |
- |
String* string_; |
Smi* flags_; |
}; |
@@ -6367,10 +6367,6 @@ |
return String::cast(string)->IsEqualTo(string_); |
} |
- HashFunction GetHashFunction() { |
- return StringHash; |
- } |
- |
uint32_t Hash() { |
if (length_field_ != 0) return length_field_ >> String::kHashShift; |
unibrow::Utf8InputBuffer<> buffer(string_.start(), |
@@ -6382,17 +6378,15 @@ |
return result; |
} |
- Object* GetObject() { |
+ uint32_t HashForObject(Object* other) { |
+ return String::cast(other)->Hash(); |
+ } |
+ |
+ Object* AsObject() { |
if (length_field_ == 0) Hash(); |
return Heap::AllocateSymbol(string_, chars_, length_field_); |
} |
- static uint32_t StringHash(Object* obj) { |
- return String::cast(obj)->Hash(); |
- } |
- |
- bool IsStringKey() { return true; } |
- |
Vector<const char> string_; |
uint32_t length_field_; |
int chars_; // Caches the number of characters when computing the hash code. |
@@ -6404,17 +6398,17 @@ |
public: |
explicit SymbolKey(String* string) : string_(string) { } |
- HashFunction GetHashFunction() { |
- return StringHash; |
- } |
- |
bool IsMatch(Object* string) { |
return String::cast(string)->Equals(string_); |
} |
uint32_t Hash() { return string_->Hash(); } |
- Object* GetObject() { |
+ uint32_t HashForObject(Object* other) { |
+ return String::cast(other)->Hash(); |
+ } |
+ |
+ Object* AsObject() { |
// If the string is a cons string, attempt to flatten it so that |
// symbols will most often be flat strings. |
if (StringShape(string_).IsCons()) { |
@@ -6442,28 +6436,27 @@ |
return String::cast(obj)->Hash(); |
} |
- bool IsStringKey() { return true; } |
- |
String* string_; |
}; |
-template<int prefix_size, int element_size> |
-void HashTable<prefix_size, element_size>::IteratePrefix(ObjectVisitor* v) { |
+template<typename Shape, typename Key> |
+void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
IteratePointers(v, 0, kElementsStartOffset); |
} |
-template<int prefix_size, int element_size> |
-void HashTable<prefix_size, element_size>::IterateElements(ObjectVisitor* v) { |
+template<typename Shape, typename Key> |
+void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { |
IteratePointers(v, |
kElementsStartOffset, |
kHeaderSize + length() * kPointerSize); |
} |
-template<int prefix_size, int element_size> |
-Object* HashTable<prefix_size, element_size>::Allocate(int at_least_space_for) { |
+template<typename Shape, typename Key> |
+Object* HashTable<Shape, Key>::Allocate( |
+ int at_least_space_for) { |
int capacity = RoundUpToPowerOf2(at_least_space_for); |
if (capacity < 4) capacity = 4; // Guarantee min capacity. |
Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); |
@@ -6475,27 +6468,28 @@ |
} |
+ |
// Find entry for key otherwise return -1. |
-template <int prefix_size, int element_size> |
-int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) { |
+template<typename Shape, typename Key> |
+int HashTable<Shape, Key>::FindEntry(Key key) { |
uint32_t nof = NumberOfElements(); |
if (nof == 0) return kNotFound; // Bail out if empty. |
uint32_t capacity = Capacity(); |
- uint32_t hash = key->Hash(); |
+ uint32_t hash = Shape::Hash(key); |
uint32_t entry = GetProbe(hash, 0, capacity); |
Object* element = KeyAt(entry); |
uint32_t passed_elements = 0; |
if (!element->IsNull()) { |
- if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
+ if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry; |
if (++passed_elements == nof) return kNotFound; |
} |
for (uint32_t i = 1; !element->IsUndefined(); i++) { |
entry = GetProbe(hash, i, capacity); |
element = KeyAt(entry); |
if (!element->IsNull()) { |
- if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
+ if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry; |
if (++passed_elements == nof) return kNotFound; |
} |
} |
@@ -6503,9 +6497,8 @@ |
} |
-template<int prefix_size, int element_size> |
-Object* HashTable<prefix_size, element_size>::EnsureCapacity( |
- int n, HashTableKey* key) { |
+template<typename Shape, typename Key> |
+Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
int capacity = Capacity(); |
int nof = NumberOfElements() + n; |
// Make sure 50% is free |
@@ -6517,18 +6510,20 @@ |
WriteBarrierMode mode = table->GetWriteBarrierMode(); |
// Copy prefix to new array. |
- for (int i = kPrefixStartIndex; i < kPrefixStartIndex + prefix_size; i++) { |
+ for (int i = kPrefixStartIndex; |
+ i < kPrefixStartIndex + Shape::kPrefixSize; |
+ i++) { |
table->set(i, get(i), mode); |
} |
// Rehash the elements. |
- uint32_t (*Hash)(Object* key) = key->GetHashFunction(); |
for (int i = 0; i < capacity; i++) { |
uint32_t from_index = EntryToIndex(i); |
- Object* key = get(from_index); |
- if (IsKey(key)) { |
+ Object* k = get(from_index); |
+ if (IsKey(k)) { |
+ uint32_t hash = Shape::HashForObject(key, k); |
uint32_t insertion_index = |
- EntryToIndex(table->FindInsertionEntry(key, Hash(key))); |
- for (int j = 0; j < element_size; j++) { |
+ EntryToIndex(table->FindInsertionEntry(hash)); |
+ for (int j = 0; j < Shape::kEntrySize; j++) { |
table->set(insertion_index + j, get(from_index + j), mode); |
} |
} |
@@ -6538,10 +6533,8 @@ |
} |
-template<int prefix_size, int element_size> |
-uint32_t HashTable<prefix_size, element_size>::FindInsertionEntry( |
- Object* key, |
- uint32_t hash) { |
+template<typename Shape, typename Key> |
+uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { |
uint32_t capacity = Capacity(); |
uint32_t entry = GetProbe(hash, 0, capacity); |
Object* element = KeyAt(entry); |
@@ -6554,19 +6547,24 @@ |
return entry; |
} |
+// Force instantiation of template instances class |
+template class HashTable<SymbolTableShape, HashTableKey*>; |
-// Force instantiation of SymbolTable's base class |
-template class HashTable<0, 1>; |
+template class HashTable<CompilationCacheShape, HashTableKey*>; |
+template class HashTable<MapCacheShape, HashTableKey*>; |
-// Force instantiation of Dictionary's base class |
-template class HashTable<2, 3>; |
+template class Dictionary<StringDictionaryShape, String*>; |
+template class Dictionary<NumberDictionaryShape, uint32_t>; |
-// Force instantiation of EvalCache's base class |
-template class HashTable<0, 2>; |
+template Object* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( |
+ int at_least_space_for); |
+template Object* Dictionary<StringDictionaryShape, String*>::Allocate( |
+ int at_least_space_for); |
+ |
// Collates undefined and unexisting elements below limit from position |
// zero of the elements. The object stays in Dictionary mode. |
Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
@@ -6574,7 +6572,7 @@ |
// Must stay in dictionary mode, either because of requires_slow_elements, |
// or because we are not going to sort (and therefore compact) all of the |
// elements. |
- Dictionary* dict = element_dictionary(); |
+ NumberDictionary* dict = element_dictionary(); |
HeapNumber* result_double = NULL; |
if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
// Allocate space for result before we start mutating the object. |
@@ -6584,9 +6582,9 @@ |
} |
int capacity = dict->Capacity(); |
- Object* obj = Dictionary::Allocate(dict->Capacity()); |
+ Object* obj = NumberDictionary::Allocate(dict->Capacity()); |
if (obj->IsFailure()) return obj; |
- Dictionary* new_dict = Dictionary::cast(obj); |
+ NumberDictionary* new_dict = NumberDictionary::cast(obj); |
AssertNoAllocation no_alloc; |
@@ -6647,7 +6645,7 @@ |
if (!HasFastElements()) { |
// Convert to fast elements containing only the existing properties. |
// Ordering is irrelevant, since we are going to sort anyway. |
- Dictionary* dict = element_dictionary(); |
+ NumberDictionary* dict = element_dictionary(); |
if (IsJSArray() || dict->requires_slow_elements() || |
dict->max_number_key() >= limit) { |
return PrepareSlowElementsForSort(limit); |
@@ -6787,7 +6785,7 @@ |
if (obj->IsFailure()) return obj; |
// Create symbol object. |
- Object* symbol = key->GetObject(); |
+ Object* symbol = key->AsObject(); |
if (symbol->IsFailure()) return symbol; |
// If the symbol table grew as part of EnsureCapacity, obj is not |
@@ -6796,7 +6794,7 @@ |
SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); |
// Add the new symbol and return it along with the symbol table. |
- entry = table->FindInsertionEntry(symbol, key->Hash()); |
+ entry = table->FindInsertionEntry(key->Hash()); |
table->set(EntryToIndex(entry), symbol); |
table->ElementAdded(); |
*s = symbol; |
@@ -6836,7 +6834,7 @@ |
CompilationCacheTable* cache = |
reinterpret_cast<CompilationCacheTable*>(obj); |
- int entry = cache->FindInsertionEntry(src, key.Hash()); |
+ int entry = cache->FindInsertionEntry(key.Hash()); |
cache->set(EntryToIndex(entry), src); |
cache->set(EntryToIndex(entry) + 1, value); |
cache->ElementAdded(); |
@@ -6853,9 +6851,9 @@ |
CompilationCacheTable* cache = |
reinterpret_cast<CompilationCacheTable*>(obj); |
- int entry = cache->FindInsertionEntry(src, key.Hash()); |
+ int entry = cache->FindInsertionEntry(key.Hash()); |
- Object* k = key.GetObject(); |
+ Object* k = key.AsObject(); |
if (k->IsFailure()) return k; |
cache->set(EntryToIndex(entry), k); |
@@ -6874,7 +6872,7 @@ |
CompilationCacheTable* cache = |
reinterpret_cast<CompilationCacheTable*>(obj); |
- int entry = cache->FindInsertionEntry(value, key.Hash()); |
+ int entry = cache->FindInsertionEntry(key.Hash()); |
cache->set(EntryToIndex(entry), value); |
cache->set(EntryToIndex(entry) + 1, value); |
cache->ElementAdded(); |
@@ -6897,13 +6895,9 @@ |
return true; |
} |
- uint32_t Hash() { return SymbolsHash(symbols_); } |
+ uint32_t Hash() { return HashForObject(symbols_); } |
- HashFunction GetHashFunction() { return SymbolsHash; } |
- |
- Object* GetObject() { return symbols_; } |
- |
- static uint32_t SymbolsHash(Object* obj) { |
+ uint32_t HashForObject(Object* obj) { |
FixedArray* symbols = FixedArray::cast(obj); |
int len = symbols->length(); |
uint32_t hash = 0; |
@@ -6913,7 +6907,7 @@ |
return hash; |
} |
- bool IsStringKey() { return false; } |
+ Object* AsObject() { return symbols_; } |
private: |
FixedArray* symbols_; |
@@ -6934,7 +6928,7 @@ |
if (obj->IsFailure()) return obj; |
MapCache* cache = reinterpret_cast<MapCache*>(obj); |
- int entry = cache->FindInsertionEntry(array, key.Hash()); |
+ int entry = cache->FindInsertionEntry(key.Hash()); |
cache->set(EntryToIndex(entry), array); |
cache->set(EntryToIndex(entry) + 1, value); |
cache->ElementAdded(); |
@@ -6942,19 +6936,21 @@ |
} |
-Object* Dictionary::Allocate(int at_least_space_for) { |
- Object* obj = DictionaryBase::Allocate(at_least_space_for); |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::Allocate(int at_least_space_for) { |
+ Object* obj = HashTable<Shape, Key>::Allocate(at_least_space_for); |
// Initialize the next enumeration index. |
if (!obj->IsFailure()) { |
- Dictionary::cast(obj)-> |
+ Dictionary<Shape, Key>::cast(obj)-> |
SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
} |
return obj; |
} |
-Object* Dictionary::GenerateNewEnumerationIndices() { |
- int length = NumberOfElements(); |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
+ int length = HashTable<Shape, Key>::NumberOfElements(); |
// Allocate and initialize iteration order array. |
Object* obj = Heap::AllocateFixedArray(length); |
@@ -6970,10 +6966,10 @@ |
FixedArray* enumeration_order = FixedArray::cast(obj); |
// Fill the enumeration order array with property details. |
- int capacity = Capacity(); |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
int pos = 0; |
for (int i = 0; i < capacity; i++) { |
- if (IsKey(KeyAt(i))) { |
+ if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
enumeration_order->set(pos++, |
Smi::FromInt(DetailsAt(i).index()), |
SKIP_WRITE_BARRIER); |
@@ -6993,10 +6989,10 @@ |
} |
// Update the dictionary with new indices. |
- capacity = Capacity(); |
+ capacity = HashTable<Shape, Key>::Capacity(); |
pos = 0; |
for (int i = 0; i < capacity; i++) { |
- if (IsKey(KeyAt(i))) { |
+ if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
PropertyDetails details = DetailsAt(i); |
PropertyDetails new_details = |
@@ -7010,20 +7006,20 @@ |
return this; |
} |
- |
-Object* Dictionary::EnsureCapacity(int n, HashTableKey* key) { |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { |
// Check whether there are enough enumeration indices to add n elements. |
- if (key->IsStringKey() && |
+ if (Shape::kIsEnumerable && |
!PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
// If not, we generate new indices for the properties. |
Object* result = GenerateNewEnumerationIndices(); |
if (result->IsFailure()) return result; |
} |
- return DictionaryBase::EnsureCapacity(n, key); |
+ return HashTable<Shape, Key>::EnsureCapacity(n, key); |
} |
-void Dictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
+void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
// Do nothing if the interval [from, to) is empty. |
if (from >= to) return; |
@@ -7045,36 +7041,26 @@ |
SetNumberOfElements(NumberOfElements() - removed_entries); |
} |
- |
-Object* Dictionary::DeleteProperty(int entry, JSObject::DeleteMode mode) { |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::DeleteProperty(int entry, |
+ JSObject::DeleteMode mode) { |
PropertyDetails details = DetailsAt(entry); |
// Ignore attributes if forcing a deletion. |
if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { |
return Heap::false_value(); |
} |
SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); |
- ElementRemoved(); |
+ HashTable<Shape, Key>::ElementRemoved(); |
return Heap::true_value(); |
} |
-int Dictionary::FindStringEntry(String* key) { |
- StringKey k(key); |
- return FindEntry(&k); |
-} |
- |
- |
-int Dictionary::FindNumberEntry(uint32_t index) { |
- NumberKey k(index); |
- return FindEntry(&k); |
-} |
- |
- |
-Object* Dictionary::AtPut(HashTableKey* key, Object* value) { |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { |
int entry = FindEntry(key); |
// If the entry is present set the value; |
- if (entry != kNotFound) { |
+ if (entry != Dictionary<Shape, Key>::kNotFound) { |
ValueAtPut(entry, value); |
return this; |
} |
@@ -7082,48 +7068,57 @@ |
// Check whether the dictionary should be extended. |
Object* obj = EnsureCapacity(1, key); |
if (obj->IsFailure()) return obj; |
- Object* k = key->GetObject(); |
+ |
+ Object* k = Shape::AsObject(key); |
if (k->IsFailure()) return k; |
PropertyDetails details = PropertyDetails(NONE, NORMAL); |
- Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); |
- return obj; |
+ return Dictionary<Shape, Key>::cast(obj)-> |
+ AddEntry(key, value, details, Shape::Hash(key)); |
} |
-Object* Dictionary::Add(HashTableKey* key, Object* value, |
- PropertyDetails details) { |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::Add(Key key, |
+ Object* value, |
+ PropertyDetails details) { |
+ // Valdate key is absent. |
+ SLOW_ASSERT((FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); |
// Check whether the dictionary should be extended. |
Object* obj = EnsureCapacity(1, key); |
if (obj->IsFailure()) return obj; |
- // Compute the key object. |
- Object* k = key->GetObject(); |
- if (k->IsFailure()) return k; |
- Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); |
- return obj; |
+ return Dictionary<Shape, Key>::cast(obj)-> |
+ AddEntry(key, value, details, Shape::Hash(key)); |
} |
// Add a key, value pair to the dictionary. |
-void Dictionary::AddEntry(Object* key, |
- Object* value, |
- PropertyDetails details, |
- uint32_t hash) { |
- uint32_t entry = FindInsertionEntry(key, hash); |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::AddEntry(Key key, |
+ Object* value, |
+ PropertyDetails details, |
+ uint32_t hash) { |
+ // Compute the key object. |
+ Object* k = Shape::AsObject(key); |
+ if (k->IsFailure()) return k; |
+ |
+ uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); |
// Insert element at empty or deleted entry |
- if (details.index() == 0 && key->IsString()) { |
+ if (details.index() == 0 && Shape::kIsEnumerable) { |
// Assign an enumeration index to the property and update |
// SetNextEnumerationIndex. |
int index = NextEnumerationIndex(); |
details = PropertyDetails(details.attributes(), details.type(), index); |
SetNextEnumerationIndex(index + 1); |
} |
- SetEntry(entry, key, value, details); |
- ASSERT(KeyAt(entry)->IsNumber() || KeyAt(entry)->IsString()); |
- ElementAdded(); |
+ SetEntry(entry, k, value, details); |
+ ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() |
+ || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); |
+ HashTable<Shape, Key>::ElementAdded(); |
+ return this; |
} |
-void Dictionary::UpdateMaxNumberKey(uint32_t key) { |
+void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
// If the dictionary requires slow elements an element has already |
// been added at a high index. |
if (requires_slow_elements()) return; |
@@ -7136,73 +7131,51 @@ |
// Update max key value. |
Object* max_index_object = get(kMaxNumberKeyIndex); |
if (!max_index_object->IsSmi() || max_number_key() < key) { |
- set(kMaxNumberKeyIndex, |
- Smi::FromInt(key << kRequiresSlowElementsTagSize), |
- SKIP_WRITE_BARRIER); |
+ FixedArray::set(kMaxNumberKeyIndex, |
+ Smi::FromInt(key << kRequiresSlowElementsTagSize), |
+ SKIP_WRITE_BARRIER); |
} |
} |
-Object* Dictionary::AddStringEntry(String* key, |
- Object* value, |
- PropertyDetails details) { |
- StringKey k(key); |
- SLOW_ASSERT(FindEntry(&k) == kNotFound); |
- return Add(&k, value, details); |
-} |
- |
- |
-Object* Dictionary::AddNumberEntry(uint32_t key, |
- Object* value, |
- PropertyDetails details) { |
- NumberKey k(key); |
+Object* NumberDictionary::AddNumberEntry(uint32_t key, |
+ Object* value, |
+ PropertyDetails details) { |
UpdateMaxNumberKey(key); |
- SLOW_ASSERT(FindEntry(&k) == kNotFound); |
- return Add(&k, value, details); |
+ SLOW_ASSERT(FindEntry(key) == kNotFound); |
+ return Add(key, value, details); |
} |
-Object* Dictionary::AtNumberPut(uint32_t key, Object* value) { |
- NumberKey k(key); |
+Object* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { |
UpdateMaxNumberKey(key); |
- return AtPut(&k, value); |
+ return AtPut(key, value); |
} |
-Object* Dictionary::SetStringEntry(int entry, |
- String* key, |
- Object* value, |
- PropertyDetails details) { |
+Object* NumberDictionary::Set(uint32_t key, |
+ Object* value, |
+ PropertyDetails details) { |
+ int entry = FindEntry(key); |
+ if (entry == kNotFound) return AddNumberEntry(key, value, details); |
// Preserve enumeration index. |
details = PropertyDetails(details.attributes(), |
details.type(), |
DetailsAt(entry).index()); |
- SetEntry(entry, key, value, details); |
+ SetEntry(entry, NumberDictionaryShape::AsObject(key), value, details); |
return this; |
} |
-Object* Dictionary::SetOrAddNumberEntry(uint32_t key, |
- Object* value, |
- PropertyDetails details) { |
- NumberKey k(key); |
- int entry = FindEntry(&k); |
- if (entry == -1) return AddNumberEntry(key, value, details); |
- // Preserve enumeration index. |
- details = PropertyDetails(details.attributes(), |
- details.type(), |
- DetailsAt(entry).index()); |
- SetEntry(entry, k.GetObject(), value, details); |
- return this; |
-} |
- |
-int Dictionary::NumberOfElementsFilterAttributes(PropertyAttributes filter) { |
- int capacity = Capacity(); |
+template<typename Shape, typename Key> |
+int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
+ PropertyAttributes filter) { |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
int result = 0; |
for (int i = 0; i < capacity; i++) { |
- Object* k = KeyAt(i); |
- if (IsKey(k)) { |
+ Object* k = HashTable<Shape, Key>::KeyAt(i); |
+ if (HashTable<Shape, Key>::IsKey(k)) { |
PropertyAttributes attr = DetailsAt(i).attributes(); |
if ((attr & filter) == 0) result++; |
} |
@@ -7211,19 +7184,22 @@ |
} |
-int Dictionary::NumberOfEnumElements() { |
+template<typename Shape, typename Key> |
+int Dictionary<Shape, Key>::NumberOfEnumElements() { |
return NumberOfElementsFilterAttributes( |
static_cast<PropertyAttributes>(DONT_ENUM)); |
} |
-void Dictionary::CopyKeysTo(FixedArray* storage, PropertyAttributes filter) { |
+template<typename Shape, typename Key> |
+void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage, |
+ PropertyAttributes filter) { |
ASSERT(storage->length() >= NumberOfEnumElements()); |
- int capacity = Capacity(); |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
int index = 0; |
for (int i = 0; i < capacity; i++) { |
- Object* k = KeyAt(i); |
- if (IsKey(k)) { |
+ Object* k = HashTable<Shape, Key>::KeyAt(i); |
+ if (HashTable<Shape, Key>::IsKey(k)) { |
PropertyAttributes attr = DetailsAt(i).attributes(); |
if ((attr & filter) == 0) storage->set(index++, k); |
} |
@@ -7233,7 +7209,8 @@ |
} |
-void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) { |
+void StringDictionary::CopyEnumKeysTo(FixedArray* storage, |
+ FixedArray* sort_array) { |
ASSERT(storage->length() >= NumberOfEnumElements()); |
int capacity = Capacity(); |
int index = 0; |
@@ -7255,14 +7232,15 @@ |
} |
-void Dictionary::CopyKeysTo(FixedArray* storage) { |
+template<typename Shape, typename Key> |
+void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) { |
ASSERT(storage->length() >= NumberOfElementsFilterAttributes( |
static_cast<PropertyAttributes>(NONE))); |
- int capacity = Capacity(); |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
int index = 0; |
for (int i = 0; i < capacity; i++) { |
- Object* k = KeyAt(i); |
- if (IsKey(k)) { |
+ Object* k = HashTable<Shape, Key>::KeyAt(i); |
+ if (HashTable<Shape, Key>::IsKey(k)) { |
storage->set(index++, k); |
} |
} |
@@ -7271,11 +7249,12 @@ |
// Backwards lookup (slow). |
-Object* Dictionary::SlowReverseLookup(Object* value) { |
- int capacity = Capacity(); |
+template<typename Shape, typename Key> |
+Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
+ int capacity = HashTable<Shape, Key>::Capacity(); |
for (int i = 0; i < capacity; i++) { |
- Object* k = KeyAt(i); |
- if (IsKey(k)) { |
+ Object* k = HashTable<Shape, Key>::KeyAt(i); |
+ if (Dictionary<Shape, Key>::IsKey(k)) { |
Object* e = ValueAt(i); |
if (e->IsJSGlobalPropertyCell()) { |
e = JSGlobalPropertyCell::cast(e)->value(); |
@@ -7287,8 +7266,8 @@ |
} |
-Object* Dictionary::TransformPropertiesToFastFor(JSObject* obj, |
- int unused_property_fields) { |
+Object* StringDictionary::TransformPropertiesToFastFor( |
+ JSObject* obj, int unused_property_fields) { |
// Make sure we preserve dictionary representation if there are too many |
// descriptors. |
if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
@@ -7296,7 +7275,8 @@ |
// Figure out if it is necessary to generate new enumeration indices. |
int max_enumeration_index = |
NextEnumerationIndex() + |
- (DescriptorArray::kMaxNumberOfDescriptors - NumberOfElements()); |
+ (DescriptorArray::kMaxNumberOfDescriptors - |
+ NumberOfElements()); |
if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
Object* result = GenerateNewEnumerationIndices(); |
if (result->IsFailure()) return result; |
@@ -7645,4 +7625,5 @@ |
} |
#endif |
+ |
} } // namespace v8::internal |