OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 10636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10647 ASSERT(args.length() == 2); | 10647 ASSERT(args.length() == 2); |
10648 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + | 10648 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + |
10649 Smi::cast(args[1])->value()); | 10649 Smi::cast(args[1])->value()); |
10650 Top::PrintStack(); | 10650 Top::PrintStack(); |
10651 OS::Abort(); | 10651 OS::Abort(); |
10652 UNREACHABLE(); | 10652 UNREACHABLE(); |
10653 return NULL; | 10653 return NULL; |
10654 } | 10654 } |
10655 | 10655 |
10656 | 10656 |
10657 MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj, | 10657 MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj, |
Vitaly Repeshko
2011/01/17 10:08:33
The name is probably too generic for this >10K lin
antonm
2011/01/17 16:46:06
I've inlined this helper into the runtime function
| |
10658 int index, | |
10659 Object* key_obj) { | 10658 Object* key_obj) { |
10660 ASSERT(index % 2 == 0); // index of the key | |
10661 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); | |
10662 ASSERT(index < cache_obj->length()); | |
10663 | |
10664 HandleScope scope; | 10659 HandleScope scope; |
10665 | 10660 |
10666 Handle<FixedArray> cache(cache_obj); | 10661 Handle<FixedArray> cache(cache_obj); |
10667 Handle<Object> key(key_obj); | 10662 Handle<Object> key(key_obj); |
10668 Handle<JSFunction> factory(JSFunction::cast( | 10663 Handle<JSFunction> factory(JSFunction::cast( |
10669 cache->get(JSFunctionResultCache::kFactoryIndex))); | 10664 cache->get(JSFunctionResultCache::kFactoryIndex))); |
10670 // TODO(antonm): consider passing a receiver when constructing a cache. | 10665 // TODO(antonm): consider passing a receiver when constructing a cache. |
10671 Handle<Object> receiver(Top::global_context()->global()); | 10666 Handle<Object> receiver(Top::global_context()->global()); |
10672 | 10667 |
10673 Handle<Object> value; | 10668 Handle<Object> value; |
10674 { | 10669 { |
10675 // This handle is nor shared, nor used later, so it's safe. | 10670 // This handle is nor shared, nor used later, so it's safe. |
10676 Object** argv[] = { key.location() }; | 10671 Object** argv[] = { key.location() }; |
10677 bool pending_exception = false; | 10672 bool pending_exception = false; |
10678 value = Execution::Call(factory, | 10673 value = Execution::Call(factory, |
10679 receiver, | 10674 receiver, |
10680 1, | 10675 1, |
10681 argv, | 10676 argv, |
10682 &pending_exception); | 10677 &pending_exception); |
10683 if (pending_exception) return Failure::Exception(); | 10678 if (pending_exception) return Failure::Exception(); |
10684 } | 10679 } |
10685 | 10680 |
10681 #ifdef DEBUG | |
10682 Handle<JSFunctionResultCache>::cast(cache)->JSFunctionResultCacheVerify(); | |
10683 #endif | |
10684 | |
10685 // Function invocation can have cleared the cache. Reread all the data. | |
Vitaly Repeshko
2011/01/17 10:08:33
nit: "may have" or "might have". "Can have" sounds
antonm
2011/01/17 16:46:06
Done.
| |
10686 const int finger_index = | |
10687 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); | |
10688 const int size = | |
10689 Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value(); | |
10690 | |
10691 // If we have spare room, put new data into it, otherwise evict post finger | |
10692 // entry which is likely to be least recently used. | |
10693 int index = -1; | |
10694 if (size < cache->length()) { | |
10695 cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2)); | |
10696 index = size; | |
10697 } else { | |
10698 index = finger_index + JSFunctionResultCache::kEntrySize; | |
10699 if (index == cache->length()) { | |
10700 index = JSFunctionResultCache::kEntriesIndex; | |
10701 } | |
10702 } | |
10703 | |
10704 ASSERT(index % 2 == 0); | |
10705 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); | |
10706 ASSERT(index < cache_obj->length()); | |
10707 | |
10686 cache->set(index, *key); | 10708 cache->set(index, *key); |
10687 cache->set(index + 1, *value); | 10709 cache->set(index + 1, *value); |
10688 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); | 10710 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); |
10689 | 10711 |
10712 #ifdef DEBUG | |
10713 Handle<JSFunctionResultCache>::cast(cache)->JSFunctionResultCacheVerify(); | |
10714 #endif | |
10715 | |
10690 return *value; | 10716 return *value; |
10691 } | 10717 } |
10692 | 10718 |
10693 | 10719 |
10694 static MaybeObject* Runtime_GetFromCache(Arguments args) { | 10720 static MaybeObject* Runtime_GetFromCache(Arguments args) { |
10695 // This is only called from codegen, so checks might be more lax. | 10721 // This is only called from codegen, so checks might be more lax. |
10696 CONVERT_CHECKED(FixedArray, cache, args[0]); | 10722 CONVERT_CHECKED(FixedArray, cache, args[0]); |
10697 Object* key = args[1]; | 10723 Object* key = args[1]; |
10698 | 10724 |
10699 const int finger_index = | 10725 const int finger_index = |
(...skipping 20 matching lines...) Expand all Loading... | |
10720 ASSERT(size <= cache->length()); | 10746 ASSERT(size <= cache->length()); |
10721 | 10747 |
10722 for (int i = size - 2; i > finger_index; i -= 2) { | 10748 for (int i = size - 2; i > finger_index; i -= 2) { |
10723 o = cache->get(i); | 10749 o = cache->get(i); |
10724 if (o == key) { | 10750 if (o == key) { |
10725 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); | 10751 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); |
10726 return cache->get(i + 1); | 10752 return cache->get(i + 1); |
10727 } | 10753 } |
10728 } | 10754 } |
10729 | 10755 |
10730 // Cache miss. If we have spare room, put new data into it, otherwise | 10756 return CacheMiss(cache, key); |
10731 // evict post finger entry which must be least recently used. | |
10732 if (size < cache->length()) { | |
10733 cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2)); | |
10734 return CacheMiss(cache, size, key); | |
10735 } else { | |
10736 int target_index = finger_index + JSFunctionResultCache::kEntrySize; | |
10737 if (target_index == cache->length()) { | |
10738 target_index = JSFunctionResultCache::kEntriesIndex; | |
10739 } | |
10740 return CacheMiss(cache, target_index, key); | |
10741 } | |
10742 } | 10757 } |
10743 | 10758 |
10744 #ifdef DEBUG | 10759 #ifdef DEBUG |
10745 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 10760 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
10746 // Exclude the code in release mode. | 10761 // Exclude the code in release mode. |
10747 static MaybeObject* Runtime_ListNatives(Arguments args) { | 10762 static MaybeObject* Runtime_ListNatives(Arguments args) { |
10748 ASSERT(args.length() == 0); | 10763 ASSERT(args.length() == 0); |
10749 HandleScope scope; | 10764 HandleScope scope; |
10750 Handle<JSArray> result = Factory::NewJSArray(0); | 10765 Handle<JSArray> result = Factory::NewJSArray(0); |
10751 int index = 0; | 10766 int index = 0; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10863 } else { | 10878 } else { |
10864 // Handle last resort GC and make sure to allow future allocations | 10879 // Handle last resort GC and make sure to allow future allocations |
10865 // to grow the heap without causing GCs (if possible). | 10880 // to grow the heap without causing GCs (if possible). |
10866 Counters::gc_last_resort_from_js.Increment(); | 10881 Counters::gc_last_resort_from_js.Increment(); |
10867 Heap::CollectAllGarbage(false); | 10882 Heap::CollectAllGarbage(false); |
10868 } | 10883 } |
10869 } | 10884 } |
10870 | 10885 |
10871 | 10886 |
10872 } } // namespace v8::internal | 10887 } } // namespace v8::internal |
OLD | NEW |