Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index cd349f9..de36877 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -36,6 +36,7 @@
#include "src/compilation-cache.h"
#include "src/debug/debug.h"
#include "src/heap/spaces.h"
+#include "src/macro-assembler.h"
#include "src/objects.h"
#include "src/parsing/parser.h"
#include "src/runtime/runtime.h"
@@ -46,7 +47,7 @@
#include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-serializer.h"
#include "test/cctest/cctest.h"
-#include "test/cctest/heap/utils-inl.h"
+#include "test/cctest/heap/heap-utils.h"
using namespace v8::internal;
@@ -91,11 +92,11 @@
Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
internal_isolate->heap()->CollectAllAvailableGarbage("serialize");
- SnapshotByteSink sink;
- StartupSerializer ser(internal_isolate, &sink);
+ StartupSerializer ser(internal_isolate,
+ v8::SnapshotCreator::FunctionCodeHandling::kClear);
ser.SerializeStrongReferences();
ser.SerializeWeakReferencesAndDeferred();
- SnapshotData snapshot_data(ser);
+ SnapshotData snapshot_data(&ser);
return WritePayload(snapshot_data.RawData());
}
@@ -280,19 +281,17 @@
}
env.Reset();
- SnapshotByteSink startup_sink;
- StartupSerializer startup_serializer(isolate, &startup_sink);
+ StartupSerializer startup_serializer(
+ isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences();
- SnapshotByteSink partial_sink;
- PartialSerializer partial_serializer(isolate, &startup_serializer,
- &partial_sink);
+ PartialSerializer partial_serializer(isolate, &startup_serializer);
partial_serializer.Serialize(&raw_foo);
startup_serializer.SerializeWeakReferencesAndDeferred();
- SnapshotData startup_snapshot(startup_serializer);
- SnapshotData partial_snapshot(partial_serializer);
+ SnapshotData startup_snapshot(&startup_serializer);
+ SnapshotData partial_snapshot(&partial_serializer);
*partial_blob_out = WritePayload(partial_snapshot.RawData());
*startup_blob_out = WritePayload(startup_snapshot.RawData());
@@ -380,17 +379,17 @@
env.Reset();
SnapshotByteSink startup_sink;
- StartupSerializer startup_serializer(isolate, &startup_sink);
+ StartupSerializer startup_serializer(
+ isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
- PartialSerializer partial_serializer(isolate, &startup_serializer,
- &partial_sink);
+ PartialSerializer partial_serializer(isolate, &startup_serializer);
partial_serializer.Serialize(&raw_context);
startup_serializer.SerializeWeakReferencesAndDeferred();
- SnapshotData startup_snapshot(startup_serializer);
- SnapshotData partial_snapshot(partial_serializer);
+ SnapshotData startup_snapshot(&startup_serializer);
+ SnapshotData partial_snapshot(&partial_serializer);
*partial_blob_out = WritePayload(partial_snapshot.RawData());
*startup_blob_out = WritePayload(startup_snapshot.RawData());
@@ -498,17 +497,17 @@
env.Reset();
SnapshotByteSink startup_sink;
- StartupSerializer startup_serializer(isolate, &startup_sink);
+ StartupSerializer startup_serializer(
+ isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
- PartialSerializer partial_serializer(isolate, &startup_serializer,
- &partial_sink);
+ PartialSerializer partial_serializer(isolate, &startup_serializer);
partial_serializer.Serialize(&raw_context);
startup_serializer.SerializeWeakReferencesAndDeferred();
- SnapshotData startup_snapshot(startup_serializer);
- SnapshotData partial_snapshot(partial_serializer);
+ SnapshotData startup_snapshot(&startup_serializer);
+ SnapshotData partial_snapshot(&partial_serializer);
*partial_blob_out = WritePayload(partial_snapshot.RawData());
*startup_blob_out = WritePayload(startup_snapshot.RawData());
@@ -792,7 +791,7 @@
TEST(SnapshotDataBlobWithWarmup) {
DisableTurbofan();
- const char* warmup = "Math.tan(1); Math.sin = 1;";
+ const char* warmup = "Math.tanh(1); Math.sinh = 1;";
v8::StartupData cold = v8::V8::CreateSnapshotDataBlob();
v8::StartupData warm = v8::V8::WarmUpSnapshotDataBlob(cold, warmup);
@@ -811,9 +810,9 @@
v8::Context::Scope c_scope(context);
// Running the warmup script has effect on whether functions are
// pre-compiled, but does not pollute the context.
- CHECK(IsCompiled("Math.tan"));
- CHECK(!IsCompiled("Math.cos"));
- CHECK(CompileRun("Math.sin")->IsFunction());
+ CHECK(IsCompiled("Math.tanh"));
+ CHECK(!IsCompiled("Math.cosh"));
+ CHECK(CompileRun("Math.sinh")->IsFunction());
}
isolate->Dispose();
}
@@ -821,9 +820,9 @@
TEST(CustomSnapshotDataBlobWithWarmup) {
DisableTurbofan();
const char* source =
- "function f() { return Math.sin(1); }\n"
- "function g() { return Math.cos(1); }\n"
- "Math.tan(1);"
+ "function f() { return Math.sinh(1); }\n"
+ "function g() { return Math.cosh(1); }\n"
+ "Math.tanh(1);"
"var a = 5";
const char* warmup = "a = f()";
@@ -845,10 +844,10 @@
// Running the warmup script has effect on whether functions are
// pre-compiled, but does not pollute the context.
CHECK(IsCompiled("f"));
- CHECK(IsCompiled("Math.sin"));
+ CHECK(IsCompiled("Math.sinh"));
CHECK(!IsCompiled("g"));
- CHECK(!IsCompiled("Math.cos"));
- CHECK(!IsCompiled("Math.tan"));
+ CHECK(!IsCompiled("Math.cosh"));
+ CHECK(!IsCompiled("Math.tanh"));
CHECK_EQ(5, CompileRun("a")->Int32Value(context).FromJust());
}
isolate->Dispose();
@@ -1827,12 +1826,302 @@
false);
delete script_data;
- SimulateIncrementalMarking(isolate->heap());
+ heap::SimulateIncrementalMarking(isolate->heap());
script_data = CodeSerializer::Serialize(isolate, shared, source);
delete script_data;
}
+#if V8_TARGET_ARCH_X64
+TEST(CodeSerializerCell) {
+ FLAG_serialize_toplevel = true;
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
+
+ v8::HandleScope scope(CcTest::isolate());
+
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ HandleScope handles(isolate);
+
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
+ v8::internal::CodeObjectRequired::kYes);
+ assembler.enable_serializer();
+ Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(0.3);
+ CHECK(isolate->heap()->InNewSpace(*number));
+ MacroAssembler* masm = &assembler;
+ masm->MoveHeapObject(rax, number);
+ masm->ret(0);
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::FUNCTION), masm->CodeObject());
+ code->set_has_reloc_info_for_serialization(true);
+
+ RelocIterator rit1(*code, 1 << RelocInfo::CELL);
+ CHECK_EQ(*number, rit1.rinfo()->target_cell()->value());
+
+ Handle<String> source = isolate->factory()->empty_string();
+ Handle<SharedFunctionInfo> sfi =
+ isolate->factory()->NewSharedFunctionInfo(source, code, false);
+ ScriptData* script_data = CodeSerializer::Serialize(isolate, sfi, source);
+
+ Handle<SharedFunctionInfo> copy =
+ CodeSerializer::Deserialize(isolate, script_data, source)
+ .ToHandleChecked();
+ RelocIterator rit2(copy->code(), 1 << RelocInfo::CELL);
+ CHECK(rit2.rinfo()->target_cell()->IsCell());
+ Handle<Cell> cell(rit2.rinfo()->target_cell());
+ CHECK(cell->value()->IsHeapNumber());
+ CHECK_EQ(0.3, HeapNumber::cast(cell->value())->value());
+
+ delete script_data;
+}
+#endif // V8_TARGET_ARCH_X64
+
+TEST(SnapshotCreatorMultipleContexts) {
+ DisableTurbofan();
+ v8::StartupData blob;
+ {
+ v8::SnapshotCreator creator;
+ v8::Isolate* isolate = creator.GetIsolate();
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+ CompileRun("var f = function() { return 1; }");
+ CHECK_EQ(0, creator.AddContext(context));
+ }
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+ CompileRun("var f = function() { return 2; }");
+ CHECK_EQ(1, creator.AddContext(context));
+ }
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ CHECK_EQ(2, creator.AddContext(context));
+ }
+ blob =
+ creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+ }
+
+ v8::Isolate::CreateParams params;
+ params.snapshot_blob = &blob;
+ params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate = v8::Isolate::New(params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> no_template = v8::Local<v8::ObjectTemplate>();
+ v8::Local<v8::Value> no_object = v8::Local<v8::Value>();
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 0);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 1);
+ }
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 1);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 2);
+ }
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 2);
+ v8::Context::Scope context_scope(context);
+ ExpectUndefined("this.f");
+ }
+ }
+
+ isolate->Dispose();
+ delete[] blob.data;
+}
+
+static void SerializedCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(v8_num(42));
+}
+
+static void SerializedCallbackReplacement(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(v8_num(1337));
+}
+
+intptr_t original_external_references[] = {
+ reinterpret_cast<intptr_t>(SerializedCallback), 0};
+
+intptr_t replaced_external_references[] = {
+ reinterpret_cast<intptr_t>(SerializedCallbackReplacement), 0};
+
+TEST(SnapshotCreatorExternalReferences) {
+ DisableTurbofan();
+ v8::StartupData blob;
+ {
+ v8::SnapshotCreator creator(original_external_references);
+ v8::Isolate* isolate = creator.GetIsolate();
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+ v8::Local<v8::FunctionTemplate> callback =
+ v8::FunctionTemplate::New(isolate, SerializedCallback);
+ v8::Local<v8::Value> function =
+ callback->GetFunction(context).ToLocalChecked();
+ CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
+ ExpectInt32("f()", 42);
+ CHECK_EQ(0, creator.AddContext(context));
+ }
+ blob =
+ creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+ }
+
+ // Deserialize with the original external reference.
+ {
+ v8::Isolate::CreateParams params;
+ params.snapshot_blob = &blob;
+ params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ params.external_references = original_external_references;
+ v8::Isolate* isolate = v8::Isolate::New(params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> no_template =
+ v8::Local<v8::ObjectTemplate>();
+ v8::Local<v8::Value> no_object = v8::Local<v8::Value>();
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 0);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 42);
+ }
+ isolate->Dispose();
+ }
+
+ // Deserialize with the some other external reference.
+ {
+ v8::Isolate::CreateParams params;
+ params.snapshot_blob = &blob;
+ params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ params.external_references = replaced_external_references;
+ v8::Isolate* isolate = v8::Isolate::New(params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> no_template =
+ v8::Local<v8::ObjectTemplate>();
+ v8::Local<v8::Value> no_object = v8::Local<v8::Value>();
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 0);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 1337);
+ }
+ isolate->Dispose();
+ }
+ delete[] blob.data;
+}
+
+TEST(SnapshotCreatorTemplates) {
+ DisableTurbofan();
+ v8::StartupData blob;
+ {
+ v8::SnapshotCreator creator(original_external_references);
+ v8::Isolate* isolate = creator.GetIsolate();
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ v8::Local<v8::FunctionTemplate> callback =
+ v8::FunctionTemplate::New(isolate, SerializedCallback);
+ global_template->Set(v8_str("f"), callback);
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, global_template);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 42);
+ CHECK_EQ(0, creator.AddContext(context));
+ CHECK_EQ(0, creator.AddTemplate(callback));
+ CHECK_EQ(1, creator.AddTemplate(global_template));
+ }
+ blob =
+ creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+ }
+
+ {
+ v8::Isolate::CreateParams params;
+ params.snapshot_blob = &blob;
+ params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ params.external_references = original_external_references;
+ v8::Isolate* isolate = v8::Isolate::New(params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ {
+ // Create a new context without a new object template.
+ v8::HandleScope handle_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> no_template =
+ v8::Local<v8::ObjectTemplate>();
+ v8::Local<v8::Value> no_object = v8::Local<v8::Value>();
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, no_extension, no_template, no_object, 0);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 42);
+
+ // Retrieve the snapshotted object template.
+ v8::Local<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::FromSnapshot(isolate, 1);
+ CHECK(!obj_template.IsEmpty());
+ v8::Local<v8::Object> object =
+ obj_template->NewInstance(context).ToLocalChecked();
+ CHECK(context->Global()->Set(context, v8_str("o"), object).FromJust());
+ ExpectInt32("o.f()", 42);
+ // Check that it instantiates to the same prototype.
+ ExpectTrue("o.f.prototype === f.prototype");
+
+ // Retrieve the snapshotted function template.
+ v8::Local<v8::FunctionTemplate> fun_template =
+ v8::FunctionTemplate::FromSnapshot(isolate, 0);
+ CHECK(!fun_template.IsEmpty());
+ v8::Local<v8::Function> fun =
+ fun_template->GetFunction(context).ToLocalChecked();
+ CHECK(context->Global()->Set(context, v8_str("g"), fun).FromJust());
+ ExpectInt32("g()", 42);
+ // Check that it instantiates to the same prototype.
+ ExpectTrue("g.prototype === f.prototype");
+ }
+
+ {
+ // Create a context with a new object template. It is merged into the
+ // deserialized global object.
+ v8::HandleScope handle_scope(isolate);
+ v8::ExtensionConfiguration* no_extension = nullptr;
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ global_template->Set(
+ v8_str("g"),
+ v8::FunctionTemplate::New(isolate, SerializedCallbackReplacement));
+ v8::Local<v8::Value> no_object = v8::Local<v8::Value>();
+ v8::Local<v8::Context> context = v8::Context::New(
+ isolate, no_extension, global_template, no_object, 0);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("g()", 1337);
+ ExpectInt32("f()", 42);
+ }
+ }
+ isolate->Dispose();
+ }
+ delete[] blob.data;
+}
TEST(SerializationMemoryStats) {
FLAG_profile_deserialization = true;