Reland "[roheap] Check that ro-heap is always passed the same read-only snapshot"

This is a reland of a5fa211f30

des_checksum and call_once_run were undefined and unused respectively when
shared read-only heap was enabled. Fixed with a copious amounts of USE.

Original change's description:
> [roheap] Check that ro-heap is always passed the same read-only snapshot
>
> Previously the ReadOnlyHeap simply discarded all but the first
> ReadOnlyDeseralizer. ClearSharedHeapForTest should be called if using a
> new ReadOnlyDeserializer (this might change in the future).
>
> Remove an obsolete 'StartupSerializerRootMapDependencies' test. It used
> to test Map::WeakCellForMap which doesn't exist anymore and was
> difficult to adapt to a shared read-only heap.
>
> Bug: v8:7464
> Change-Id: I64b8e953b0e3466e003541ec8a9321e439a01d33
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1660612
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Dan Elphick <delphick@chromium.org>
> Commit-Queue: Maciej Goszczycki <goszczycki@google.com>
> Cr-Commit-Position: refs/heads/master@{#62250}

TBR: yangguo@chromium.org
Bug: v8:7464
Change-Id: Id66e781be890c5ed03d066f8c62de703d5cb435e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1667415
Reviewed-by: Dan Elphick <delphick@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62302}
This commit is contained in:
Maciej Goszczycki 2019-06-19 15:36:43 +01:00 committed by Commit Bot
parent 82622c52f5
commit a5e7c03bc6
5 changed files with 76 additions and 58 deletions

View File

@ -28,16 +28,39 @@ ReadOnlyHeap* ReadOnlyHeap::shared_ro_heap_ = nullptr;
void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) {
DCHECK_NOT_NULL(isolate);
#ifdef V8_SHARED_RO_HEAP
// Make sure we are only sharing read-only space when deserializing. Otherwise
// we would be trying to create heap objects inside an already initialized
// read-only space. Use ClearSharedHeapForTest if you need a new read-only
// space.
DCHECK_IMPLIES(shared_ro_heap_ != nullptr, des != nullptr);
bool call_once_ran = false;
base::Optional<Checksum> des_checksum;
#ifdef DEBUG
if (des != nullptr) des_checksum = des->GetChecksum();
#endif // DEBUG
base::CallOnce(&setup_ro_heap_once, [isolate, des]() {
shared_ro_heap_ = CreateAndAttachToIsolate(isolate);
if (des != nullptr) shared_ro_heap_->DeseralizeIntoIsolate(isolate, des);
});
base::CallOnce(&setup_ro_heap_once,
[isolate, des, des_checksum, &call_once_ran]() {
shared_ro_heap_ = CreateAndAttachToIsolate(isolate);
if (des != nullptr) {
#ifdef DEBUG
shared_ro_heap_->read_only_blob_checksum_ = des_checksum;
#endif // DEBUG
shared_ro_heap_->DeseralizeIntoIsolate(isolate, des);
}
call_once_ran = true;
});
USE(call_once_ran);
USE(des_checksum);
#ifdef DEBUG
const base::Optional<Checksum> last_checksum =
shared_ro_heap_->read_only_blob_checksum_;
if (last_checksum || des_checksum) {
// The read-only heap was set up from a snapshot. Make sure it's the always
// the same snapshot.
CHECK_EQ(last_checksum, des_checksum);
} else {
// The read-only heap objects were created. Make sure this happens only
// once, during this call.
CHECK(call_once_ran);
}
#endif // DEBUG
isolate->heap()->SetUpFromReadOnlyHeap(shared_ro_heap_);
if (des != nullptr) {

View File

@ -5,7 +5,10 @@
#ifndef V8_HEAP_READ_ONLY_HEAP_H_
#define V8_HEAP_READ_ONLY_HEAP_H_
#include <utility>
#include "src/base/macros.h"
#include "src/base/optional.h"
#include "src/objects/heap-object.h"
#include "src/objects/objects.h"
#include "src/roots/roots.h"
@ -61,6 +64,8 @@ class ReadOnlyHeap final {
ReadOnlySpace* read_only_space() const { return read_only_space_; }
private:
using Checksum = std::pair<uint32_t, uint32_t>;
// Creates a new read-only heap and attaches it to the provided isolate.
static ReadOnlyHeap* CreateAndAttachToIsolate(Isolate* isolate);
// Runs the read-only deserailizer and calls InitFromIsolate to complete
@ -77,10 +82,15 @@ class ReadOnlyHeap final {
std::vector<Object> read_only_object_cache_;
#ifdef V8_SHARED_RO_HEAP
#ifdef DEBUG
// The checksum of the blob the read-only heap was deserialized from, if any.
base::Optional<Checksum> read_only_blob_checksum_;
#endif // DEBUG
Address read_only_roots_[kEntriesCount];
V8_EXPORT_PRIVATE static ReadOnlyHeap* shared_ro_heap_;
#endif
#endif // V8_SHARED_RO_HEAP
explicit ReadOnlyHeap(ReadOnlySpace* ro_space) : read_only_space_(ro_space) {}
DISALLOW_COPY_AND_ASSIGN(ReadOnlyHeap);

View File

@ -5,6 +5,7 @@
#ifndef V8_SNAPSHOT_DESERIALIZER_H_
#define V8_SNAPSHOT_DESERIALIZER_H_
#include <utility>
#include <vector>
#include "src/objects/allocation-site.h"
@ -39,6 +40,9 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
~Deserializer() override;
void SetRehashability(bool v) { can_rehash_ = v; }
std::pair<uint32_t, uint32_t> GetChecksum() const {
return source_.GetChecksum();
}
protected:
// Create a deserializer from a snapshot byte source.

View File

@ -5,7 +5,10 @@
#ifndef V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
#define V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
#include <utility>
#include "src/base/logging.h"
#include "src/snapshot/serializer-common.h"
#include "src/utils/utils.h"
namespace v8 {
@ -66,6 +69,11 @@ class SnapshotByteSource final {
int position() { return position_; }
void set_position(int position) { position_ = position; }
std::pair<uint32_t, uint32_t> GetChecksum() const {
Checksum checksum(Vector<const byte>(data_, length_));
return {checksum.a(), checksum.b()};
}
private:
const byte* data_;
int length_;

View File

@ -148,8 +148,10 @@ namespace {
// Convenience wrapper around the convenience wrapper.
v8::StartupData CreateSnapshotDataBlob(const char* embedded_source) {
return CreateSnapshotDataBlobInternal(
v8::StartupData data = CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling::kClear, embedded_source);
ReadOnlyHeap::ClearSharedHeapForTest();
return data;
}
} // namespace
@ -275,53 +277,6 @@ UNINITIALIZED_TEST(StartupSerializerOnce32K) {
TestStartupSerializerOnceImpl();
}
UNINITIALIZED_TEST(StartupSerializerRootMapDependencies) {
DisableAlwaysOpt();
v8::SnapshotCreator snapshot_creator;
v8::Isolate* isolate = snapshot_creator.GetIsolate();
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
// Here is interesting retaining path:
// - FreeSpaceMap
// - Map for Map types itself
// - NullValue
// - Internalized one byte string
// - Map for Internalized one byte string
// - TheHoleValue
// - HeapNumber
// HeapNumber objects require kDoubleUnaligned on 32-bit
// platforms. So, without special measures we're risking to serialize
// object, requiring alignment before FreeSpaceMap is fully serialized.
v8::internal::Handle<Map> map(
ReadOnlyRoots(internal_isolate).one_byte_internalized_string_map(),
internal_isolate);
// Need to avoid DCHECKs inside SnapshotCreator.
snapshot_creator.SetDefaultContext(v8::Context::New(isolate));
}
v8::StartupData startup_data = snapshot_creator.CreateBlob(
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
v8::Isolate::CreateParams params;
params.snapshot_blob = &startup_data;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
isolate = v8::Isolate::New(params);
{
v8::HandleScope handle_scope(isolate);
v8::Isolate::Scope isolate_scope(isolate);
v8::Local<v8::Context> env = v8::Context::New(isolate);
env->Enter();
SanityCheck(isolate);
}
isolate->Dispose();
delete[] startup_data.data;
}
UNINITIALIZED_TEST(StartupSerializerTwice) {
DisableAlwaysOpt();
v8::Isolate* isolate = TestSerializer::NewIsolateInitialized();
@ -811,6 +766,7 @@ void TestCustomSnapshotDataBlobWithIrregexpCode(
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 =
CreateSnapshotDataBlobInternal(function_code_handling, source);
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
@ -958,6 +914,7 @@ void TypedArrayTestHelper(
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -1085,6 +1042,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobDetachedArrayBuffer) {
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -1155,6 +1113,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobOnOrOffHeapTypedArray) {
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -1208,6 +1167,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobTypedArrayNoEmbedderFieldCallback) {
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2591,6 +2551,7 @@ UNINITIALIZED_TEST(SnapshotCreatorMultipleContexts) {
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2729,6 +2690,7 @@ UNINITIALIZED_TEST(SnapshotCreatorExternalReferences) {
// Deserialize with the original external reference.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2754,6 +2716,7 @@ UNINITIALIZED_TEST(SnapshotCreatorExternalReferences) {
// Deserialize with some other external reference.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2802,6 +2765,7 @@ UNINITIALIZED_TEST(SnapshotCreatorShortExternalReferences) {
// Deserialize with an incomplete list of external references.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2862,6 +2826,7 @@ UNINITIALIZED_TEST(SnapshotCreatorNoExternalReferencesDefault) {
// Deserialize with an incomplete list of external references.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2911,6 +2876,7 @@ UNINITIALIZED_TEST(SnapshotCreatorPreparseDataAndNoOuterScope) {
// Deserialize with an incomplete list of external references.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -2950,6 +2916,7 @@ UNINITIALIZED_TEST(SnapshotCreatorArrayJoinWithKeep) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotArrayJoinWithKeep();
ReadOnlyHeap::ClearSharedHeapForTest();
// Deserialize with an incomplete list of external references.
{
@ -2977,6 +2944,7 @@ TEST(SnapshotCreatorNoExternalReferencesCustomFail1) {
// Deserialize with an incomplete list of external references.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -3002,6 +2970,7 @@ TEST(SnapshotCreatorNoExternalReferencesCustomFail2) {
// Deserialize with an incomplete list of external references.
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -3120,6 +3089,7 @@ UNINITIALIZED_TEST(SnapshotCreatorTemplates) {
}
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -3533,6 +3503,7 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
}
{
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -3667,6 +3638,7 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) {
CHECK(!blob.CanBeRehashed());
}
ReadOnlyHeap::ClearSharedHeapForTest();
i::FLAG_hash_seed = 1337;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@ -3802,6 +3774,7 @@ UNINITIALIZED_TEST(WeakArraySerializationInSnapshot) {
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
ReadOnlyHeap::ClearSharedHeapForTest();
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();