The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-serialize.cc @ 40c0f755

History | View | Annotate | Download (8.97 KB)

1
// Copyright 2007-2008 the V8 project authors. All rights reserved.
2
// 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>
29
#include <map>
30
#include <string>
31

    
32
#include "sys/stat.h"
33
#include "v8.h"
34

    
35
#include "debug.h"
36
#include "ic-inl.h"
37
#include "runtime.h"
38
#include "serialize.h"
39
#include "scopeinfo.h"
40
#include "snapshot.h"
41
#include "cctest.h"
42

    
43
using namespace v8::internal;
44

    
45
static int local_counters[256];
46
static int counter_count = 0;
47
static std::map<std::string, int> counter_table;
48

    
49

    
50
// Callback receiver to track counters in test.
51
static int* counter_function(const char* name) {
52
  std::string counter(name);
53
  if (counter_table.find(counter) == counter_table.end()) {
54
    local_counters[counter_count] = 0;
55
    counter_table[counter] = counter_count++;
56
  }
57

    
58
  return &local_counters[counter_table[counter]];
59
}
60

    
61

    
62
template <class T>
63
static Address AddressOf(T id) {
64
  return ExternalReference(id).address();
65
}
66

    
67

    
68
template <class T>
69
static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) {
70
  return encoder.Encode(AddressOf(id));
71
}
72

    
73

    
74
static int make_code(TypeCode type, int id) {
75
  return static_cast<uint32_t>(type) << kReferenceTypeShift | id;
76
}
77

    
78

    
79
static int register_code(int reg) {
80
  return Debug::k_register_address << kDebugIdShift | reg;
81
}
82

    
83

    
84
TEST(ExternalReferenceEncoder) {
85
  StatsTable::SetCounterFunction(counter_function);
86
  Heap::Setup(false);
87
  ExternalReferenceEncoder encoder;
88
  CHECK_EQ(make_code(BUILTIN, Builtins::ArrayCode),
89
           Encode(encoder, Builtins::ArrayCode));
90
  CHECK_EQ(make_code(RUNTIME_FUNCTION, Runtime::kAbort),
91
           Encode(encoder, Runtime::kAbort));
92
  CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
93
           Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
94
  CHECK_EQ(make_code(DEBUG_ADDRESS, register_code(3)),
95
           Encode(encoder, Debug_Address(Debug::k_register_address, 3)));
96
  ExternalReference keyed_load_function_prototype =
97
      ExternalReference(&Counters::keyed_load_function_prototype);
98
  CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
99
           encoder.Encode(keyed_load_function_prototype.address()));
100
  ExternalReference passed_function =
101
      ExternalReference::builtin_passed_function();
102
  CHECK_EQ(make_code(UNCLASSIFIED, 1),
103
           encoder.Encode(passed_function.address()));
104
  ExternalReference the_hole_value_location =
105
      ExternalReference::the_hole_value_location();
106
  CHECK_EQ(make_code(UNCLASSIFIED, 2),
107
           encoder.Encode(the_hole_value_location.address()));
108
  ExternalReference stack_guard_limit_address =
109
      ExternalReference::address_of_stack_guard_limit();
110
  CHECK_EQ(make_code(UNCLASSIFIED, 3),
111
           encoder.Encode(stack_guard_limit_address.address()));
112
  CHECK_EQ(make_code(UNCLASSIFIED, 5),
113
           encoder.Encode(ExternalReference::debug_break().address()));
114
  CHECK_EQ(make_code(UNCLASSIFIED, 6),
115
           encoder.Encode(ExternalReference::new_space_start().address()));
116
}
117

    
118

    
119
TEST(ExternalReferenceDecoder) {
120
  StatsTable::SetCounterFunction(counter_function);
121
  Heap::Setup(false);
122
  ExternalReferenceDecoder decoder;
123
  CHECK_EQ(AddressOf(Builtins::ArrayCode),
124
           decoder.Decode(make_code(BUILTIN, Builtins::ArrayCode)));
125
  CHECK_EQ(AddressOf(Runtime::kAbort),
126
           decoder.Decode(make_code(RUNTIME_FUNCTION, Runtime::kAbort)));
127
  CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
128
           decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
129
  CHECK_EQ(AddressOf(Debug_Address(Debug::k_register_address, 3)),
130
           decoder.Decode(make_code(DEBUG_ADDRESS, register_code(3))));
131
  ExternalReference keyed_load_function =
132
      ExternalReference(&Counters::keyed_load_function_prototype);
133
  CHECK_EQ(keyed_load_function.address(),
134
           decoder.Decode(
135
               make_code(STATS_COUNTER,
136
                         Counters::k_keyed_load_function_prototype)));
137
  CHECK_EQ(ExternalReference::builtin_passed_function().address(),
138
           decoder.Decode(make_code(UNCLASSIFIED, 1)));
139
  CHECK_EQ(ExternalReference::the_hole_value_location().address(),
140
           decoder.Decode(make_code(UNCLASSIFIED, 2)));
141
  CHECK_EQ(ExternalReference::address_of_stack_guard_limit().address(),
142
           decoder.Decode(make_code(UNCLASSIFIED, 3)));
143
  CHECK_EQ(ExternalReference::debug_break().address(),
144
           decoder.Decode(make_code(UNCLASSIFIED, 5)));
145
  CHECK_EQ(ExternalReference::new_space_start().address(),
146
           decoder.Decode(make_code(UNCLASSIFIED, 6)));
147
}
148

    
149

    
150
static void Serialize() {
151
#ifdef DEBUG
152
  FLAG_debug_serialization = true;
153
#endif
154
  StatsTable::SetCounterFunction(counter_function);
155

    
156
  v8::HandleScope scope;
157
  const int kExtensionCount = 1;
158
  const char* extension_list[kExtensionCount] = { "v8/gc" };
159
  v8::ExtensionConfiguration extensions(kExtensionCount, extension_list);
160
  Serializer::Enable();
161
  v8::Persistent<v8::Context> env = v8::Context::New(&extensions);
162
  env->Enter();
163

    
164
  Snapshot::WriteToFile(FLAG_testing_serialization_file);
165
}
166

    
167

    
168
// Test that the whole heap can be serialized when running from the
169
// internal snapshot.
170
// (Smoke test.)
171
TEST(SerializeInternal) {
172
  Snapshot::Initialize(NULL);
173
  Serialize();
174
}
175

    
176

    
177
// Test that the whole heap can be serialized when running from a
178
// bootstrapped heap.
179
// (Smoke test.)
180
TEST(Serialize) {
181
  if (Snapshot::IsEnabled()) return;
182
  Serialize();
183
}
184

    
185

    
186
// Test that the heap isn't destroyed after a serialization.
187
TEST(SerializeNondestructive) {
188
  if (Snapshot::IsEnabled()) return;
189
  StatsTable::SetCounterFunction(counter_function);
190
  v8::HandleScope scope;
191
  Serializer::Enable();
192
  v8::Persistent<v8::Context> env = v8::Context::New();
193
  v8::Context::Scope context_scope(env);
194
  Serializer().Serialize();
195
  const char* c_source = "\"abcd\".charAt(2) == 'c'";
196
  v8::Local<v8::String> source = v8::String::New(c_source);
197
  v8::Local<v8::Script> script = v8::Script::Compile(source);
198
  v8::Local<v8::Value> value = script->Run();
199
  CHECK(value->BooleanValue());
200
}
201

    
202
//----------------------------------------------------------------------------
203
// Tests that the heap can be deserialized.
204

    
205
static void Deserialize() {
206
#ifdef DEBUG
207
  FLAG_debug_serialization = true;
208
#endif
209
  CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
210
}
211

    
212

    
213
static void SanityCheck() {
214
  v8::HandleScope scope;
215
#ifdef DEBUG
216
  Heap::Verify();
217
#endif
218
  CHECK(Top::global()->IsJSObject());
219
  CHECK(Top::global_context()->IsContext());
220
  CHECK(Top::special_function_table()->IsFixedArray());
221
  CHECK(Heap::symbol_table()->IsSymbolTable());
222
  CHECK(!Factory::LookupAsciiSymbol("Empty")->IsFailure());
223
}
224

    
225

    
226
DEPENDENT_TEST(Deserialize, Serialize) {
227
  v8::HandleScope scope;
228

    
229
  Deserialize();
230

    
231
  SanityCheck();
232
}
233

    
234
DEPENDENT_TEST(DeserializeAndRunScript, Serialize) {
235
  v8::HandleScope scope;
236

    
237
  Deserialize();
238

    
239
  const char* c_source = "\"1234\".length";
240
  v8::Local<v8::String> source = v8::String::New(c_source);
241
  v8::Local<v8::Script> script = v8::Script::Compile(source);
242
  CHECK_EQ(4, script->Run()->Int32Value());
243
}
244

    
245

    
246
DEPENDENT_TEST(DeserializeNatives, Serialize) {
247
  v8::HandleScope scope;
248

    
249
  Deserialize();
250

    
251
  const char* c_source = "\"abcd\".charAt(2) == 'c'";
252
  v8::Local<v8::String> source = v8::String::New(c_source);
253
  v8::Local<v8::Script> script = v8::Script::Compile(source);
254
  v8::Local<v8::Value> value = script->Run();
255
  CHECK(value->BooleanValue());
256
}
257

    
258

    
259
DEPENDENT_TEST(DeserializeExtensions, Serialize) {
260
  v8::HandleScope scope;
261

    
262
  Deserialize();
263
  const char* c_source = "gc();";
264
  v8::Local<v8::String> source = v8::String::New(c_source);
265
  v8::Local<v8::Script> script = v8::Script::Compile(source);
266
  v8::Local<v8::Value> value = script->Run();
267
  CHECK(value->IsUndefined());
268
}