Index: src/compilation-cache.cc |
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc |
index af9fbb573499d18df351c01f780b3baa577baf28..15cf9ac28fa4546a6e86c50268195db37a306506 100644 |
--- a/src/compilation-cache.cc |
+++ b/src/compilation-cache.cc |
@@ -19,12 +19,11 @@ static const int kRegExpGenerations = 2; |
// Initial size of each compilation cache table allocated. |
static const int kInitialCacheSize = 64; |
- |
CompilationCache::CompilationCache(Isolate* isolate) |
: isolate_(isolate), |
- script_(isolate, 1), |
- eval_global_(isolate, 1), |
- eval_contextual_(isolate, 1), |
+ script_(isolate), |
+ eval_global_(isolate), |
+ eval_contextual_(isolate), |
reg_exp_(isolate, kRegExpGenerations), |
enabled_(true) { |
CompilationSubCache* subcaches[kSubCacheCount] = |
@@ -103,11 +102,8 @@ void CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) { |
} |
} |
- |
-CompilationCacheScript::CompilationCacheScript(Isolate* isolate, |
- int generations) |
- : CompilationSubCache(isolate, generations) {} |
- |
+CompilationCacheScript::CompilationCacheScript(Isolate* isolate) |
+ : CompilationSubCache(isolate, 1) {} |
// 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 |
@@ -141,29 +137,31 @@ bool CompilationCacheScript::HasOrigin(Handle<SharedFunctionInfo> function_info, |
// be cached in the same script generation. Currently the first use |
// will be cached, but subsequent code from different source / line |
// won't. |
-Handle<SharedFunctionInfo> CompilationCacheScript::Lookup( |
+InfoVectorPair CompilationCacheScript::Lookup( |
Handle<String> source, Handle<Object> name, int line_offset, |
int column_offset, ScriptOriginOptions resource_options, |
Handle<Context> context, LanguageMode language_mode) { |
- Object* result = NULL; |
- int generation; |
+ InfoVectorPair result; |
// Probe the script generation tables. Make sure not to leak handles |
// into the caller's handle scope. |
{ HandleScope scope(isolate()); |
- for (generation = 0; generation < generations(); generation++) { |
- Handle<CompilationCacheTable> table = GetTable(generation); |
- Handle<Object> probe = table->Lookup(source, context, language_mode); |
- if (probe->IsSharedFunctionInfo()) { |
- Handle<SharedFunctionInfo> function_info = |
- Handle<SharedFunctionInfo>::cast(probe); |
- // Break when we've found a suitable shared function info that |
- // matches the origin. |
- if (HasOrigin(function_info, name, line_offset, column_offset, |
- resource_options)) { |
- result = *function_info; |
- break; |
- } |
+ const int generation = 0; |
+ DCHECK(generations() == 1); |
+ Handle<CompilationCacheTable> table = GetTable(generation); |
+ InfoVectorPair probe = table->LookupScript(source, context, language_mode); |
+ if (probe.has_shared()) { |
+ Handle<SharedFunctionInfo> function_info(probe.shared(), isolate()); |
+ Handle<Cell> vector_handle; |
+ if (probe.has_vector()) { |
+ vector_handle = Handle<Cell>(probe.vector(), isolate()); |
+ } |
+ // Break when we've found a suitable shared function info that |
+ // matches the origin. |
+ if (HasOrigin(function_info, name, line_offset, column_offset, |
+ resource_options)) { |
+ result = InfoVectorPair(*function_info, |
+ probe.has_vector() ? *vector_handle : nullptr); |
} |
} |
} |
@@ -171,72 +169,61 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup( |
// Once outside the manacles of the handle scope, we need to recheck |
// to see if we actually found a cached script. If so, we return a |
// handle created in the caller's handle scope. |
- if (result != NULL) { |
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result), |
- isolate()); |
+ if (result.has_shared()) { |
+ Handle<SharedFunctionInfo> shared(result.shared(), isolate()); |
+ // TODO(mvstanton): Make sure HasOrigin can't allocate, or it will |
+ // mess up our InfoVectorPair. |
DCHECK( |
HasOrigin(shared, name, line_offset, column_offset, resource_options)); |
- // 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, context, language_mode, shared); |
isolate()->counters()->compilation_cache_hits()->Increment(); |
- return shared; |
} else { |
isolate()->counters()->compilation_cache_misses()->Increment(); |
- return Handle<SharedFunctionInfo>::null(); |
} |
+ return result; |
} |
- |
-void CompilationCacheScript::Put(Handle<String> source, |
- Handle<Context> context, |
+void CompilationCacheScript::Put(Handle<String> source, Handle<Context> context, |
LanguageMode language_mode, |
- Handle<SharedFunctionInfo> function_info) { |
+ Handle<SharedFunctionInfo> function_info, |
+ Handle<Cell> literals) { |
HandleScope scope(isolate()); |
Handle<CompilationCacheTable> table = GetFirstTable(); |
- SetFirstTable(CompilationCacheTable::Put(table, source, context, |
- language_mode, function_info)); |
+ SetFirstTable(CompilationCacheTable::PutScript( |
+ table, source, context, language_mode, function_info, literals)); |
} |
- |
-MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup( |
+InfoVectorPair CompilationCacheEval::Lookup( |
Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
- LanguageMode language_mode, int scope_position) { |
+ Handle<Context> native_context, LanguageMode language_mode, |
+ int scope_position) { |
HandleScope scope(isolate()); |
// Make sure not to leak the table into the surrounding handle |
// scope. Otherwise, we risk keeping old tables around even after |
// having cleared the cache. |
- Handle<Object> result = isolate()->factory()->undefined_value(); |
- int generation; |
- for (generation = 0; generation < generations(); generation++) { |
- Handle<CompilationCacheTable> table = GetTable(generation); |
- result = |
- table->LookupEval(source, outer_info, language_mode, scope_position); |
- if (result->IsSharedFunctionInfo()) break; |
- } |
- if (result->IsSharedFunctionInfo()) { |
- Handle<SharedFunctionInfo> function_info = |
- Handle<SharedFunctionInfo>::cast(result); |
- if (generation != 0) { |
- Put(source, outer_info, function_info, scope_position); |
- } |
+ InfoVectorPair result; |
+ const int generation = 0; |
+ DCHECK(generations() == 1); |
+ Handle<CompilationCacheTable> table = GetTable(generation); |
+ result = table->LookupEval(source, outer_info, native_context, language_mode, |
+ scope_position); |
+ if (result.has_shared()) { |
isolate()->counters()->compilation_cache_hits()->Increment(); |
- return scope.CloseAndEscape(function_info); |
} else { |
isolate()->counters()->compilation_cache_misses()->Increment(); |
- return MaybeHandle<SharedFunctionInfo>(); |
} |
+ return result; |
} |
- |
void CompilationCacheEval::Put(Handle<String> source, |
Handle<SharedFunctionInfo> outer_info, |
Handle<SharedFunctionInfo> function_info, |
- int scope_position) { |
+ Handle<Context> native_context, |
+ Handle<Cell> literals, int scope_position) { |
HandleScope scope(isolate()); |
Handle<CompilationCacheTable> table = GetFirstTable(); |
- table = CompilationCacheTable::PutEval(table, source, outer_info, |
- function_info, scope_position); |
+ table = |
+ CompilationCacheTable::PutEval(table, source, outer_info, function_info, |
+ native_context, literals, scope_position); |
SetFirstTable(table); |
} |
@@ -286,32 +273,33 @@ void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { |
script_.Remove(function_info); |
} |
- |
-MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript( |
+InfoVectorPair CompilationCache::LookupScript( |
Handle<String> source, Handle<Object> name, int line_offset, |
int column_offset, ScriptOriginOptions resource_options, |
Handle<Context> context, LanguageMode language_mode) { |
- if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); |
+ InfoVectorPair empty_result; |
+ if (!IsEnabled()) return empty_result; |
return script_.Lookup(source, name, line_offset, column_offset, |
resource_options, context, language_mode); |
} |
- |
-MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval( |
+InfoVectorPair CompilationCache::LookupEval( |
Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
Handle<Context> context, LanguageMode language_mode, int scope_position) { |
- if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); |
+ InfoVectorPair result; |
+ if (!IsEnabled()) return result; |
- MaybeHandle<SharedFunctionInfo> result; |
if (context->IsNativeContext()) { |
- result = |
- eval_global_.Lookup(source, outer_info, language_mode, scope_position); |
+ result = eval_global_.Lookup(source, outer_info, context, language_mode, |
+ scope_position); |
} else { |
DCHECK(scope_position != kNoSourcePosition); |
- result = eval_contextual_.Lookup(source, outer_info, language_mode, |
- scope_position); |
+ Handle<Context> native_context(context->native_context(), isolate()); |
+ result = eval_contextual_.Lookup(source, outer_info, native_context, |
+ language_mode, scope_position); |
} |
+ |
return result; |
} |
@@ -323,30 +311,31 @@ MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, |
return reg_exp_.Lookup(source, flags); |
} |
- |
-void CompilationCache::PutScript(Handle<String> source, |
- Handle<Context> context, |
+void CompilationCache::PutScript(Handle<String> source, Handle<Context> context, |
LanguageMode language_mode, |
- Handle<SharedFunctionInfo> function_info) { |
+ Handle<SharedFunctionInfo> function_info, |
+ Handle<Cell> literals) { |
if (!IsEnabled()) return; |
- script_.Put(source, context, language_mode, function_info); |
+ script_.Put(source, context, language_mode, function_info, literals); |
} |
- |
void CompilationCache::PutEval(Handle<String> source, |
Handle<SharedFunctionInfo> outer_info, |
Handle<Context> context, |
Handle<SharedFunctionInfo> function_info, |
- int scope_position) { |
+ Handle<Cell> literals, int scope_position) { |
if (!IsEnabled()) return; |
HandleScope scope(isolate()); |
if (context->IsNativeContext()) { |
- eval_global_.Put(source, outer_info, function_info, scope_position); |
+ eval_global_.Put(source, outer_info, function_info, context, literals, |
+ scope_position); |
} else { |
DCHECK(scope_position != kNoSourcePosition); |
- eval_contextual_.Put(source, outer_info, function_info, scope_position); |
+ Handle<Context> native_context(context->native_context(), isolate()); |
+ eval_contextual_.Put(source, outer_info, function_info, native_context, |
+ literals, scope_position); |
} |
} |