Commit 9f787147 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Disable the compilation caching for scripts to make it

possible to start generating code specific to a global
object. We should start caching scripts but make the
mechanism local to a specific global context inspired
by the way we handle eval-caching. 
Review URL: http://codereview.chromium.org/40007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1406 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 92aa4ab3
...@@ -154,18 +154,14 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { ...@@ -154,18 +154,14 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) {
// Get outer context and create a new context based on it. // Get outer context and create a new context based on it.
frame_->PushFunction(); frame_->PushFunction();
Result context = frame_->CallRuntime(Runtime::kNewContext, 1); Result context = frame_->CallRuntime(Runtime::kNewContext, 1);
// Update context local. // Update context local.
frame_->SaveContextRegister(); frame_->SaveContextRegister();
if (kDebug) { // Verify that the runtime call result and esi agree.
JumpTarget verified_true(this); if (FLAG_debug_code) {
// Verify eax and esi are the same in debug mode
__ cmp(context.reg(), Operand(esi)); __ cmp(context.reg(), Operand(esi));
context.Unuse(); __ Assert(equal, "Runtime::NewContext should end up in esi");
verified_true.Branch(equal);
frame_->SpillAll();
__ int3();
verified_true.Bind();
} }
} }
...@@ -1870,16 +1866,10 @@ void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { ...@@ -1870,16 +1866,10 @@ void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
// Update context local. // Update context local.
frame_->SaveContextRegister(); frame_->SaveContextRegister();
if (kDebug) { // Verify that the runtime call result and esi agree.
JumpTarget verified_true(this); if (FLAG_debug_code) {
// Verify that the result of the runtime call and the esi register are
// the same in debug mode.
__ cmp(context.reg(), Operand(esi)); __ cmp(context.reg(), Operand(esi));
context.Unuse(); __ Assert(equal, "Runtime::NewContext should end up in esi");
verified_true.Branch(equal);
frame_->SpillAll();
__ int3();
verified_true.Bind();
} }
} }
......
...@@ -60,31 +60,8 @@ static Handle<CompilationCacheTable> GetTable(CompilationCache::Entry entry) { ...@@ -60,31 +60,8 @@ static Handle<CompilationCacheTable> GetTable(CompilationCache::Entry entry) {
} }
// We only re-use a cached function for some script source code if the
// script originates from the same places. 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, static Handle<JSFunction> Lookup(Handle<String> source,
Handle<Context> context,
CompilationCache::Entry entry) { CompilationCache::Entry entry) {
// Make sure not to leak the table into the surrounding handle // Make sure not to leak the table into the surrounding handle
// scope. Otherwise, we risk keeping old tables around even after // scope. Otherwise, we risk keeping old tables around even after
...@@ -92,7 +69,7 @@ static Handle<JSFunction> Lookup(Handle<String> source, ...@@ -92,7 +69,7 @@ static Handle<JSFunction> Lookup(Handle<String> source,
Object* result; Object* result;
{ HandleScope scope; { HandleScope scope;
Handle<CompilationCacheTable> table = GetTable(entry); Handle<CompilationCacheTable> table = GetTable(entry);
result = table->Lookup(*source); result = table->LookupEval(*source, *context);
} }
if (result->IsJSFunction()) { if (result->IsJSFunction()) {
return Handle<JSFunction>(JSFunction::cast(result)); return Handle<JSFunction>(JSFunction::cast(result));
...@@ -102,21 +79,20 @@ static Handle<JSFunction> Lookup(Handle<String> source, ...@@ -102,21 +79,20 @@ static Handle<JSFunction> Lookup(Handle<String> source,
} }
static Handle<JSFunction> Lookup(Handle<String> source, static Handle<FixedArray> Lookup(Handle<String> source,
Handle<Context> context, JSRegExp::Flags flags) {
CompilationCache::Entry entry) {
// Make sure not to leak the table into the surrounding handle // Make sure not to leak the table into the surrounding handle
// scope. Otherwise, we risk keeping old tables around even after // scope. Otherwise, we risk keeping old tables around even after
// having cleared the cache. // having cleared the cache.
Object* result; Object* result;
{ HandleScope scope; { HandleScope scope;
Handle<CompilationCacheTable> table = GetTable(entry); Handle<CompilationCacheTable> table = GetTable(CompilationCache::REGEXP);
result = table->LookupEval(*source, *context); result = table->LookupRegExp(*source, flags);
} }
if (result->IsJSFunction()) { if (result->IsFixedArray()) {
return Handle<JSFunction>(JSFunction::cast(result)); return Handle<FixedArray>(FixedArray::cast(result));
} else { } else {
return Handle<JSFunction>::null(); return Handle<FixedArray>::null();
} }
} }
...@@ -125,16 +101,10 @@ Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source, ...@@ -125,16 +101,10 @@ Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
Handle<Object> name, Handle<Object> name,
int line_offset, int line_offset,
int column_offset) { int column_offset) {
Handle<JSFunction> result = Lookup(source, SCRIPT); // TODO(245): Start caching scripts again but make it local to a
if (result.is_null()) { // global context to avoid sharing code between independent
Counters::compilation_cache_misses.Increment(); // environments.
} else if (HasOrigin(result, name, line_offset, column_offset)) { return Handle<JSFunction>::null();
Counters::compilation_cache_hits.Increment();
} else {
result = Handle<JSFunction>::null();
Counters::compilation_cache_misses.Increment();
}
return result;
} }
...@@ -152,17 +122,28 @@ Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source, ...@@ -152,17 +122,28 @@ Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
} }
void CompilationCache::PutFunction(Handle<String> source, Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
JSRegExp::Flags flags) {
Handle<FixedArray> result = Lookup(source, flags);
if (result.is_null()) {
Counters::compilation_cache_misses.Increment();
} else {
Counters::compilation_cache_hits.Increment();
}
return result;
}
void CompilationCache::PutScript(Handle<String> source,
Entry entry, Entry entry,
Handle<JSFunction> boilerplate) { Handle<JSFunction> boilerplate) {
HandleScope scope; // TODO(245): Start caching scripts again but make it local to a
ASSERT(boilerplate->IsBoilerplate()); // global context to avoid sharing code between independent
Handle<CompilationCacheTable> table = GetTable(entry); // environments.
CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
} }
void CompilationCache::PutEvalFunction(Handle<String> source, void CompilationCache::PutEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
Entry entry, Entry entry,
Handle<JSFunction> boilerplate) { Handle<JSFunction> boilerplate) {
...@@ -173,19 +154,6 @@ void CompilationCache::PutEvalFunction(Handle<String> source, ...@@ -173,19 +154,6 @@ void CompilationCache::PutEvalFunction(Handle<String> source,
} }
Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
JSRegExp::Flags flags) {
Handle<CompilationCacheTable> table = GetTable(REGEXP);
Object* result = table->LookupRegExp(*source, flags);
if (result->IsFixedArray()) {
Counters::regexp_cache_hits.Increment();
return Handle<FixedArray>(FixedArray::cast(result));
} else {
Counters::regexp_cache_misses.Increment();
return Handle<FixedArray>();
}
}
void CompilationCache::PutRegExp(Handle<String> source, void CompilationCache::PutRegExp(Handle<String> source,
JSRegExp::Flags flags, JSRegExp::Flags flags,
......
...@@ -67,26 +67,25 @@ class CompilationCache { ...@@ -67,26 +67,25 @@ class CompilationCache {
static Handle<FixedArray> LookupRegExp(Handle<String> source, static Handle<FixedArray> LookupRegExp(Handle<String> source,
JSRegExp::Flags flags); JSRegExp::Flags flags);
// Associate the (source, flags) pair to the given regexp data.
// This may overwrite an existing mapping.
static void PutRegExp(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data);
// Associate the (source, kind) pair to the boilerplate. This may // Associate the (source, kind) pair to the boilerplate. This may
// overwrite an existing mapping. // overwrite an existing mapping.
static void PutFunction(Handle<String> source, static void PutScript(Handle<String> source,
Entry entry, Entry entry,
Handle<JSFunction> boilerplate); Handle<JSFunction> boilerplate);
// Associate the (source, context->closure()->shared(), kind) // Associate the (source, context->closure()->shared(), kind) triple
// triple with the boilerplate. This may overwrite an existing // with the boilerplate. This may overwrite an existing mapping.
// mapping. static void PutEval(Handle<String> source,
static void PutEvalFunction(Handle<String> source,
Handle<Context> context, Handle<Context> context,
Entry entry, Entry entry,
Handle<JSFunction> boilerplate); Handle<JSFunction> boilerplate);
// Associate the (source, flags) pair to the given regexp data.
// This may overwrite an existing mapping.
static void PutRegExp(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data);
// Clear the cache - also used to initialize the cache at startup. // Clear the cache - also used to initialize the cache at startup.
static void Clear(); static void Clear();
......
...@@ -210,7 +210,7 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source, ...@@ -210,7 +210,7 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source,
extension, extension,
pre_data); pre_data);
if (extension == NULL && !result.is_null()) { if (extension == NULL && !result.is_null()) {
CompilationCache::PutFunction(source, CompilationCache::SCRIPT, result); CompilationCache::PutScript(source, CompilationCache::SCRIPT, result);
} }
// Get rid of the pre-parsing data (if necessary). // Get rid of the pre-parsing data (if necessary).
...@@ -220,7 +220,6 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source, ...@@ -220,7 +220,6 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source,
} }
if (result.is_null()) Top::ReportPendingMessages(); if (result.is_null()) Top::ReportPendingMessages();
return result; return result;
} }
...@@ -249,7 +248,7 @@ Handle<JSFunction> Compiler::CompileEval(Handle<String> source, ...@@ -249,7 +248,7 @@ Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
script->set_line_offset(Smi::FromInt(line_offset)); script->set_line_offset(Smi::FromInt(line_offset));
result = MakeFunction(is_global, true, script, context, NULL, NULL); result = MakeFunction(is_global, true, script, context, NULL, NULL);
if (!result.is_null()) { if (!result.is_null()) {
CompilationCache::PutEvalFunction(source, context, entry, result); CompilationCache::PutEval(source, context, entry, result);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment