- Adjust the number to string cache based on the max semispace size.
Flushed at compacting mark sweep. - Simplified FindEntry by eliminating the counter. Review URL: http://codereview.chromium.org/527006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3543 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
429f3cf9f2
commit
1f3eba4470
44
src/heap.cc
44
src/heap.cc
@ -576,6 +576,8 @@ void Heap::MarkCompactPrologue(bool is_compacting) {
|
||||
|
||||
Top::MarkCompactPrologue(is_compacting);
|
||||
ThreadManager::MarkCompactPrologue(is_compacting);
|
||||
|
||||
if (is_compacting) FlushNumberStringCache();
|
||||
}
|
||||
|
||||
|
||||
@ -1573,10 +1575,7 @@ bool Heap::CreateInitialObjects() {
|
||||
|
||||
CreateFixedStubs();
|
||||
|
||||
// Allocate the number->string conversion cache
|
||||
obj = AllocateFixedArray(kNumberStringCacheSize * 2);
|
||||
if (obj->IsFailure()) return false;
|
||||
set_number_string_cache(FixedArray::cast(obj));
|
||||
if (InitializeNumberStringCache()->IsFailure()) return false;
|
||||
|
||||
// Allocate cache for single character strings.
|
||||
obj = AllocateFixedArray(String::kMaxAsciiCharCode+1);
|
||||
@ -1607,25 +1606,45 @@ bool Heap::CreateInitialObjects() {
|
||||
}
|
||||
|
||||
|
||||
Object* Heap::InitializeNumberStringCache() {
|
||||
// Compute the size of the number string cache based on the max heap size.
|
||||
// max_semispace_size_ == 512 KB => number_string_cache_size = 32.
|
||||
// max_semispace_size_ == 8 MB => number_string_cache_size = 16KB.
|
||||
int number_string_cache_size = max_semispace_size_ / 512;
|
||||
number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size));
|
||||
Object* obj = AllocateFixedArray(number_string_cache_size * 2);
|
||||
if (!obj->IsFailure()) set_number_string_cache(FixedArray::cast(obj));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void Heap::FlushNumberStringCache() {
|
||||
// Flush the number to string cache.
|
||||
int len = number_string_cache()->length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
number_string_cache()->set_undefined(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int double_get_hash(double d) {
|
||||
DoubleRepresentation rep(d);
|
||||
return ((static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) &
|
||||
(Heap::kNumberStringCacheSize - 1));
|
||||
return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32);
|
||||
}
|
||||
|
||||
|
||||
static inline int smi_get_hash(Smi* smi) {
|
||||
return (smi->value() & (Heap::kNumberStringCacheSize - 1));
|
||||
return smi->value();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Object* Heap::GetNumberStringCache(Object* number) {
|
||||
int hash;
|
||||
int mask = (number_string_cache()->length() >> 1) - 1;
|
||||
if (number->IsSmi()) {
|
||||
hash = smi_get_hash(Smi::cast(number));
|
||||
hash = smi_get_hash(Smi::cast(number)) & mask;
|
||||
} else {
|
||||
hash = double_get_hash(number->Number());
|
||||
hash = double_get_hash(number->Number()) & mask;
|
||||
}
|
||||
Object* key = number_string_cache()->get(hash * 2);
|
||||
if (key == number) {
|
||||
@ -1641,11 +1660,12 @@ Object* Heap::GetNumberStringCache(Object* number) {
|
||||
|
||||
void Heap::SetNumberStringCache(Object* number, String* string) {
|
||||
int hash;
|
||||
int mask = (number_string_cache()->length() >> 1) - 1;
|
||||
if (number->IsSmi()) {
|
||||
hash = smi_get_hash(Smi::cast(number));
|
||||
hash = smi_get_hash(Smi::cast(number)) & mask;
|
||||
number_string_cache()->set(hash * 2, number, SKIP_WRITE_BARRIER);
|
||||
} else {
|
||||
hash = double_get_hash(number->Number());
|
||||
hash = double_get_hash(number->Number()) & mask;
|
||||
number_string_cache()->set(hash * 2, number);
|
||||
}
|
||||
number_string_cache()->set(hash * 2 + 1, string);
|
||||
|
@ -820,9 +820,6 @@ class Heap : public AllStatic {
|
||||
// Update the cache with a new number-string pair.
|
||||
static void SetNumberStringCache(Object* number, String* str);
|
||||
|
||||
// Entries in the cache. Must be a power of 2.
|
||||
static const int kNumberStringCacheSize = 64;
|
||||
|
||||
// Adjusts the amount of registered external memory.
|
||||
// Returns the adjusted value.
|
||||
static inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
|
||||
@ -1098,6 +1095,12 @@ class Heap : public AllStatic {
|
||||
SharedFunctionInfo* shared,
|
||||
Object* prototype);
|
||||
|
||||
|
||||
// Initializes the number to string cache based on the max semispace size.
|
||||
static Object* InitializeNumberStringCache();
|
||||
// Flush the number to string cache.
|
||||
static void FlushNumberStringCache();
|
||||
|
||||
static const int kInitialSymbolTableSize = 2048;
|
||||
static const int kInitialEvalCacheSize = 64;
|
||||
|
||||
|
@ -6848,30 +6848,18 @@ Object* HashTable<Shape, Key>::Allocate(
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Find entry for key otherwise return -1.
|
||||
// Find entry for key otherwise return kNotFound.
|
||||
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 = 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() && 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() && Shape::IsMatch(key, element)) return entry;
|
||||
if (++passed_elements == nof) return kNotFound;
|
||||
}
|
||||
uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
|
||||
uint32_t count = 1;
|
||||
// EnsureCapacity will guarantee the hash table is never full.
|
||||
while (true) {
|
||||
Object* element = KeyAt(entry);
|
||||
if (element->IsUndefined()) break; // Empty entry.
|
||||
if (!element->IsNull() && Shape::IsMatch(key, element)) return entry;
|
||||
entry = NextProbe(entry, count++, capacity);
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
@ -6918,17 +6906,18 @@ Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
for (uint32_t i = 1; !(element->IsUndefined() || element->IsNull()); i++) {
|
||||
entry = GetProbe(hash, i, capacity);
|
||||
element = KeyAt(entry);
|
||||
uint32_t entry = FirstProbe(hash, capacity);
|
||||
uint32_t count = 1;
|
||||
// EnsureCapacity will guarantee the hash table is never full.
|
||||
while (true) {
|
||||
Object* element = KeyAt(entry);
|
||||
if (element->IsUndefined() || element->IsNull()) break;
|
||||
entry = NextProbe(entry, count++, capacity);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -7007,6 +6996,10 @@ int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements();
|
||||
template
|
||||
int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
|
||||
|
||||
template
|
||||
int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
|
||||
|
||||
|
||||
// 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) {
|
||||
|
@ -1988,6 +1988,14 @@ class HashTable: public FixedArray {
|
||||
return (hash + GetProbeOffset(number)) & (size - 1);
|
||||
}
|
||||
|
||||
static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
|
||||
return hash & (size - 1);
|
||||
}
|
||||
|
||||
static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) {
|
||||
return (last + number) & (size - 1);
|
||||
}
|
||||
|
||||
// Ensure enough space for n additional elements.
|
||||
Object* EnsureCapacity(int n, Key key);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user