Commit b62f0948 authored by yangguo's avatar yangguo Committed by Commit bot

Store embed-script flag as metadata into snapshot blob.

R=vogelheim@chromium.org

Review URL: https://codereview.chromium.org/848023002

Cr-Commit-Position: refs/heads/master@{#26049}
parent 214387fc
...@@ -229,11 +229,13 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) { ...@@ -229,11 +229,13 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
Isolate::Scope isolate_scope(isolate); Isolate::Scope isolate_scope(isolate);
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Persistent<Context> context; Persistent<Context> context;
i::Snapshot::Metadata metadata;
{ {
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
Handle<Context> new_context = Context::New(isolate); Handle<Context> new_context = Context::New(isolate);
context.Reset(isolate, new_context); context.Reset(isolate, new_context);
if (custom_source != NULL) { if (custom_source != NULL) {
metadata.set_embeds_script(true);
Context::Scope context_scope(new_context); Context::Scope context_scope(new_context);
if (!RunExtraCode(isolate, custom_source)) context.Reset(); if (!RunExtraCode(isolate, custom_source)) context.Reset();
} }
...@@ -264,7 +266,8 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) { ...@@ -264,7 +266,8 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
i::SnapshotData sd(snapshot_sink, ser); i::SnapshotData sd(snapshot_sink, ser);
i::SnapshotData csd(context_sink, context_ser); i::SnapshotData csd(context_sink, context_ser);
result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData()); result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData(),
metadata);
} }
} }
isolate->Dispose(); isolate->Dispose();
......
...@@ -2578,6 +2578,11 @@ bool Genesis::ConfigureApiObject(Handle<JSObject> object, ...@@ -2578,6 +2578,11 @@ bool Genesis::ConfigureApiObject(Handle<JSObject> object,
void Genesis::TransferNamedProperties(Handle<JSObject> from, void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<JSObject> to) { Handle<JSObject> to) {
// If JSObject::AddProperty asserts due to already existing property,
// it is likely due to both global objects sharing property name(s).
// Merging those two global objects is impossible.
// The global template must not create properties that already exist
// in the snapshotted global object.
if (from->HasFastProperties()) { if (from->HasFastProperties()) {
Handle<DescriptorArray> descs = Handle<DescriptorArray> descs =
Handle<DescriptorArray>(from->map()->instance_descriptors()); Handle<DescriptorArray>(from->map()->instance_descriptors());
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/heap/mark-compact.h" #include "src/heap/mark-compact.h"
#include "src/macro-assembler.h" #include "src/macro-assembler.h"
#include "src/msan.h" #include "src/msan.h"
#include "src/snapshot.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -1044,6 +1045,8 @@ bool PagedSpace::Expand() { ...@@ -1044,6 +1045,8 @@ bool PagedSpace::Expand() {
intptr_t PagedSpace::SizeOfFirstPage() { intptr_t PagedSpace::SizeOfFirstPage() {
// If the snapshot contains a custom script, all size guarantees are off.
if (Snapshot::EmbedsScript()) return AreaSize();
// If using an ool constant pool then transfer the constant pool allowance // If using an ool constant pool then transfer the constant pool allowance
// from the code space to the old pointer space. // from the code space to the old pointer space.
static const int constant_pool_delta = FLAG_enable_ool_constant_pool ? 48 : 0; static const int constant_pool_delta = FLAG_enable_ool_constant_pool ? 48 : 0;
......
...@@ -19,6 +19,21 @@ bool Snapshot::HaveASnapshotToStartFrom() { ...@@ -19,6 +19,21 @@ bool Snapshot::HaveASnapshotToStartFrom() {
} }
#ifdef DEBUG
bool Snapshot::SnapshotIsValid(v8::StartupData* snapshot_blob) {
return !Snapshot::ExtractStartupData(snapshot_blob).is_empty() &&
!Snapshot::ExtractContextData(snapshot_blob).is_empty();
}
#endif // DEBUG
bool Snapshot::EmbedsScript() {
if (!HaveASnapshotToStartFrom()) return false;
const v8::StartupData blob = SnapshotBlob();
return ExtractMetadata(&blob).embeds_script();
}
bool Snapshot::Initialize(Isolate* isolate) { bool Snapshot::Initialize(Isolate* isolate) {
if (!HaveASnapshotToStartFrom()) return false; if (!HaveASnapshotToStartFrom()) return false;
base::ElapsedTimer timer; base::ElapsedTimer timer;
...@@ -54,6 +69,9 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot( ...@@ -54,6 +69,9 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
Handle<Object> result; Handle<Object> result;
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>(); if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();
CHECK(result->IsContext()); CHECK(result->IsContext());
// If the snapshot does not contain a custom script, we need to update
// the global object for exactly one context.
CHECK(EmbedsScript() || (*outdated_contexts_out)->length() == 1);
if (FLAG_profile_deserialization) { if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
int bytes = context_data.length(); int bytes = context_data.length();
...@@ -65,28 +83,37 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot( ...@@ -65,28 +83,37 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
v8::StartupData Snapshot::CreateSnapshotBlob( v8::StartupData Snapshot::CreateSnapshotBlob(
const Vector<const byte> startup_data, const Vector<const byte> startup_data,
const Vector<const byte> context_data) { const Vector<const byte> context_data, Snapshot::Metadata metadata) {
int startup_length = startup_data.length(); int startup_length = startup_data.length();
int context_length = context_data.length(); int context_length = context_data.length();
int context_offset = kIntSize + startup_length; int context_offset = ContextOffset(startup_length);
int length = context_offset + context_length; int length = context_offset + context_length;
char* data = new char[length]; char* data = new char[length];
memcpy(data, &startup_length, kIntSize); memcpy(data + kMetadataOffset, &metadata.RawValue(), kInt32Size);
memcpy(data + kIntSize, startup_data.begin(), startup_length); memcpy(data + kStartupLengthOffset, &startup_length, kInt32Size);
memcpy(data + kStartupDataOffset, startup_data.begin(), startup_length);
memcpy(data + context_offset, context_data.begin(), context_length); memcpy(data + context_offset, context_data.begin(), context_length);
v8::StartupData result = {data, length}; v8::StartupData result = {data, length};
return result; return result;
} }
Snapshot::Metadata Snapshot::ExtractMetadata(const v8::StartupData* data) {
uint32_t raw;
memcpy(&raw, data->data + kMetadataOffset, kInt32Size);
return Metadata(raw);
}
Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) { Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) {
DCHECK_LT(kIntSize, data->raw_size); DCHECK_LT(kIntSize, data->raw_size);
int startup_length; int startup_length;
memcpy(&startup_length, data->data, kIntSize); memcpy(&startup_length, data->data + kStartupLengthOffset, kInt32Size);
DCHECK_LT(startup_length, data->raw_size); DCHECK_LT(startup_length, data->raw_size);
const byte* startup_data = const byte* startup_data =
reinterpret_cast<const byte*>(data->data + kIntSize); reinterpret_cast<const byte*>(data->data + kStartupDataOffset);
return Vector<const byte>(startup_data, startup_length); return Vector<const byte>(startup_data, startup_length);
} }
...@@ -94,8 +121,8 @@ Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) { ...@@ -94,8 +121,8 @@ Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) {
Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data) { Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data) {
DCHECK_LT(kIntSize, data->raw_size); DCHECK_LT(kIntSize, data->raw_size);
int startup_length; int startup_length;
memcpy(&startup_length, data->data, kIntSize); memcpy(&startup_length, data->data + kStartupLengthOffset, kIntSize);
int context_offset = kIntSize + startup_length; int context_offset = ContextOffset(startup_length);
const byte* context_data = const byte* context_data =
reinterpret_cast<const byte*>(data->data + context_offset); reinterpret_cast<const byte*>(data->data + context_offset);
DCHECK_LT(context_offset, data->raw_size); DCHECK_LT(context_offset, data->raw_size);
......
...@@ -26,9 +26,7 @@ void SetSnapshotFromFile(StartupData* snapshot_blob) { ...@@ -26,9 +26,7 @@ void SetSnapshotFromFile(StartupData* snapshot_blob) {
DCHECK(snapshot_blob->data); DCHECK(snapshot_blob->data);
DCHECK(snapshot_blob->raw_size > 0); DCHECK(snapshot_blob->raw_size > 0);
DCHECK(!external_startup_blob.data); DCHECK(!external_startup_blob.data);
// Validate snapshot blob. DCHECK(Snapshot::SnapshotIsValid(snapshot_blob));
DCHECK(!Snapshot::ExtractStartupData(snapshot_blob).is_empty());
DCHECK(!Snapshot::ExtractContextData(snapshot_blob).is_empty());
external_startup_blob = *snapshot_blob; external_startup_blob = *snapshot_blob;
} }
......
...@@ -12,6 +12,21 @@ namespace internal { ...@@ -12,6 +12,21 @@ namespace internal {
class Snapshot : public AllStatic { class Snapshot : public AllStatic {
public: public:
class Metadata {
public:
explicit Metadata(uint32_t data = 0) : data_(data) {}
bool embeds_script() { return EmbedsScriptBits::decode(data_); }
void set_embeds_script(bool v) {
data_ = EmbedsScriptBits::update(data_, v);
}
uint32_t& RawValue() { return data_; }
private:
class EmbedsScriptBits : public BitField<bool, 0, 1> {};
uint32_t data_;
};
// Initialize the Isolate from the internal snapshot. Returns false if no // Initialize the Isolate from the internal snapshot. Returns false if no
// snapshot could be found. // snapshot could be found.
static bool Initialize(Isolate* isolate); static bool Initialize(Isolate* isolate);
...@@ -21,17 +36,32 @@ class Snapshot : public AllStatic { ...@@ -21,17 +36,32 @@ class Snapshot : public AllStatic {
static bool HaveASnapshotToStartFrom(); static bool HaveASnapshotToStartFrom();
static bool EmbedsScript();
// To be implemented by the snapshot source. // To be implemented by the snapshot source.
static const v8::StartupData SnapshotBlob(); static const v8::StartupData SnapshotBlob();
static v8::StartupData CreateSnapshotBlob( static v8::StartupData CreateSnapshotBlob(
const Vector<const byte> startup_data, const Vector<const byte> startup_data,
const Vector<const byte> context_data); const Vector<const byte> context_data, Metadata metadata);
#ifdef DEBUG
static bool SnapshotIsValid(v8::StartupData* snapshot_blob);
#endif // DEBUG
private:
static Vector<const byte> ExtractStartupData(const v8::StartupData* data); static Vector<const byte> ExtractStartupData(const v8::StartupData* data);
static Vector<const byte> ExtractContextData(const v8::StartupData* data); static Vector<const byte> ExtractContextData(const v8::StartupData* data);
static Metadata ExtractMetadata(const v8::StartupData* data);
static const int kMetadataOffset = 0;
static const int kStartupLengthOffset = kMetadataOffset + kInt32Size;
static const int kStartupDataOffset = kStartupLengthOffset + kInt32Size;
static int ContextOffset(int startup_length) {
return kStartupDataOffset + startup_length;
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot); DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment