Index: src/compilation-cache.cc |
=================================================================== |
--- src/compilation-cache.cc (revision 7267) |
+++ src/compilation-cache.cc (working copy) |
@@ -33,8 +33,6 @@ |
namespace v8 { |
namespace internal { |
-// The number of sub caches covering the different types to cache. |
-static const int kSubCacheCount = 4; |
// The number of generations for each sub cache. |
// The number of ScriptGenerations is carefully chosen based on histograms. |
@@ -47,162 +45,32 @@ |
// Initial size of each compilation cache table allocated. |
static const int kInitialCacheSize = 64; |
-// Index for the first generation in the cache. |
-static const int kFirstGeneration = 0; |
-// The compilation cache consists of several generational sub-caches which uses |
-// this class as a base class. A sub-cache contains a compilation cache tables |
-// for each generation of the sub-cache. Since the same source code string has |
-// different compiled code for scripts and evals, we use separate sub-caches |
-// for different compilation modes, to avoid retrieving the wrong result. |
-class CompilationSubCache { |
- public: |
- explicit CompilationSubCache(int generations): generations_(generations) { |
- tables_ = NewArray<Object*>(generations); |
+CompilationCache::CompilationCache() |
+ : script_(kScriptGenerations), |
+ eval_global_(kEvalGlobalGenerations), |
+ eval_contextual_(kEvalContextualGenerations), |
+ reg_exp_(kRegExpGenerations), |
+ enabled_(true), |
+ eager_optimizing_set_(NULL) { |
+ CompilationSubCache* subcaches[kSubCacheCount] = |
+ {&script_, &eval_global_, &eval_contextual_, ®_exp_}; |
+ for (int i = 0; i < kSubCacheCount; ++i) { |
+ subcaches_[i] = subcaches[i]; |
} |
+} |
- ~CompilationSubCache() { DeleteArray(tables_); } |
- // Get the compilation cache tables for a specific generation. |
- Handle<CompilationCacheTable> GetTable(int generation); |
- |
- // Accessors for first generation. |
- Handle<CompilationCacheTable> GetFirstTable() { |
- return GetTable(kFirstGeneration); |
- } |
- void SetFirstTable(Handle<CompilationCacheTable> value) { |
- ASSERT(kFirstGeneration < generations_); |
- tables_[kFirstGeneration] = *value; |
- } |
- |
- // Age the sub-cache by evicting the oldest generation and creating a new |
- // young generation. |
- void Age(); |
- |
- // GC support. |
- void Iterate(ObjectVisitor* v); |
- void IterateFunctions(ObjectVisitor* v); |
- |
- // Clear this sub-cache evicting all its content. |
- void Clear(); |
- |
- // Remove given shared function info from sub-cache. |
- void Remove(Handle<SharedFunctionInfo> function_info); |
- |
- // Number of generations in this sub-cache. |
- inline int generations() { return generations_; } |
- |
- private: |
- int generations_; // Number of generations. |
- Object** tables_; // Compilation cache tables - one for each generation. |
- |
- DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); |
-}; |
- |
- |
-// Sub-cache for scripts. |
-class CompilationCacheScript : public CompilationSubCache { |
- public: |
- explicit CompilationCacheScript(int generations) |
- : CompilationSubCache(generations) { } |
- |
- Handle<SharedFunctionInfo> Lookup(Handle<String> source, |
- Handle<Object> name, |
- int line_offset, |
- int column_offset); |
- void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info); |
- |
- private: |
- MUST_USE_RESULT MaybeObject* TryTablePut( |
- Handle<String> source, Handle<SharedFunctionInfo> function_info); |
- |
- // Note: Returns a new hash table if operation results in expansion. |
- Handle<CompilationCacheTable> TablePut( |
- Handle<String> source, Handle<SharedFunctionInfo> function_info); |
- |
- bool HasOrigin(Handle<SharedFunctionInfo> function_info, |
- Handle<Object> name, |
- int line_offset, |
- int column_offset); |
- |
- DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript); |
-}; |
- |
- |
-// Sub-cache for eval scripts. |
-class CompilationCacheEval: public CompilationSubCache { |
- public: |
- explicit CompilationCacheEval(int generations) |
- : CompilationSubCache(generations) { } |
- |
- Handle<SharedFunctionInfo> Lookup(Handle<String> source, |
- Handle<Context> context, |
- StrictModeFlag strict_mode); |
- |
- void Put(Handle<String> source, |
- Handle<Context> context, |
- Handle<SharedFunctionInfo> function_info); |
- |
- private: |
- MUST_USE_RESULT MaybeObject* TryTablePut( |
- Handle<String> source, |
- Handle<Context> context, |
- Handle<SharedFunctionInfo> function_info); |
- |
- |
- // Note: Returns a new hash table if operation results in expansion. |
- Handle<CompilationCacheTable> TablePut( |
- Handle<String> source, |
- Handle<Context> context, |
- Handle<SharedFunctionInfo> function_info); |
- |
- DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); |
-}; |
- |
- |
-// Sub-cache for regular expressions. |
-class CompilationCacheRegExp: public CompilationSubCache { |
- public: |
- explicit CompilationCacheRegExp(int generations) |
- : CompilationSubCache(generations) { } |
- |
- Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); |
- |
- void Put(Handle<String> source, |
- JSRegExp::Flags flags, |
- Handle<FixedArray> data); |
- private: |
- MUST_USE_RESULT MaybeObject* TryTablePut(Handle<String> source, |
- JSRegExp::Flags flags, |
- Handle<FixedArray> data); |
- |
- // Note: Returns a new hash table if operation results in expansion. |
- Handle<CompilationCacheTable> TablePut(Handle<String> source, |
- JSRegExp::Flags flags, |
- Handle<FixedArray> data); |
- |
- DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); |
-}; |
- |
- |
-// Statically allocate all the sub-caches. |
-static CompilationCacheScript script(kScriptGenerations); |
-static CompilationCacheEval eval_global(kEvalGlobalGenerations); |
-static CompilationCacheEval eval_contextual(kEvalContextualGenerations); |
-static CompilationCacheRegExp reg_exp(kRegExpGenerations); |
-static CompilationSubCache* subcaches[kSubCacheCount] = |
- {&script, &eval_global, &eval_contextual, ®_exp}; |
- |
- |
-// Current enable state of the compilation cache. |
-static bool enabled = true; |
-static inline bool IsEnabled() { |
- return FLAG_compilation_cache && enabled; |
+CompilationCache::~CompilationCache() { |
+ delete eager_optimizing_set_; |
+ eager_optimizing_set_ = NULL; |
} |
static Handle<CompilationCacheTable> AllocateTable(int size) { |
- CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), |
+ Isolate* isolate = Isolate::Current(); |
+ CALL_HEAP_FUNCTION(isolate, |
+ CompilationCacheTable::Allocate(size), |
CompilationCacheTable); |
} |
@@ -221,7 +89,6 @@ |
return result; |
} |
- |
void CompilationSubCache::Age() { |
// Age the generations implicitly killing off the oldest. |
for (int i = generations_ - 1; i > 0; i--) { |
@@ -229,12 +96,12 @@ |
} |
// Set the first generation as unborn. |
- tables_[0] = Heap::undefined_value(); |
+ tables_[0] = HEAP->undefined_value(); |
} |
void CompilationSubCache::IterateFunctions(ObjectVisitor* v) { |
- Object* undefined = Heap::raw_unchecked_undefined_value(); |
+ Object* undefined = HEAP->raw_unchecked_undefined_value(); |
for (int i = 0; i < generations_; i++) { |
if (tables_[i] != undefined) { |
reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v); |
@@ -249,7 +116,7 @@ |
void CompilationSubCache::Clear() { |
- MemsetPointer(tables_, Heap::undefined_value(), generations_); |
+ MemsetPointer(tables_, HEAP->undefined_value(), generations_); |
} |
@@ -265,6 +132,13 @@ |
} |
+CompilationCacheScript::CompilationCacheScript(int generations) |
+ : CompilationSubCache(generations), |
+ script_histogram_(NULL), |
+ script_histogram_initialized_(false) { |
+} |
+ |
+ |
// We only re-use a cached function for some script source code if the |
// script originates from the same place. This is to avoid issues |
// when reporting errors, etc. |
@@ -320,15 +194,19 @@ |
} |
} |
- static void* script_histogram = StatsTable::CreateHistogram( |
- "V8.ScriptCache", |
- 0, |
- kScriptGenerations, |
- kScriptGenerations + 1); |
+ Isolate* isolate = Isolate::Current(); |
+ if (!script_histogram_initialized_) { |
+ script_histogram_ = isolate->stats_table()->CreateHistogram( |
+ "V8.ScriptCache", |
+ 0, |
+ kScriptGenerations, |
+ kScriptGenerations + 1); |
+ script_histogram_initialized_ = true; |
+ } |
- if (script_histogram != NULL) { |
+ if (script_histogram_ != NULL) { |
// The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. |
- StatsTable::AddHistogramSample(script_histogram, generation); |
+ isolate->stats_table()->AddHistogramSample(script_histogram_, generation); |
} |
// Once outside the manacles of the handle scope, we need to recheck |
@@ -340,10 +218,10 @@ |
// If the script was found in a later generation, we promote it to |
// the first generation to let it survive longer in the cache. |
if (generation != 0) Put(source, shared); |
- Counters::compilation_cache_hits.Increment(); |
+ isolate->counters()->compilation_cache_hits()->Increment(); |
return shared; |
} else { |
- Counters::compilation_cache_misses.Increment(); |
+ isolate->counters()->compilation_cache_misses()->Increment(); |
return Handle<SharedFunctionInfo>::null(); |
} |
} |
@@ -360,7 +238,10 @@ |
Handle<CompilationCacheTable> CompilationCacheScript::TablePut( |
Handle<String> source, |
Handle<SharedFunctionInfo> function_info) { |
- CALL_HEAP_FUNCTION(TryTablePut(source, function_info), CompilationCacheTable); |
+ Isolate* isolate = Isolate::Current(); |
+ CALL_HEAP_FUNCTION(isolate, |
+ TryTablePut(source, function_info), |
+ CompilationCacheTable); |
} |
@@ -395,10 +276,10 @@ |
if (generation != 0) { |
Put(source, context, function_info); |
} |
- Counters::compilation_cache_hits.Increment(); |
+ COUNTERS->compilation_cache_hits()->Increment(); |
return function_info; |
} else { |
- Counters::compilation_cache_misses.Increment(); |
+ COUNTERS->compilation_cache_misses()->Increment(); |
return Handle<SharedFunctionInfo>::null(); |
} |
} |
@@ -417,7 +298,9 @@ |
Handle<String> source, |
Handle<Context> context, |
Handle<SharedFunctionInfo> function_info) { |
- CALL_HEAP_FUNCTION(TryTablePut(source, context, function_info), |
+ Isolate* isolate = Isolate::Current(); |
+ CALL_HEAP_FUNCTION(isolate, |
+ TryTablePut(source, context, function_info), |
CompilationCacheTable); |
} |
@@ -451,10 +334,10 @@ |
if (generation != 0) { |
Put(source, flags, data); |
} |
- Counters::compilation_cache_hits.Increment(); |
+ COUNTERS->compilation_cache_hits()->Increment(); |
return data; |
} else { |
- Counters::compilation_cache_misses.Increment(); |
+ COUNTERS->compilation_cache_misses()->Increment(); |
return Handle<FixedArray>::null(); |
} |
} |
@@ -473,7 +356,10 @@ |
Handle<String> source, |
JSRegExp::Flags flags, |
Handle<FixedArray> data) { |
- CALL_HEAP_FUNCTION(TryTablePut(source, flags, data), CompilationCacheTable); |
+ Isolate* isolate = Isolate::Current(); |
+ CALL_HEAP_FUNCTION(isolate, |
+ TryTablePut(source, flags, data), |
+ CompilationCacheTable); |
} |
@@ -488,9 +374,9 @@ |
void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { |
if (!IsEnabled()) return; |
- eval_global.Remove(function_info); |
- eval_contextual.Remove(function_info); |
- script.Remove(function_info); |
+ eval_global_.Remove(function_info); |
+ eval_contextual_.Remove(function_info); |
+ script_.Remove(function_info); |
} |
@@ -502,7 +388,7 @@ |
return Handle<SharedFunctionInfo>::null(); |
} |
- return script.Lookup(source, name, line_offset, column_offset); |
+ return script_.Lookup(source, name, line_offset, column_offset); |
} |
@@ -517,9 +403,9 @@ |
Handle<SharedFunctionInfo> result; |
if (is_global) { |
- result = eval_global.Lookup(source, context, strict_mode); |
+ result = eval_global_.Lookup(source, context, strict_mode); |
} else { |
- result = eval_contextual.Lookup(source, context, strict_mode); |
+ result = eval_contextual_.Lookup(source, context, strict_mode); |
} |
return result; |
} |
@@ -531,7 +417,7 @@ |
return Handle<FixedArray>::null(); |
} |
- return reg_exp.Lookup(source, flags); |
+ return reg_exp_.Lookup(source, flags); |
} |
@@ -541,7 +427,7 @@ |
return; |
} |
- script.Put(source, function_info); |
+ script_.Put(source, function_info); |
} |
@@ -555,9 +441,9 @@ |
HandleScope scope; |
if (is_global) { |
- eval_global.Put(source, context, function_info); |
+ eval_global_.Put(source, context, function_info); |
} else { |
- eval_contextual.Put(source, context, function_info); |
+ eval_contextual_.Put(source, context, function_info); |
} |
} |
@@ -570,7 +456,7 @@ |
return; |
} |
- reg_exp.Put(source, flags, data); |
+ reg_exp_.Put(source, flags, data); |
} |
@@ -579,9 +465,11 @@ |
} |
-static HashMap* EagerOptimizingSet() { |
- static HashMap map(&SourceHashCompare); |
- return ↦ |
+HashMap* CompilationCache::EagerOptimizingSet() { |
+ if (eager_optimizing_set_ == NULL) { |
+ eager_optimizing_set_ = new HashMap(&SourceHashCompare); |
+ } |
+ return eager_optimizing_set_; |
} |
@@ -615,38 +503,39 @@ |
void CompilationCache::Clear() { |
for (int i = 0; i < kSubCacheCount; i++) { |
- subcaches[i]->Clear(); |
+ subcaches_[i]->Clear(); |
} |
} |
+ |
void CompilationCache::Iterate(ObjectVisitor* v) { |
for (int i = 0; i < kSubCacheCount; i++) { |
- subcaches[i]->Iterate(v); |
+ subcaches_[i]->Iterate(v); |
} |
} |
void CompilationCache::IterateFunctions(ObjectVisitor* v) { |
for (int i = 0; i < kSubCacheCount; i++) { |
- subcaches[i]->IterateFunctions(v); |
+ subcaches_[i]->IterateFunctions(v); |
} |
} |
void CompilationCache::MarkCompactPrologue() { |
for (int i = 0; i < kSubCacheCount; i++) { |
- subcaches[i]->Age(); |
+ subcaches_[i]->Age(); |
} |
} |
void CompilationCache::Enable() { |
- enabled = true; |
+ enabled_ = true; |
} |
void CompilationCache::Disable() { |
- enabled = false; |
+ enabled_ = false; |
Clear(); |
} |