Revert "Add support to produce code cache after execute."

This reverts commit 5d4a090377.

Reason for revert: Speculative revert due to timeouts on testing with
--isolates:
https://build.chromium.org/p/client.v8/builders/V8%20Linux/builds/21889
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20debug/builds/18138

Original change's description:
> Add support to produce code cache after execute.
> 
> Adds new API function to request code cache. Earlier code cache was
> produced along with compile requests. This new API allows us to request
> code cache after executing. Also adds support in the code serializer to
> serialize after executing the script.
> 
> Bug: chromium:783124
> Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
> Change-Id: Id7b972a2b4c8dcf7a6d9f5ea210890ae968320bd
> Reviewed-on: https://chromium-review.googlesource.com/781767
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Commit-Queue: Mythri Alle <mythria@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#49717}

TBR=ulan@chromium.org,rmcilroy@chromium.org,yangguo@chromium.org,mythria@chromium.org

Change-Id: Id9e0285e73bbc3ea3908b4b7bbf6599e4f7cd76e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:783124
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/796870
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49722}
This commit is contained in:
Michael Achenbach 2017-11-29 14:58:50 +00:00 committed by Commit Bot
parent 27fd921a28
commit 5ff7af939e
13 changed files with 117 additions and 314 deletions

View File

@ -1576,14 +1576,6 @@ class V8_EXPORT ScriptCompiler {
Local<String> arguments[], size_t context_extension_count,
Local<Object> context_extensions[]);
/**
* Creates and returns code cache for the specified unbound_script.
* This will return nullptr if the script cannot be serialized. The
* CachedData returned by this function should be owned by the caller.
*/
static CachedData* CreateCodeCache(Local<UnboundScript> unbound_script,
Local<String> source);
private:
static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundInternal(
Isolate* isolate, Source* source, CompileOptions options,

View File

@ -2660,26 +2660,6 @@ uint32_t ScriptCompiler::CachedDataVersionTag() {
static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
}
ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
Local<UnboundScript> unbound_script, Local<String> source) {
i::Handle<i::SharedFunctionInfo> shared =
i::Handle<i::SharedFunctionInfo>::cast(
Utils::OpenHandle(*unbound_script));
DCHECK(shared->is_toplevel());
i::Handle<i::Script> script(i::Script::cast(shared->script()));
i::Isolate* isolate = shared->GetIsolate();
// TODO(7110): Enable serialization of Asm modules once the AsmWasmData is
// context independent.
if (script->ContainsAsmModule()) return nullptr;
if (isolate->debug()->is_loaded()) return nullptr;
i::ScriptData* script_data =
i::CodeSerializer::Serialize(isolate, shared, Utils::OpenHandle(*source));
CachedData* result = new CachedData(
script_data->data(), script_data->length(), CachedData::BufferOwned);
script_data->ReleaseDataOwnership();
delete script_data;
return result;
}
MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
ScriptOrigin* origin) {

View File

@ -1176,6 +1176,15 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
namespace {
bool ContainsAsmModule(Handle<Script> script) {
DisallowHeapAllocation no_gc;
SharedFunctionInfo::ScriptIterator iter(script);
while (SharedFunctionInfo* info = iter.Next()) {
if (info->HasAsmWasmData()) return true;
}
return false;
}
bool ShouldProduceCodeCache(ScriptCompiler::CompileOptions options) {
return options == ScriptCompiler::kProduceCodeCache ||
options == ScriptCompiler::kProduceFullCodeCache;
@ -1563,7 +1572,7 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
compilation_cache->PutScript(source, context, language_mode, result,
vector);
if (ShouldProduceCodeCache(compile_options) &&
!script->ContainsAsmModule()) {
!ContainsAsmModule(script)) {
compile_timer.set_producing_code_cache();
HistogramTimerScope histogram_timer(

199
src/d8.cc
View File

@ -506,8 +506,6 @@ std::vector<Worker*> Shell::workers_;
std::vector<ExternalizedContents> Shell::externalized_contents_;
base::LazyMutex Shell::isolate_status_lock_;
std::map<v8::Isolate*, bool> Shell::isolate_status_;
std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
Shell::cached_code_map_;
Global<Context> Shell::evaluation_context_;
ArrayBuffer::Allocator* Shell::array_buffer_allocator;
@ -568,37 +566,95 @@ class BackgroundCompileThread : public base::Thread {
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task_;
};
ScriptCompiler::CachedData* Shell::LookupCodeCache(Isolate* isolate,
Local<Value> name) {
CHECK(name->IsString());
v8::String::Utf8Value key(isolate, name);
DCHECK(*key);
auto entry = cached_code_map_.find(*key);
if (entry != cached_code_map_.end() && entry->second) {
int length = entry->second->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, entry->second->data, length);
ScriptCompiler::CachedData* cached_data = new ScriptCompiler::CachedData(
cache, length, ScriptCompiler::CachedData::BufferOwned);
return cached_data;
ScriptCompiler::CachedData* CompileForCachedData(
Local<String> source, Local<Value> name,
ScriptCompiler::CompileOptions compile_options) {
int source_length = source->Length();
uint16_t* source_buffer = new uint16_t[source_length];
source->Write(source_buffer, 0, source_length);
int name_length = 0;
uint16_t* name_buffer = nullptr;
if (name->IsString()) {
Local<String> name_string = Local<String>::Cast(name);
name_length = name_string->Length();
name_buffer = new uint16_t[name_length];
name_string->Write(name_buffer, 0, name_length);
}
return nullptr;
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = Shell::array_buffer_allocator;
i::FLAG_hash_seed ^= 1337; // Use a different hash seed.
Isolate* temp_isolate = Isolate::New(create_params);
i::FLAG_hash_seed ^= 1337; // Restore old hash seed.
temp_isolate->SetHostImportModuleDynamicallyCallback(
Shell::HostImportModuleDynamically);
temp_isolate->SetHostInitializeImportMetaObjectCallback(
Shell::HostInitializeImportMetaObject);
ScriptCompiler::CachedData* result = nullptr;
{
Isolate::Scope isolate_scope(temp_isolate);
HandleScope handle_scope(temp_isolate);
Context::Scope context_scope(Context::New(temp_isolate));
Local<String> source_copy =
v8::String::NewFromTwoByte(temp_isolate, source_buffer,
v8::NewStringType::kNormal, source_length)
.ToLocalChecked();
Local<Value> name_copy;
if (name_buffer) {
name_copy =
v8::String::NewFromTwoByte(temp_isolate, name_buffer,
v8::NewStringType::kNormal, name_length)
.ToLocalChecked();
} else {
name_copy = v8::Undefined(temp_isolate);
}
ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy));
if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source,
compile_options)
.IsEmpty() &&
script_source.GetCachedData()) {
int length = script_source.GetCachedData()->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, script_source.GetCachedData()->data, length);
result = new ScriptCompiler::CachedData(
cache, length, ScriptCompiler::CachedData::BufferOwned);
}
}
temp_isolate->Dispose();
delete[] source_buffer;
delete[] name_buffer;
return result;
}
void Shell::StoreInCodeCache(Isolate* isolate, Local<Value> name,
const ScriptCompiler::CachedData* cache_data) {
CHECK(name->IsString());
if (cache_data == nullptr) return;
v8::String::Utf8Value key(isolate, name);
DCHECK(*key);
int length = cache_data->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, cache_data->data, length);
cached_code_map_[*key] = std::unique_ptr<ScriptCompiler::CachedData>(
new ScriptCompiler::CachedData(cache, length,
ScriptCompiler::CachedData::BufferOwned));
// Compile a string within the current v8 context.
MaybeLocal<Script> Shell::CompileString(
Isolate* isolate, Local<String> source, Local<Value> name,
ScriptCompiler::CompileOptions compile_options) {
Local<Context> context(isolate->GetCurrentContext());
ScriptOrigin origin(name);
if (compile_options == ScriptCompiler::kNoCompileOptions) {
ScriptCompiler::Source script_source(source, origin);
return ScriptCompiler::Compile(context, &script_source, compile_options);
}
ScriptCompiler::CachedData* data =
CompileForCachedData(source, name, compile_options);
ScriptCompiler::Source cached_source(source, origin, data);
if (compile_options == ScriptCompiler::kProduceCodeCache) {
compile_options = ScriptCompiler::kConsumeCodeCache;
} else if (compile_options == ScriptCompiler::kProduceParserCache) {
compile_options = ScriptCompiler::kConsumeParserCache;
} else {
DCHECK(false); // A new compile option?
}
if (data == nullptr) compile_options = ScriptCompiler::kNoCompileOptions;
MaybeLocal<Script> result =
ScriptCompiler::Compile(context, &cached_source, compile_options);
CHECK(data == nullptr || !data->rejected);
return result;
}
// Executes a string within the current v8 context.
bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Value> name, bool print_result,
@ -615,22 +671,7 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
MaybeLocal<Script> maybe_script;
Local<Context> context(isolate->GetCurrentContext());
ScriptOrigin origin(name);
if (options.compile_options == ScriptCompiler::kConsumeCodeCache) {
ScriptCompiler::CachedData* cached_code = LookupCodeCache(isolate, name);
if (cached_code != nullptr) {
ScriptCompiler::Source script_source(source, origin, cached_code);
maybe_script = ScriptCompiler::Compile(context, &script_source,
options.compile_options);
CHECK(!cached_code->rejected);
} else {
ScriptCompiler::Source script_source(source, origin);
maybe_script = ScriptCompiler::Compile(
context, &script_source, ScriptCompiler::kNoCompileOptions);
}
} else if (options.stress_background_compile) {
if (options.stress_background_compile) {
// Start a background thread compiling the script.
BackgroundCompileThread background_compile_thread(isolate, source);
background_compile_thread.Start();
@ -638,26 +679,18 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
// In parallel, compile on the main thread to flush out any data races.
{
TryCatch ignore_try_catch(isolate);
ScriptCompiler::Source script_source(source, origin);
USE(ScriptCompiler::Compile(context, &script_source,
ScriptCompiler::kNoCompileOptions));
Shell::CompileString(isolate, source, name, options.compile_options);
}
// Join with background thread and finalize compilation.
background_compile_thread.Join();
ScriptOrigin origin(name);
maybe_script = v8::ScriptCompiler::Compile(
context, background_compile_thread.streamed_source(), source, origin);
isolate->GetCurrentContext(),
background_compile_thread.streamed_source(), source, origin);
} else {
ScriptCompiler::Source script_source(source, origin);
ScriptCompiler::CompileOptions compile_options =
options.cache_code_after_execute ? ScriptCompiler::kNoCompileOptions
: options.compile_options;
maybe_script =
ScriptCompiler::Compile(context, &script_source, compile_options);
if (compile_options == ScriptCompiler::kProduceCodeCache ||
compile_options == ScriptCompiler::kProduceParserCache) {
StoreInCodeCache(isolate, name, script_source.GetCachedData());
}
Shell::CompileString(isolate, source, name, options.compile_options);
}
Local<Script> script;
@ -668,14 +701,6 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
}
maybe_result = script->Run(realm);
if (options.compile_options == ScriptCompiler::kProduceCodeCache &&
options.cache_code_after_execute) {
// Serialize and store it in memory for the next execution.
ScriptCompiler::CachedData* cached_data =
ScriptCompiler::CreateCodeCache(script->GetUnboundScript(), source);
StoreInCodeCache(isolate, name, cached_data);
delete cached_data;
}
if (!EmptyMessageQueues(isolate)) success = false;
data->realm_current_ = data->realm_switch_;
}
@ -2843,9 +2868,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
options.compile_options = v8::ScriptCompiler::kProduceParserCache;
} else if (strncmp(value, "=none", 6) == 0) {
options.compile_options = v8::ScriptCompiler::kNoCompileOptions;
} else if (strncmp(value, "=after-execute", 10) == 0) {
options.compile_options = v8::ScriptCompiler::kProduceCodeCache;
options.cache_code_after_execute = true;
} else {
printf("Unknown option to --cache.\n");
return false;
@ -3391,47 +3413,6 @@ int Shell::Main(int argc, char* argv[]) {
bool last_run = i == options.stress_runs - 1;
result = RunMain(isolate, argc, argv, last_run);
}
} else if (options.compile_options ==
v8::ScriptCompiler::kProduceCodeCache ||
options.compile_options ==
v8::ScriptCompiler::kProduceParserCache) {
printf("============ Run: Produce code cache ============\n");
// First run to produce the cache
result = RunMain(isolate, argc, argv, false);
// Change the options to consume cache
if (options.compile_options == v8::ScriptCompiler::kProduceCodeCache) {
options.compile_options = v8::ScriptCompiler::kConsumeCodeCache;
} else if (options.compile_options ==
v8::ScriptCompiler::kProduceParserCache) {
options.compile_options = v8::ScriptCompiler::kConsumeParserCache;
} else {
// We only expect ProduceCodeCache or ProduceParserCache here.
// compile_options cannot be NoCompileOptions.
UNREACHABLE();
}
printf("============ Run: Consume code cache ============\n");
// Second run to consume the cache in new isolate
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = Shell::array_buffer_allocator;
i::FLAG_hash_seed ^= 1337; // Use a different hash seed.
Isolate* isolate2 = Isolate::New(create_params);
i::FLAG_hash_seed ^= 1337; // Restore old hash seed.
isolate2->SetHostImportModuleDynamicallyCallback(
Shell::HostImportModuleDynamically);
isolate2->SetHostInitializeImportMetaObjectCallback(
Shell::HostInitializeImportMetaObject);
{
D8Console console(isolate2);
debug::SetConsoleDelegate(isolate2, &console);
PerIsolateData data(isolate2);
Isolate::Scope isolate_scope(isolate2);
result = RunMain(isolate2, argc, argv, false);
}
cached_code_map_.clear();
isolate2->Dispose();
} else {
bool last_run = true;
result = RunMain(isolate, argc, argv, last_run);

View File

@ -296,7 +296,6 @@ class ShellOptions {
num_isolates(1),
compile_options(v8::ScriptCompiler::kNoCompileOptions),
stress_background_compile(false),
cache_code_after_execute(false),
isolate_sources(nullptr),
icu_data_file(nullptr),
natives_blob(nullptr),
@ -330,7 +329,6 @@ class ShellOptions {
int num_isolates;
v8::ScriptCompiler::CompileOptions compile_options;
bool stress_background_compile;
bool cache_code_after_execute;
SourceGroup* isolate_sources;
const char* icu_data_file;
const char* natives_blob;
@ -346,6 +344,9 @@ class ShellOptions {
class Shell : public i::AllStatic {
public:
static MaybeLocal<Script> CompileString(
Isolate* isolate, Local<String> source, Local<Value> name,
v8::ScriptCompiler::CompileOptions compile_options);
static bool ExecuteString(Isolate* isolate, Local<String> source,
Local<Value> name, bool print_result,
bool report_exceptions);
@ -503,16 +504,10 @@ class Shell : public i::AllStatic {
int index);
static MaybeLocal<Module> FetchModuleTree(v8::Local<v8::Context> context,
const std::string& file_name);
static ScriptCompiler::CachedData* LookupCodeCache(Isolate* isolate,
Local<Value> name);
static void StoreInCodeCache(Isolate* isolate, Local<Value> name,
const ScriptCompiler::CachedData* data);
// We may have multiple isolates running concurrently, so the access to
// the isolate_status_ needs to be concurrency-safe.
static base::LazyMutex isolate_status_lock_;
static std::map<Isolate*, bool> isolate_status_;
static std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
cached_code_map_;
};

View File

@ -13263,15 +13263,6 @@ bool Script::GetPositionInfo(Handle<Script> script, int position,
bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
bool Script::ContainsAsmModule() {
DisallowHeapAllocation no_gc;
SharedFunctionInfo::ScriptIterator iter(Handle<Script>(this));
while (SharedFunctionInfo* info = iter.Next()) {
if (info->HasAsmWasmData()) return true;
}
return false;
}
namespace {
bool GetPositionInfoSlow(const Script* script, int position,
Script::PositionInfo* info) {

View File

@ -635,14 +635,6 @@ ByteArray* BytecodeArray::SourcePositionTable() {
->source_position_table();
}
void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
Object* maybe_table = source_position_table();
if (maybe_table->IsByteArray()) return;
DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
->source_position_table());
}
int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
int BytecodeArray::SizeIncludingMetadata() {

View File

@ -790,7 +790,6 @@ class BytecodeArray : public FixedArrayBase {
DECL_ACCESSORS(source_position_table, Object)
inline ByteArray* SourcePositionTable();
inline void ClearFrameCacheFromSourcePositionTable();
DECL_CAST(BytecodeArray)

View File

@ -118,9 +118,6 @@ class Script : public Struct {
// Retrieve source position from where eval was called.
int GetEvalPosition();
// Check if the script contains any Asm modules.
bool ContainsAsmModule();
// Init line_ends array with source code positions of line ends.
static void InitLineEnds(Handle<Script> script);

View File

@ -106,37 +106,12 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
}
if (obj->IsScript()) {
Script* script_obj = Script::cast(obj);
DCHECK_NE(script_obj->compilation_type(), Script::COMPILATION_TYPE_EVAL);
// Wrapper object is a context-dependent JSValue. Reset it here.
script_obj->set_wrapper(isolate()->heap()->undefined_value());
// We want to differentiate between undefined and uninitialized_symbol for
// context_data for now. It is hack to allow debugging for scripts that are
// included as a part of custom snapshot. (see debug::Script::IsEmbedded())
Object* context_data = script_obj->context_data();
if (context_data != isolate()->heap()->undefined_value() &&
context_data != isolate()->heap()->uninitialized_symbol()) {
script_obj->set_context_data(isolate()->heap()->undefined_value());
}
// We don't want to serialize host options to avoid serializing unnecessary
// object graph.
FixedArray* host_options = script_obj->host_defined_options();
script_obj->set_host_defined_options(
isolate()->heap()->empty_fixed_array());
SerializeGeneric(obj, how_to_code, where_to_point);
script_obj->set_host_defined_options(host_options);
script_obj->set_context_data(context_data);
return;
Script::cast(obj)->set_wrapper(isolate()->heap()->undefined_value());
}
if (obj->IsSharedFunctionInfo()) {
SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
// TODO(7110): Enable serializing of Asm modules once the AsmWasmData
// is context independent.
DCHECK(!sfi->IsApiFunction() && !sfi->HasAsmWasmData());
// Do not serialize when a debugger is active.
DCHECK(sfi->debug_info()->IsSmi());
// Mark SFI to indicate whether the code is cached.
bool was_deserialized = sfi->deserialized();
sfi->set_deserialized(sfi->is_compiled());
@ -145,11 +120,6 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
return;
}
if (obj->IsBytecodeArray()) {
// Clear the stack frame cache if present
BytecodeArray::cast(obj)->ClearFrameCacheFromSourcePositionTable();
}
// Past this point we should not see any (context-specific) maps anymore.
CHECK(!obj->IsMap());
// There should be no references to the global object embedded.

View File

@ -234,13 +234,6 @@ HeapObject* Deserializer<AllocatorT>::PostProcessNewObject(HeapObject* obj,
void* backing_store = off_heap_backing_stores_[store_index->value()];
fta->set_external_pointer(backing_store);
}
} else if (obj->IsBytecodeArray()) {
// TODO(mythria): Remove these once we store the default values for these
// fields in the serializer.
BytecodeArray* bytecode_array = BytecodeArray::cast(obj);
bytecode_array->set_interrupt_budget(
interpreter::Interpreter::kInterruptBudget);
bytecode_array->set_osr_loop_nesting_level(0);
}
// Check alignment.
DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment()));

View File

@ -57,8 +57,6 @@
namespace v8 {
namespace internal {
enum CodeCacheType { kLazy, kEager, kAfterExecute };
void DisableLazyDeserialization() {
// UNINITIALIZED tests do not set up the isolate sufficiently for lazy
// deserialization to work.
@ -1840,8 +1838,8 @@ static void SerializerCodeEventListener(const v8::JitCodeEvent* event) {
}
}
v8::ScriptCompiler::CachedData* ProduceCache(
const char* source, CodeCacheType cacheType = CodeCacheType::kLazy) {
v8::ScriptCompiler::CachedData* ProduceCache(const char* source,
bool eager = false) {
v8::ScriptCompiler::CachedData* cache;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -1855,23 +1853,19 @@ v8::ScriptCompiler::CachedData* ProduceCache(
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
v8::ScriptCompiler::CompileOptions options;
switch (cacheType) {
case CodeCacheType::kLazy:
options = v8::ScriptCompiler::kProduceCodeCache;
break;
case CodeCacheType::kEager:
options = v8::ScriptCompiler::kProduceFullCodeCache;
break;
case CodeCacheType::kAfterExecute:
options = v8::ScriptCompiler::kNoCompileOptions;
break;
default:
UNREACHABLE();
}
v8::ScriptCompiler::CompileOptions options =
eager ? v8::ScriptCompiler::kProduceFullCodeCache
: v8::ScriptCompiler::kProduceCodeCache;
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(isolate1, &source, options)
.ToLocalChecked();
const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
CHECK(data);
// Persist cached data.
uint8_t* buffer = NewArray<uint8_t>(data->length);
MemCopy(buffer, data->data, data->length);
cache = new v8::ScriptCompiler::CachedData(
buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate1->GetCurrentContext())
@ -1880,18 +1874,6 @@ v8::ScriptCompiler::CachedData* ProduceCache(
result->ToString(isolate1->GetCurrentContext()).ToLocalChecked();
CHECK(result_string->Equals(isolate1->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
if (cacheType == CodeCacheType::kAfterExecute) {
cache = ScriptCompiler::CreateCodeCache(script, source_str);
} else {
const ScriptCompiler::CachedData* data = source.GetCachedData();
CHECK(data);
uint8_t* buffer = NewArray<uint8_t>(data->length);
MemCopy(buffer, data->data, data->length);
cache = new v8::ScriptCompiler::CachedData(
buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
}
CHECK(cache);
}
isolate1->Dispose();
return cache;
@ -1954,8 +1936,7 @@ TEST(CodeSerializerIsolatesEager) {
" }"
"}"
"f()() + 'def'";
v8::ScriptCompiler::CachedData* cache =
ProduceCache(source, CodeCacheType::kEager);
v8::ScriptCompiler::CachedData* cache = ProduceCache(source, true);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -1993,68 +1974,6 @@ TEST(CodeSerializerIsolatesEager) {
isolate2->Dispose();
}
TEST(CodeSerializerAfterExecute) {
// We test that no compilations happen when running this code. Forcing
// to always optimize breaks this test.
bool prev_opt_value = FLAG_opt;
bool prev_always_opt_value = FLAG_always_opt;
FLAG_always_opt = false;
FLAG_opt = false;
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache =
ProduceCache(source, CodeCacheType::kAfterExecute);
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> script;
{
DisallowCompilation no_compile_expected(
reinterpret_cast<Isolate*>(isolate2));
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK(!cache->rejected);
CheckDeserializedFlag(script);
Handle<SharedFunctionInfo> sfi = v8::Utils::OpenHandle(*script);
CHECK(sfi->HasBytecodeArray());
BytecodeArray* bytecode = sfi->bytecode_array();
CHECK_EQ(bytecode->interrupt_budget(),
interpreter::Interpreter::kInterruptBudget);
CHECK_EQ(bytecode->osr_loop_nesting_level(), 0);
{
DisallowCompilation no_compile_expected(
reinterpret_cast<Isolate*>(isolate2));
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_string =
result->ToString(isolate2->GetCurrentContext()).ToLocalChecked();
CHECK(
result_string->Equals(isolate2->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
}
}
isolate2->Dispose();
// Restore the flags.
FLAG_always_opt = prev_always_opt_value;
FLAG_opt = prev_opt_value;
}
TEST(CodeSerializerFlagChange) {
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source);

View File

@ -1,15 +0,0 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --cache=after-execute
function g() {
function h() {
function k() { return 0; };
return k;
}
return h();
}
g();