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) {
Isolate::Scope isolate_scope(isolate);
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Persistent<Context> context;
i::Snapshot::Metadata metadata;
{
HandleScope handle_scope(isolate);
Handle<Context> new_context = Context::New(isolate);
context.Reset(isolate, new_context);
if (custom_source != NULL) {
metadata.set_embeds_script(true);
Context::Scope context_scope(new_context);
if (!RunExtraCode(isolate, custom_source)) context.Reset();
}
......@@ -264,7 +266,8 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
i::SnapshotData sd(snapshot_sink, 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();
......
......@@ -2578,6 +2578,11 @@ bool Genesis::ConfigureApiObject(Handle<JSObject> object,
void Genesis::TransferNamedProperties(Handle<JSObject> from,
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()) {
Handle<DescriptorArray> descs =
Handle<DescriptorArray>(from->map()->instance_descriptors());
......
......@@ -10,6 +10,7 @@
#include "src/heap/mark-compact.h"
#include "src/macro-assembler.h"
#include "src/msan.h"
#include "src/snapshot.h"
namespace v8 {
namespace internal {
......@@ -1044,6 +1045,8 @@ bool PagedSpace::Expand() {
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
// from the code space to the old pointer space.
static const int constant_pool_delta = FLAG_enable_ool_constant_pool ? 48 : 0;
......
......@@ -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) {
if (!HaveASnapshotToStartFrom()) return false;
base::ElapsedTimer timer;
......@@ -54,6 +69,9 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
Handle<Object> result;
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();
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) {
double ms = timer.Elapsed().InMillisecondsF();
int bytes = context_data.length();
......@@ -65,28 +83,37 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
v8::StartupData Snapshot::CreateSnapshotBlob(
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 context_length = context_data.length();
int context_offset = kIntSize + startup_length;
int context_offset = ContextOffset(startup_length);
int length = context_offset + context_length;
char* data = new char[length];
memcpy(data, &startup_length, kIntSize);
memcpy(data + kIntSize, startup_data.begin(), startup_length);
memcpy(data + kMetadataOffset, &metadata.RawValue(), kInt32Size);
memcpy(data + kStartupLengthOffset, &startup_length, kInt32Size);
memcpy(data + kStartupDataOffset, startup_data.begin(), startup_length);
memcpy(data + context_offset, context_data.begin(), context_length);
v8::StartupData result = {data, length};
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) {
DCHECK_LT(kIntSize, data->raw_size);
int startup_length;
memcpy(&startup_length, data->data, kIntSize);
memcpy(&startup_length, data->data + kStartupLengthOffset, kInt32Size);
DCHECK_LT(startup_length, data->raw_size);
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);
}
......@@ -94,8 +121,8 @@ Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) {
Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data) {
DCHECK_LT(kIntSize, data->raw_size);
int startup_length;
memcpy(&startup_length, data->data, kIntSize);
int context_offset = kIntSize + startup_length;
memcpy(&startup_length, data->data + kStartupLengthOffset, kIntSize);
int context_offset = ContextOffset(startup_length);
const byte* context_data =
reinterpret_cast<const byte*>(data->data + context_offset);
DCHECK_LT(context_offset, data->raw_size);
......
......@@ -26,9 +26,7 @@ void SetSnapshotFromFile(StartupData* snapshot_blob) {
DCHECK(snapshot_blob->data);
DCHECK(snapshot_blob->raw_size > 0);
DCHECK(!external_startup_blob.data);
// Validate snapshot blob.
DCHECK(!Snapshot::ExtractStartupData(snapshot_blob).is_empty());
DCHECK(!Snapshot::ExtractContextData(snapshot_blob).is_empty());
DCHECK(Snapshot::SnapshotIsValid(snapshot_blob));
external_startup_blob = *snapshot_blob;
}
......
......@@ -12,6 +12,21 @@ namespace internal {
class Snapshot : public AllStatic {
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
// snapshot could be found.
static bool Initialize(Isolate* isolate);
......@@ -21,17 +36,32 @@ class Snapshot : public AllStatic {
static bool HaveASnapshotToStartFrom();
static bool EmbedsScript();
// To be implemented by the snapshot source.
static const v8::StartupData SnapshotBlob();
static v8::StartupData CreateSnapshotBlob(
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> 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);
};
......
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