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

Side by Side Diff: src/objects.cc

Issue 10990076: Short term JSON eval cache Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 2 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
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | src/v8.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | src/v8.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698