From 339bc81390580433813b7d99b9e626c2b5acf3a9 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Thu, 10 Jul 2014 10:28:05 +0000 Subject: [PATCH] Refactor ScriptData class for cached compile data. R=marja@chromium.org, vogelheim@chromium.org Review URL: https://codereview.chromium.org/376223002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22314 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 6 + src/api.cc | 62 ++------ src/compiler.cc | 12 ++ src/compiler.h | 32 +++- src/messages.js | 2 - src/mksnapshot.cc | 43 +++--- src/parser.cc | 280 ++++++++-------------------------- src/parser.h | 101 ++++-------- src/preparse-data.cc | 19 ++- src/preparse-data.h | 12 +- src/serialize.cc | 74 +++++---- src/serialize.h | 64 +++++++- src/snapshot-source-sink.cc | 6 +- src/snapshot-source-sink.h | 19 +-- test/cctest/test-api.cc | 121 +-------------- test/cctest/test-parsing.cc | 93 ++++++----- test/cctest/test-serialize.cc | 4 +- 17 files changed, 369 insertions(+), 581 deletions(-) diff --git a/include/v8.h b/include/v8.h index 11bf598006..82d5784514 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1087,6 +1087,12 @@ class V8_EXPORT ScriptCompiler { /** * Compiles the specified script (context-independent). + * Cached data as part of the source object can be optionally produced to be + * consumed later to speed up compilation of identical source scripts. + * + * Note that when producing cached data, the source must point to NULL for + * cached data. When consuming cached data, the cached data must have been + * produced by the same version of V8. * * \param source Script source code. * \return Compiled script object (context independent; for running it must be diff --git a/src/api.cc b/src/api.cc index d01d826e70..106c1fd916 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1699,43 +1699,19 @@ Local ScriptCompiler::CompileUnbound( Isolate* v8_isolate, Source* source, CompileOptions options) { - i::ScriptData* script_data_impl = NULL; + i::ScriptData* script_data = NULL; i::CachedDataMode cached_data_mode = i::NO_CACHED_DATA; i::Isolate* isolate = reinterpret_cast(v8_isolate); ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()", return Local()); if (options & kProduceDataToCache) { cached_data_mode = i::PRODUCE_CACHED_DATA; - ASSERT(source->cached_data == NULL); - if (source->cached_data) { - // Asked to produce cached data even though there is some already -> not - // good. Fail the compilation. - EXCEPTION_PREAMBLE(isolate); - i::Handle result = isolate->factory()->NewSyntaxError( - "invalid_cached_data", isolate->factory()->NewJSArray(0)); - isolate->Throw(*result); - isolate->ReportPendingMessages(); - has_pending_exception = true; - EXCEPTION_BAILOUT_CHECK(isolate, Local()); - } + CHECK(source->cached_data == NULL); } else if (source->cached_data) { cached_data_mode = i::CONSUME_CACHED_DATA; - // ScriptData takes care of aligning, in case the data is not aligned - // correctly. - script_data_impl = i::ScriptData::New( - reinterpret_cast(source->cached_data->data), - source->cached_data->length); - // If the cached data is not valid, fail the compilation. - if (script_data_impl == NULL || !script_data_impl->SanityCheck()) { - EXCEPTION_PREAMBLE(isolate); - i::Handle result = isolate->factory()->NewSyntaxError( - "invalid_cached_data", isolate->factory()->NewJSArray(0)); - isolate->Throw(*result); - isolate->ReportPendingMessages(); - delete script_data_impl; - has_pending_exception = true; - EXCEPTION_BAILOUT_CHECK(isolate, Local()); - } + // ScriptData takes care of pointer-aligning the data. + script_data = new i::ScriptData(source->cached_data->data, + source->cached_data->length); } i::Handle str = Utils::OpenHandle(*(source->source_string)); @@ -1763,36 +1739,28 @@ Local ScriptCompiler::CompileUnbound( source->resource_is_shared_cross_origin == v8::True(v8_isolate); } EXCEPTION_PREAMBLE(isolate); - i::Handle result = - i::Compiler::CompileScript(str, - name_obj, - line_offset, - column_offset, - is_shared_cross_origin, - isolate->global_context(), - NULL, - &script_data_impl, - cached_data_mode, - i::NOT_NATIVES_CODE); + i::Handle result = i::Compiler::CompileScript( + str, name_obj, line_offset, column_offset, is_shared_cross_origin, + isolate->global_context(), NULL, &script_data, cached_data_mode, + i::NOT_NATIVES_CODE); has_pending_exception = result.is_null(); if (has_pending_exception && cached_data_mode == i::CONSUME_CACHED_DATA) { // This case won't happen during normal operation; we have compiled // successfully and produced cached data, and but the second compilation // of the same source code fails. - delete script_data_impl; - script_data_impl = NULL; + delete script_data; + script_data = NULL; } EXCEPTION_BAILOUT_CHECK(isolate, Local()); raw_result = *result; - if ((options & kProduceDataToCache) && script_data_impl != NULL) { + if ((options & kProduceDataToCache) && script_data != NULL) { // script_data_impl now contains the data that was generated. source will // take the ownership. source->cached_data = new CachedData( - reinterpret_cast(script_data_impl->Data()), - script_data_impl->Length(), CachedData::BufferOwned); - script_data_impl->owns_store_ = false; + script_data->data(), script_data->length(), CachedData::BufferOwned); + script_data->ReleaseDataOwnership(); } - delete script_data_impl; + delete script_data; } i::Handle result(raw_result, isolate); return ToApiHandle(result); diff --git a/src/compiler.cc b/src/compiler.cc index 59c6a3693f..00c2667c1e 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -31,6 +31,18 @@ namespace v8 { namespace internal { +ScriptData::ScriptData(const byte* data, int length) + : owns_data_(false), data_(data), length_(length) { + if (!IsAligned(reinterpret_cast(data), kPointerAlignment)) { + byte* copy = NewArray(length); + ASSERT(IsAligned(reinterpret_cast(data_), kPointerAlignment)); + CopyBytes(copy, data, length); + data_ = copy; + AcquireDataOwnership(); + } +} + + CompilationInfo::CompilationInfo(Handle