[serializer] add options to compile eagerly and pre-age for code cache.

R=vogelheim@chromium.org
BUG=chromium:594551
LOG=N

Review URL: https://codereview.chromium.org/1804433004

Cr-Commit-Position: refs/heads/master@{#34761}
This commit is contained in:
yangguo 2016-03-14 11:55:41 -07:00 committed by Commit bot
parent 3617612f8b
commit bae3efface
7 changed files with 73 additions and 3 deletions

View File

@ -1410,6 +1410,9 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
FLAG_min_preparse_length) &&
!info->is_debug();
// Consider parsing eagerly when targeting the code cache.
parse_allow_lazy &= !(FLAG_serialize_eager && info->will_serialize());
parse_info->set_allow_lazy_parsing(parse_allow_lazy);
if (!parse_allow_lazy &&
(options == ScriptCompiler::kProduceParserCache ||
@ -1770,6 +1773,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile();
// Consider compiling eagerly when targeting the code cache.
lazy &= !(FLAG_serialize_eager && info.will_serialize());
// Generate code
TimerEventScope<TimerEventCompileCode> timer(isolate);
TRACE_EVENT0("v8", "V8.CompileCode");

View File

@ -319,8 +319,8 @@ class CompilationInfo {
// Generate a pre-aged prologue if we are optimizing for size, which
// will make code flushing more aggressive. Only apply to Code::FUNCTION,
// since StaticMarkingVisitor::IsFlushable only flushes proper functions.
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
!is_debug() && output_code_kind() == Code::FUNCTION;
return FLAG_optimize_for_size && FLAG_age_code && !is_debug() &&
output_code_kind() == Code::FUNCTION;
}
void EnsureFeedbackVector();

View File

@ -582,6 +582,8 @@ DEFINE_BOOL(trace_stub_failures, false,
"trace deoptimization of generated code stubs")
DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
DEFINE_BOOL(serialize_eager, false, "compile eagerly when caching scripts")
DEFINE_BOOL(serialize_age_code, false, "pre age code in the code cache")
DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
// compiler.cc

View File

@ -14359,6 +14359,12 @@ void Code::MakeYoung(Isolate* isolate) {
if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate);
}
void Code::PreAge(Isolate* isolate) {
byte* sequence = FindCodeAgeSequence();
if (sequence != NULL) {
PatchPlatformCodeAge(isolate, sequence, kPreAgedCodeAge, NO_MARKING_PARITY);
}
}
void Code::MarkToBeExecutedOnce(Isolate* isolate) {
byte* sequence = FindCodeAgeSequence();
@ -14368,7 +14374,6 @@ void Code::MarkToBeExecutedOnce(Isolate* isolate) {
}
}
void Code::MakeOlder(MarkingParity current_parity) {
byte* sequence = FindCodeAgeSequence();
if (sequence != NULL) {

View File

@ -5258,6 +5258,7 @@ class Code: public HeapObject {
static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
void MakeYoung(Isolate* isolate);
void PreAge(Isolate* isolate);
void MarkToBeExecutedOnce(Isolate* isolate);
void MakeOlder(MarkingParity);
static bool IsYoungSequence(Isolate* isolate, byte* sequence);

View File

@ -41,6 +41,7 @@ void Deserializer::FlushICacheForNewIsolate() {
void Deserializer::FlushICacheForNewCodeObjects() {
DCHECK(deserializing_user_code_);
for (Code* code : new_code_objects_) {
if (FLAG_serialize_age_code) code->PreAge(isolate_);
Assembler::FlushICache(isolate_, code->instruction_start(),
code->instruction_size());
}

View File

@ -1642,6 +1642,61 @@ TEST(CodeSerializerInternalReference) {
isolate->Dispose();
}
TEST(CodeSerializerEagerCompilationAndPreAge) {
if (FLAG_ignition) return;
FLAG_lazy = true;
FLAG_serialize_toplevel = true;
FLAG_serialize_age_code = true;
FLAG_serialize_eager = true;
FLAG_min_preparse_length = 1;
static const char* source =
"function f() {"
" function g() {"
" return 1;"
" }"
" return g();"
"}"
"'abcdef';";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> unbound =
v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
CHECK(!cache->rejected);
Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate2);
HandleScope i_scope(i_isolate);
Handle<SharedFunctionInfo> toplevel = v8::Utils::OpenHandle(*unbound);
Handle<Script> script(Script::cast(toplevel->script()));
WeakFixedArray::Iterator iterator(script->shared_function_infos());
// Every function has been pre-compiled from the code cache.
int count = 0;
while (SharedFunctionInfo* shared = iterator.Next<SharedFunctionInfo>()) {
CHECK(shared->is_compiled());
CHECK_EQ(Code::kPreAgedCodeAge, shared->code()->GetAge());
count++;
}
CHECK_EQ(3, count);
}
isolate2->Dispose();
}
TEST(Regress503552) {
// Test that the code serializer can deal with weak cells that form a linked