Commit c0cf4f83 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Support external code space in serializers

... by updating the checks for not_mapped_symbol root and using proper
cage base values depending on the host object type.

Bug: v8:11880
Change-Id: I28908cbb5b1023addaee248028661d480734e29c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3222760
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77435}
parent 761f8928
...@@ -1890,6 +1890,7 @@ filegroup( ...@@ -1890,6 +1890,7 @@ filegroup(
"src/snapshot/serializer-deserializer.h", "src/snapshot/serializer-deserializer.h",
"src/snapshot/serializer.cc", "src/snapshot/serializer.cc",
"src/snapshot/serializer.h", "src/snapshot/serializer.h",
"src/snapshot/serializer-inl.h",
"src/snapshot/snapshot-compression.cc", "src/snapshot/snapshot-compression.cc",
"src/snapshot/snapshot-compression.h", "src/snapshot/snapshot-compression.h",
"src/snapshot/snapshot-data.cc", "src/snapshot/snapshot-data.cc",
......
...@@ -3334,6 +3334,7 @@ v8_header_set("v8_internal_headers") { ...@@ -3334,6 +3334,7 @@ v8_header_set("v8_internal_headers") {
"src/snapshot/references.h", "src/snapshot/references.h",
"src/snapshot/roots-serializer.h", "src/snapshot/roots-serializer.h",
"src/snapshot/serializer-deserializer.h", "src/snapshot/serializer-deserializer.h",
"src/snapshot/serializer-inl.h",
"src/snapshot/serializer.h", "src/snapshot/serializer.h",
"src/snapshot/shared-heap-deserializer.h", "src/snapshot/shared-heap-deserializer.h",
"src/snapshot/shared-heap-serializer.h", "src/snapshot/shared-heap-serializer.h",
......
...@@ -844,9 +844,9 @@ void UncompiledData::InitAfterBytecodeFlush( ...@@ -844,9 +844,9 @@ void UncompiledData::InitAfterBytecodeFlush(
set_end_position(end_position); set_end_position(end_position);
} }
HeapObject SharedFunctionInfo::script() const { DEF_GETTER(SharedFunctionInfo, script, HeapObject) {
HeapObject maybe_script = script_or_debug_info(kAcquireLoad); HeapObject maybe_script = script_or_debug_info(cage_base, kAcquireLoad);
if (maybe_script.IsDebugInfo()) { if (maybe_script.IsDebugInfo(cage_base)) {
return DebugInfo::cast(maybe_script).script(); return DebugInfo::cast(maybe_script).script();
} }
return maybe_script; return maybe_script;
......
...@@ -378,7 +378,7 @@ class SharedFunctionInfo ...@@ -378,7 +378,7 @@ class SharedFunctionInfo
// - a DebugInfo which holds the actual script [HasDebugInfo()]. // - a DebugInfo which holds the actual script [HasDebugInfo()].
DECL_RELEASE_ACQUIRE_ACCESSORS(script_or_debug_info, HeapObject) DECL_RELEASE_ACQUIRE_ACCESSORS(script_or_debug_info, HeapObject)
inline HeapObject script() const; DECL_GETTER(script, HeapObject)
inline void set_script(HeapObject script); inline void set_script(HeapObject script);
// True if the underlying script was parsed and compiled in REPL mode. // True if the underlying script was parsed and compiled in REPL mode.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "src/heap/read-only-heap.h" #include "src/heap/read-only-heap.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/slots.h" #include "src/objects/slots.h"
#include "src/snapshot/serializer-inl.h"
#include "src/snapshot/startup-serializer.h" #include "src/snapshot/startup-serializer.h"
namespace v8 { namespace v8 {
...@@ -40,7 +41,7 @@ void ReadOnlySerializer::SerializeObjectImpl(Handle<HeapObject> obj) { ...@@ -40,7 +41,7 @@ void ReadOnlySerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
// in the root table, so don't try to serialize a reference and rely on the // in the root table, so don't try to serialize a reference and rely on the
// below CHECK(!did_serialize_not_mapped_symbol_) to make sure it doesn't // below CHECK(!did_serialize_not_mapped_symbol_) to make sure it doesn't
// serialize twice. // serialize twice.
if (*obj != ReadOnlyRoots(isolate()).not_mapped_symbol()) { if (!IsNotMappedSymbol(*obj)) {
if (SerializeHotObject(obj)) return; if (SerializeHotObject(obj)) return;
if (IsRootAndHasBeenSerialized(*obj) && SerializeRoot(obj)) return; if (IsRootAndHasBeenSerialized(*obj) && SerializeRoot(obj)) return;
if (SerializeBackReference(obj)) return; if (SerializeBackReference(obj)) return;
...@@ -52,7 +53,7 @@ void ReadOnlySerializer::SerializeObjectImpl(Handle<HeapObject> obj) { ...@@ -52,7 +53,7 @@ void ReadOnlySerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
ObjectSerializer object_serializer(this, obj, &sink_); ObjectSerializer object_serializer(this, obj, &sink_);
object_serializer.Serialize(); object_serializer.Serialize();
#ifdef DEBUG #ifdef DEBUG
if (*obj == ReadOnlyRoots(isolate()).not_mapped_symbol()) { if (IsNotMappedSymbol(*obj)) {
CHECK(!did_serialize_not_mapped_symbol_); CHECK(!did_serialize_not_mapped_symbol_);
did_serialize_not_mapped_symbol_ = true; did_serialize_not_mapped_symbol_ = true;
} else { } else {
...@@ -94,7 +95,7 @@ void ReadOnlySerializer::FinalizeSerialization() { ...@@ -94,7 +95,7 @@ void ReadOnlySerializer::FinalizeSerialization() {
ReadOnlyHeapObjectIterator iterator(isolate()->read_only_heap()); ReadOnlyHeapObjectIterator iterator(isolate()->read_only_heap());
for (HeapObject object = iterator.Next(); !object.is_null(); for (HeapObject object = iterator.Next(); !object.is_null();
object = iterator.Next()) { object = iterator.Next()) {
if (object == ReadOnlyRoots(isolate()).not_mapped_symbol()) { if (IsNotMappedSymbol(object)) {
CHECK(did_serialize_not_mapped_symbol_); CHECK(did_serialize_not_mapped_symbol_);
} else { } else {
CHECK_NOT_NULL(serialized_objects_.Find(object)); CHECK_NOT_NULL(serialized_objects_.Find(object));
......
// Copyright 2021 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_SERIALIZER_INL_H_
#define V8_SNAPSHOT_SERIALIZER_INL_H_
#include "src/roots/roots-inl.h"
#include "src/snapshot/serializer.h"
namespace v8 {
namespace internal {
bool Serializer::IsNotMappedSymbol(HeapObject obj) const {
Object not_mapped_symbol = ReadOnlyRoots(isolate()).not_mapped_symbol();
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// It's possible that a Code object might have the same compressed value
// as the not_mapped_symbol, so we must compare full pointers.
// TODO(v8:11880): Avoid the need for this special case by never putting
// Code references anywhere except the CodeDadaContainer objects.
// In particular, the Code objects should not appear in serializer's
// identity map. This should be possible once the IsolateData::builtins
// table is migrated to contain CodeT references.
return obj.ptr() == not_mapped_symbol.ptr();
}
return obj == not_mapped_symbol;
}
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_SERIALIZER_INL_H_
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/objects/slots-inl.h" #include "src/objects/slots-inl.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "src/snapshot/serializer-deserializer.h" #include "src/snapshot/serializer-deserializer.h"
#include "src/snapshot/serializer-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -343,7 +344,7 @@ ExternalReferenceEncoder::Value Serializer::EncodeExternalReference( ...@@ -343,7 +344,7 @@ ExternalReferenceEncoder::Value Serializer::EncodeExternalReference(
} }
void Serializer::RegisterObjectIsPending(Handle<HeapObject> obj) { void Serializer::RegisterObjectIsPending(Handle<HeapObject> obj) {
if (*obj == ReadOnlyRoots(isolate()).not_mapped_symbol()) return; if (IsNotMappedSymbol(*obj)) return;
// Add the given object to the pending objects -> forward refs map. // Add the given object to the pending objects -> forward refs map.
auto find_result = forward_refs_per_pending_object_.FindOrInsert(obj); auto find_result = forward_refs_per_pending_object_.FindOrInsert(obj);
...@@ -358,7 +359,7 @@ void Serializer::RegisterObjectIsPending(Handle<HeapObject> obj) { ...@@ -358,7 +359,7 @@ void Serializer::RegisterObjectIsPending(Handle<HeapObject> obj) {
} }
void Serializer::ResolvePendingObject(Handle<HeapObject> obj) { void Serializer::ResolvePendingObject(Handle<HeapObject> obj) {
if (*obj == ReadOnlyRoots(isolate()).not_mapped_symbol()) return; if (IsNotMappedSymbol(*obj)) return;
std::vector<int>* refs; std::vector<int>* refs;
CHECK(forward_refs_per_pending_object_.Delete(obj, &refs)); CHECK(forward_refs_per_pending_object_.Delete(obj, &refs));
...@@ -435,7 +436,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space, ...@@ -435,7 +436,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space,
// Make sure the map serialization didn't accidentally recursively serialize // Make sure the map serialization didn't accidentally recursively serialize
// this object. // this object.
DCHECK_IMPLIES( DCHECK_IMPLIES(
*object_ != ReadOnlyRoots(isolate()).not_mapped_symbol(), !serializer_->IsNotMappedSymbol(*object_),
serializer_->reference_map()->LookupReference(object_) == nullptr); serializer_->reference_map()->LookupReference(object_) == nullptr);
// Now that the object is allocated, we can resolve pending references to // Now that the object is allocated, we can resolve pending references to
...@@ -454,7 +455,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space, ...@@ -454,7 +455,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space,
serializer_->back_refs_.Push(*object_); serializer_->back_refs_.Push(*object_);
DCHECK_EQ(serializer_->back_refs_.size(), serializer_->num_back_refs_); DCHECK_EQ(serializer_->back_refs_.size(), serializer_->num_back_refs_);
#endif #endif
if (*object_ != ReadOnlyRoots(isolate()).not_mapped_symbol()) { if (!serializer_->IsNotMappedSymbol(*object_)) {
// Only add the object to the map if it's not not_mapped_symbol, else // Only add the object to the map if it's not not_mapped_symbol, else
// the reference IdentityMap has issues. We don't expect to have back // the reference IdentityMap has issues. We don't expect to have back
// references to the not_mapped_symbol anyway, so it's fine. // references to the not_mapped_symbol anyway, so it's fine.
...@@ -575,7 +576,8 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() { ...@@ -575,7 +576,8 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
// Instead of serializing this as an external string, we serialize // Instead of serializing this as an external string, we serialize
// an imaginary sequential string with the same content. // an imaginary sequential string with the same content.
ReadOnlyRoots roots(isolate()); ReadOnlyRoots roots(isolate());
DCHECK(object_->IsExternalString()); PtrComprCageBase cage_base(isolate());
DCHECK(object_->IsExternalString(cage_base));
Handle<ExternalString> string = Handle<ExternalString>::cast(object_); Handle<ExternalString> string = Handle<ExternalString>::cast(object_);
int length = string->length(); int length = string->length();
Map map; Map map;
...@@ -583,8 +585,8 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() { ...@@ -583,8 +585,8 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
int allocation_size; int allocation_size;
const byte* resource; const byte* resource;
// Find the map and size for the imaginary sequential string. // Find the map and size for the imaginary sequential string.
bool internalized = object_->IsInternalizedString(); bool internalized = object_->IsInternalizedString(cage_base);
if (object_->IsExternalOneByteString()) { if (object_->IsExternalOneByteString(cage_base)) {
map = internalized ? roots.one_byte_internalized_string_map() map = internalized ? roots.one_byte_internalized_string_map()
: roots.one_byte_string_map(); : roots.one_byte_string_map();
allocation_size = SeqOneByteString::SizeFor(length); allocation_size = SeqOneByteString::SizeFor(length);
...@@ -683,32 +685,33 @@ void Serializer::ObjectSerializer::Serialize() { ...@@ -683,32 +685,33 @@ void Serializer::ObjectSerializer::Serialize() {
PrintF("\n"); PrintF("\n");
} }
if (object_->IsExternalString()) { PtrComprCageBase cage_base(isolate());
if (object_->IsExternalString(cage_base)) {
SerializeExternalString(); SerializeExternalString();
return; return;
} else if (!ReadOnlyHeap::Contains(*object_)) { } else if (!ReadOnlyHeap::Contains(*object_)) {
// Only clear padding for strings outside the read-only heap. Read-only heap // Only clear padding for strings outside the read-only heap. Read-only heap
// should have been cleared elsewhere. // should have been cleared elsewhere.
if (object_->IsSeqOneByteString()) { if (object_->IsSeqOneByteString(cage_base)) {
// Clear padding bytes at the end. Done here to avoid having to do this // Clear padding bytes at the end. Done here to avoid having to do this
// at allocation sites in generated code. // at allocation sites in generated code.
Handle<SeqOneByteString>::cast(object_)->clear_padding(); Handle<SeqOneByteString>::cast(object_)->clear_padding();
} else if (object_->IsSeqTwoByteString()) { } else if (object_->IsSeqTwoByteString(cage_base)) {
Handle<SeqTwoByteString>::cast(object_)->clear_padding(); Handle<SeqTwoByteString>::cast(object_)->clear_padding();
} }
} }
if (object_->IsJSTypedArray()) { if (object_->IsJSTypedArray(cage_base)) {
SerializeJSTypedArray(); SerializeJSTypedArray();
return; return;
} else if (object_->IsJSArrayBuffer()) { } else if (object_->IsJSArrayBuffer(cage_base)) {
SerializeJSArrayBuffer(); SerializeJSArrayBuffer();
return; return;
} }
// We don't expect fillers. // We don't expect fillers.
DCHECK(!object_->IsFreeSpaceOrFiller()); DCHECK(!object_->IsFreeSpaceOrFiller(cage_base));
if (object_->IsScript()) { if (object_->IsScript(cage_base)) {
// Clear cached line ends. // Clear cached line ends.
Oddball undefined = ReadOnlyRoots(isolate()).undefined_value(); Oddball undefined = ReadOnlyRoots(isolate()).undefined_value();
Handle<Script>::cast(object_)->set_line_ends(undefined); Handle<Script>::cast(object_)->set_line_ends(undefined);
...@@ -827,11 +830,12 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host, ...@@ -827,11 +830,12 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host,
MaybeObjectSlot start, MaybeObjectSlot start,
MaybeObjectSlot end) { MaybeObjectSlot end) {
HandleScope scope(isolate()); HandleScope scope(isolate());
PtrComprCageBase cage_base(isolate());
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
MaybeObjectSlot current = start; MaybeObjectSlot current = start;
while (current < end) { while (current < end) {
while (current < end && (*current)->IsSmi()) { while (current < end && current.load(cage_base).IsSmi()) {
++current; ++current;
} }
if (current < end) { if (current < end) {
...@@ -839,15 +843,15 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host, ...@@ -839,15 +843,15 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host,
} }
// TODO(ishell): Revisit this change once we stick to 32-bit compressed // TODO(ishell): Revisit this change once we stick to 32-bit compressed
// tagged values. // tagged values.
while (current < end && (*current)->IsCleared()) { while (current < end && current.load(cage_base).IsCleared()) {
sink_->Put(kClearedWeakReference, "ClearedWeakReference"); sink_->Put(kClearedWeakReference, "ClearedWeakReference");
bytes_processed_so_far_ += kTaggedSize; bytes_processed_so_far_ += kTaggedSize;
++current; ++current;
} }
HeapObject current_contents; HeapObject current_contents;
HeapObjectReferenceType reference_type; HeapObjectReferenceType reference_type;
while (current < end && while (current < end && current.load(cage_base).GetHeapObject(
(*current)->GetHeapObject(&current_contents, &reference_type)) { &current_contents, &reference_type)) {
// Write a weak prefix if we need it. This has to be done before the // Write a weak prefix if we need it. This has to be done before the
// potential pending object serialization. // potential pending object serialization.
if (reference_type == HeapObjectReferenceType::WEAK) { if (reference_type == HeapObjectReferenceType::WEAK) {
...@@ -896,8 +900,11 @@ void Serializer::ObjectSerializer::VisitCodePointer(HeapObject host, ...@@ -896,8 +900,11 @@ void Serializer::ObjectSerializer::VisitCodePointer(HeapObject host,
HandleScope scope(isolate()); HandleScope scope(isolate());
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
// TODO(v8:11880): support external code space. #if V8_EXTERNAL_CODE_SPACE
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host); PtrComprCageBase code_cage_base(isolate()->code_cage_base());
#else
PtrComprCageBase code_cage_base(isolate());
#endif
Object contents = slot.load(code_cage_base); Object contents = slot.load(code_cage_base);
DCHECK(HAS_STRONG_HEAP_OBJECT_TAG(contents.ptr())); DCHECK(HAS_STRONG_HEAP_OBJECT_TAG(contents.ptr()));
DCHECK(contents.IsCode()); DCHECK(contents.IsCode());
...@@ -1106,13 +1113,14 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) { ...@@ -1106,13 +1113,14 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
__msan_check_mem_is_initialized( __msan_check_mem_is_initialized(
reinterpret_cast<void*>(object_start + base), bytes_to_output); reinterpret_cast<void*>(object_start + base), bytes_to_output);
#endif // MEMORY_SANITIZER #endif // MEMORY_SANITIZER
if (object_->IsBytecodeArray()) { PtrComprCageBase cage_base(isolate_);
if (object_->IsBytecodeArray(cage_base)) {
// The bytecode age field can be changed by GC concurrently. // The bytecode age field can be changed by GC concurrently.
byte field_value = BytecodeArray::kNoAgeBytecodeAge; byte field_value = BytecodeArray::kNoAgeBytecodeAge;
OutputRawWithCustomField(sink_, object_start, base, bytes_to_output, OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
BytecodeArray::kBytecodeAgeOffset, BytecodeArray::kBytecodeAgeOffset,
sizeof(field_value), &field_value); sizeof(field_value), &field_value);
} else if (object_->IsDescriptorArray()) { } else if (object_->IsDescriptorArray(cage_base)) {
// The number of marked descriptors field can be changed by GC // The number of marked descriptors field can be changed by GC
// concurrently. // concurrently.
static byte field_value[2] = {0}; static byte field_value[2] = {0};
...@@ -1120,7 +1128,8 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) { ...@@ -1120,7 +1128,8 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
sink_, object_start, base, bytes_to_output, sink_, object_start, base, bytes_to_output,
DescriptorArray::kRawNumberOfMarkedDescriptorsOffset, DescriptorArray::kRawNumberOfMarkedDescriptorsOffset,
sizeof(field_value), field_value); sizeof(field_value), field_value);
} else if (V8_EXTERNAL_CODE_SPACE_BOOL && object_->IsCodeDataContainer()) { } else if (V8_EXTERNAL_CODE_SPACE_BOOL &&
object_->IsCodeDataContainer(cage_base)) {
// The CodeEntryPoint field is just a cached value which will be // The CodeEntryPoint field is just a cached value which will be
// recomputed after deserialization, so write zeros to keep the snapshot // recomputed after deserialization, so write zeros to keep the snapshot
// deterministic. // deterministic.
......
...@@ -204,6 +204,10 @@ class Serializer : public SerializerDeserializer { ...@@ -204,6 +204,10 @@ class Serializer : public SerializerDeserializer {
Serializer* serializer_; Serializer* serializer_;
}; };
// Compares obj with not_mapped_symbol root. When V8_EXTERNAL_CODE_SPACE is
// enabled it compares full pointers.
V8_INLINE bool IsNotMappedSymbol(HeapObject obj) const;
void SerializeDeferredObjects(); void SerializeDeferredObjects();
void SerializeObject(Handle<HeapObject> o); void SerializeObject(Handle<HeapObject> o);
virtual void SerializeObjectImpl(Handle<HeapObject> o) = 0; virtual void SerializeObjectImpl(Handle<HeapObject> o) = 0;
......
...@@ -222,6 +222,7 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot( ...@@ -222,6 +222,7 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
void Snapshot::ClearReconstructableDataForSerialization( void Snapshot::ClearReconstructableDataForSerialization(
Isolate* isolate, bool clear_recompilable_data) { Isolate* isolate, bool clear_recompilable_data) {
// Clear SFIs and JSRegExps. // Clear SFIs and JSRegExps.
PtrComprCageBase cage_base(isolate);
if (clear_recompilable_data) { if (clear_recompilable_data) {
HandleScope scope(isolate); HandleScope scope(isolate);
...@@ -231,16 +232,17 @@ void Snapshot::ClearReconstructableDataForSerialization( ...@@ -231,16 +232,17 @@ void Snapshot::ClearReconstructableDataForSerialization(
DisallowGarbageCollection disallow_gc; DisallowGarbageCollection disallow_gc;
i::HeapObjectIterator it(isolate->heap()); i::HeapObjectIterator it(isolate->heap());
for (i::HeapObject o = it.Next(); !o.is_null(); o = it.Next()) { for (i::HeapObject o = it.Next(); !o.is_null(); o = it.Next()) {
if (o.IsSharedFunctionInfo()) { if (o.IsSharedFunctionInfo(cage_base)) {
i::SharedFunctionInfo shared = i::SharedFunctionInfo::cast(o); i::SharedFunctionInfo shared = i::SharedFunctionInfo::cast(o);
if (shared.script().IsScript() && if (shared.script(cage_base).IsScript(cage_base) &&
Script::cast(shared.script()).type() == Script::TYPE_EXTENSION) { Script::cast(shared.script(cage_base)).type() ==
Script::TYPE_EXTENSION) {
continue; // Don't clear extensions, they cannot be recompiled. continue; // Don't clear extensions, they cannot be recompiled.
} }
if (shared.CanDiscardCompiled()) { if (shared.CanDiscardCompiled()) {
sfis_to_clear.emplace_back(shared, isolate); sfis_to_clear.emplace_back(shared, isolate);
} }
} else if (o.IsJSRegExp()) { } else if (o.IsJSRegExp(cage_base)) {
i::JSRegExp regexp = i::JSRegExp::cast(o); i::JSRegExp regexp = i::JSRegExp::cast(o);
if (regexp.HasCompiledCode()) { if (regexp.HasCompiledCode()) {
regexp.DiscardCompiledCodeForSerialization(); regexp.DiscardCompiledCodeForSerialization();
...@@ -261,14 +263,15 @@ void Snapshot::ClearReconstructableDataForSerialization( ...@@ -261,14 +263,15 @@ void Snapshot::ClearReconstructableDataForSerialization(
i::HeapObjectIterator it(isolate->heap()); i::HeapObjectIterator it(isolate->heap());
for (i::HeapObject o = it.Next(); !o.is_null(); o = it.Next()) { for (i::HeapObject o = it.Next(); !o.is_null(); o = it.Next()) {
if (!o.IsJSFunction()) continue; if (!o.IsJSFunction(cage_base)) continue;
i::JSFunction fun = i::JSFunction::cast(o); i::JSFunction fun = i::JSFunction::cast(o);
fun.CompleteInobjectSlackTrackingIfActive(); fun.CompleteInobjectSlackTrackingIfActive();
i::SharedFunctionInfo shared = fun.shared(); i::SharedFunctionInfo shared = fun.shared();
if (shared.script().IsScript() && if (shared.script(cage_base).IsScript(cage_base) &&
Script::cast(shared.script()).type() == Script::TYPE_EXTENSION) { Script::cast(shared.script(cage_base)).type() ==
Script::TYPE_EXTENSION) {
continue; // Don't clear extensions, they cannot be recompiled. continue; // Don't clear extensions, they cannot be recompiled.
} }
...@@ -276,8 +279,8 @@ void Snapshot::ClearReconstructableDataForSerialization( ...@@ -276,8 +279,8 @@ void Snapshot::ClearReconstructableDataForSerialization(
if (fun.CanDiscardCompiled()) { if (fun.CanDiscardCompiled()) {
fun.set_code(*BUILTIN_CODE(isolate, CompileLazy)); fun.set_code(*BUILTIN_CODE(isolate, CompileLazy));
} }
if (!fun.raw_feedback_cell().value().IsUndefined()) { if (!fun.raw_feedback_cell(cage_base).value(cage_base).IsUndefined()) {
fun.raw_feedback_cell().set_value( fun.raw_feedback_cell(cage_base).set_value(
i::ReadOnlyRoots(isolate).undefined_value()); i::ReadOnlyRoots(isolate).undefined_value());
} }
#ifdef DEBUG #ifdef DEBUG
......
...@@ -134,8 +134,9 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) { ...@@ -134,8 +134,9 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
#endif // DEBUG #endif // DEBUG
void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) { void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
PtrComprCageBase cage_base(isolate());
#ifdef DEBUG #ifdef DEBUG
if (obj->IsJSFunction()) { if (obj->IsJSFunction(cage_base)) {
v8::base::OS::PrintError("Reference stack:\n"); v8::base::OS::PrintError("Reference stack:\n");
PrintStack(std::cerr); PrintStack(std::cerr);
obj->Print(std::cerr); obj->Print(std::cerr);
...@@ -157,7 +158,7 @@ void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) { ...@@ -157,7 +158,7 @@ void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
use_simulator = true; use_simulator = true;
#endif #endif
if (use_simulator && obj->IsAccessorInfo()) { if (use_simulator && obj->IsAccessorInfo(cage_base)) {
// Wipe external reference redirects in the accessor info. // Wipe external reference redirects in the accessor info.
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj); Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj);
Address original_address = Address original_address =
...@@ -165,17 +166,18 @@ void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) { ...@@ -165,17 +166,18 @@ void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
Foreign::cast(info->js_getter()) Foreign::cast(info->js_getter())
.set_foreign_address(isolate(), original_address); .set_foreign_address(isolate(), original_address);
accessor_infos_.Push(*info); accessor_infos_.Push(*info);
} else if (use_simulator && obj->IsCallHandlerInfo()) { } else if (use_simulator && obj->IsCallHandlerInfo(cage_base)) {
Handle<CallHandlerInfo> info = Handle<CallHandlerInfo>::cast(obj); Handle<CallHandlerInfo> info = Handle<CallHandlerInfo>::cast(obj);
Address original_address = Address original_address =
Foreign::cast(info->callback()).foreign_address(isolate()); Foreign::cast(info->callback()).foreign_address(isolate());
Foreign::cast(info->js_callback()) Foreign::cast(info->js_callback())
.set_foreign_address(isolate(), original_address); .set_foreign_address(isolate(), original_address);
call_handler_infos_.Push(*info); call_handler_infos_.Push(*info);
} else if (obj->IsScript() && Handle<Script>::cast(obj)->IsUserJavaScript()) { } else if (obj->IsScript(cage_base) &&
Handle<Script>::cast(obj)->IsUserJavaScript()) {
Handle<Script>::cast(obj)->set_context_data( Handle<Script>::cast(obj)->set_context_data(
ReadOnlyRoots(isolate()).uninitialized_symbol()); ReadOnlyRoots(isolate()).uninitialized_symbol());
} else if (obj->IsSharedFunctionInfo()) { } else if (obj->IsSharedFunctionInfo(cage_base)) {
// Clear inferred name for native functions. // Clear inferred name for native functions.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(obj); Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(obj);
if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) { if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) {
......
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