};
+// Current enable state of the compilation cache.
+static bool enabled = true;
+static inline bool IsEnabled() {
+ return FLAG_compilation_cache && enabled;
+}
+
// Keep separate tables for the different entry kinds.
static Object* tables[NUMBER_OF_TABLE_ENTRIES] = { 0, };
Handle<Object> name,
int line_offset,
int column_offset) {
+ if (!IsEnabled()) {
+ return Handle<JSFunction>::null();
+ }
+
// Use an int for the generation index, so value range propagation
// in gcc 4.3+ won't assume it can only go up to LAST_ENTRY when in
// fact it can go up to SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS.
Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
Handle<Context> context,
Entry entry) {
+ if (!IsEnabled()) {
+ return Handle<JSFunction>::null();
+ }
+
ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL);
Handle<JSFunction> result = Lookup(source, context, entry);
if (result.is_null()) {
Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
JSRegExp::Flags flags) {
+ if (!IsEnabled()) {
+ return Handle<FixedArray>::null();
+ }
+
Handle<FixedArray> result = Lookup(source, flags);
if (result.is_null()) {
Counters::compilation_cache_misses.Increment();
void CompilationCache::PutScript(Handle<String> source,
Handle<JSFunction> boilerplate) {
+ if (!IsEnabled()) {
+ return;
+ }
+
HandleScope scope;
ASSERT(boilerplate->IsBoilerplate());
Handle<CompilationCacheTable> table = GetTable(SCRIPT);
Handle<Context> context,
Entry entry,
Handle<JSFunction> boilerplate) {
+ if (!IsEnabled()) {
+ return;
+ }
+
HandleScope scope;
ASSERT(boilerplate->IsBoilerplate());
Handle<CompilationCacheTable> table = GetTable(entry);
void CompilationCache::PutRegExp(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data) {
+ if (!IsEnabled()) {
+ return;
+ }
+
HandleScope scope;
Handle<CompilationCacheTable> table = GetTable(REGEXP);
CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
}
+void CompilationCache::Enable() {
+ enabled = true;
+}
+
+
+void CompilationCache::Disable() {
+ enabled = false;
+ Clear();
+}
+
+
} } // namespace v8::internal
// take place. This is used to retire entries from the cache to
// avoid keeping them alive too long without using them.
static void MarkCompactPrologue();
+
+ // Enable/disable compilation cache. Used by debugger to disable compilation
+ // cache during debugging to make sure new scripts are always compiled.
+ static void Enable();
+ static void Disable();
};
#include "arguments.h"
#include "bootstrapper.h"
#include "code-stubs.h"
+#include "compilation-cache.h"
#include "compiler.h"
#include "debug.h"
#include "execution.h"
if (callback->IsUndefined()) {
UnloadDebugger();
}
+
+ // Disable the compilation cache when the debugger is active.
+ if (IsDebuggerActive()) {
+ CompilationCache::Disable();
+ } else {
+ CompilationCache::Enable();
+ }
}
ProcessCommand(Vector<const uint16_t>::empty());
}
}
+
+ // Disable the compilation cache when the debugger is active.
+ if (IsDebuggerActive()) {
+ CompilationCache::Disable();
+ } else {
+ CompilationCache::Enable();
+ }
}
DEFINE_int(min_preparse_length, 1024,
"Minimum length for automatic enable preparsing")
+// compilation-cache.cc
+DEFINE_bool(compilation_cache, true, "enable compilation cache")
+
// debug.cc
DEFINE_bool(remote_debugging, false, "enable remote debugging")
DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response")
}
CHECK_EQ(5, break_point_hit_count);
- // BUG(343): It should not really be necessary to clear the
- // compilation cache here, but right now the debugger relies on the
- // script being recompiled, not just fetched from the cache.
- i::CompilationCache::Clear();
-
// Reload the script and get f again checking that the ignore survives.
v8::Script::Compile(script, &origin)->Run();
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1);
script1->SetData(v8::String::New("data"));
script1->Run();
- v8::Script::Compile(script, &origin1)->Run();
v8::Local<v8::Function> f;
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
CHECK_EQ("name", last_script_name_hit);
CHECK_EQ("data", last_script_data_hit);
+ // Compile the same script again without setting data. As the compilation
+ // cache is disabled when debugging expect the data to be missing.
+ v8::Script::Compile(script, &origin1)->Run();
+ f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
+ f->Call(env->Global(), 0, NULL);
+ CHECK_EQ(2, break_point_hit_count);
+ CHECK_EQ("name", last_script_name_hit);
+ CHECK_EQ("", last_script_data_hit); // Undefined results in empty string.
+
v8::Local<v8::String> data_obj_source = v8::String::New(
"({ a: 'abc',\n"
" b: 123,\n"
script2->SetData(data_obj);
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
f->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, break_point_hit_count);
+ CHECK_EQ(3, break_point_hit_count);
CHECK_EQ("new name", last_script_name_hit);
CHECK_EQ("abc 123", last_script_data_hit);
}