OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 9989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10000 } | 10000 } |
10001 | 10001 |
10002 | 10002 |
10003 static Object* Runtime_DeleteHandleScopeExtensions(Arguments args) { | 10003 static Object* Runtime_DeleteHandleScopeExtensions(Arguments args) { |
10004 ASSERT(args.length() == 0); | 10004 ASSERT(args.length() == 0); |
10005 HandleScope::DeleteExtensions(); | 10005 HandleScope::DeleteExtensions(); |
10006 return Heap::undefined_value(); | 10006 return Heap::undefined_value(); |
10007 } | 10007 } |
10008 | 10008 |
10009 | 10009 |
| 10010 static Object* CacheMiss(FixedArray* cache_obj, int index, Object* key_obj) { |
| 10011 ASSERT(index % 2 == 0); // index of the key |
| 10012 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); |
| 10013 ASSERT(index < cache_obj->length()); |
| 10014 |
| 10015 HandleScope scope; |
| 10016 |
| 10017 Handle<FixedArray> cache(cache_obj); |
| 10018 Handle<Object> key(key_obj); |
| 10019 Handle<JSFunction> factory(JSFunction::cast( |
| 10020 cache->get(JSFunctionResultCache::kFactoryIndex))); |
| 10021 // TODO(antonm): consider passing a receiver when constructing a cache. |
| 10022 Handle<Object> receiver(Top::global_context()->global()); |
| 10023 |
| 10024 Handle<Object> value; |
| 10025 { |
| 10026 // This handle is nor shared, nor used later, so it's safe. |
| 10027 Object** argv[] = { key.location() }; |
| 10028 bool pending_exception = false; |
| 10029 value = Execution::Call(factory, |
| 10030 receiver, |
| 10031 1, |
| 10032 argv, |
| 10033 &pending_exception); |
| 10034 if (pending_exception) return Failure::Exception(); |
| 10035 } |
| 10036 |
| 10037 cache->set(index, *key); |
| 10038 cache->set(index + 1, *value); |
| 10039 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); |
| 10040 |
| 10041 return *value; |
| 10042 } |
| 10043 |
| 10044 |
| 10045 static Object* Runtime_GetFromCache(Arguments args) { |
| 10046 // This is only called from codegen, so checks might be more lax. |
| 10047 CONVERT_CHECKED(FixedArray, cache, args[0]); |
| 10048 Object* key = args[1]; |
| 10049 |
| 10050 const int finger_index = |
| 10051 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); |
| 10052 |
| 10053 Object* o = cache->get(finger_index); |
| 10054 if (o == key) { |
| 10055 // The fastest case: hit the same place again. |
| 10056 return cache->get(finger_index + 1); |
| 10057 } |
| 10058 |
| 10059 for (int i = finger_index - 2; |
| 10060 i >= JSFunctionResultCache::kEntriesIndex; |
| 10061 i -= 2) { |
| 10062 o = cache->get(i); |
| 10063 if (o == key) { |
| 10064 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); |
| 10065 return cache->get(i + 1); |
| 10066 } |
| 10067 } |
| 10068 |
| 10069 const int size = |
| 10070 Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value(); |
| 10071 ASSERT(size <= cache->length()); |
| 10072 |
| 10073 for (int i = size - 2; i > finger_index; i -= 2) { |
| 10074 o = cache->get(i); |
| 10075 if (o == key) { |
| 10076 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); |
| 10077 return cache->get(i + 1); |
| 10078 } |
| 10079 } |
| 10080 |
| 10081 // Cache miss. If we have spare room, put new data into it, otherwise |
| 10082 // evict post finger entry which must be least recently used. |
| 10083 if (size < cache->length()) { |
| 10084 cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2)); |
| 10085 return CacheMiss(cache, size, key); |
| 10086 } else { |
| 10087 int target_index = (finger_index < cache->length()) ? |
| 10088 finger_index + 2 : JSFunctionResultCache::kEntriesIndex; |
| 10089 return CacheMiss(cache, target_index, key); |
| 10090 } |
| 10091 } |
| 10092 |
10010 #ifdef DEBUG | 10093 #ifdef DEBUG |
10011 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 10094 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
10012 // Exclude the code in release mode. | 10095 // Exclude the code in release mode. |
10013 static Object* Runtime_ListNatives(Arguments args) { | 10096 static Object* Runtime_ListNatives(Arguments args) { |
10014 ASSERT(args.length() == 0); | 10097 ASSERT(args.length() == 0); |
10015 HandleScope scope; | 10098 HandleScope scope; |
10016 Handle<JSArray> result = Factory::NewJSArray(0); | 10099 Handle<JSArray> result = Factory::NewJSArray(0); |
10017 int index = 0; | 10100 int index = 0; |
10018 bool inline_runtime_functions = false; | 10101 bool inline_runtime_functions = false; |
10019 #define ADD_ENTRY(Name, argc, ressize) \ | 10102 #define ADD_ENTRY(Name, argc, ressize) \ |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10099 } else { | 10182 } else { |
10100 // Handle last resort GC and make sure to allow future allocations | 10183 // Handle last resort GC and make sure to allow future allocations |
10101 // to grow the heap without causing GCs (if possible). | 10184 // to grow the heap without causing GCs (if possible). |
10102 Counters::gc_last_resort_from_js.Increment(); | 10185 Counters::gc_last_resort_from_js.Increment(); |
10103 Heap::CollectAllGarbage(false); | 10186 Heap::CollectAllGarbage(false); |
10104 } | 10187 } |
10105 } | 10188 } |
10106 | 10189 |
10107 | 10190 |
10108 } } // namespace v8::internal | 10191 } } // namespace v8::internal |
OLD | NEW |