blob: 2dcf1c6f1e0f1b328334e7827cf563f03c3a24e8 [file] [log] [blame]
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001// Copyright 2007-2010 the V8 project authors. All rights reserved.
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <signal.h>
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000029
machenbach@chromium.org196eb602014-06-04 00:06:13 +000030#include <sys/stat.h>
ulan@chromium.org57ff8812013-05-10 08:16:55 +000031
machenbach@chromium.org196eb602014-06-04 00:06:13 +000032#include "src/v8.h"
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000033
machenbach@chromium.org196eb602014-06-04 00:06:13 +000034#include "src/bootstrapper.h"
35#include "src/debug.h"
36#include "src/ic-inl.h"
37#include "src/natives.h"
38#include "src/objects.h"
39#include "src/runtime.h"
40#include "src/scopeinfo.h"
41#include "src/serialize.h"
42#include "src/snapshot.h"
43#include "src/spaces.h"
44#include "test/cctest/cctest.h"
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000045
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000046using namespace v8::internal;
47
ager@chromium.org5ec48922009-05-05 07:25:34 +000048static const unsigned kCounters = 256;
49static int local_counters[kCounters];
50static const char* local_counter_names[kCounters];
51
52
53static unsigned CounterHash(const char* s) {
54 unsigned hash = 0;
55 while (*++s) {
56 hash |= hash << 5;
57 hash += *s;
58 }
59 return hash;
60}
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000061
62
63// Callback receiver to track counters in test.
ager@chromium.orga74f0da2008-12-03 16:05:52 +000064static int* counter_function(const char* name) {
ager@chromium.org5ec48922009-05-05 07:25:34 +000065 unsigned hash = CounterHash(name) % kCounters;
66 unsigned original_hash = hash;
67 USE(original_hash);
68 while (true) {
69 if (local_counter_names[hash] == name) {
70 return &local_counters[hash];
71 }
72 if (local_counter_names[hash] == 0) {
73 local_counter_names[hash] = name;
74 return &local_counters[hash];
75 }
76 if (strcmp(local_counter_names[hash], name) == 0) {
77 return &local_counters[hash];
78 }
79 hash = (hash + 1) % kCounters;
80 ASSERT(hash != original_hash); // Hash table has been filled up.
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000081 }
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000082}
83
84
85template <class T>
86static Address AddressOf(T id) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +000087 return ExternalReference(id, CcTest::i_isolate()).address();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000088}
89
90
91template <class T>
92static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) {
93 return encoder.Encode(AddressOf(id));
94}
95
96
97static int make_code(TypeCode type, int id) {
98 return static_cast<uint32_t>(type) << kReferenceTypeShift | id;
99}
100
101
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000102TEST(ExternalReferenceEncoder) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000103 Isolate* isolate = CcTest::i_isolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000104 isolate->stats_table()->SetCounterFunction(counter_function);
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000105 v8::V8::Initialize();
106
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000107 ExternalReferenceEncoder encoder(isolate);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000108 CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
109 Encode(encoder, Builtins::kArrayCode));
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000110 CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000111 Encode(encoder, Runtime::kAbort));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000112 ExternalReference total_compile_size =
113 ExternalReference(isolate->counters()->total_compile_size());
114 CHECK_EQ(make_code(STATS_COUNTER, Counters::k_total_compile_size),
115 encoder.Encode(total_compile_size.address()));
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000116 ExternalReference stack_limit_address =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000117 ExternalReference::address_of_stack_limit(isolate);
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000118 CHECK_EQ(make_code(UNCLASSIFIED, 4),
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000119 encoder.Encode(stack_limit_address.address()));
120 ExternalReference real_stack_limit_address =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000121 ExternalReference::address_of_real_stack_limit(isolate);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000122 CHECK_EQ(make_code(UNCLASSIFIED, 5),
123 encoder.Encode(real_stack_limit_address.address()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000124 CHECK_EQ(make_code(UNCLASSIFIED, 16),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000125 encoder.Encode(ExternalReference::debug_break(isolate).address()));
whesse@chromium.org2c186ca2010-06-16 11:32:39 +0000126 CHECK_EQ(make_code(UNCLASSIFIED, 10),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000127 encoder.Encode(
128 ExternalReference::new_space_start(isolate).address()));
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000129 CHECK_EQ(make_code(UNCLASSIFIED, 3),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000130 encoder.Encode(
131 ExternalReference::roots_array_start(isolate).address()));
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000132 CHECK_EQ(make_code(UNCLASSIFIED, 52),
133 encoder.Encode(ExternalReference::cpu_features().address()));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000134}
135
136
137TEST(ExternalReferenceDecoder) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000138 Isolate* isolate = CcTest::i_isolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000139 isolate->stats_table()->SetCounterFunction(counter_function);
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000140 v8::V8::Initialize();
141
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000142 ExternalReferenceDecoder decoder(isolate);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000143 CHECK_EQ(AddressOf(Builtins::kArrayCode),
144 decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000145 CHECK_EQ(AddressOf(Runtime::kAbort),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000146 decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
147 Runtime::kAbort)));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000148 ExternalReference total_compile_size =
149 ExternalReference(isolate->counters()->total_compile_size());
150 CHECK_EQ(total_compile_size.address(),
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000151 decoder.Decode(
152 make_code(STATS_COUNTER,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000153 Counters::k_total_compile_size)));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000154 CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000155 decoder.Decode(make_code(UNCLASSIFIED, 4)));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000156 CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000157 decoder.Decode(make_code(UNCLASSIFIED, 5)));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000158 CHECK_EQ(ExternalReference::debug_break(isolate).address(),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000159 decoder.Decode(make_code(UNCLASSIFIED, 16)));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000160 CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
whesse@chromium.org2c186ca2010-06-16 11:32:39 +0000161 decoder.Decode(make_code(UNCLASSIFIED, 10)));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000162}
163
164
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000165class FileByteSink : public SnapshotByteSink {
166 public:
167 explicit FileByteSink(const char* snapshot_file) {
168 fp_ = OS::FOpen(snapshot_file, "wb");
169 file_name_ = snapshot_file;
170 if (fp_ == NULL) {
171 PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
172 exit(1);
173 }
174 }
175 virtual ~FileByteSink() {
176 if (fp_ != NULL) {
177 fclose(fp_);
178 }
179 }
180 virtual void Put(int byte, const char* description) {
181 if (fp_ != NULL) {
182 fputc(byte, fp_);
183 }
184 }
185 virtual int Position() {
186 return ftell(fp_);
187 }
188 void WriteSpaceUsed(
189 int new_space_used,
190 int pointer_space_used,
191 int data_space_used,
192 int code_space_used,
193 int map_space_used,
danno@chromium.org41728482013-06-12 22:31:22 +0000194 int cell_space_used,
195 int property_cell_space_used);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000196
197 private:
198 FILE* fp_;
199 const char* file_name_;
200};
201
202
203void FileByteSink::WriteSpaceUsed(
204 int new_space_used,
205 int pointer_space_used,
206 int data_space_used,
207 int code_space_used,
208 int map_space_used,
danno@chromium.org41728482013-06-12 22:31:22 +0000209 int cell_space_used,
210 int property_cell_space_used) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000211 int file_name_length = StrLength(file_name_) + 10;
212 Vector<char> name = Vector<char>::New(file_name_length + 1);
213 OS::SNPrintF(name, "%s.size", file_name_);
214 FILE* fp = OS::FOpen(name.start(), "w");
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000215 name.Dispose();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000216 fprintf(fp, "new %d\n", new_space_used);
217 fprintf(fp, "pointer %d\n", pointer_space_used);
218 fprintf(fp, "data %d\n", data_space_used);
219 fprintf(fp, "code %d\n", code_space_used);
220 fprintf(fp, "map %d\n", map_space_used);
221 fprintf(fp, "cell %d\n", cell_space_used);
danno@chromium.org41728482013-06-12 22:31:22 +0000222 fprintf(fp, "property cell %d\n", property_cell_space_used);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000223 fclose(fp);
224}
225
226
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000227static bool WriteToFile(Isolate* isolate, const char* snapshot_file) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000228 FileByteSink file(snapshot_file);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000229 StartupSerializer ser(isolate, &file);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000230 ser.Serialize();
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000231
232 file.WriteSpaceUsed(
233 ser.CurrentAllocationAddress(NEW_SPACE),
234 ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
235 ser.CurrentAllocationAddress(OLD_DATA_SPACE),
236 ser.CurrentAllocationAddress(CODE_SPACE),
237 ser.CurrentAllocationAddress(MAP_SPACE),
danno@chromium.org41728482013-06-12 22:31:22 +0000238 ser.CurrentAllocationAddress(CELL_SPACE),
239 ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000240
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000241 return true;
242}
243
244
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000245static void Serialize() {
ager@chromium.org3811b432009-10-28 14:53:37 +0000246 // We have to create one context. One reason for this is so that the builtins
247 // can be loaded from v8natives.js and their addresses can be processed. This
248 // will clear the pending fixups array, which would otherwise contain GC roots
249 // that would confuse the serialization/deserialization process.
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000250 v8::Isolate* isolate = CcTest::isolate();
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000251 {
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000252 v8::HandleScope scope(isolate);
253 v8::Context::New(isolate);
254 }
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000255
256 Isolate* internal_isolate = CcTest::i_isolate();
257 internal_isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "serialize");
258 WriteToFile(internal_isolate, FLAG_testing_serialization_file);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000259}
260
261
ager@chromium.org3811b432009-10-28 14:53:37 +0000262// Test that the whole heap can be serialized.
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000263TEST(Serialize) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000264 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.orgfb547e02014-05-23 00:04:50 +0000265 CcTest::i_isolate()->enable_serializer();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000266 v8::V8::Initialize();
267 Serialize();
268 }
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000269}
270
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000271
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000272// Test that heap serialization is non-destructive.
273TEST(SerializeTwice) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000274 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.orgfb547e02014-05-23 00:04:50 +0000275 CcTest::i_isolate()->enable_serializer();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000276 v8::V8::Initialize();
277 Serialize();
278 Serialize();
279 }
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000280}
281
282
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000283//----------------------------------------------------------------------------
284// Tests that the heap can be deserialized.
285
machenbach@chromium.org196eb602014-06-04 00:06:13 +0000286
287static void ReserveSpaceForSnapshot(Deserializer* deserializer,
288 const char* file_name) {
289 int file_name_length = StrLength(file_name) + 10;
290 Vector<char> name = Vector<char>::New(file_name_length + 1);
291 OS::SNPrintF(name, "%s.size", file_name);
292 FILE* fp = OS::FOpen(name.start(), "r");
293 name.Dispose();
294 int new_size, pointer_size, data_size, code_size, map_size, cell_size,
295 property_cell_size;
296#ifdef _MSC_VER
297 // Avoid warning about unsafe fscanf from MSVC.
298 // Please note that this is only fine if %c and %s are not being used.
299#define fscanf fscanf_s
300#endif
301 CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
302 CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
303 CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
304 CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
305 CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
306 CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
307 CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
308#ifdef _MSC_VER
309#undef fscanf
310#endif
311 fclose(fp);
312 deserializer->set_reservation(NEW_SPACE, new_size);
313 deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
314 deserializer->set_reservation(OLD_DATA_SPACE, data_size);
315 deserializer->set_reservation(CODE_SPACE, code_size);
316 deserializer->set_reservation(MAP_SPACE, map_size);
317 deserializer->set_reservation(CELL_SPACE, cell_size);
318 deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
319}
320
321
322bool InitializeFromFile(const char* snapshot_file) {
323 int len;
324 byte* str = ReadBytes(snapshot_file, &len);
325 if (!str) return false;
326 bool success;
327 {
328 SnapshotByteSource source(str, len);
329 Deserializer deserializer(&source);
330 ReserveSpaceForSnapshot(&deserializer, snapshot_file);
331 success = V8::Initialize(&deserializer);
332 }
333 DeleteArray(str);
334 return success;
335}
336
337
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000338static void Deserialize() {
machenbach@chromium.org196eb602014-06-04 00:06:13 +0000339 CHECK(InitializeFromFile(FLAG_testing_serialization_file));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000340}
341
342
343static void SanityCheck() {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000344 Isolate* isolate = CcTest::i_isolate();
345 v8::HandleScope scope(CcTest::isolate());
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000346#ifdef VERIFY_HEAP
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000347 CcTest::heap()->Verify();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000348#endif
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000349 CHECK(isolate->global_object()->IsJSObject());
350 CHECK(isolate->native_context()->IsContext());
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000351 CHECK(CcTest::heap()->string_table()->IsStringTable());
machenbach@chromium.orga86d4162014-05-01 00:05:11 +0000352 isolate->factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000353}
354
355
iposva@chromium.org245aa852009-02-10 00:49:54 +0000356DEPENDENT_TEST(Deserialize, Serialize) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000357 // The serialize-deserialize tests only work if the VM is built without
358 // serialization. That doesn't matter. We don't need to be able to
359 // serialize a snapshot in a VM that is booted from a snapshot.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000360 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000361 v8::Isolate* isolate = CcTest::isolate();
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000362 v8::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000363 Deserialize();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000364
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000365 v8::Local<v8::Context> env = v8::Context::New(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000366 env->Enter();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000367
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000368 SanityCheck();
369 }
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000370}
371
372
373DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000374 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000375 v8::Isolate* isolate = CcTest::isolate();
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000376 v8::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000377 Deserialize();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000378
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000379 v8::Local<v8::Context> env = v8::Context::New(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000380 env->Enter();
ager@chromium.org3811b432009-10-28 14:53:37 +0000381
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000382 SanityCheck();
383 }
ager@chromium.org3811b432009-10-28 14:53:37 +0000384}
385
386
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000387DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000388 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000389 v8::Isolate* isolate = CcTest::isolate();
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000390 v8::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000391 Deserialize();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000392
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000393 v8::Local<v8::Context> env = v8::Context::New(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000394 env->Enter();
ager@chromium.org3811b432009-10-28 14:53:37 +0000395
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000396 const char* c_source = "\"1234\".length";
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000397 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000398 v8::Local<v8::Script> script = v8::Script::Compile(source);
399 CHECK_EQ(4, script->Run()->Int32Value());
400 }
ager@chromium.org3811b432009-10-28 14:53:37 +0000401}
402
403
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000404DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
405 SerializeTwice) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000406 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000407 v8::Isolate* isolate = CcTest::isolate();
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000408 v8::HandleScope scope(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000409 Deserialize();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000410
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000411 v8::Local<v8::Context> env = v8::Context::New(isolate);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000412 env->Enter();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000413
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000414 const char* c_source = "\"1234\".length";
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000415 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000416 v8::Local<v8::Script> script = v8::Script::Compile(source);
417 CHECK_EQ(4, script->Run()->Int32Value());
418 }
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000419}
420
421
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000422TEST(PartialSerialization) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000423 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000424 Isolate* isolate = CcTest::i_isolate();
machenbach@chromium.orgfb547e02014-05-23 00:04:50 +0000425 CcTest::i_isolate()->enable_serializer();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000426 v8::V8::Initialize();
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000427 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000428 Heap* heap = isolate->heap();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000429
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000430 v8::Persistent<v8::Context> env;
431 {
432 HandleScope scope(isolate);
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000433 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000434 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000435 ASSERT(!env.IsEmpty());
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000436 {
437 v8::HandleScope handle_scope(v8_isolate);
438 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
439 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000440 // Make sure all builtin scripts are cached.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000441 { HandleScope scope(isolate);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000442 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000443 isolate->bootstrapper()->NativesSourceLookup(i);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000444 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000445 }
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000446 heap->CollectAllGarbage(Heap::kNoGCFlags);
447 heap->CollectAllGarbage(Heap::kNoGCFlags);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000448
449 Object* raw_foo;
450 {
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000451 v8::HandleScope handle_scope(v8_isolate);
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000452 v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000453 ASSERT(!foo.IsEmpty());
454 raw_foo = *(v8::Utils::OpenHandle(*foo));
455 }
456
457 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
458 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
459 OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
460
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000461 {
462 v8::HandleScope handle_scope(v8_isolate);
463 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
464 }
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000465 env.Reset();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000466
467 FileByteSink startup_sink(startup_name.start());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000468 StartupSerializer startup_serializer(isolate, &startup_sink);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000469 startup_serializer.SerializeStrongReferences();
470
471 FileByteSink partial_sink(FLAG_testing_serialization_file);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000472 PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000473 p_ser.Serialize(&raw_foo);
474 startup_serializer.SerializeWeakReferences();
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000475
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000476 partial_sink.WriteSpaceUsed(
477 p_ser.CurrentAllocationAddress(NEW_SPACE),
478 p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
479 p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
480 p_ser.CurrentAllocationAddress(CODE_SPACE),
481 p_ser.CurrentAllocationAddress(MAP_SPACE),
danno@chromium.org41728482013-06-12 22:31:22 +0000482 p_ser.CurrentAllocationAddress(CELL_SPACE),
483 p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000484
485 startup_sink.WriteSpaceUsed(
486 startup_serializer.CurrentAllocationAddress(NEW_SPACE),
487 startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
488 startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
489 startup_serializer.CurrentAllocationAddress(CODE_SPACE),
490 startup_serializer.CurrentAllocationAddress(MAP_SPACE),
danno@chromium.org41728482013-06-12 22:31:22 +0000491 startup_serializer.CurrentAllocationAddress(CELL_SPACE),
492 startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000493 startup_name.Dispose();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000494 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000495}
496
497
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000498DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
machenbach@chromium.org196eb602014-06-04 00:06:13 +0000499 if (!Snapshot::HaveASnapshotToStartFrom()) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000500 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
501 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
502 OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
503
machenbach@chromium.org196eb602014-06-04 00:06:13 +0000504 CHECK(InitializeFromFile(startup_name.start()));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000505 startup_name.Dispose();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000506
507 const char* file_name = FLAG_testing_serialization_file;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000508
509 int snapshot_size = 0;
510 byte* snapshot = ReadBytes(file_name, &snapshot_size);
511
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000512 Isolate* isolate = CcTest::i_isolate();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000513 Object* root;
514 {
515 SnapshotByteSource source(snapshot, snapshot_size);
516 Deserializer deserializer(&source);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000517 ReserveSpaceForSnapshot(&deserializer, file_name);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000518 deserializer.DeserializePartial(isolate, &root);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000519 CHECK(root->IsString());
520 }
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000521 HandleScope handle_scope(isolate);
522 Handle<Object> root_handle(root, isolate);
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +0000523
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000524
525 Object* root2;
526 {
527 SnapshotByteSource source(snapshot, snapshot_size);
528 Deserializer deserializer(&source);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000529 ReserveSpaceForSnapshot(&deserializer, file_name);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000530 deserializer.DeserializePartial(isolate, &root2);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000531 CHECK(root2->IsString());
532 CHECK(*root_handle == root2);
533 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000534 }
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000535}
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000536
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000537
538TEST(ContextSerialization) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000539 if (!Snapshot::HaveASnapshotToStartFrom()) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000540 Isolate* isolate = CcTest::i_isolate();
machenbach@chromium.orgfb547e02014-05-23 00:04:50 +0000541 CcTest::i_isolate()->enable_serializer();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000542 v8::V8::Initialize();
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000543 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000544 Heap* heap = isolate->heap();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000545
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000546 v8::Persistent<v8::Context> env;
547 {
548 HandleScope scope(isolate);
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000549 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000550 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000551 ASSERT(!env.IsEmpty());
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000552 {
553 v8::HandleScope handle_scope(v8_isolate);
554 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
555 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000556 // Make sure all builtin scripts are cached.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000557 { HandleScope scope(isolate);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000558 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000559 isolate->bootstrapper()->NativesSourceLookup(i);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000560 }
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000561 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000562 // If we don't do this then we end up with a stray root pointing at the
563 // context even after we have disposed of env.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000564 heap->CollectAllGarbage(Heap::kNoGCFlags);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000565
566 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
567 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
568 OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
569
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000570 {
571 v8::HandleScope handle_scope(v8_isolate);
572 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
573 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000574
danno@chromium.orgf95d4b92013-06-13 14:40:17 +0000575 i::Object* raw_context = *v8::Utils::OpenPersistent(env);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000576
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000577 env.Reset();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000578
579 FileByteSink startup_sink(startup_name.start());
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000580 StartupSerializer startup_serializer(isolate, &startup_sink);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000581 startup_serializer.SerializeStrongReferences();
582
583 FileByteSink partial_sink(FLAG_testing_serialization_file);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000584 PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000585 p_ser.Serialize(&raw_context);
586 startup_serializer.SerializeWeakReferences();
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000587
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000588 partial_sink.WriteSpaceUsed(
589 p_ser.CurrentAllocationAddress(NEW_SPACE),
590 p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
591 p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
592 p_ser.CurrentAllocationAddress(CODE_SPACE),
593 p_ser.CurrentAllocationAddress(MAP_SPACE),
danno@chromium.org41728482013-06-12 22:31:22 +0000594 p_ser.CurrentAllocationAddress(CELL_SPACE),
595 p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000596
597 startup_sink.WriteSpaceUsed(
598 startup_serializer.CurrentAllocationAddress(NEW_SPACE),
599 startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
600 startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
601 startup_serializer.CurrentAllocationAddress(CODE_SPACE),
602 startup_serializer.CurrentAllocationAddress(MAP_SPACE),
danno@chromium.org41728482013-06-12 22:31:22 +0000603 startup_serializer.CurrentAllocationAddress(CELL_SPACE),
604 startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000605 startup_name.Dispose();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000606 }
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000607}
608
609
610DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000611 if (!Snapshot::HaveASnapshotToStartFrom()) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000612 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
613 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
614 OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
615
machenbach@chromium.org196eb602014-06-04 00:06:13 +0000616 CHECK(InitializeFromFile(startup_name.start()));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000617 startup_name.Dispose();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000618
619 const char* file_name = FLAG_testing_serialization_file;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000620
621 int snapshot_size = 0;
622 byte* snapshot = ReadBytes(file_name, &snapshot_size);
623
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000624 Isolate* isolate = CcTest::i_isolate();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000625 Object* root;
626 {
627 SnapshotByteSource source(snapshot, snapshot_size);
628 Deserializer deserializer(&source);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000629 ReserveSpaceForSnapshot(&deserializer, file_name);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000630 deserializer.DeserializePartial(isolate, &root);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000631 CHECK(root->IsContext());
632 }
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000633 HandleScope handle_scope(isolate);
634 Handle<Object> root_handle(root, isolate);
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +0000635
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000636
637 Object* root2;
638 {
639 SnapshotByteSource source(snapshot, snapshot_size);
640 Deserializer deserializer(&source);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000641 ReserveSpaceForSnapshot(&deserializer, file_name);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000642 deserializer.DeserializePartial(isolate, &root2);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000643 CHECK(root2->IsContext());
644 CHECK(*root_handle != root2);
645 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000646 }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000647}
648
649
ager@chromium.org3811b432009-10-28 14:53:37 +0000650TEST(TestThatAlwaysSucceeds) {
651}
652
653
654TEST(TestThatAlwaysFails) {
655 bool ArtificialFailure = false;
656 CHECK(ArtificialFailure);
657}
658
659
660DEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) {
661 bool ArtificialFailure2 = false;
662 CHECK(ArtificialFailure2);
663}