Commit 1d3d3c5a authored by Nico Weber's avatar Nico Weber

Make v8_context_snapshot.bin writing deterministic.

V8 currently writes the raw values for embedder fields always,
so don't put pointers (which differ even between runs of the same
binary, due to ASLR) in there until that's fixed. Instead, put
a magic integer there and transform that to a pointer at
deserialization time.

(Also remove a redundant call from CreatePlainWrapper() --
the caller of CreatePlainWrapper() already sets the embedder
field, no need to do that twice. This part is behavior-preserving.)

Bug: 870584
Change-Id: I6b29286ec8c7a68a662d51c36b5642b968f2e343
Reviewed-on: https://chromium-review.googlesource.com/c/1293791
Commit-Queue: Nico Weber <thakis@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarHans Wennborg <hans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601628}
parent 79cd52f8
...@@ -56,10 +56,7 @@ v8::Local<v8::Object> CreatePlainWrapper(v8::Isolate* isolate, ...@@ -56,10 +56,7 @@ v8::Local<v8::Object> CreatePlainWrapper(v8::Isolate* isolate,
v8::Local<v8::Object> instance_template = v8::Local<v8::Object> instance_template =
V8ObjectConstructor::NewInstance(isolate, interface_object) V8ObjectConstructor::NewInstance(isolate, interface_object)
.ToLocalChecked(); .ToLocalChecked();
v8::Local<v8::Object> wrapper = instance_template->Clone(); return instance_template->Clone();
wrapper->SetAlignedPointerInInternalField(kV8DOMWrapperTypeIndex,
const_cast<WrapperTypeInfo*>(type));
return wrapper;
} }
int GetSnapshotIndexForWorld(const DOMWrapperWorld& world) { int GetSnapshotIndexForWorld(const DOMWrapperWorld& world) {
...@@ -94,6 +91,9 @@ enum class InternalFieldType : uint8_t { ...@@ -94,6 +91,9 @@ enum class InternalFieldType : uint8_t {
kHTMLDocumentObject, kHTMLDocumentObject,
}; };
constexpr uintptr_t SerializedHTMLDocumentHack =
(uintptr_t)((unsigned)InternalFieldType::kHTMLDocumentType << 3u);
const WrapperTypeInfo* FieldTypeToWrapperTypeInfo(InternalFieldType type) { const WrapperTypeInfo* FieldTypeToWrapperTypeInfo(InternalFieldType type) {
switch (type) { switch (type) {
case InternalFieldType::kNone: case InternalFieldType::kNone:
...@@ -326,13 +326,15 @@ v8::StartupData V8ContextSnapshot::SerializeInternalField( ...@@ -326,13 +326,15 @@ v8::StartupData V8ContextSnapshot::SerializeInternalField(
InternalFieldType field_type = InternalFieldType::kNone; InternalFieldType field_type = InternalFieldType::kNone;
const WrapperTypeInfo* wrapper_type = ToWrapperTypeInfo(object); const WrapperTypeInfo* wrapper_type = ToWrapperTypeInfo(object);
if (kV8DOMWrapperObjectIndex == index) { if (kV8DOMWrapperObjectIndex == index) {
if (blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) { if ((uintptr_t)wrapper_type == SerializedHTMLDocumentHack ||
blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) {
field_type = InternalFieldType::kHTMLDocumentObject; field_type = InternalFieldType::kHTMLDocumentObject;
} }
DCHECK_LE(kV8DefaultWrapperInternalFieldCount, DCHECK_LE(kV8DefaultWrapperInternalFieldCount,
object->InternalFieldCount()); object->InternalFieldCount());
} else if (kV8DOMWrapperTypeIndex == index) { } else if (kV8DOMWrapperTypeIndex == index) {
if (blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) { if ((uintptr_t)wrapper_type == SerializedHTMLDocumentHack ||
blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) {
field_type = InternalFieldType::kHTMLDocumentType; field_type = InternalFieldType::kHTMLDocumentType;
} else if (blink::V8Document::wrapperTypeInfo.Equals(wrapper_type)) { } else if (blink::V8Document::wrapperTypeInfo.Equals(wrapper_type)) {
field_type = InternalFieldType::kDocumentType; field_type = InternalFieldType::kDocumentType;
...@@ -494,8 +496,12 @@ void V8ContextSnapshot::TakeSnapshotForWorld(v8::SnapshotCreator* creator, ...@@ -494,8 +496,12 @@ void V8ContextSnapshot::TakeSnapshotForWorld(v8::SnapshotCreator* creator,
v8::Local<v8::Object> document_wrapper = CreatePlainWrapper( v8::Local<v8::Object> document_wrapper = CreatePlainWrapper(
isolate, world, context, &V8HTMLDocument::wrapperTypeInfo); isolate, world, context, &V8HTMLDocument::wrapperTypeInfo);
int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex}; int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
void* values[] = {nullptr, const_cast<WrapperTypeInfo*>( // TODO(https://crbug.com/870584): Once v8 no longer writes pointers
&V8HTMLDocument::wrapperTypeInfo)}; // that have explicit serialization code into the snapshot, put
// const_cast<WrapperTypeInfo*>(&V8HTMLDocument::wrapperTypeInfo)
// here and remove the SerializedHTMLDocumentHack instances in
// SerializeEmbedderFields().
void* values[] = {nullptr, (void*)SerializedHTMLDocumentHack};
document_wrapper->SetAlignedPointerInInternalFields(base::size(indices), document_wrapper->SetAlignedPointerInInternalFields(base::size(indices),
indices, values); indices, values);
......
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