* Remove old snapshot implementation

Review URL: http://codereview.chromium.org/394007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3307 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2009-11-16 12:08:40 +00:00
parent 5f3bdbe5a6
commit 64941f1cf9
13 changed files with 112 additions and 1857 deletions

View File

@ -2636,11 +2636,7 @@ bool v8::V8::Initialize() {
if (i::V8::IsRunning()) return true;
ENTER_V8;
HandleScope scope;
if (i::FLAG_new_snapshot) {
if (i::Snapshot::Initialize2()) return true;
} else {
if (i::Snapshot::Initialize()) return true;
}
if (i::Snapshot::Initialize()) return true;
return i::V8::Initialize(NULL);
}

View File

@ -471,12 +471,16 @@ class ExternalReference BASE_EMBEDDED {
static void* Redirect(void* address, bool fp_return = false) {
if (redirector_ == NULL) return address;
return (*redirector_)(address, fp_return);
void* answer = (*redirector_)(address, fp_return);
return answer;
}
static void* Redirect(Address address_arg, bool fp_return = false) {
void* address = reinterpret_cast<void*>(address_arg);
return redirector_ == NULL ? address : (*redirector_)(address, fp_return);
void* answer = (redirector_ == NULL) ?
address :
(*redirector_)(address, fp_return);
return answer;
}
void* address_;

View File

@ -36,6 +36,8 @@ static int fatal_error_handler_nesting_depth = 0;
// Contains protection against recursive calls (faults while handling faults).
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
fflush(stdout);
fflush(stderr);
fatal_error_handler_nesting_depth++;
// First time we try to print an error message
if (fatal_error_handler_nesting_depth < 2) {

View File

@ -252,7 +252,6 @@ class Variable;
class VariableProxy;
class RelocInfo;
class Deserializer;
class GenericDeserializer; // TODO(erikcorry): Get rid of this.
class MessageLocation;
class ObjectGroup;
class TickSample;

View File

@ -87,27 +87,12 @@ class CounterCollection {
// We statically allocate a set of local counters to be used if we
// don't want to store the stats in a memory-mapped file
static CounterCollection local_counters;
static CounterCollection* counters = &local_counters;
typedef std::map<std::string, int*> CounterMap;
typedef std::map<std::string, int*>::iterator CounterMapIterator;
static CounterMap counter_table_;
// Callback receiver when v8 has a counter to track.
static int* counter_callback(const char* name) {
std::string counter = name;
// See if this counter name is already known.
if (counter_table_.find(counter) != counter_table_.end())
return counter_table_[counter];
Counter* ctr = counters->GetNextCounter();
if (ctr == NULL) return NULL;
int* ptr = ctr->Bind(name);
counter_table_[counter] = ptr;
return ptr;
}
class CppByteSink : public i::SnapshotByteSink {
public:
@ -151,57 +136,6 @@ class CppByteSink : public i::SnapshotByteSink {
};
// Write C++ code that defines Snapshot::snapshot_ to contain the snapshot
// to the file given by filename. Only the first size chars are written.
static int WriteInternalSnapshotToFile(const char* filename,
const v8::internal::byte* bytes,
int size) {
FILE* f = i::OS::FOpen(filename, "wb");
if (f == NULL) {
i::OS::PrintError("Cannot open file %s for writing.\n", filename);
return 0;
}
fprintf(f, "// Autogenerated snapshot file. Do not edit.\n\n");
fprintf(f, "#include \"v8.h\"\n");
fprintf(f, "#include \"platform.h\"\n\n");
fprintf(f, "#include \"snapshot.h\"\n\n");
fprintf(f, "namespace v8 {\nnamespace internal {\n\n");
fprintf(f, "const byte Snapshot::data_[] = {");
int written = 0;
written += fprintf(f, "0x%x", bytes[0]);
for (int i = 1; i < size; ++i) {
written += fprintf(f, ",0x%x", bytes[i]);
// The following is needed to keep the line length low on Visual C++:
if (i % 512 == 0) fprintf(f, "\n");
}
fprintf(f, "};\n\n");
fprintf(f, "int Snapshot::size_ = %d;\n\n", size);
fprintf(f, "} } // namespace v8::internal\n");
fclose(f);
return written;
}
int main2(int argc, char** argv) {
i::Serializer::Enable();
Persistent<Context> context = v8::Context::New();
// Make sure all builtin scripts are cached.
{ HandleScope scope;
for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
i::Bootstrapper::NativesSourceLookup(i);
}
}
context.Dispose();
CppByteSink sink(argv[1]);
i::Serializer2 ser(&sink);
// This results in a somewhat smaller snapshot, probably because it gets rid
// of some things that are cached between garbage collections.
i::Heap::CollectAllGarbage(true);
ser.Serialize();
return 0;
}
int main(int argc, char** argv) {
#ifdef ENABLE_LOGGING_AND_PROFILING
// By default, log code create information in the snapshot.
@ -215,38 +149,20 @@ int main(int argc, char** argv) {
i::FlagList::PrintHelp();
return !i::FLAG_help;
}
if (i::FLAG_new_snapshot) {
return main2(argc, argv);
}
v8::V8::SetCounterFunction(counter_callback);
v8::HandleScope scope;
const int kExtensionCount = 1;
const char* extension_list[kExtensionCount] = { "v8/gc" };
v8::ExtensionConfiguration extensions(kExtensionCount, extension_list);
i::Serializer::Enable();
v8::Context::New(&extensions);
Persistent<Context> context = v8::Context::New();
// Make sure all builtin scripts are cached.
{ HandleScope scope;
for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
i::Bootstrapper::NativesSourceLookup(i);
}
}
// Get rid of unreferenced scripts with a global GC.
i::Heap::CollectAllGarbage(false);
i::Serializer ser;
context.Dispose();
CppByteSink sink(argv[1]);
i::Serializer ser(&sink);
// This results in a somewhat smaller snapshot, probably because it gets rid
// of some things that are cached between garbage collections.
i::Heap::CollectAllGarbage(true);
ser.Serialize();
v8::internal::byte* bytes;
int len;
ser.Finalize(&bytes, &len);
WriteInternalSnapshotToFile(argv[1], bytes, len);
i::DeleteArray(bytes);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -108,260 +108,6 @@ class ExternalReferenceDecoder {
};
// A Serializer recursively visits objects to construct a serialized
// representation of the Heap stored in a string. Serialization is
// destructive. We use a similar mechanism to the GC to ensure that
// each object is visited once, namely, we modify the map pointer of
// each visited object to contain the relative address in the
// appropriate space where that object will be allocated when the heap
// is deserialized.
// Helper classes defined in serialize.cc.
class RelativeAddress;
class SimulatedHeapSpace;
class SnapshotWriter;
class ReferenceUpdater;
class Serializer: public ObjectVisitor {
public:
Serializer();
virtual ~Serializer();
// Serialize the current state of the heap. This operation destroys the
// heap contents and the contents of the roots into the heap.
void Serialize();
// Returns the serialized buffer. Ownership is transferred to the
// caller. Only the destructor and getters may be called after this call.
void Finalize(byte** str, int* len);
int roots() { return roots_; }
int objects() { return objects_; }
#ifdef DEBUG
// insert "tag" into the serialized stream
virtual void Synchronize(const char* tag);
#endif
static bool enabled() { return serialization_enabled_; }
static void Enable() {
if (!serialization_enabled_) {
ASSERT(!too_late_to_enable_now_);
}
serialization_enabled_ = true;
}
static void Disable() { serialization_enabled_ = false; }
// Call this when you have made use of the fact that there is no serialization
// going on.
static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
private:
friend class ReferenceUpdater;
virtual void VisitPointers(Object** start, Object** end);
virtual void VisitCodeTarget(RelocInfo* rinfo);
bool IsVisited(HeapObject* obj);
Address GetSavedAddress(HeapObject* obj);
void SaveAddress(HeapObject* obj, Address addr);
void PutEncodedAddress(Address addr);
// Write the global flags into the file.
void PutFlags();
// Write global information into the header of the file.
void PutHeader();
// Write the contents of the log into the file.
void PutLog();
// Serialize 'obj', and return its encoded RelativeAddress.
Address PutObject(HeapObject* obj);
// Write a stack of handles to the file bottom first.
void PutGlobalHandleStack(const List<Handle<Object> >& stack);
// Write the context stack into the file.
void PutContextStack();
// Return the encoded RelativeAddress where this object will be
// allocated on deserialization. On the first visit of 'o',
// serialize its contents. On return, *serialized will be true iff
// 'o' has just been serialized.
Address Encode(Object* o, bool* serialized);
// Simulate the allocation of 'obj', returning the address where it will
// be allocated on deserialization
RelativeAddress Allocate(HeapObject* obj);
void InitializeAllocators();
SnapshotWriter* writer_;
bool root_; // serializing a root?
int roots_; // number of roots visited
int objects_; // number of objects serialized
static bool serialization_enabled_;
// Did we already make use of the fact that serialization was not enabled?
static bool too_late_to_enable_now_;
int flags_end_; // The position right after the flags.
// An array of per-space SimulatedHeapSpaces used as memory allocators.
SimulatedHeapSpace* allocator_[LAST_SPACE+1];
// A list of global handles at serialization time.
List<Object**> global_handles_;
ExternalReferenceEncoder* reference_encoder_;
HashMap saved_addresses_;
DISALLOW_COPY_AND_ASSIGN(Serializer);
};
// Helper class to read the bytes of the serialized heap.
class SnapshotReader {
public:
SnapshotReader(const byte* str, int len): str_(str), end_(str + len) {}
void ExpectC(char expected) {
int c = GetC();
USE(c);
ASSERT(c == expected);
}
int GetC() {
if (str_ >= end_) return EOF;
return *str_++;
}
int GetInt() {
int result;
GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
return result;
}
Address GetAddress() {
Address result;
GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
return result;
}
void GetBytes(Address a, int size) {
ASSERT(str_ + size <= end_);
memcpy(a, str_, size);
str_ += size;
}
char* GetString() {
ExpectC('[');
int size = GetInt();
ExpectC(']');
char* s = NewArray<char>(size + 1);
GetBytes(reinterpret_cast<Address>(s), size);
s[size] = 0;
return s;
}
private:
const byte* str_;
const byte* end_;
};
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
// TODO(erikcorry): Get rid of this superclass when we are using the new
// snapshot code exclusively.
class GenericDeserializer: public ObjectVisitor {
public:
virtual void GetLog() = 0;
virtual void Deserialize() = 0;
};
// TODO(erikcorry): Get rid of this class.
class Deserializer: public GenericDeserializer {
public:
// Create a deserializer. The snapshot is held in str and has size len.
Deserializer(const byte* str, int len);
virtual ~Deserializer();
// Read the flags from the header of the file, and set those that
// should be inherited from the snapshot.
void GetFlags();
// Read saved profiling information from the file and log it if required.
void GetLog();
// Deserialize the snapshot into an empty heap.
void Deserialize();
int roots() { return roots_; }
int objects() { return objects_; }
#ifdef DEBUG
// Check for the presence of "tag" in the serialized stream
virtual void Synchronize(const char* tag);
#endif
private:
virtual void VisitPointers(Object** start, Object** end);
virtual void VisitCodeTarget(RelocInfo* rinfo);
virtual void VisitExternalReferences(Address* start, Address* end);
virtual void VisitRuntimeEntry(RelocInfo* rinfo);
Address GetEncodedAddress();
// Read other global information (except flags) from the header of the file.
void GetHeader();
// Read a stack of handles from the file bottom first.
void GetGlobalHandleStack(List<Handle<Object> >* stack);
// Read the context stack from the file.
void GetContextStack();
Object* GetObject();
// Get the encoded address. In debug mode we make sure
// it matches the given expectations.
void ExpectEncodedAddress(Address expected);
// Given an encoded address (the result of
// RelativeAddress::Encode), return the object to which it points,
// which will be either an Smi or a HeapObject in the current heap.
Object* Resolve(Address encoded_address);
SnapshotReader reader_;
bool root_; // Deserializing a root?
int roots_; // number of roots visited
int objects_; // number of objects serialized
bool has_log_; // The file has log information.
// Resolve caches the following:
List<Page*> map_pages_; // All pages in the map space.
List<Page*> cell_pages_; // All pages in the cell space.
List<Page*> old_pointer_pages_; // All pages in the old pointer space.
List<Page*> old_data_pages_; // All pages in the old data space.
List<Page*> code_pages_; // All pages in the code space.
List<Object*> large_objects_; // All known large objects.
// A list of global handles at deserialization time.
List<Object**> global_handles_;
ExternalReferenceDecoder* reference_decoder_;
#ifdef DEBUG
bool expect_debug_information_;
#endif
DISALLOW_COPY_AND_ASSIGN(Deserializer);
};
class SnapshotByteSource {
public:
SnapshotByteSource(const byte* array, int length)
@ -407,6 +153,7 @@ class SnapshotByteSource {
int position_;
};
// It is very common to have a reference to the object at word 10 in space 2,
// the object at word 5 in space 2 and the object at word 28 in space 4. This
// only works for objects in the first page of a space.
@ -436,10 +183,9 @@ class SnapshotByteSource {
f(14, 32) \
f(15, 36)
// The SerDes class is a common superclass for Serializer2 and Deserializer2
// The SerDes class is a common superclass for Serializer and Deserializer
// which is used to store common constants and methods used by both.
// TODO(erikcorry): This should inherit from ObjectVisitor.
class SerDes: public GenericDeserializer {
class SerDes: public ObjectVisitor {
protected:
enum DataType {
RAW_DATA_SERIALIZATION = 0,
@ -483,16 +229,15 @@ class SerDes: public GenericDeserializer {
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
class Deserializer2: public SerDes {
class Deserializer: public SerDes {
public:
// Create a deserializer from a snapshot byte source.
explicit Deserializer2(SnapshotByteSource* source);
explicit Deserializer(SnapshotByteSource* source);
virtual ~Deserializer2() { }
virtual ~Deserializer() { }
// Deserialize the snapshot into an empty heap.
void Deserialize();
void GetLog() { } // TODO(erikcorry): Get rid of this.
#ifdef DEBUG
virtual void Synchronize(const char* tag);
#endif
@ -530,7 +275,7 @@ class Deserializer2: public SerDes {
// START_NEW_PAGE_SERIALIZATION tag.
Address last_object_address_;
DISALLOW_COPY_AND_ASSIGN(Deserializer2);
DISALLOW_COPY_AND_ASSIGN(Deserializer);
};
@ -545,15 +290,26 @@ class SnapshotByteSink {
};
class Serializer2 : public SerDes {
class Serializer : public SerDes {
public:
explicit Serializer2(SnapshotByteSink* sink);
explicit Serializer(SnapshotByteSink* sink);
// Serialize the current state of the heap. This operation destroys the
// heap contents.
void Serialize();
void VisitPointers(Object** start, Object** end);
void GetLog() { } // TODO(erikcorry): Get rid of this.
void Deserialize() { } // TODO(erikcorry): Get rid of this.
static void Enable() {
if (!serialization_enabled_) {
ASSERT(!too_late_to_enable_now_);
}
serialization_enabled_ = true;
}
static void Disable() { serialization_enabled_ = false; }
// Call this when you have made use of the fact that there is no serialization
// going on.
static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
static bool enabled() { return serialization_enabled_; }
#ifdef DEBUG
virtual void Synchronize(const char* tag);
#endif
@ -565,7 +321,7 @@ class Serializer2 : public SerDes {
};
class ObjectSerializer : public ObjectVisitor {
public:
ObjectSerializer(Serializer2* serializer,
ObjectSerializer(Serializer* serializer,
Object* o,
SnapshotByteSink* sink,
ReferenceRepresentation representation)
@ -591,7 +347,7 @@ class Serializer2 : public SerDes {
private:
void OutputRawData(Address up_to);
Serializer2* serializer_;
Serializer* serializer_;
HeapObject* object_;
SnapshotByteSink* sink_;
ReferenceRepresentation reference_representation_;
@ -626,11 +382,14 @@ class Serializer2 : public SerDes {
SnapshotByteSink* sink_;
int current_root_index_;
ExternalReferenceEncoder* external_reference_encoder_;
static bool serialization_enabled_;
// Did we already make use of the fact that serialization was not enabled?
static bool too_late_to_enable_now_;
friend class ObjectSerializer;
friend class Deserializer2;
friend class Deserializer;
DISALLOW_COPY_AND_ASSIGN(Serializer2);
DISALLOW_COPY_AND_ASSIGN(Serializer);
};
} } // namespace v8::internal

View File

@ -38,15 +38,8 @@ namespace v8 {
namespace internal {
bool Snapshot::Deserialize(const byte* content, int len) {
Deserializer des(content, len);
des.GetFlags();
return V8::Initialize(&des);
}
bool Snapshot::Deserialize2(const byte* content, int len) {
SnapshotByteSource source(content, len);
Deserializer2 deserializer(&source);
Deserializer deserializer(&source);
return V8::Initialize(&deserializer);
}
@ -56,46 +49,17 @@ bool Snapshot::Initialize(const char* snapshot_file) {
int len;
byte* str = ReadBytes(snapshot_file, &len);
if (!str) return false;
bool result = Deserialize(str, len);
DeleteArray(str);
return result;
} else if (size_ > 0) {
return Deserialize(data_, size_);
}
return false;
}
bool Snapshot::Initialize2(const char* snapshot_file) {
if (snapshot_file) {
int len;
byte* str = ReadBytes(snapshot_file, &len);
if (!str) return false;
Deserialize2(str, len);
Deserialize(str, len);
DeleteArray(str);
return true;
} else if (size_ > 0) {
Deserialize2(data_, size_);
Deserialize(data_, size_);
return true;
}
return false;
}
bool Snapshot::WriteToFile(const char* snapshot_file) {
Serializer ser;
ser.Serialize();
byte* str;
int len;
ser.Finalize(&str, &len);
int written = WriteBytes(snapshot_file, str, len);
DeleteArray(str);
return written == len;
}
class FileByteSink : public SnapshotByteSink {
public:
explicit FileByteSink(const char* snapshot_file) {
@ -121,9 +85,9 @@ class FileByteSink : public SnapshotByteSink {
};
bool Snapshot::WriteToFile2(const char* snapshot_file) {
bool Snapshot::WriteToFile(const char* snapshot_file) {
FileByteSink file(snapshot_file);
Serializer2 ser(&file);
Serializer ser(&file);
ser.Serialize();
return true;
}

View File

@ -37,7 +37,6 @@ class Snapshot {
// NULL, use the internal snapshot instead. Returns false if no snapshot
// could be found.
static bool Initialize(const char* snapshot_file = NULL);
static bool Initialize2(const char* snapshot_file = NULL);
// Returns whether or not the snapshot is enabled.
static bool IsEnabled() { return size_ != 0; }
@ -45,14 +44,12 @@ class Snapshot {
// Write snapshot to the given file. Returns true if snapshot was written
// successfully.
static bool WriteToFile(const char* snapshot_file);
static bool WriteToFile2(const char* snapshot_file);
private:
static const byte data_[];
static int size_;
static bool Deserialize(const byte* content, int len);
static bool Deserialize2(const byte* content, int len);
DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
};

View File

@ -43,7 +43,7 @@ bool V8::has_been_setup_ = false;
bool V8::has_been_disposed_ = false;
bool V8::has_fatal_error_ = false;
bool V8::Initialize(GenericDeserializer *des) {
bool V8::Initialize(Deserializer *des) {
bool create_heap_objects = des == NULL;
if (has_been_disposed_ || has_fatal_error_) return false;
if (IsRunning()) return true;
@ -59,7 +59,6 @@ bool V8::Initialize(GenericDeserializer *des) {
// Enable logging before setting up the heap
Logger::Setup();
if (des) des->GetLog();
// Setup the platform OS support.
OS::Setup();

View File

@ -72,6 +72,8 @@
namespace v8 {
namespace internal {
class Deserializer;
class V8 : public AllStatic {
public:
// Global actions.
@ -80,7 +82,7 @@ class V8 : public AllStatic {
// created from scratch. If a non-null Deserializer is given, the
// initial state is created by reading the deserialized data into an
// empty heap.
static bool Initialize(GenericDeserializer* des);
static bool Initialize(Deserializer* des);
static void TearDown();
static bool IsRunning() { return is_running_; }
// To be dead you have to have lived

View File

@ -33,12 +33,6 @@ test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux
# BUG(382): Weird test. Can't guarantee that it never times out.
test-api/ApplyInterruption: PASS || TIMEOUT
# This is about to go away anyway since new snapshot code is on the way.
test-serialize/Deserialize: FAIL
test-serialize/DeserializeAndRunScript: FAIL || CRASH
test-serialize/DeserializeNatives: FAIL || CRASH
test-serialize/DeserializeExtensions: FAIL || CRASH
# These tests always fail. They are here to test test.py. If
# they don't fail then test.py has failed.
test-serialize/TestThatAlwaysFails: FAIL

View File

@ -174,83 +174,32 @@ TEST(ExternalReferenceDecoder) {
static void Serialize() {
#ifdef DEBUG
FLAG_debug_serialization = true;
#endif
StatsTable::SetCounterFunction(counter_function);
v8::HandleScope scope;
const int kExtensionCount = 1;
const char* extension_list[kExtensionCount] = { "v8/gc" };
v8::ExtensionConfiguration extensions(kExtensionCount, extension_list);
Serializer::Enable();
v8::Persistent<v8::Context> env = v8::Context::New(&extensions);
env->Enter();
Snapshot::WriteToFile(FLAG_testing_serialization_file);
}
static void Serialize2() {
// We have to create one context. One reason for this is so that the builtins
// can be loaded from v8natives.js and their addresses can be processed. This
// will clear the pending fixups array, which would otherwise contain GC roots
// that would confuse the serialization/deserialization process.
v8::Persistent<v8::Context> env = v8::Context::New();
env.Dispose();
Snapshot::WriteToFile2(FLAG_testing_serialization_file);
}
// Test that the whole heap can be serialized when running from a
// bootstrapped heap.
// (Smoke test.)
TEST(Serialize) {
if (Snapshot::IsEnabled()) return;
Serialize();
Snapshot::WriteToFile(FLAG_testing_serialization_file);
}
// Test that the whole heap can be serialized.
TEST(Serialize2) {
TEST(Serialize) {
Serializer::Enable();
v8::V8::Initialize();
Serialize2();
Serialize();
}
// Test that the heap isn't destroyed after a serialization.
TEST(SerializeNondestructive) {
if (Snapshot::IsEnabled()) return;
StatsTable::SetCounterFunction(counter_function);
v8::HandleScope scope;
Serializer::Enable();
v8::Persistent<v8::Context> env = v8::Context::New();
v8::Context::Scope context_scope(env);
Serializer().Serialize();
const char* c_source = "\"abcd\".charAt(2) == 'c'";
v8::Local<v8::String> source = v8::String::New(c_source);
v8::Local<v8::Script> script = v8::Script::Compile(source);
v8::Local<v8::Value> value = script->Run();
CHECK(value->BooleanValue());
}
//----------------------------------------------------------------------------
// Tests that the heap can be deserialized.
static void Deserialize() {
#ifdef DEBUG
FLAG_debug_serialization = true;
#endif
CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
}
static void Deserialize2() {
CHECK(Snapshot::Initialize2(FLAG_testing_serialization_file));
}
static void SanityCheck() {
v8::HandleScope scope;
#ifdef DEBUG
@ -269,15 +218,6 @@ DEPENDENT_TEST(Deserialize, Serialize) {
Deserialize();
SanityCheck();
}
DEPENDENT_TEST(Deserialize2, Serialize2) {
v8::HandleScope scope;
Deserialize2();
fflush(stdout);
v8::Persistent<v8::Context> env = v8::Context::New();
@ -287,23 +227,11 @@ DEPENDENT_TEST(Deserialize2, Serialize2) {
}
DEPENDENT_TEST(DeserializeAndRunScript, Serialize) {
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
v8::HandleScope scope;
Deserialize();
const char* c_source = "\"1234\".length";
v8::Local<v8::String> source = v8::String::New(c_source);
v8::Local<v8::Script> script = v8::Script::Compile(source);
CHECK_EQ(4, script->Run()->Int32Value());
}
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize2) {
v8::HandleScope scope;
Deserialize2();
v8::Persistent<v8::Context> env = v8::Context::New();
env->Enter();
@ -314,31 +242,6 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize2) {
}
DEPENDENT_TEST(DeserializeNatives, Serialize) {
v8::HandleScope scope;
Deserialize();
const char* c_source = "\"abcd\".charAt(2) == 'c'";
v8::Local<v8::String> source = v8::String::New(c_source);
v8::Local<v8::Script> script = v8::Script::Compile(source);
v8::Local<v8::Value> value = script->Run();
CHECK(value->BooleanValue());
}
DEPENDENT_TEST(DeserializeExtensions, Serialize) {
v8::HandleScope scope;
Deserialize();
const char* c_source = "gc();";
v8::Local<v8::String> source = v8::String::New(c_source);
v8::Local<v8::Script> script = v8::Script::Compile(source);
v8::Local<v8::Value> value = script->Run();
CHECK(value->IsUndefined());
}
TEST(TestThatAlwaysSucceeds) {
}