Revision: 3184
Author: [email protected]
Date: Fri Oct 30 03:23:12 2009
Log: Introduce a switch for the new snapshot code and switch
it on by default. Includes bug fixes for new snapshots.
Review URL: http://codereview.chromium.org/342054
http://code.google.com/p/v8/source/detail?r=3184
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/global-handles.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/mksnapshot.cc
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/serialize.h
/branches/bleeding_edge/src/snapshot-common.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/test/cctest/test-serialize.cc
=======================================
--- /branches/bleeding_edge/src/api.cc Tue Oct 27 01:13:59 2009
+++ /branches/bleeding_edge/src/api.cc Fri Oct 30 03:23:12 2009
@@ -2621,11 +2621,12 @@
if (i::V8::IsRunning()) return true;
ENTER_V8;
HandleScope scope;
- if (i::Snapshot::Initialize()) {
- return true;
+ if (i::FLAG_new_snapshot) {
+ if (i::Snapshot::Initialize2()) return true;
} else {
- return i::V8::Initialize(NULL);
- }
+ if (i::Snapshot::Initialize()) return true;
+ }
+ return i::V8::Initialize(NULL);
}
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Wed Oct 28 05:37:54 2009
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Fri Oct 30 03:23:12 2009
@@ -437,13 +437,25 @@
INLINE(static Address target_address_at(Address pc));
INLINE(static void set_target_address_at(Address pc, Address target));
- // Modify the code target address in a constant pool entry.
- inline static void set_target_at(Address constant_pool_entry, Address
target);
+ // This sets the branch destination (which is in the constant pool on
ARM).
+ // This is for calls and branches within generated code.
+ inline static void set_target_at(Address constant_pool_entry,
+ Address target) {
+ set_target_address_at(constant_pool_entry, target);
+ }
+
+ // This sets the branch destination (which is in the constant pool on
ARM).
+ // This is for calls and branches to runtime code.
+ inline static void set_external_target_at(Address constant_pool_entry,
+ Address target) {
+ set_target_address_at(constant_pool_entry, target);
+ }
// Here we are patching the address in the constant pool, not the actual
call
// instruction. The address in the constant pool is the same size as a
// pointer.
static const int kCallTargetSize = kPointerSize;
+ static const int kExternalTargetSize = kPointerSize;
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Tue Oct 27 07:56:50 2009
+++ /branches/bleeding_edge/src/flag-definitions.h Fri Oct 30 03:23:12 2009
@@ -196,6 +196,7 @@
// mksnapshot.cc
DEFINE_bool(h, false, "print this message")
+DEFINE_bool(new_snapshot, true, "use new snapshot implementation")
// parser.cc
DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
=======================================
--- /branches/bleeding_edge/src/global-handles.cc Mon Oct 26 05:54:41 2009
+++ /branches/bleeding_edge/src/global-handles.cc Fri Oct 30 03:23:12 2009
@@ -398,6 +398,7 @@
}
}
}
+
void GlobalHandles::TearDown() {
// Reset all the lists.
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Wed Oct 28 05:37:54
2009
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Fri Oct 30 03:23:12
2009
@@ -440,12 +440,21 @@
inline static void set_target_address_at(Address pc, Address target);
// This sets the branch destination (which is in the instruction on x86).
+ // This is for calls and branches within generated code.
inline static void set_target_at(Address instruction_payload,
Address target) {
set_target_address_at(instruction_payload, target);
}
+
+ // This sets the branch destination (which is in the instruction on x86).
+ // This is for calls and branches to runtime code.
+ inline static void set_external_target_at(Address instruction_payload,
+ Address target) {
+ set_target_address_at(instruction_payload, target);
+ }
static const int kCallTargetSize = kPointerSize;
+ static const int kExternalTargetSize = kPointerSize;
// Distance between the address of the code target in the call
instruction
// and the return address
=======================================
--- /branches/bleeding_edge/src/mksnapshot.cc Mon Aug 24 19:54:39 2009
+++ /branches/bleeding_edge/src/mksnapshot.cc Fri Oct 30 03:23:12 2009
@@ -109,6 +109,48 @@
}
+class CppByteSink : public i::SnapshotByteSink {
+ public:
+ explicit CppByteSink(const char* snapshot_file) : bytes_written_(0) {
+ fp_ = i::OS::FOpen(snapshot_file, "wb");
+ if (fp_ == NULL) {
+ i::PrintF("Unable to write to snapshot file \"%s\"\n",
snapshot_file);
+ exit(1);
+ }
+ fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n");
+ fprintf(fp_, "#include \"v8.h\"\n");
+ fprintf(fp_, "#include \"platform.h\"\n\n");
+ fprintf(fp_, "#include \"snapshot.h\"\n\n");
+ fprintf(fp_, "namespace v8 {\nnamespace internal {\n\n");
+ fprintf(fp_, "const byte Snapshot::data_[] = {");
+ }
+
+ virtual ~CppByteSink() {
+ if (fp_ != NULL) {
+ fprintf(fp_, "};\n\n");
+ fprintf(fp_, "int Snapshot::size_ = %d;\n\n", bytes_written_);
+ fprintf(fp_, "} } // namespace v8::internal\n");
+ fclose(fp_);
+ }
+ }
+
+ virtual void Put(int byte, const char* description) {
+ if (bytes_written_ != 0) {
+ fprintf(fp_, ",");
+ }
+ fprintf(fp_, "%d", byte);
+ bytes_written_++;
+ if ((bytes_written_ & 0x3f) == 0) {
+ fprintf(fp_, "\n");
+ }
+ }
+
+ private:
+ FILE* fp_;
+ int bytes_written_;
+};
+
+
// 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,
@@ -116,7 +158,7 @@
int size) {
FILE* f = i::OS::FOpen(filename, "wb");
if (f == NULL) {
- i::OS::PrintError("Cannot open file %s for reading.\n", filename);
+ i::OS::PrintError("Cannot open file %s for writing.\n", filename);
return 0;
}
fprintf(f, "// Autogenerated snapshot file. Do not edit.\n\n");
@@ -138,6 +180,23 @@
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);
+ ser.Serialize();
+ return 0;
+}
int main(int argc, char** argv) {
@@ -153,6 +212,10 @@
i::FlagList::PrintHelp();
return !i::FLAG_help;
}
+
+ if (i::FLAG_new_snapshot) {
+ return main2(argc, argv);
+ }
v8::V8::SetCounterFunction(counter_callback);
v8::HandleScope scope;
=======================================
--- /branches/bleeding_edge/src/serialize.cc Wed Oct 28 05:37:54 2009
+++ /branches/bleeding_edge/src/serialize.cc Fri Oct 30 03:23:12 2009
@@ -1927,10 +1927,8 @@
case RAW_DATA_SERIALIZATION: {
int size = source_->GetInt();
byte* raw_data_out = reinterpret_cast<byte*>(current);
- for (int j = 0; j < size; j++) {
- *raw_data_out++ = source_->Get();
- }
- current = reinterpret_cast<Object**>(raw_data_out);
+ source_->CopyRaw(raw_data_out, size);
+ current = reinterpret_cast<Object**>(raw_data_out + size);
break;
}
case OBJECT_SERIALIZATION: {
@@ -1984,6 +1982,15 @@
*current++ = reinterpret_cast<Object*>(address);
break;
}
+ case EXTERNAL_BRANCH_TARGET_SERIALIZATION: {
+ int reference_id = source_->GetInt();
+ Address address =
external_reference_decoder_->Decode(reference_id);
+ Address location_of_branch_data =
reinterpret_cast<Address>(current);
+ Assembler::set_external_target_at(location_of_branch_data,
address);
+ location_of_branch_data += Assembler::kExternalTargetSize;
+ current = reinterpret_cast<Object**>(location_of_branch_data);
+ break;
+ }
default:
UNREACHABLE();
}
@@ -2157,6 +2164,18 @@
}
bytes_processed_so_far_ += (end - start) * kPointerSize;
}
+
+
+void Serializer2::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
+ Address target_start = rinfo->target_address_address();
+ OutputRawData(target_start);
+ Address target = rinfo->target_address();
+ uint32_t encoding = serializer_->EncodeExternalReference(target);
+ CHECK(target == NULL ? encoding == 0 : encoding != 0);
+ sink_->Put(EXTERNAL_BRANCH_TARGET_SERIALIZATION, "External reference");
+ sink_->PutInt(encoding, "reference id");
+ bytes_processed_so_far_ += Assembler::kExternalTargetSize;
+}
void Serializer2::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
@@ -2183,8 +2202,8 @@
unsigned int data = object_start[bytes_processed_so_far_ + i];
sink_->Put(data, "byte");
}
- }
- bytes_processed_so_far_ += skipped;
+ bytes_processed_so_far_ += skipped;
+ }
}
=======================================
--- /branches/bleeding_edge/src/serialize.h Tue Oct 27 04:54:01 2009
+++ /branches/bleeding_edge/src/serialize.h Fri Oct 30 03:23:12 2009
@@ -362,6 +362,11 @@
ASSERT(position_ < length_);
return data_[position_++];
}
+
+ void CopyRaw(byte* to, int number_of_bytes) {
+ memcpy(to, data_ + position_, number_of_bytes);
+ position_ += number_of_bytes;
+ }
int GetInt() {
// A little unwind to catch the really small ints.
@@ -405,6 +410,7 @@
BACKREF_SERIALIZATION,
CODE_BACKREF_SERIALIZATION,
EXTERNAL_REFERENCE_SERIALIZATION,
+ EXTERNAL_BRANCH_TARGET_SERIALIZATION,
SYNCHRONIZE
};
// Our Smi encoding is much more efficient for small positive integers
than it
@@ -521,6 +527,7 @@
void VisitPointers(Object** start, Object** end);
void VisitExternalReferences(Address* start, Address* end);
void VisitCodeTarget(RelocInfo* target);
+ void VisitRuntimeEntry(RelocInfo* reloc);
private:
void OutputRawData(Address up_to);
=======================================
--- /branches/bleeding_edge/src/snapshot-common.cc Tue Oct 27 06:19:14 2009
+++ /branches/bleeding_edge/src/snapshot-common.cc Fri Oct 30 03:23:12 2009
@@ -73,10 +73,12 @@
if (!str) return false;
Deserialize2(str, len);
DeleteArray(str);
+ return true;
} else if (size_ > 0) {
Deserialize2(data_, size_);
- }
- return true;
+ return true;
+ }
+ return false;
}
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Wed Oct 28 05:37:54 2009
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Fri Oct 30 03:23:12 2009
@@ -458,14 +458,25 @@
// the relative displacements stored in the code.
static inline Address target_address_at(Address pc);
static inline void set_target_address_at(Address pc, Address target);
+
// This sets the branch destination (which is in the instruction on x64).
+ // This is for calls and branches within generated code.
inline static void set_target_at(Address instruction_payload,
Address target) {
set_target_address_at(instruction_payload, target);
}
+
+ // This sets the branch destination (which is a load instruction on x64).
+ // This is for calls and branches to runtime code.
+ inline static void set_external_target_at(Address instruction_payload,
+ Address target) {
+ *reinterpret_cast<Address*>(instruction_payload) = target;
+ }
+
inline Handle<Object> code_target_object_handle_at(Address pc);
// Number of bytes taken up by the branch target in the code.
- static const int kCallTargetSize = 4; // Use 32-bit displacement.
+ static const int kCallTargetSize = 4; // Use 32-bit displacement.
+ static const int kExternalTargetSize = 8; // Use 64-bit absolute.
// Distance between the address of the code target in the call
instruction
// and the return address pushed on the stack.
static const int kCallTargetAddressOffset = 4; // Use 32-bit
displacement.
=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Tue Oct 27
04:54:01 2009
+++ /branches/bleeding_edge/test/cctest/test-serialize.cc Fri Oct 30
03:23:12 2009
@@ -195,15 +195,6 @@
env.Dispose();
Snapshot::WriteToFile2(FLAG_testing_serialization_file);
}
-
-
-// Test that the whole heap can be serialized when running from the
-// internal snapshot.
-// (Smoke test.)
-TEST(SerializeInternal) {
- Snapshot::Initialize(NULL);
- Serialize();
-}
// Test that the whole heap can be serialized when running from a
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---