Put back compilation cache
authordavemoore@chromium.org <davemoore@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 6 Apr 2009 18:08:06 +0000 (18:08 +0000)
committerdavemoore@chromium.org <davemoore@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 6 Apr 2009 18:08:06 +0000 (18:08 +0000)
Review URL: http://codereview.chromium.org/56185

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1679 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compilation-cache.cc
src/compilation-cache.h
src/compiler.cc

index 3775bc2fbed0467ad1a2817e42a7bab74d81139f..4c02d86ce28cc90c4f1e9cd7113a7f5f0a68b046 100644 (file)
@@ -97,14 +97,65 @@ static Handle<FixedArray> Lookup(Handle<String> source,
 }
 
 
+// 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.
+static bool HasOrigin(Handle<JSFunction> boilerplate,
+                      Handle<Object> name,
+                      int line_offset,
+                      int column_offset) {
+  Handle<Script> script =
+      Handle<Script>(Script::cast(boilerplate->shared()->script()));
+  // If the script name isn't set, the boilerplate script should have
+  // an undefined name to have the same origin.
+  if (name.is_null()) {
+    return script->name()->IsUndefined();
+  }
+  // Do the fast bailout checks first.
+  if (line_offset != script->line_offset()->value()) return false;
+  if (column_offset != script->column_offset()->value()) return false;
+  // Check that both names are strings. If not, no match.
+  if (!name->IsString() || !script->name()->IsString()) return false;
+  // Compare the two name strings for equality.
+  return String::cast(*name)->Equals(String::cast(script->name()));
+}
+
+
+static Handle<JSFunction> Lookup(Handle<String> source,
+                                 CompilationCache::Entry entry) {
+  // 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.
+  Object* result;
+  { HandleScope scope;
+    Handle<CompilationCacheTable> table = GetTable(entry);
+    result = table->Lookup(*source);
+  }
+  if (result->IsJSFunction()) {
+    return Handle<JSFunction>(JSFunction::cast(result));
+  } else {
+    return Handle<JSFunction>::null();
+  }
+}
+
+
+// TODO(245): Need to allow identical code from different contexts to be
+// cached. Currently the first use will be cached, but subsequent code
+// from different source / line won't.
 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
                                                   Handle<Object> name,
                                                   int line_offset,
                                                   int column_offset) {
-  // TODO(245): Start caching scripts again but make it local to a
-  // global context to avoid sharing code between independent
-  // environments.
-  return Handle<JSFunction>::null();
+  Handle<JSFunction> result = Lookup(source, SCRIPT);
+  if (result.is_null()) {
+    Counters::compilation_cache_misses.Increment();
+  } else if (HasOrigin(result, name, line_offset, column_offset)) {
+    Counters::compilation_cache_hits.Increment();
+  } else {
+    result = Handle<JSFunction>::null();
+    Counters::compilation_cache_misses.Increment();
+  }
+  return result;
 }
 
 
@@ -135,11 +186,11 @@ Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
 
 
 void CompilationCache::PutScript(Handle<String> source,
-                                 Entry entry,
                                  Handle<JSFunction> boilerplate) {
-  // TODO(245): Start caching scripts again but make it local to a
-  // global context to avoid sharing code between independent
-  // environments.
+  HandleScope scope;
+  ASSERT(boilerplate->IsBoilerplate());
+  Handle<CompilationCacheTable> table = GetTable(SCRIPT);
+  CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
 }
 
 
index 045a6f8d9fb380e06efdccc48628590afe028d38..38a9e3a3a857e4fceeae7c99691ab47806cbd86b 100644 (file)
@@ -70,7 +70,6 @@ class CompilationCache {
   // Associate the (source, kind) pair to the boilerplate. This may
   // overwrite an existing mapping.
   static void PutScript(Handle<String> source,
-                        Entry entry,
                         Handle<JSFunction> boilerplate);
 
   // Associate the (source, context->closure()->shared(), kind) triple
index e2bf960c957b8c532a06697557fa00f2a25943b4..ced094c0f2290db3df029f79f9342aa2d666595c 100644 (file)
@@ -215,7 +215,7 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source,
                           extension,
                           pre_data);
     if (extension == NULL && !result.is_null()) {
-      CompilationCache::PutScript(source, CompilationCache::SCRIPT, result);
+      CompilationCache::PutScript(source, result);
     }
 
     // Get rid of the pre-parsing data (if necessary).