OLD | NEW |
1 // Copyright 2006-2008 Google Inc. All Rights Reserved. | 1 // Copyright 2006-2008 Google Inc. 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 5215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5226 | 5226 |
5227 | 5227 |
5228 int JSObject::GetEnumElementKeys(FixedArray* storage) { | 5228 int JSObject::GetEnumElementKeys(FixedArray* storage) { |
5229 return GetLocalElementKeys(storage, | 5229 return GetLocalElementKeys(storage, |
5230 static_cast<PropertyAttributes>(DONT_ENUM)); | 5230 static_cast<PropertyAttributes>(DONT_ENUM)); |
5231 } | 5231 } |
5232 | 5232 |
5233 | 5233 |
5234 // The NumberKey uses carries the uint32_t as key. | 5234 // The NumberKey uses carries the uint32_t as key. |
5235 // This avoids allocation in HasProperty. | 5235 // This avoids allocation in HasProperty. |
5236 class Dictionary::NumberKey : public Dictionary::Key { | 5236 class NumberKey : public HashTableKey { |
5237 public: | 5237 public: |
5238 explicit NumberKey(uint32_t number) { | 5238 explicit NumberKey(uint32_t number) { |
5239 number_ = number; | 5239 number_ = number; |
5240 } | 5240 } |
5241 | 5241 |
5242 private: | 5242 private: |
5243 bool IsMatch(Object* other) { | 5243 bool IsMatch(Object* other) { |
5244 return number_ == ToUint32(other); | 5244 return number_ == ToUint32(other); |
5245 } | 5245 } |
5246 | 5246 |
(...skipping 25 matching lines...) Expand all Loading... |
5272 static uint32_t ToUint32(Object* obj) { | 5272 static uint32_t ToUint32(Object* obj) { |
5273 ASSERT(obj->IsNumber()); | 5273 ASSERT(obj->IsNumber()); |
5274 return static_cast<uint32_t>(obj->Number()); | 5274 return static_cast<uint32_t>(obj->Number()); |
5275 } | 5275 } |
5276 | 5276 |
5277 bool IsStringKey() { return false; } | 5277 bool IsStringKey() { return false; } |
5278 | 5278 |
5279 uint32_t number_; | 5279 uint32_t number_; |
5280 }; | 5280 }; |
5281 | 5281 |
| 5282 |
5282 // StringKey simply carries a string object as key. | 5283 // StringKey simply carries a string object as key. |
5283 class Dictionary::StringKey : public Dictionary::Key { | 5284 class StringKey : public HashTableKey { |
5284 public: | 5285 public: |
5285 explicit StringKey(String* string) { | 5286 explicit StringKey(String* string) { |
5286 string_ = string; | 5287 string_ = string; |
5287 } | 5288 } |
5288 | 5289 |
5289 private: | |
5290 bool IsMatch(Object* other) { | 5290 bool IsMatch(Object* other) { |
5291 if (!other->IsString()) return false; | 5291 if (!other->IsString()) return false; |
5292 return string_->Equals(String::cast(other)); | 5292 return string_->Equals(String::cast(other)); |
5293 } | 5293 } |
5294 | 5294 |
5295 uint32_t Hash() { return StringHash(string_); } | 5295 uint32_t Hash() { return StringHash(string_); } |
5296 | 5296 |
5297 HashFunction GetHashFunction() { return StringHash; } | 5297 HashFunction GetHashFunction() { return StringHash; } |
5298 | 5298 |
5299 Object* GetObject() { return string_; } | 5299 Object* GetObject() { return string_; } |
5300 | 5300 |
5301 static uint32_t StringHash(Object* obj) { | 5301 static uint32_t StringHash(Object* obj) { |
5302 return String::cast(obj)->Hash(); | 5302 return String::cast(obj)->Hash(); |
5303 } | 5303 } |
5304 | 5304 |
5305 bool IsStringKey() { return true; } | 5305 bool IsStringKey() { return true; } |
5306 | 5306 |
5307 String* string_; | 5307 String* string_; |
5308 }; | 5308 }; |
5309 | 5309 |
5310 // Utf8Key carries a vector of chars as key. | 5310 // Utf8SymbolKey carries a vector of chars as key. |
5311 class SymbolTable::Utf8Key : public SymbolTable::Key { | 5311 class Utf8SymbolKey : public HashTableKey { |
5312 public: | 5312 public: |
5313 explicit Utf8Key(Vector<const char> string) | 5313 explicit Utf8SymbolKey(Vector<const char> string) |
5314 : string_(string), hash_(0) { } | 5314 : string_(string), hash_(0) { } |
5315 | 5315 |
5316 bool IsMatch(Object* other) { | 5316 bool IsMatch(Object* other) { |
5317 if (!other->IsString()) return false; | 5317 if (!other->IsString()) return false; |
5318 return String::cast(other)->IsEqualTo(string_); | 5318 return String::cast(other)->IsEqualTo(string_); |
5319 } | 5319 } |
5320 | 5320 |
5321 HashFunction GetHashFunction() { | 5321 HashFunction GetHashFunction() { |
5322 return StringHash; | 5322 return StringHash; |
5323 } | 5323 } |
(...skipping 19 matching lines...) Expand all Loading... |
5343 } | 5343 } |
5344 | 5344 |
5345 bool IsStringKey() { return true; } | 5345 bool IsStringKey() { return true; } |
5346 | 5346 |
5347 Vector<const char> string_; | 5347 Vector<const char> string_; |
5348 uint32_t hash_; | 5348 uint32_t hash_; |
5349 int chars_; // Caches the number of characters when computing the hash code. | 5349 int chars_; // Caches the number of characters when computing the hash code. |
5350 }; | 5350 }; |
5351 | 5351 |
5352 | 5352 |
5353 // StringKey carries a string object as key. | 5353 // SymbolKey carries a string/symbol object as key. |
5354 class SymbolTable::StringKey : public SymbolTable::Key { | 5354 class SymbolKey : public HashTableKey { |
5355 public: | 5355 public: |
5356 explicit StringKey(String* string) : string_(string) { } | 5356 explicit SymbolKey(String* string) : string_(string) { } |
5357 | 5357 |
5358 HashFunction GetHashFunction() { | 5358 HashFunction GetHashFunction() { |
5359 return StringHash; | 5359 return StringHash; |
5360 } | 5360 } |
5361 | 5361 |
5362 bool IsMatch(Object* other) { | 5362 bool IsMatch(Object* other) { |
5363 if (!other->IsString()) return false; | 5363 if (!other->IsString()) return false; |
5364 return String::cast(other)->Equals(string_); | 5364 return String::cast(other)->Equals(string_); |
5365 } | 5365 } |
5366 | 5366 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5410 if (!obj->IsFailure()) { | 5410 if (!obj->IsFailure()) { |
5411 HashTable::cast(obj)->SetNumberOfElements(0); | 5411 HashTable::cast(obj)->SetNumberOfElements(0); |
5412 HashTable::cast(obj)->SetCapacity(capacity); | 5412 HashTable::cast(obj)->SetCapacity(capacity); |
5413 } | 5413 } |
5414 return obj; | 5414 return obj; |
5415 } | 5415 } |
5416 | 5416 |
5417 | 5417 |
5418 // Find entry for key otherwise return -1. | 5418 // Find entry for key otherwise return -1. |
5419 template <int prefix_size, int element_size> | 5419 template <int prefix_size, int element_size> |
5420 int HashTable<prefix_size, element_size>::FindEntry(Key* key) { | 5420 int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) { |
5421 uint32_t nof = NumberOfElements(); | 5421 uint32_t nof = NumberOfElements(); |
5422 if (nof == 0) return -1; // Bail out if empty. | 5422 if (nof == 0) return -1; // Bail out if empty. |
5423 | 5423 |
5424 uint32_t capacity = Capacity(); | 5424 uint32_t capacity = Capacity(); |
5425 uint32_t hash = key->Hash(); | 5425 uint32_t hash = key->Hash(); |
5426 uint32_t entry = GetProbe(hash, 0, capacity); | 5426 uint32_t entry = GetProbe(hash, 0, capacity); |
5427 | 5427 |
5428 Object* element = KeyAt(entry); | 5428 Object* element = KeyAt(entry); |
5429 uint32_t passed_elements = 0; | 5429 uint32_t passed_elements = 0; |
5430 if (!element->IsNull()) { | 5430 if (!element->IsNull()) { |
5431 if (!element->IsUndefined() && key->IsMatch(element)) return entry; | 5431 if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
5432 if (++passed_elements == nof) return -1; | 5432 if (++passed_elements == nof) return -1; |
5433 } | 5433 } |
5434 for (uint32_t i = 1; !element->IsUndefined(); i++) { | 5434 for (uint32_t i = 1; !element->IsUndefined(); i++) { |
5435 entry = GetProbe(hash, i, capacity); | 5435 entry = GetProbe(hash, i, capacity); |
5436 element = KeyAt(entry); | 5436 element = KeyAt(entry); |
5437 if (!element->IsNull()) { | 5437 if (!element->IsNull()) { |
5438 if (!element->IsUndefined() && key->IsMatch(element)) return entry; | 5438 if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
5439 if (++passed_elements == nof) return -1; | 5439 if (++passed_elements == nof) return -1; |
5440 } | 5440 } |
5441 } | 5441 } |
5442 return -1; | 5442 return -1; |
5443 } | 5443 } |
5444 | 5444 |
5445 | 5445 |
5446 template<int prefix_size, int element_size> | 5446 template<int prefix_size, int element_size> |
5447 Object* HashTable<prefix_size, element_size>::EnsureCapacity(int n, Key* key) { | 5447 Object* HashTable<prefix_size, element_size>::EnsureCapacity( |
| 5448 int n, HashTableKey* key) { |
5448 int capacity = Capacity(); | 5449 int capacity = Capacity(); |
5449 int nof = NumberOfElements() + n; | 5450 int nof = NumberOfElements() + n; |
5450 // Make sure 20% is free | 5451 // Make sure 20% is free |
5451 if (nof + (nof >> 2) <= capacity) return this; | 5452 if (nof + (nof >> 2) <= capacity) return this; |
5452 | 5453 |
5453 Object* obj = Allocate(nof * 2); | 5454 Object* obj = Allocate(nof * 2); |
5454 if (obj->IsFailure()) return obj; | 5455 if (obj->IsFailure()) return obj; |
5455 HashTable* dict = HashTable::cast(obj); | 5456 HashTable* dict = HashTable::cast(obj); |
5456 WriteBarrierMode mode = dict->GetWriteBarrierMode(); | 5457 WriteBarrierMode mode = dict->GetWriteBarrierMode(); |
5457 | 5458 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5495 | 5496 |
5496 | 5497 |
5497 // Force instantiation of SymbolTable's base class | 5498 // Force instantiation of SymbolTable's base class |
5498 template class HashTable<0, 1>; | 5499 template class HashTable<0, 1>; |
5499 | 5500 |
5500 | 5501 |
5501 // Force instantiation of Dictionary's base class | 5502 // Force instantiation of Dictionary's base class |
5502 template class HashTable<2, 3>; | 5503 template class HashTable<2, 3>; |
5503 | 5504 |
5504 | 5505 |
| 5506 // Force instantiation of EvalCache's base class |
| 5507 template class HashTable<0, 2>; |
| 5508 |
| 5509 |
5505 Object* SymbolTable::LookupString(String* string, Object** s) { | 5510 Object* SymbolTable::LookupString(String* string, Object** s) { |
5506 StringKey key(string); | 5511 SymbolKey key(string); |
5507 return LookupKey(&key, s); | 5512 return LookupKey(&key, s); |
5508 } | 5513 } |
5509 | 5514 |
5510 | 5515 |
5511 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 5516 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { |
5512 Utf8Key key(str); | 5517 Utf8SymbolKey key(str); |
5513 return LookupKey(&key, s); | 5518 return LookupKey(&key, s); |
5514 } | 5519 } |
5515 | 5520 |
5516 | 5521 |
5517 Object* SymbolTable::LookupKey(Key* key, Object** s) { | 5522 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
5518 int entry = FindEntry(key); | 5523 int entry = FindEntry(key); |
5519 | 5524 |
5520 // Symbol already in table. | 5525 // Symbol already in table. |
5521 if (entry != -1) { | 5526 if (entry != -1) { |
5522 *s = KeyAt(entry); | 5527 *s = KeyAt(entry); |
5523 return this; | 5528 return this; |
5524 } | 5529 } |
5525 | 5530 |
5526 // Adding new symbol. Grow table if needed. | 5531 // Adding new symbol. Grow table if needed. |
5527 Object* obj = EnsureCapacity(1, key); | 5532 Object* obj = EnsureCapacity(1, key); |
(...skipping 10 matching lines...) Expand all Loading... |
5538 | 5543 |
5539 // Add the new symbol and return it along with the symbol table. | 5544 // Add the new symbol and return it along with the symbol table. |
5540 entry = table->FindInsertionEntry(symbol, key->Hash()); | 5545 entry = table->FindInsertionEntry(symbol, key->Hash()); |
5541 table->set(EntryToIndex(entry), symbol); | 5546 table->set(EntryToIndex(entry), symbol); |
5542 table->ElementAdded(); | 5547 table->ElementAdded(); |
5543 *s = symbol; | 5548 *s = symbol; |
5544 return table; | 5549 return table; |
5545 } | 5550 } |
5546 | 5551 |
5547 | 5552 |
| 5553 Object* EvalCache::Lookup(String* src) { |
| 5554 StringKey key(src); |
| 5555 int entry = FindEntry(&key); |
| 5556 if (entry != -1) { |
| 5557 return get(EntryToIndex(entry) + 1); |
| 5558 } else { |
| 5559 return Heap::undefined_value(); |
| 5560 } |
| 5561 } |
| 5562 |
| 5563 |
| 5564 Object* EvalCache::Put(String* src, Object* value) { |
| 5565 StringKey key(src); |
| 5566 Object* obj = EnsureCapacity(1, &key); |
| 5567 if (obj->IsFailure()) return obj; |
| 5568 |
| 5569 EvalCache* cache = reinterpret_cast<EvalCache*>(obj); |
| 5570 int entry = cache->FindInsertionEntry(src, key.Hash()); |
| 5571 cache->set(EntryToIndex(entry), src); |
| 5572 cache->set(EntryToIndex(entry) + 1, value); |
| 5573 cache->ElementAdded(); |
| 5574 return cache; |
| 5575 } |
| 5576 |
| 5577 |
5548 Object* Dictionary::Allocate(int at_least_space_for) { | 5578 Object* Dictionary::Allocate(int at_least_space_for) { |
5549 Object* obj = DictionaryBase::Allocate(at_least_space_for); | 5579 Object* obj = DictionaryBase::Allocate(at_least_space_for); |
5550 // Initialize the next enumeration index. | 5580 // Initialize the next enumeration index. |
5551 if (!obj->IsFailure()) { | 5581 if (!obj->IsFailure()) { |
5552 Dictionary::cast(obj)-> | 5582 Dictionary::cast(obj)-> |
5553 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 5583 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
5554 } | 5584 } |
5555 return obj; | 5585 return obj; |
5556 } | 5586 } |
5557 | 5587 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5600 DetailsAtPut(i, new_details); | 5630 DetailsAtPut(i, new_details); |
5601 } | 5631 } |
5602 } | 5632 } |
5603 | 5633 |
5604 // Set the next enumeration index. | 5634 // Set the next enumeration index. |
5605 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 5635 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
5606 return this; | 5636 return this; |
5607 } | 5637 } |
5608 | 5638 |
5609 | 5639 |
5610 Object* Dictionary::EnsureCapacity(int n, Key* key) { | 5640 Object* Dictionary::EnsureCapacity(int n, HashTableKey* key) { |
5611 // Check whether there are enough enumeration indices to add n elements. | 5641 // Check whether there are enough enumeration indices to add n elements. |
5612 if (key->IsStringKey() && | 5642 if (key->IsStringKey() && |
5613 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 5643 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
5614 // If not, we generate new indices for the properties. | 5644 // If not, we generate new indices for the properties. |
5615 Object* result = GenerateNewEnumerationIndices(); | 5645 Object* result = GenerateNewEnumerationIndices(); |
5616 if (result->IsFailure()) return result; | 5646 if (result->IsFailure()) return result; |
5617 } | 5647 } |
5618 return DictionaryBase::EnsureCapacity(n, key); | 5648 return DictionaryBase::EnsureCapacity(n, key); |
5619 } | 5649 } |
5620 | 5650 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5656 return FindEntry(&k); | 5686 return FindEntry(&k); |
5657 } | 5687 } |
5658 | 5688 |
5659 | 5689 |
5660 int Dictionary::FindNumberEntry(uint32_t index) { | 5690 int Dictionary::FindNumberEntry(uint32_t index) { |
5661 NumberKey k(index); | 5691 NumberKey k(index); |
5662 return FindEntry(&k); | 5692 return FindEntry(&k); |
5663 } | 5693 } |
5664 | 5694 |
5665 | 5695 |
5666 Object* Dictionary::AtPut(Key* key, Object* value) { | 5696 Object* Dictionary::AtPut(HashTableKey* key, Object* value) { |
5667 int entry = FindEntry(key); | 5697 int entry = FindEntry(key); |
5668 | 5698 |
5669 // If the entry is present set the value; | 5699 // If the entry is present set the value; |
5670 if (entry != -1) { | 5700 if (entry != -1) { |
5671 ValueAtPut(entry, value); | 5701 ValueAtPut(entry, value); |
5672 return this; | 5702 return this; |
5673 } | 5703 } |
5674 | 5704 |
5675 // Check whether the dictionary should be extended. | 5705 // Check whether the dictionary should be extended. |
5676 Object* obj = EnsureCapacity(1, key); | 5706 Object* obj = EnsureCapacity(1, key); |
5677 if (obj->IsFailure()) return obj; | 5707 if (obj->IsFailure()) return obj; |
5678 Object* k = key->GetObject(); | 5708 Object* k = key->GetObject(); |
5679 if (k->IsFailure()) return k; | 5709 if (k->IsFailure()) return k; |
5680 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 5710 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
5681 Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); | 5711 Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); |
5682 return obj; | 5712 return obj; |
5683 } | 5713 } |
5684 | 5714 |
5685 | 5715 |
5686 Object* Dictionary::Add(Key* key, Object* value, PropertyDetails details) { | 5716 Object* Dictionary::Add(HashTableKey* key, Object* value, |
| 5717 PropertyDetails details) { |
5687 // Check whether the dictionary should be extended. | 5718 // Check whether the dictionary should be extended. |
5688 Object* obj = EnsureCapacity(1, key); | 5719 Object* obj = EnsureCapacity(1, key); |
5689 if (obj->IsFailure()) return obj; | 5720 if (obj->IsFailure()) return obj; |
5690 // Compute the key object. | 5721 // Compute the key object. |
5691 Object* k = key->GetObject(); | 5722 Object* k = key->GetObject(); |
5692 if (k->IsFailure()) return k; | 5723 if (k->IsFailure()) return k; |
5693 Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); | 5724 Dictionary::cast(obj)->AddEntry(k, value, details, key->Hash()); |
5694 return obj; | 5725 return obj; |
5695 } | 5726 } |
5696 | 5727 |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6203 // No break point. | 6234 // No break point. |
6204 if (break_point_objects()->IsUndefined()) return 0; | 6235 if (break_point_objects()->IsUndefined()) return 0; |
6205 // Single beak point. | 6236 // Single beak point. |
6206 if (!break_point_objects()->IsFixedArray()) return 1; | 6237 if (!break_point_objects()->IsFixedArray()) return 1; |
6207 // Multiple break points. | 6238 // Multiple break points. |
6208 return FixedArray::cast(break_point_objects())->length(); | 6239 return FixedArray::cast(break_point_objects())->length(); |
6209 } | 6240 } |
6210 | 6241 |
6211 | 6242 |
6212 } } // namespace v8::internal | 6243 } } // namespace v8::internal |
OLD | NEW |