Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(640)

Side by Side Diff: src/objects.cc

Issue 457: Added a EvalCache that caches eval'ed scripts and compiled function boilerpla... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698