v8_postmortem_support = false
v8_use_default_platform = true
v8_use_snapshot = true
-v8_use_external_startup_data = false
v8_enable_extra_checks = is_debug
v8_target_arch = cpu_arch
v8_random_seed = "314159265"
"ENABLE_HANDLE_ZAPPING",
]
}
- if (v8_use_external_startup_data == true) {
- defines += [
- "V8_USE_EXTERNAL_STARTUP_DATA",
- ]
- }
}
config("toolchain") {
"$target_gen_dir/experimental-libraries.cc",
"$target_gen_dir/trig-table.cc",
"src/snapshot-empty.cc",
- "src/snapshot-common.cc",
]
configs -= [ "//build/config/compiler:chromium_code" ]
"src/serialize.h",
"src/small-pointer-list.h",
"src/smart-pointers.h",
- "src/snapshot-source-sink.cc",
- "src/snapshot-source-sink.h",
+ "src/snapshot-common.cc",
"src/snapshot.h",
"src/spaces-inl.h",
"src/spaces.cc",
# Use the v8 provided v8::Platform implementation.
'v8_use_default_platform%': 1,
-
- # Use external files for startup data blobs:
- # the JS builtins sources and the start snapshot.
- 'v8_use_external_startup_data%': 0,
},
'target_defaults': {
'conditions': [
'defines': ['V8_USE_DEFAULT_PLATFORM',],
}],
['v8_compress_startup_data=="bz2"', {
- 'defines': ['COMPRESS_STARTUP_DATA_BZ2',],
- }],
- ['v8_use_external_startup_data==1', {
- 'defines': ['V8_USE_EXTERNAL_STARTUP_DATA',],
+ 'defines': [
+ 'COMPRESS_STARTUP_DATA_BZ2',
+ ],
}],
], # conditions
'configurations': {
static void GetCompressedStartupData(StartupData* compressed_data);
static void SetDecompressedStartupData(StartupData* decompressed_data);
- /**
- * Hand startup data to V8, in case the embedder has chosen to build
- * V8 with external startup data.
- *
- * Note:
- * - By default the startup data is linked into the V8 library, in which
- * case this function is not meaningful.
- * - If this needs to be called, it needs to be called before V8
- * tries to make use of its built-ins.
- * - To avoid unnecessary copies of data, V8 will point directly into the
- * given data blob, so pretty please keep it around until V8 exit.
- * - Compression of the startup blob might be useful, but needs to
- * handled entirely on the embedders' side.
- * - The call will abort if the data is invalid.
- */
- static void SetNativesDataBlob(StartupData* startup_blob);
- static void SetSnapshotDataBlob(StartupData* startup_blob);
-
/**
* Adds a message listener.
*
#include "src/icu_util.h"
#include "src/json-parser.h"
#include "src/messages.h"
+#ifdef COMPRESS_STARTUP_DATA_BZ2
#include "src/natives.h"
+#endif
#include "src/parser.h"
#include "src/platform.h"
#include "src/platform/time.h"
}
-void V8::SetNativesDataBlob(StartupData* natives_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- i::SetNativesFromFile(natives_blob);
-#else
- CHECK(false);
-#endif
-}
-
-
-void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- i::SetSnapshotFromFile(snapshot_blob);
-#else
- CHECK(false);
-#endif
-}
-
-
void V8::SetFatalErrorHandler(FatalErrorCallback that) {
i::Isolate* isolate = i::Isolate::UncheckedCurrent();
isolate->set_exception_behavior(that);
return false;
}
#endif // V8_SHARED
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- else if (strncmp(argv[i], "--natives_blob=", 15) == 0) {
- options.natives_blob = argv[i] + 15;
- argv[i] = NULL;
- } else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) {
- options.snapshot_blob = argv[i] + 16;
- argv[i] = NULL;
- }
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
}
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
};
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-class StartupDataHandler {
- public:
- StartupDataHandler(const char* natives_blob,
- const char* snapshot_blob) {
- Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob);
- Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob);
- }
-
- ~StartupDataHandler() {
- delete[] natives_.data;
- delete[] snapshot_.data;
- }
-
- private:
- void Load(const char* blob_file,
- v8::StartupData* startup_data,
- void (*setter_fn)(v8::StartupData*)) {
- startup_data->data = NULL;
- startup_data->compressed_size = 0;
- startup_data->raw_size = 0;
-
- if (!blob_file)
- return;
-
- FILE* file = fopen(blob_file, "rb");
- if (!file)
- return;
-
- fseek(file, 0, SEEK_END);
- startup_data->raw_size = ftell(file);
- rewind(file);
-
- startup_data->data = new char[startup_data->raw_size];
- startup_data->compressed_size = fread(
- const_cast<char*>(startup_data->data), 1, startup_data->raw_size,
- file);
- fclose(file);
-
- if (startup_data->raw_size == startup_data->compressed_size)
- (*setter_fn)(startup_data);
- }
-
- v8::StartupData natives_;
- v8::StartupData snapshot_;
-
- // Disallow copy & assign.
- StartupDataHandler(const StartupDataHandler& other);
- void operator=(const StartupDataHandler& other);
-};
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-
-
int Shell::Main(int argc, char* argv[]) {
if (!SetOptions(argc, argv)) return 1;
v8::V8::InitializeICU(options.icu_data_file);
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob);
-#endif
SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg");
SetFlagsFromString("--redirect-code-traces-to=code.asm");
ShellArrayBufferAllocator array_buffer_allocator;
mock_arraybuffer_allocator(false),
num_isolates(1),
isolate_sources(NULL),
- icu_data_file(NULL),
- natives_blob(NULL),
- snapshot_blob(NULL) { }
+ icu_data_file(NULL) { }
~ShellOptions() {
delete[] isolate_sources;
int num_isolates;
SourceGroup* isolate_sources;
const char* icu_data_file;
- const char* natives_blob;
- const char* snapshot_blob;
};
#ifdef V8_SHARED
"(mksnapshot only)")
DEFINE_string(raw_context_file, NULL, "A file to write the raw context "
"snapshot bytes to. (mksnapshot only)")
-DEFINE_string(startup_blob, NULL, "Write V8 startup blob file. "
- "(mksnapshot only)")
+DEFINE_bool(omit, false, "Omit raw snapshot bytes in generated code. "
+ "(mksnapshot only)")
// code-stubs-hydrogen.cc
DEFINE_bool(profile_hydrogen_code_stub_compilation, false,
max_semi_space_size_ = Page::kPageSize;
}
- if (Snapshot::HaveASnapshotToStartFrom()) {
+ if (Snapshot::IsEnabled()) {
// If we are using a snapshot we always reserve the default amount
// of memory for each semispace because code in the snapshot has
// write-barrier code that relies on the size and alignment of new
: fp_(GetFileDescriptorOrDie(snapshot_file))
, raw_file_(NULL)
, raw_context_file_(NULL)
- , startup_blob_file_(NULL)
- , compressor_(NULL) {
+ , compressor_(NULL)
+ , omit_(false) {
}
~SnapshotWriter() {
fclose(fp_);
if (raw_file_) fclose(raw_file_);
if (raw_context_file_) fclose(raw_context_file_);
- if (startup_blob_file_) fclose(startup_blob_file_);
}
void SetCompressor(Compressor* compressor) {
compressor_ = compressor;
}
+ void SetOmit(bool omit) {
+ omit_ = omit;
+ }
+
void SetRawFiles(const char* raw_file, const char* raw_context_file) {
raw_file_ = GetFileDescriptorOrDie(raw_file);
raw_context_file_ = GetFileDescriptorOrDie(raw_context_file);
}
- void SetStartupBlobFile(const char* startup_blob_file) {
- if (startup_blob_file != NULL)
- startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file);
- }
-
void WriteSnapshot(const i::List<char>& snapshot_data,
const i::Serializer& serializer,
const i::List<char>& context_snapshot_data,
const i::Serializer& context_serializer) const {
- WriteSnapshotFile(snapshot_data, serializer,
- context_snapshot_data, context_serializer);
- MaybeWriteStartupBlob(snapshot_data, serializer,
- context_snapshot_data, context_serializer);
- }
-
- private:
- void MaybeWriteStartupBlob(const i::List<char>& snapshot_data,
- const i::Serializer& serializer,
- const i::List<char>& context_snapshot_data,
- const i::Serializer& context_serializer) const {
- if (!startup_blob_file_)
- return;
-
- i::List<char> startup_blob;
- ListSnapshotSink sink(&startup_blob);
-
- int spaces[] = {
- i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE,
- i::MAP_SPACE, i::CELL_SPACE, i::PROPERTY_CELL_SPACE
- };
-
- i::byte* snapshot_bytes = reinterpret_cast<i::byte*>(snapshot_data.begin());
- sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot");
- for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i)
- sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces");
-
- i::byte* context_bytes =
- reinterpret_cast<i::byte*>(context_snapshot_data.begin());
- sink.PutBlob(context_bytes, context_snapshot_data.length(), "context");
- for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i)
- sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]),
- "spaces");
-
- size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(),
- startup_blob_file_);
- if (written != (size_t)startup_blob.length()) {
- i::PrintF("Writing snapshot file failed.. Aborting.\n");
- exit(1);
- }
- }
-
- void WriteSnapshotFile(const i::List<char>& snapshot_data,
- const i::Serializer& serializer,
- const i::List<char>& context_snapshot_data,
- const i::Serializer& context_serializer) const {
WriteFilePrefix();
WriteData("", snapshot_data, raw_file_);
WriteData("context_", context_snapshot_data, raw_context_file_);
WriteFileSuffix();
}
+ private:
void WriteFilePrefix() const {
fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n");
fprintf(fp_, "#include \"src/v8.h\"\n");
const i::List<char>& source_data,
const i::List<char>* data_to_be_written) const {
fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix);
- WriteSnapshotData(data_to_be_written);
+ if (!omit_)
+ WriteSnapshotData(data_to_be_written);
fprintf(fp_, "};\n");
fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix,
data_to_be_written->length());
- if (data_to_be_written == &source_data) {
+ if (data_to_be_written == &source_data && !omit_) {
fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n",
prefix, prefix);
fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n",
FILE* fp_;
FILE* raw_file_;
FILE* raw_context_file_;
- FILE* startup_blob_file_;
Compressor* compressor_;
+ bool omit_;
};
{
SnapshotWriter writer(argv[1]);
+ writer.SetOmit(i::FLAG_omit);
if (i::FLAG_raw_file && i::FLAG_raw_context_file)
writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
- if (i::FLAG_startup_blob)
- writer.SetStartupBlobFile(i::FLAG_startup_blob);
#ifdef COMPRESS_STARTUP_DATA_BZ2
BZip2Compressor bzip2;
writer.SetCompressor(&bzip2);
+++ /dev/null
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/natives.h"
-
-#include "src/checks.h"
-#include "src/list.h"
-#include "src/list-inl.h"
-#include "src/snapshot-source-sink.h"
-#include "src/vector.h"
-
-namespace v8 {
-namespace internal {
-
-
-/**
- * NativesStore stores the 'native' (builtin) JS libraries.
- *
- * NativesStore needs to be initialized before using V8, usually by the
- * embedder calling v8::SetNativesDataBlob, which calls SetNativesFromFile
- * below.
- */
-class NativesStore {
- public:
- ~NativesStore() {}
-
- int GetBuiltinsCount() { return native_names_.length(); }
- int GetDebuggerCount() { return debugger_count_; }
- Vector<const char> GetScriptName(int index) { return native_names_[index]; }
- Vector<const char> GetRawScriptSource(int index) {
- return native_source_[index];
- }
-
- int GetIndex(const char* name) {
- for (int i = 0; i < native_names_.length(); ++i) {
- if (strcmp(name, native_names_[i].start()) == 0) {
- return i;
- }
- }
- ASSERT(false);
- return -1;
- }
-
- int GetRawScriptsSize() {
- ASSERT(false); // Used for compression. Doesn't really make sense here.
- return 0;
- }
-
- Vector<const byte> GetScriptsSource() {
- ASSERT(false); // Used for compression. Doesn't really make sense here.
- return Vector<const byte>();
- }
-
- static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
- NativesStore* store = new NativesStore;
-
- // We expect the libraries in the following format:
- // int: # of debugger sources.
- // 2N blobs: N pairs of source name + actual source.
- // then, repeat for non-debugger sources.
- int debugger_count = source->GetInt();
- for (int i = 0; i < debugger_count; ++i)
- store->ReadNameAndContentPair(source);
- int library_count = source->GetInt();
- for (int i = 0; i < library_count; ++i)
- store->ReadNameAndContentPair(source);
-
- store->debugger_count_ = debugger_count;
- return store;
- }
-
- private:
- NativesStore() : debugger_count_(0) {}
-
- bool ReadNameAndContentPair(SnapshotByteSource* bytes) {
- const byte* name;
- int name_length;
- const byte* source;
- int source_length;
- bool success = bytes->GetBlob(&name, &name_length) &&
- bytes->GetBlob(&source, &source_length);
- if (success) {
- Vector<const char> name_vector(
- reinterpret_cast<const char*>(name), name_length);
- Vector<const char> source_vector(
- reinterpret_cast<const char*>(source), source_length);
- native_names_.Add(name_vector);
- native_source_.Add(source_vector);
- }
- return success;
- }
-
- List<Vector<const char> > native_names_;
- List<Vector<const char> > native_source_;
- int debugger_count_;
-
- DISALLOW_COPY_AND_ASSIGN(NativesStore);
-};
-
-
-template<NativeType type>
-class NativesHolder {
- public:
- static NativesStore* get() {
- ASSERT(holder_);
- return holder_;
- }
- static void set(NativesStore* store) {
- ASSERT(store);
- holder_ = store;
- }
-
- private:
- static NativesStore* holder_;
-};
-
-template<NativeType type>
-NativesStore* NativesHolder<type>::holder_ = NULL;
-
-
-/**
- * Read the Natives (library sources) blob, as generated by js2c + the build
- * system.
- */
-void SetNativesFromFile(StartupData* natives_blob) {
- ASSERT(natives_blob);
- ASSERT(natives_blob->data);
- ASSERT(natives_blob->raw_size > 0);
-
- SnapshotByteSource bytes(
- reinterpret_cast<const byte*>(natives_blob->data),
- natives_blob->raw_size);
- NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
- NativesHolder<EXPERIMENTAL>::set(NativesStore::MakeFromScriptsSource(&bytes));
- ASSERT(!bytes.HasMore());
-}
-
-
-// Implement NativesCollection<T> bsaed on NativesHolder + NativesStore.
-//
-// (The callers expect a purely static interface, since this is how the
-// natives are usually compiled in. Since we implement them based on
-// runtime content, we have to implement this indirection to offer
-// a static interface.)
-template<NativeType type>
-int NativesCollection<type>::GetBuiltinsCount() {
- return NativesHolder<type>::get()->GetBuiltinsCount();
-}
-
-template<NativeType type>
-int NativesCollection<type>::GetDebuggerCount() {
- return NativesHolder<type>::get()->GetDebuggerCount();
-}
-
-template<NativeType type>
-int NativesCollection<type>::GetIndex(const char* name) {
- return NativesHolder<type>::get()->GetIndex(name);
-}
-
-template<NativeType type>
-int NativesCollection<type>::GetRawScriptsSize() {
- return NativesHolder<type>::get()->GetRawScriptsSize();
-}
-
-template<NativeType type>
-Vector<const char> NativesCollection<type>::GetRawScriptSource(int index) {
- return NativesHolder<type>::get()->GetRawScriptSource(index);
-}
-
-template<NativeType type>
-Vector<const char> NativesCollection<type>::GetScriptName(int index) {
- return NativesHolder<type>::get()->GetScriptName(index);
-}
-
-template<NativeType type>
-Vector<const byte> NativesCollection<type>::GetScriptsSource() {
- return NativesHolder<type>::get()->GetScriptsSource();
-}
-
-
-// The compiler can't 'see' all uses of the static methods and hence
-// my chose to elide them. This we'll explicitly instantiate these.
-template class NativesCollection<CORE>;
-template class NativesCollection<EXPERIMENTAL>;
-template class NativesCollection<D8>;
-template class NativesCollection<TEST>;
-
-} // namespace v8::internal
-} // namespace v8
#ifndef V8_NATIVES_H_
#define V8_NATIVES_H_
-#include "src/vector.h"
-
-namespace v8 { class StartupData; } // Forward declaration.
-
namespace v8 {
namespace internal {
typedef NativesCollection<CORE> Natives;
typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-// Used for reading the natives at runtime. Implementation in natives-empty.cc
-void SetNativesFromFile(StartupData* natives_blob);
-#endif
-
} } // namespace v8::internal
#endif // V8_NATIVES_H_
#include "src/runtime.h"
#include "src/serialize.h"
#include "src/snapshot.h"
-#include "src/snapshot-source-sink.h"
#include "src/stub-cache.h"
#include "src/v8threads.h"
}
+void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
+ ASSERT(integer < 1 << 22);
+ integer <<= 2;
+ int bytes = 1;
+ if (integer > 0xff) bytes = 2;
+ if (integer > 0xffff) bytes = 3;
+ integer |= bytes;
+ Put(static_cast<int>(integer & 0xff), "IntPart1");
+ if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2");
+ if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3");
+}
+
+
Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
: isolate_(isolate),
sink_(sink),
}
+bool SnapshotByteSource::AtEOF() {
+ if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false;
+ for (int x = position_; x < length_; x++) {
+ if (data_[x] != SerializerDeserializer::nop()) return false;
+ }
+ return true;
+}
+
} } // namespace v8::internal
#define V8_SERIALIZE_H_
#include "src/hashmap.h"
-#include "src/isolate.h"
-#include "src/snapshot-source-sink.h"
-#include "src/heap-profiler.h"
namespace v8 {
namespace internal {
};
+class SnapshotByteSource {
+ public:
+ SnapshotByteSource(const byte* array, int length)
+ : data_(array), length_(length), position_(0) { }
+
+ bool HasMore() { return position_ < length_; }
+
+ int Get() {
+ ASSERT(position_ < length_);
+ return data_[position_++];
+ }
+
+ int32_t GetUnalignedInt() {
+#if defined(V8_HOST_CAN_READ_UNALIGNED) && __BYTE_ORDER == __LITTLE_ENDIAN
+ int32_t answer;
+ ASSERT(position_ + sizeof(answer) <= length_ + 0u);
+ answer = *reinterpret_cast<const int32_t*>(data_ + position_);
+#else
+ int32_t answer = data_[position_];
+ answer |= data_[position_ + 1] << 8;
+ answer |= data_[position_ + 2] << 16;
+ answer |= data_[position_ + 3] << 24;
+#endif
+ return answer;
+ }
+
+ void Advance(int by) { position_ += by; }
+
+ inline void CopyRaw(byte* to, int number_of_bytes);
+
+ inline int GetInt();
+
+ bool AtEOF();
+
+ int position() { return position_; }
+
+ private:
+ const byte* data_;
+ int length_;
+ int position_;
+};
+
+
// The Serializer/Deserializer class is a common superclass for Serializer and
// Deserializer which is used to store common constants and methods used by
// both.
};
+int SnapshotByteSource::GetInt() {
+ // This way of variable-length encoding integers does not suffer from branch
+ // mispredictions.
+ uint32_t answer = GetUnalignedInt();
+ int bytes = answer & 3;
+ Advance(bytes);
+ uint32_t mask = 0xffffffffu;
+ mask >>= 32 - (bytes << 3);
+ answer &= mask;
+ answer >>= 2;
+ return answer;
+}
+
+
+void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) {
+ MemCopy(to, data_ + position_, number_of_bytes);
+ position_ += number_of_bytes;
+}
+
+
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
class Deserializer: public SerializerDeserializer {
public:
};
+class SnapshotByteSink {
+ public:
+ virtual ~SnapshotByteSink() { }
+ virtual void Put(int byte, const char* description) = 0;
+ virtual void PutSection(int byte, const char* description) {
+ Put(byte, description);
+ }
+ void PutInt(uintptr_t integer, const char* description);
+ virtual int Position() = 0;
+};
+
+
// Mapping objects to their location after deserialization.
// This is used during building, but not at runtime by V8.
class SerializationAddressMapper {
namespace internal {
+static void ReserveSpaceForSnapshot(Deserializer* deserializer,
+ const char* file_name) {
+ int file_name_length = StrLength(file_name) + 10;
+ Vector<char> name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(name, "%s.size", file_name);
+ FILE* fp = OS::FOpen(name.start(), "r");
+ CHECK_NE(NULL, fp);
+ int new_size, pointer_size, data_size, code_size, map_size, cell_size,
+ property_cell_size;
+#ifdef _MSC_VER
+ // Avoid warning about unsafe fscanf from MSVC.
+ // Please note that this is only fine if %c and %s are not being used.
+#define fscanf fscanf_s
+#endif
+ CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
+ CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
+ CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
+ CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
+ CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
+ CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
+ CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
+#ifdef _MSC_VER
+#undef fscanf
+#endif
+ fclose(fp);
+ deserializer->set_reservation(NEW_SPACE, new_size);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_size);
+ deserializer->set_reservation(CODE_SPACE, code_size);
+ deserializer->set_reservation(MAP_SPACE, map_size);
+ deserializer->set_reservation(CELL_SPACE, cell_size);
+ deserializer->set_reservation(PROPERTY_CELL_SPACE,
+ property_cell_size);
+ name.Dispose();
+}
+
+
void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
deserializer->set_reservation(NEW_SPACE, new_space_used_);
deserializer->set_reservation(OLD_POINTER_SPACE, pointer_space_used_);
}
-bool Snapshot::Initialize() {
- if (size_ > 0) {
+bool Snapshot::Initialize(const char* snapshot_file) {
+ if (snapshot_file) {
+ int len;
+ byte* str = ReadBytes(snapshot_file, &len);
+ if (!str) return false;
+ bool success;
+ {
+ SnapshotByteSource source(str, len);
+ Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, snapshot_file);
+ success = V8::Initialize(&deserializer);
+ }
+ DeleteArray(str);
+ return success;
+ } else if (size_ > 0) {
ElapsedTimer timer;
if (FLAG_profile_deserialization) {
timer.Start();
return Handle<Context>(Context::cast(root));
}
-
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-// Dummy implementations of Set*FromFile(..) APIs.
-//
-// These are meant for use with snapshot-external.cc. Should this file
-// be compiled with those options we just supply these dummy implementations
-// below. This happens when compiling the mksnapshot utility.
-void SetNativesFromFile(StartupData* data) { CHECK(false); }
-void SetSnapshotFromFile(StartupData* data) { CHECK(false); }
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-
} } // namespace v8::internal
+++ /dev/null
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Used for building with external snapshots.
-
-#include "src/snapshot.h"
-
-#include "src/v8.h" // for V8::Initialize
-#include "src/serialize.h"
-#include "src/snapshot-source-sink.h"
-
-namespace v8 {
-namespace internal {
-
-
-struct SnapshotImpl {
- public:
- const byte* data;
- int size;
- int new_space_used;
- int pointer_space_used;
- int data_space_used;
- int code_space_used;
- int map_space_used;
- int cell_space_used;
- int property_cell_space_used;
-
- const byte* context_data;
- int context_size;
- int context_new_space_used;
- int context_pointer_space_used;
- int context_data_space_used;
- int context_code_space_used;
- int context_map_space_used;
- int context_cell_space_used;
- int context_property_cell_space_used;
-};
-
-
-static SnapshotImpl* snapshot_impl_ = NULL;
-
-
-bool Snapshot::HaveASnapshotToStartFrom() {
- return snapshot_impl_ != NULL;
-}
-
-
-bool Snapshot::Initialize() {
- if (!HaveASnapshotToStartFrom())
- return false;
-
- ElapsedTimer timer;
- if (FLAG_profile_deserialization) {
- timer.Start();
- }
- SnapshotByteSource source(snapshot_impl_->data, snapshot_impl_->size);
- Deserializer deserializer(&source);
- deserializer.set_reservation(NEW_SPACE, snapshot_impl_->new_space_used);
- deserializer.set_reservation(OLD_POINTER_SPACE,
- snapshot_impl_->pointer_space_used);
- deserializer.set_reservation(OLD_DATA_SPACE,
- snapshot_impl_->data_space_used);
- deserializer.set_reservation(CODE_SPACE, snapshot_impl_->code_space_used);
- deserializer.set_reservation(MAP_SPACE, snapshot_impl_->map_space_used);
- deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used);
- deserializer.set_reservation(PROPERTY_CELL_SPACE,
- snapshot_impl_->property_cell_space_used);
- bool success = V8::Initialize(&deserializer);
- if (FLAG_profile_deserialization) {
- double ms = timer.Elapsed().InMillisecondsF();
- PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
- }
- return success;
-}
-
-
-Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
- if (!HaveASnapshotToStartFrom())
- return Handle<Context>();
-
- SnapshotByteSource source(snapshot_impl_->context_data,
- snapshot_impl_->context_size);
- Deserializer deserializer(&source);
- deserializer.set_reservation(NEW_SPACE,
- snapshot_impl_->context_new_space_used);
- deserializer.set_reservation(OLD_POINTER_SPACE,
- snapshot_impl_->context_pointer_space_used);
- deserializer.set_reservation(OLD_DATA_SPACE,
- snapshot_impl_->context_data_space_used);
- deserializer.set_reservation(CODE_SPACE,
- snapshot_impl_->context_code_space_used);
- deserializer.set_reservation(MAP_SPACE,
- snapshot_impl_->context_map_space_used);
- deserializer.set_reservation(CELL_SPACE,
- snapshot_impl_->context_cell_space_used);
- deserializer.set_reservation(PROPERTY_CELL_SPACE,
- snapshot_impl_->
- context_property_cell_space_used);
- Object* root;
- deserializer.DeserializePartial(isolate, &root);
- CHECK(root->IsContext());
- return Handle<Context>(Context::cast(root));
-}
-
-
-void SetSnapshotFromFile(StartupData* snapshot_blob) {
- ASSERT(snapshot_blob);
- ASSERT(snapshot_blob->data);
- ASSERT(snapshot_blob->raw_size > 0);
- ASSERT(!snapshot_impl_);
-
- snapshot_impl_ = new SnapshotImpl;
- SnapshotByteSource source(reinterpret_cast<const byte*>(snapshot_blob->data),
- snapshot_blob->raw_size);
-
- bool success = source.GetBlob(&snapshot_impl_->data,
- &snapshot_impl_->size);
- snapshot_impl_->new_space_used = source.GetInt();
- snapshot_impl_->pointer_space_used = source.GetInt();
- snapshot_impl_->data_space_used = source.GetInt();
- snapshot_impl_->code_space_used = source.GetInt();
- snapshot_impl_->map_space_used = source.GetInt();
- snapshot_impl_->cell_space_used = source.GetInt();
- snapshot_impl_->property_cell_space_used = source.GetInt();
-
- success &= source.GetBlob(&snapshot_impl_->context_data,
- &snapshot_impl_->context_size);
- snapshot_impl_->context_new_space_used = source.GetInt();
- snapshot_impl_->context_pointer_space_used = source.GetInt();
- snapshot_impl_->context_data_space_used = source.GetInt();
- snapshot_impl_->context_code_space_used = source.GetInt();
- snapshot_impl_->context_map_space_used = source.GetInt();
- snapshot_impl_->context_cell_space_used = source.GetInt();
- snapshot_impl_->context_property_cell_space_used = source.GetInt();
-
- ASSERT(success);
-}
-
-} } // namespace v8::internal
+++ /dev/null
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-#include "src/snapshot-source-sink.h"
-#include "src/checks.h"
-
-#include "src/handles-inl.h"
-#include "src/serialize.h" // for SerializerDeserializer::nop() in AtEOF()
-
-
-namespace v8 {
-namespace internal {
-
-
-SnapshotByteSource::SnapshotByteSource(const byte* array, int length)
- : data_(array), length_(length), position_(0) {
-}
-
-
-SnapshotByteSource::~SnapshotByteSource() { }
-
-
-int32_t SnapshotByteSource::GetUnalignedInt() {
- ASSERT(position_ < length_); // Require at least one byte left.
-#if defined(V8_HOST_CAN_READ_UNALIGNED) && __BYTE_ORDER == __LITTLE_ENDIAN
- int32_t answer = *reinterpret_cast<const int32_t*>(data_ + position_);
-#else
- int32_t answer = data_[position_];
- answer |= data_[position_ + 1] << 8;
- answer |= data_[position_ + 2] << 16;
- answer |= data_[position_ + 3] << 24;
-#endif
- return answer;
-}
-
-
-void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) {
- MemCopy(to, data_ + position_, number_of_bytes);
- position_ += number_of_bytes;
-}
-
-
-void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
- ASSERT(integer < 1 << 22);
- integer <<= 2;
- int bytes = 1;
- if (integer > 0xff) bytes = 2;
- if (integer > 0xffff) bytes = 3;
- integer |= bytes;
- Put(static_cast<int>(integer & 0xff), "IntPart1");
- if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2");
- if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3");
-}
-
-void SnapshotByteSink::PutRaw(byte* data, int number_of_bytes,
- const char* description) {
- for (int i = 0; i < number_of_bytes; ++i) {
- Put(data[i], description);
- }
-}
-
-void SnapshotByteSink::PutBlob(byte* data, int number_of_bytes,
- const char* description) {
- PutInt(number_of_bytes, description);
- PutRaw(data, number_of_bytes, description);
-}
-
-
-bool SnapshotByteSource::AtEOF() {
- if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false;
- for (int x = position_; x < length_; x++) {
- if (data_[x] != SerializerDeserializer::nop()) return false;
- }
- return true;
-}
-
-
-bool SnapshotByteSource::GetBlob(const byte** data, int* number_of_bytes) {
- int size = GetInt();
- *number_of_bytes = size;
-
- if (position_ + size < length_) {
- *data = &data_[position_];
- Advance(size);
- return true;
- } else {
- Advance(length_ - position_); // proceed until end.
- return false;
- }
-}
-
-} // namespace v8::internal
-} // namespace v8
+++ /dev/null
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_SNAPSHOT_SOURCE_SINK_H_
-#define V8_SNAPSHOT_SOURCE_SINK_H_
-
-#include "src/checks.h"
-#include "src/utils.h"
-
-namespace v8 {
-namespace internal {
-
-
-/**
- * Source to read snapshot and builtins files from.
- *
- * Note: Memory ownership remains with callee.
- */
-class SnapshotByteSource V8_FINAL {
- public:
- SnapshotByteSource(const byte* array, int length);
- ~SnapshotByteSource();
-
- bool HasMore() { return position_ < length_; }
-
- int Get() {
- ASSERT(position_ < length_);
- return data_[position_++];
- }
-
- int32_t GetUnalignedInt();
-
- void Advance(int by) { position_ += by; }
-
- void CopyRaw(byte* to, int number_of_bytes);
-
- inline int GetInt() {
- // This way of variable-length encoding integers does not suffer from branch
- // mispredictions.
- uint32_t answer = GetUnalignedInt();
- int bytes = answer & 3;
- Advance(bytes);
- uint32_t mask = 0xffffffffu;
- mask >>= 32 - (bytes << 3);
- answer &= mask;
- answer >>= 2;
- return answer;
- }
-
- bool GetBlob(const byte** data, int* number_of_bytes);
-
- bool AtEOF();
-
- int position() { return position_; }
-
- private:
- const byte* data_;
- int length_;
- int position_;
-
- DISALLOW_COPY_AND_ASSIGN(SnapshotByteSource);
-};
-
-
-/**
- * Sink to write snapshot files to.
- *
- * Subclasses must implement actual storage or i/o.
- */
-class SnapshotByteSink {
- public:
- virtual ~SnapshotByteSink() { }
- virtual void Put(int byte, const char* description) = 0;
- virtual void PutSection(int byte, const char* description) {
- Put(byte, description);
- }
- void PutInt(uintptr_t integer, const char* description);
- void PutRaw(byte* data, int number_of_bytes, const char* description);
- void PutBlob(byte* data, int number_of_bytes, const char* description);
- virtual int Position() = 0;
-};
-
-
-} // namespace v8::internal
-} // namespace v8
-
-#endif // V8_SNAPSHOT_SOURCE_SINK_H_
class Snapshot {
public:
- // Initialize the VM from the internal snapshot. Returns false if no snapshot
+ // Initialize the VM from the given snapshot file. If snapshot_file is
+ // NULL, use the internal snapshot instead. Returns false if no snapshot
// could be found.
- static bool Initialize();
+ static bool Initialize(const char* snapshot_file = NULL);
static bool HaveASnapshotToStartFrom();
// Create a new context using the internal partial snapshot.
static Handle<Context> NewContextFromSnapshot(Isolate* isolate);
- // These methods support COMPRESS_STARTUP_DATA_BZ2.
+ // Returns whether or not the snapshot is enabled.
+ static bool IsEnabled() { return size_ != 0; }
+
+ // Write snapshot to the given file. Returns true if snapshot was written
+ // successfully.
+ static bool WriteToFile(const char* snapshot_file);
+
static const byte* data() { return data_; }
static int size() { return size_; }
static int raw_size() { return raw_size_; }
DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
};
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-void SetSnapshotFromFile(StartupData* snapshot_blob);
-#endif
-
} } // namespace v8::internal
#endif // V8_SNAPSHOT_H_
//----------------------------------------------------------------------------
// Tests that the heap can be deserialized.
-
-static void ReserveSpaceForSnapshot(Deserializer* deserializer,
- const char* file_name) {
- int file_name_length = StrLength(file_name) + 10;
- Vector<char> name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(name, "%s.size", file_name);
- FILE* fp = OS::FOpen(name.start(), "r");
- name.Dispose();
- int new_size, pointer_size, data_size, code_size, map_size, cell_size,
- property_cell_size;
-#ifdef _MSC_VER
- // Avoid warning about unsafe fscanf from MSVC.
- // Please note that this is only fine if %c and %s are not being used.
-#define fscanf fscanf_s
-#endif
- CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
- CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
- CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
- CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
- CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
- CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
- CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
-#ifdef _MSC_VER
-#undef fscanf
-#endif
- fclose(fp);
- deserializer->set_reservation(NEW_SPACE, new_size);
- deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
- deserializer->set_reservation(OLD_DATA_SPACE, data_size);
- deserializer->set_reservation(CODE_SPACE, code_size);
- deserializer->set_reservation(MAP_SPACE, map_size);
- deserializer->set_reservation(CELL_SPACE, cell_size);
- deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
-}
-
-
-bool InitializeFromFile(const char* snapshot_file) {
- int len;
- byte* str = ReadBytes(snapshot_file, &len);
- if (!str) return false;
- bool success;
- {
- SnapshotByteSource source(str, len);
- Deserializer deserializer(&source);
- ReserveSpaceForSnapshot(&deserializer, snapshot_file);
- success = V8::Initialize(&deserializer);
- }
- DeleteArray(str);
- return success;
-}
-
-
static void Deserialize() {
- CHECK(InitializeFromFile(FLAG_testing_serialization_file));
+ CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
}
}
+static void ReserveSpaceForSnapshot(Deserializer* deserializer,
+ const char* file_name) {
+ int file_name_length = StrLength(file_name) + 10;
+ Vector<char> name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(name, "%s.size", file_name);
+ FILE* fp = OS::FOpen(name.start(), "r");
+ name.Dispose();
+ int new_size, pointer_size, data_size, code_size, map_size, cell_size,
+ property_cell_size;
+#ifdef _MSC_VER
+ // Avoid warning about unsafe fscanf from MSVC.
+ // Please note that this is only fine if %c and %s are not being used.
+#define fscanf fscanf_s
+#endif
+ CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
+ CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
+ CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
+ CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
+ CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
+ CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
+ CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
+#ifdef _MSC_VER
+#undef fscanf
+#endif
+ fclose(fp);
+ deserializer->set_reservation(NEW_SPACE, new_size);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_size);
+ deserializer->set_reservation(CODE_SPACE, code_size);
+ deserializer->set_reservation(MAP_SPACE, map_size);
+ deserializer->set_reservation(CELL_SPACE, cell_size);
+ deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
+}
+
+
DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
- if (!Snapshot::HaveASnapshotToStartFrom()) {
+ if (!Snapshot::IsEnabled()) {
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- CHECK(InitializeFromFile(startup_name.start()));
+ CHECK(Snapshot::Initialize(startup_name.start()));
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- CHECK(InitializeFromFile(startup_name.start()));
+ CHECK(Snapshot::Initialize(startup_name.start()));
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
+++ /dev/null
-#!/usr/bin/env python
-#
-# Copyright 2014 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This utility concatenates several files into one. On Unix-like systems
-# it is equivalent to:
-# cat file1 file2 file3 ...files... > target
-#
-# The reason for writing a seperate utility is that 'cat' is not available
-# on all supported build platforms, but Python is, and hence this provides
-# us with an easy and uniform way of doing this on all platforms.
-
-import optparse
-
-
-def Concatenate(filenames):
- """Concatenate files.
-
- Args:
- files: Array of file names.
- The last name is the target; all earlier ones are sources.
-
- Returns:
- True, if the operation was successful.
- """
- if len(filenames) < 2:
- print "An error occured generating %s:\nNothing to do." % filenames[-1]
- return False
-
- try:
- with open(filenames[-1], "wb") as target:
- for filename in filenames[:-1]:
- with open(filename, "rb") as current:
- target.write(current.read())
- return True
- except IOError as e:
- print "An error occured when writing %s:\n%s" % (filenames[-1], e)
- return False
-
-
-def main():
- parser = optparse.OptionParser()
- parser.set_usage("""Concatenate several files into one.
- Equivalent to: cat file1 ... > target.""")
- (options, args) = parser.parse_args()
- exit(0 if Concatenate(args) else 1)
-
-
-if __name__ == "__main__":
- main()
}, {
'toolsets': ['target'],
}],
-
- ['v8_use_snapshot=="true" and v8_use_external_startup_data==0', {
+ ['v8_use_snapshot=="true"', {
# The dependency on v8_base should come from a transitive
# dependency however the Android toolchain requires libv8_base.a
# to appear before libv8_snapshot.a so it's listed explicitly.
'dependencies': ['v8_base', 'v8_snapshot'],
- }],
- ['v8_use_snapshot!="true" and v8_use_external_startup_data==0', {
+ },
+ {
# The dependency on v8_base should come from a transitive
# dependency however the Android toolchain requires libv8_base.a
# to appear before libv8_snapshot.a so it's listed explicitly.
'dependencies': ['v8_base', 'v8_nosnapshot'],
}],
- ['v8_use_external_startup_data==1', {
- 'dependencies': ['v8_base', 'v8_external_snapshot'],
- }],
['component=="shared_library"', {
'type': '<(component)',
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
'<(INTERMEDIATE_DIR)/snapshot.cc',
- '../../src/snapshot-common.cc',
],
'actions': [
{
'action': [
'<@(_inputs)',
'<@(mksnapshot_flags)',
- '<@(INTERMEDIATE_DIR)/snapshot.cc'
+ '<@(_outputs)'
],
},
],
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
- '../../src/snapshot-common.cc',
'../../src/snapshot-empty.cc',
],
'conditions': [
}],
]
},
- {
- 'target_name': 'v8_external_snapshot',
- 'type': 'static_library',
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- 'dependencies': [
- 'mksnapshot#host',
- 'js2c#host',
- 'generate_trig_table#host',
- 'natives_blob#host',
- ]}, {
- 'toolsets': ['target'],
- 'dependencies': [
- 'mksnapshot',
- 'js2c',
- 'generate_trig_table',
- 'natives_blob',
- ],
- }],
- ['component=="shared_library"', {
- 'defines': [
- 'V8_SHARED',
- 'BUILDING_V8_SHARED',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'V8_SHARED',
- 'USING_V8_SHARED',
- ],
- },
- }],
- ],
- 'dependencies': [
- 'v8_base',
- ],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
- '../../src/natives-external.cc',
- '../../src/snapshot-external.cc',
- ],
- 'actions': [
- {
- 'action_name': 'run_mksnapshot (external)',
- 'inputs': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/snapshot.cc',
- '<(PRODUCT_DIR)/snapshot_blob.bin',
- ],
- 'variables': {
- 'mksnapshot_flags': [
- '--log-snapshot-positions',
- '--logfile', '<(INTERMEDIATE_DIR)/snapshot.log',
- ],
- 'conditions': [
- ['v8_random_seed!=0', {
- 'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'],
- }],
- ],
- },
- 'action': [
- '<@(_inputs)',
- '<@(mksnapshot_flags)',
- '<@(INTERMEDIATE_DIR)/snapshot.cc',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
- ],
- },
- ],
- },
{ 'target_name': 'generate_trig_table',
'type': 'none',
'conditions': [
'../../src/serialize.h',
'../../src/small-pointer-list.h',
'../../src/smart-pointers.h',
+ '../../src/snapshot-common.cc',
'../../src/snapshot.h',
- '../../src/snapshot-source-sink.cc',
- '../../src/snapshot-source-sink.h',
'../../src/spaces-inl.h',
'../../src/spaces.cc',
'../../src/spaces.h',
}],
],
},
- {
- 'target_name': 'natives_blob',
- 'type': 'none',
- 'dependencies': ['js2c'],
- 'actions': [{
- 'action_name': 'concatenate_natives_blob',
- 'inputs': [
- '../../tools/concatenate-files.py',
- '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
- '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
- ],
- 'outputs': [
- '<(PRODUCT_DIR)/natives_blob.bin',
- ],
- 'action': ['python', '<@(_inputs)', '<@(_outputs)'],
- }],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host'],
- }, {
- 'toolsets': ['target'],
- }],
- ],
- },
{
'target_name': 'js2c',
'type': 'none',
'../../src/harmony-array.js',
'../../src/harmony-math.js'
],
- 'libraries_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
- 'libraries_experimental_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
},
'actions': [
{
'action': [
'python',
'../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
+ '<@(_outputs)',
'CORE',
'<(v8_compress_startup_data)',
'<@(library_files)',
'<@(i18n_library_files)',
],
- 'conditions': [
- [ 'v8_use_external_startup_data==1', {
- 'outputs': ['<@(libraries_bin_file)'],
- 'action': [
- '--startup_blob', '<@(libraries_bin_file)',
- ],
- }],
- ],
},
{
'action_name': 'js2c_experimental',
'action': [
'python',
'../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
+ '<@(_outputs)',
'EXPERIMENTAL',
'<(v8_compress_startup_data)',
'<@(experimental_library_files)'
],
- 'conditions': [
- [ 'v8_use_external_startup_data==1', {
- 'outputs': ['<@(libraries_experimental_bin_file)'],
- 'action': [
- '--startup_blob', '<@(libraries_experimental_bin_file)'
- ],
- }],
- ],
},
],
},
return result
-def BuildMetadata(sources, source_bytes, native_type):
+def BuildMetadata(sources, source_bytes, native_type, omit):
"""Build the meta data required to generate a libaries file.
Args:
source_bytes: A list of source bytes.
(The concatenation of all sources; might be compressed.)
native_type: The parameter for the NativesCollection template.
+ omit: bool, whether we should omit the sources in the output.
Returns:
A dictionary for use with HEADER_TEMPLATE.
assert offset == len(raw_sources)
# If we have the raw sources we can declare them accordingly.
- have_raw_sources = source_bytes == raw_sources
+ have_raw_sources = source_bytes == raw_sources and not omit
raw_sources_declaration = (RAW_SOURCES_DECLARATION
if have_raw_sources else RAW_SOURCES_COMPRESSION_DECLARATION)
"builtin_count": len(sources.modules),
"debugger_count": sum(sources.is_debugger_id),
"sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes),
+ "sources_data": ToCArray(source_bytes) if not omit else "",
"raw_sources_declaration": raw_sources_declaration,
"raw_total_length": sum(map(len, sources.modules)),
"total_length": total_length,
raise Error("Unknown compression type %s." % compression_type)
-def PutInt(blob_file, value):
- assert(value >= 0 and value < (1 << 20))
- size = 1 if (value < 1 << 6) else (2 if (value < 1 << 14) else 3)
- value_with_length = (value << 2) | size
-
- byte_sequence = bytearray()
- for i in xrange(size):
- byte_sequence.append(value_with_length & 255)
- value_with_length >>= 8;
- blob_file.write(byte_sequence)
-
-
-def PutStr(blob_file, value):
- PutInt(blob_file, len(value));
- blob_file.write(value);
-
-
-def WriteStartupBlob(sources, startup_blob):
- """Write a startup blob, as expected by V8 Initialize ...
- TODO(vogelheim): Add proper method name.
-
- Args:
- sources: A Sources instance with the prepared sources.
- startup_blob_file: Name of file to write the blob to.
- """
- output = open(startup_blob, "wb")
-
- debug_sources = sum(sources.is_debugger_id);
- PutInt(output, debug_sources)
- for i in xrange(debug_sources):
- PutStr(output, sources.names[i]);
- PutStr(output, sources.modules[i]);
-
- PutInt(output, len(sources.names) - debug_sources)
- for i in xrange(debug_sources, len(sources.names)):
- PutStr(output, sources.names[i]);
- PutStr(output, sources.modules[i]);
-
- output.close()
-
-
-def JS2C(source, target, native_type, compression_type, raw_file, startup_blob):
+def JS2C(source, target, native_type, compression_type, raw_file, omit):
sources = PrepareSources(source)
sources_bytes = CompressMaybe(sources, compression_type)
- metadata = BuildMetadata(sources, sources_bytes, native_type)
+ metadata = BuildMetadata(sources, sources_bytes, native_type, omit)
# Optionally emit raw file.
if raw_file:
output.write(sources_bytes)
output.close()
- if startup_blob:
- WriteStartupBlob(sources, startup_blob);
-
# Emit resulting source file.
output = open(target, "w")
output.write(HEADER_TEMPLATE % metadata)
def main():
parser = optparse.OptionParser()
parser.add_option("--raw", action="store",
- help="file to write the processed sources array to.")
- parser.add_option("--startup_blob", action="store",
- help="file to write the startup blob to.")
+ help="file to write the processed sources array to.")
+ parser.add_option("--omit", dest="omit", action="store_true",
+ help="Omit the raw sources from the generated code.")
parser.set_usage("""js2c out.cc type compression sources.js ...
out.cc: C code to be generated.
type: type parameter for NativesCollection template.
sources.js: JS internal sources or macros.py.""")
(options, args) = parser.parse_args()
- JS2C(args[3:], args[0], args[1], args[2], options.raw, options.startup_blob)
+ JS2C(args[3:], args[0], args[1], args[2], options.raw, options.omit)
if __name__ == "__main__":