| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. 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 11460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11471 i < kPrefixStartIndex + Shape::kPrefixSize; | 11471 i < kPrefixStartIndex + Shape::kPrefixSize; |
| 11472 i++) { | 11472 i++) { |
| 11473 new_table->set(i, get(i), mode); | 11473 new_table->set(i, get(i), mode); |
| 11474 } | 11474 } |
| 11475 | 11475 |
| 11476 // Rehash the elements. | 11476 // Rehash the elements. |
| 11477 int capacity = Capacity(); | 11477 int capacity = Capacity(); |
| 11478 for (int i = 0; i < capacity; i++) { | 11478 for (int i = 0; i < capacity; i++) { |
| 11479 uint32_t from_index = EntryToIndex(i); | 11479 uint32_t from_index = EntryToIndex(i); |
| 11480 Object* k = get(from_index); | 11480 Object* k = get(from_index); |
| 11481 if (IsKey(k)) { | 11481 if (IsKey(k) && !k->IsNull()) { |
| 11482 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 11482 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); |
| 11483 uint32_t insertion_index = | 11483 uint32_t insertion_index = |
| 11484 EntryToIndex(new_table->FindInsertionEntry(hash)); | 11484 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 11485 for (int j = 0; j < Shape::kEntrySize; j++) { | 11485 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 11486 new_table->set(insertion_index + j, get(from_index + j), mode); | 11486 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 11487 } | 11487 } |
| 11488 } | 11488 } |
| 11489 } | 11489 } |
| 11490 new_table->SetNumberOfElements(NumberOfElements()); | 11490 new_table->SetNumberOfElements(NumberOfElements()); |
| 11491 new_table->SetNumberOfDeletedElements(0); | 11491 new_table->SetNumberOfDeletedElements(0); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11566 return entry; | 11566 return entry; |
| 11567 } | 11567 } |
| 11568 | 11568 |
| 11569 // Force instantiation of template instances class. | 11569 // Force instantiation of template instances class. |
| 11570 // Please note this list is compiler dependent. | 11570 // Please note this list is compiler dependent. |
| 11571 | 11571 |
| 11572 template class HashTable<SymbolTableShape, HashTableKey*>; | 11572 template class HashTable<SymbolTableShape, HashTableKey*>; |
| 11573 | 11573 |
| 11574 template class HashTable<CompilationCacheShape, HashTableKey*>; | 11574 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 11575 | 11575 |
| 11576 template class HashTable<ShortTermJSONEvalCacheShape, HashTableKey*>; |
| 11577 |
| 11576 template class HashTable<MapCacheShape, HashTableKey*>; | 11578 template class HashTable<MapCacheShape, HashTableKey*>; |
| 11577 | 11579 |
| 11578 template class HashTable<ObjectHashTableShape<1>, Object*>; | 11580 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 11579 | 11581 |
| 11580 template class HashTable<ObjectHashTableShape<2>, Object*>; | 11582 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 11581 | 11583 |
| 11582 template class Dictionary<StringDictionaryShape, String*>; | 11584 template class Dictionary<StringDictionaryShape, String*>; |
| 11583 | 11585 |
| 11584 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 11586 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
| 11585 | 11587 |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12358 return cache; | 12360 return cache; |
| 12359 } | 12361 } |
| 12360 | 12362 |
| 12361 | 12363 |
| 12362 MaybeObject* CompilationCacheTable::PutEval(String* src, | 12364 MaybeObject* CompilationCacheTable::PutEval(String* src, |
| 12363 Context* context, | 12365 Context* context, |
| 12364 SharedFunctionInfo* value, | 12366 SharedFunctionInfo* value, |
| 12365 int scope_position) { | 12367 int scope_position) { |
| 12366 StringSharedKey key(src, | 12368 StringSharedKey key(src, |
| 12367 context->closure()->shared(), | 12369 context->closure()->shared(), |
| 12368 value->language_mode(), | 12370 value->language_mode() ? STRICT_MODE : CLASSIC_MODE, |
| 12369 scope_position); | 12371 scope_position); |
| 12370 Object* obj; | 12372 Object* obj; |
| 12371 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 12373 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 12372 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12374 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 12373 } | 12375 } |
| 12374 | 12376 |
| 12375 CompilationCacheTable* cache = | 12377 CompilationCacheTable* cache = |
| 12376 reinterpret_cast<CompilationCacheTable*>(obj); | 12378 reinterpret_cast<CompilationCacheTable*>(obj); |
| 12377 int entry = cache->FindInsertionEntry(key.Hash()); | 12379 int entry = cache->FindInsertionEntry(key.Hash()); |
| 12378 | 12380 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 12402 int entry = cache->FindInsertionEntry(key.Hash()); | 12404 int entry = cache->FindInsertionEntry(key.Hash()); |
| 12403 // We store the value in the key slot, and compare the search key | 12405 // We store the value in the key slot, and compare the search key |
| 12404 // to the stored value with a custon IsMatch function during lookups. | 12406 // to the stored value with a custon IsMatch function during lookups. |
| 12405 cache->set(EntryToIndex(entry), value); | 12407 cache->set(EntryToIndex(entry), value); |
| 12406 cache->set(EntryToIndex(entry) + 1, value); | 12408 cache->set(EntryToIndex(entry) + 1, value); |
| 12407 cache->ElementAdded(); | 12409 cache->ElementAdded(); |
| 12408 return cache; | 12410 return cache; |
| 12409 } | 12411 } |
| 12410 | 12412 |
| 12411 | 12413 |
| 12414 MaybeObject* CompilationCacheTable::PutRaw(Object* key, |
| 12415 SharedFunctionInfo* value, |
| 12416 HashTableKey* hasher) { |
| 12417 Object* obj; |
| 12418 { MaybeObject* maybe_obj = EnsureCapacity(1, hasher); |
| 12419 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 12420 } |
| 12421 |
| 12422 CompilationCacheTable* cache = |
| 12423 reinterpret_cast<CompilationCacheTable*>(obj); |
| 12424 int entry = cache->FindInsertionEntry(hasher->HashForObject(key)); |
| 12425 cache->set(EntryToIndex(entry), key); |
| 12426 cache->set(EntryToIndex(entry) + 1, value); |
| 12427 cache->ElementAdded(); |
| 12428 return cache; |
| 12429 } |
| 12430 |
| 12431 |
| 12412 void CompilationCacheTable::Remove(Object* value) { | 12432 void CompilationCacheTable::Remove(Object* value) { |
| 12413 Object* the_hole_value = GetHeap()->the_hole_value(); | 12433 Object* the_hole_value = GetHeap()->the_hole_value(); |
| 12414 for (int entry = 0, size = Capacity(); entry < size; entry++) { | 12434 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
| 12415 int entry_index = EntryToIndex(entry); | 12435 int entry_index = EntryToIndex(entry); |
| 12416 int value_index = entry_index + 1; | 12436 int value_index = entry_index + 1; |
| 12417 if (get(value_index) == value) { | 12437 if (get(value_index) == value) { |
| 12418 NoWriteBarrierSet(this, entry_index, the_hole_value); | 12438 NoWriteBarrierSet(this, entry_index, the_hole_value); |
| 12419 NoWriteBarrierSet(this, value_index, the_hole_value); | 12439 NoWriteBarrierSet(this, value_index, the_hole_value); |
| 12420 ElementRemoved(); | 12440 ElementRemoved(); |
| 12421 } | 12441 } |
| 12422 } | 12442 } |
| 12423 return; | 12443 return; |
| 12424 } | 12444 } |
| 12425 | 12445 |
| 12426 | 12446 |
| 12447 MaybeObject* ShortTermJSONEvalCacheTable::Allocate() { |
| 12448 ShortTermJSONEvalCacheTable* table; |
| 12449 { MaybeObject* maybe_table = |
| 12450 HashTable<ShortTermJSONEvalCacheShape, |
| 12451 HashTableKey*>::Allocate(max_entries(), |
| 12452 USE_DEFAULT_MINIMUM_CAPACITY, |
| 12453 TENURED); |
| 12454 if (!maybe_table->To<ShortTermJSONEvalCacheTable>(&table)) |
| 12455 return maybe_table; |
| 12456 } |
| 12457 |
| 12458 Smi* zero = Smi::FromInt(0); |
| 12459 table->set(ShortTermJSONEvalCacheShape::kTotalSourceSizeIndex, zero); |
| 12460 table->set(ShortTermJSONEvalCacheShape::kAgeIndex, zero); |
| 12461 return table; |
| 12462 } |
| 12463 |
| 12464 |
| 12465 int ShortTermJSONEvalCacheTable::total_source_size() { |
| 12466 Object* size = get(ShortTermJSONEvalCacheShape::kTotalSourceSizeIndex); |
| 12467 return Smi::cast(size)->value(); |
| 12468 } |
| 12469 |
| 12470 |
| 12471 void ShortTermJSONEvalCacheTable::set_total_source_size(int size) { |
| 12472 set(ShortTermJSONEvalCacheShape::kTotalSourceSizeIndex, Smi::FromInt(size)); |
| 12473 } |
| 12474 |
| 12475 |
| 12476 Object* ShortTermJSONEvalCacheTable::Lookup(String* src) { |
| 12477 // Try to find the eval in the cache |
| 12478 StringKey key(src); |
| 12479 int entry = FindEntry(&key); |
| 12480 if (entry == kNotFound) { |
| 12481 return GetHeap()->undefined_value(); |
| 12482 } |
| 12483 |
| 12484 // Reset the age of the entry |
| 12485 int value_index = EntryToIndex(entry) + 1; |
| 12486 int age_index = value_index + 1; |
| 12487 set(age_index, NextAge()); |
| 12488 |
| 12489 return get(value_index); |
| 12490 } |
| 12491 |
| 12492 |
| 12493 MaybeObject* ShortTermJSONEvalCacheTable::Put(String* src, |
| 12494 SharedFunctionInfo* value) { |
| 12495 int size = ValueSize(value); |
| 12496 if (size >= max_total_source_size()) { |
| 12497 return this; |
| 12498 } |
| 12499 ASSERT(value->code()->kind() == Code::FUNCTION); |
| 12500 |
| 12501 // Reserve space for this element. |
| 12502 Reserve(size); |
| 12503 ASSERT(total_source_size() + size <= max_total_source_size()); |
| 12504 ASSERT(NumberOfElements() + 1 <= max_entries()); |
| 12505 |
| 12506 // Create the key |
| 12507 StringKey key(src); |
| 12508 Object* k; |
| 12509 { MaybeObject* maybe_k = key.AsObject(); |
| 12510 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 12511 } |
| 12512 |
| 12513 // Reallocate and rehash the table if we've gone stale. |
| 12514 ShortTermJSONEvalCacheTable* table; |
| 12515 { |
| 12516 MaybeObject* maybe_t = EnsureCapacity(1, &key); |
| 12517 if (!maybe_t->To<ShortTermJSONEvalCacheTable>(&table)) return maybe_t; |
| 12518 } |
| 12519 |
| 12520 // Add the new entry |
| 12521 uint32_t entry = table->FindInsertionEntry(key.Hash()); |
| 12522 int index = table->EntryToIndex(entry); |
| 12523 Smi* age = table->NextAge(); |
| 12524 table->set(index, k); |
| 12525 table->set(index+1, value); |
| 12526 table->set(index+2, age); |
| 12527 table->ElementAdded(); |
| 12528 |
| 12529 table->set_total_source_size(total_source_size() + size); |
| 12530 |
| 12531 return table; |
| 12532 } |
| 12533 |
| 12534 |
| 12535 void ShortTermJSONEvalCacheTable::Remove(Object* value) { |
| 12536 int elements_removed = 0; |
| 12537 int source_size_removed = 0; |
| 12538 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
| 12539 int key_index = EntryToIndex(entry); |
| 12540 int value_index = key_index + 1; |
| 12541 if (get(value_index) == value) { |
| 12542 set_the_hole(key_index); |
| 12543 set_the_hole(value_index); |
| 12544 elements_removed += 1; |
| 12545 source_size_removed = ValueSize(SharedFunctionInfo::cast(value)); |
| 12546 } |
| 12547 } |
| 12548 ElementsRemoved(elements_removed); |
| 12549 set_total_source_size(total_source_size() - source_size_removed); |
| 12550 } |
| 12551 |
| 12552 |
| 12553 int ShortTermJSONEvalCacheTable::ValueSize(SharedFunctionInfo* value) { |
| 12554 return value->end_position() - value->start_position(); |
| 12555 } |
| 12556 |
| 12557 |
| 12558 void ShortTermJSONEvalCacheTable::Reserve(int size) { |
| 12559 ASSERT(0 <= size && size < max_total_source_size()); |
| 12560 while (NumberOfElements() == max_entries() || |
| 12561 total_source_size() + size > max_total_source_size()) { |
| 12562 RemoveOldest(); |
| 12563 } |
| 12564 } |
| 12565 |
| 12566 int ShortTermJSONEvalCacheTable::max_entries() { |
| 12567 ASSERT(FLAG_json_eval_cache_max_entries > 0); |
| 12568 return FLAG_json_eval_cache_max_entries; |
| 12569 } |
| 12570 |
| 12571 int ShortTermJSONEvalCacheTable::max_total_source_size() { |
| 12572 ASSERT(FLAG_json_eval_cache_max_size > 0); |
| 12573 return FLAG_json_eval_cache_max_size; |
| 12574 } |
| 12575 |
| 12576 |
| 12577 void ShortTermJSONEvalCacheTable::RemoveOldest() { |
| 12578 ASSERT(NumberOfElements() > 0); |
| 12579 |
| 12580 // Locate the oldest element. Smaller age values indicate older elements. |
| 12581 int oldest_age = -1; |
| 12582 int oldest_entry = -1; |
| 12583 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
| 12584 int key_index = EntryToIndex(entry); |
| 12585 if (get(key_index)->IsTheHole() || get(key_index)->IsUndefined()) continue; |
| 12586 int age_index = key_index + 2; |
| 12587 int age = Smi::cast(get(age_index))->value(); |
| 12588 if (oldest_entry == -1 || age < oldest_age) { |
| 12589 oldest_entry = entry; |
| 12590 oldest_age = age; |
| 12591 } |
| 12592 } |
| 12593 |
| 12594 // Remove the element from this table. |
| 12595 int oldest_key_index = EntryToIndex(oldest_entry); |
| 12596 int oldest_value_index = oldest_key_index + 1; |
| 12597 int oldest_age_index = oldest_key_index + 2; |
| 12598 SharedFunctionInfo* value = SharedFunctionInfo::cast(get(oldest_value_index)); |
| 12599 int size = ValueSize(value); |
| 12600 set_total_source_size(total_source_size() - size); |
| 12601 set_the_hole(oldest_key_index); |
| 12602 set_the_hole(oldest_value_index); |
| 12603 set_the_hole(oldest_age_index); |
| 12604 ElementRemoved(); |
| 12605 } |
| 12606 |
| 12607 |
| 12608 int ShortTermJSONEvalCacheTable::current_age() { |
| 12609 return Smi::cast(get(ShortTermJSONEvalCacheShape::kAgeIndex))->value(); |
| 12610 } |
| 12611 |
| 12612 |
| 12613 void ShortTermJSONEvalCacheTable::set_current_age(int age) { |
| 12614 set(ShortTermJSONEvalCacheShape::kAgeIndex, Smi::FromInt(age)); |
| 12615 } |
| 12616 |
| 12617 |
| 12618 Smi* ShortTermJSONEvalCacheTable::NextAge() { |
| 12619 // We need to protect against overflowing to non-Smi values here. |
| 12620 // If we reach the maximum Smi value, we roll over to 0. This will |
| 12621 // make old age values invalid, but this is unlikely to ever happen |
| 12622 // since age is reset when the browser goes idle. |
| 12623 int age = current_age(); |
| 12624 int next_age = age == Smi::kMaxValue ? 0 : age + 1; |
| 12625 set_current_age(next_age); |
| 12626 return Smi::FromInt(age); |
| 12627 } |
| 12628 |
| 12629 |
| 12427 // SymbolsKey used for HashTable where key is array of symbols. | 12630 // SymbolsKey used for HashTable where key is array of symbols. |
| 12428 class SymbolsKey : public HashTableKey { | 12631 class SymbolsKey : public HashTableKey { |
| 12429 public: | 12632 public: |
| 12430 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { } | 12633 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { } |
| 12431 | 12634 |
| 12432 bool IsMatch(Object* symbols) { | 12635 bool IsMatch(Object* symbols) { |
| 12433 FixedArray* o = FixedArray::cast(symbols); | 12636 FixedArray* o = FixedArray::cast(symbols); |
| 12434 int len = symbols_->length(); | 12637 int len = symbols_->length(); |
| 12435 if (o->length() != len) return false; | 12638 if (o->length() != len) return false; |
| 12436 for (int i = 0; i < len; i++) { | 12639 for (int i = 0; i < len; i++) { |
| (...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13546 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13749 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13547 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13750 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13548 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13751 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13549 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13752 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13550 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13753 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13551 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13754 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13552 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13755 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13553 } | 13756 } |
| 13554 | 13757 |
| 13555 } } // namespace v8::internal | 13758 } } // namespace v8::internal |
| OLD | NEW |