v8/test/cctest/test-serialize.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

5145 lines
184 KiB
C++
Raw Normal View History

// Copyright 2007-2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <signal.h>
#include <sys/stat.h>
Reland "[include] Split out v8.h" This is a reland of d1b27019d3bf86360ea838c317f8505fac6d3a7e Fixes include: Adding missing file to bazel build Forward-declaring classing before friend-classing them to fix win/gcc Add missing v8-isolate.h include for vtune builds Original change's description: > [include] Split out v8.h > > This moves every single class/function out of include/v8.h into a > separate header in include/, which v8.h then includes so that > externally nothing appears to have changed. > > Every include of v8.h from inside v8 has been changed to a more > fine-grained include. > > Previously inline functions defined at the bottom of v8.h would call > private non-inline functions in the V8 class. Since that class is now > in v8-initialization.h and is rarely included (as that would create > dependency cycles), this is not possible and so those methods have been > moved out of the V8 class into the namespace v8::api_internal. > > None of the previous files in include/ now #include v8.h, which means > if embedders were relying on this transitive dependency then it will > give compile failures. > > v8-inspector.h does depend on v8-scripts.h for the time being to ensure > that Chrome continue to compile but that change will be reverted once > those transitive #includes in chrome are changed to include it directly. > > Full design: > https://docs.google.com/document/d/1rTD--I8hCAr-Rho1WTumZzFKaDpEp0IJ8ejZtk4nJdA/edit?usp=sharing > > Bug: v8:11965 > Change-Id: I53b84b29581632710edc80eb11f819c2097a2877 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3097448 > Reviewed-by: Yang Guo <yangguo@chromium.org> > Reviewed-by: Camillo Bruni <cbruni@chromium.org> > Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Commit-Queue: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/main@{#76424} Cq-Include-Trybots: luci.v8.try:v8_linux_vtunejit Bug: v8:11965 Change-Id: I99f5d3a73bf8fe25b650adfaf9567dc4e44a09e6 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3113629 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Commit-Queue: Dan Elphick <delphick@chromium.org> Cr-Commit-Position: refs/heads/main@{#76460}
2021-08-23 13:01:06 +00:00
#include "include/v8-extension.h"
#include "include/v8-function.h"
#include "include/v8-locker.h"
#include "src/api/api-inl.h"
#include "src/codegen/compilation-cache.h"
#include "src/codegen/compiler.h"
#include "src/codegen/script-details.h"
#include "src/common/assert-scope.h"
#include "src/heap/heap-inl.h"
#include "src/heap/parked-scope.h"
#include "src/heap/read-only-heap.h"
#include "src/heap/safepoint.h"
#include "src/heap/spaces.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/code-serializer.h"
#include "src/snapshot/context-deserializer.h"
#include "src/snapshot/context-serializer.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/read-only-serializer.h"
#include "src/snapshot/shared-heap-deserializer.h"
#include "src/snapshot/shared-heap-serializer.h"
#include "src/snapshot/snapshot-compression.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-deserializer.h"
#include "src/snapshot/startup-serializer.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
#include "test/cctest/setup-isolate-for-tests.h"
namespace v8 {
namespace internal {
enum CodeCacheType { kLazy, kEager, kAfterExecute };
void DisableAlwaysOpt() {
// Isolates prepared for serialization do not optimize. The only exception is
// with the flag --always-turbofan.
v8_flags.always_turbofan = false;
}
// A convenience struct to simplify management of the blobs required to
// deserialize an isolate.
struct StartupBlobs {
base::Vector<const byte> startup;
base::Vector<const byte> read_only;
base::Vector<const byte> shared_space;
void Dispose() {
startup.Dispose();
read_only.Dispose();
shared_space.Dispose();
}
};
// TestSerializer is used for testing isolate serialization.
class TestSerializer {
public:
static v8::Isolate* NewIsolateInitialized() {
[builtins] Properly handle cctest heap creation in embedded builds Some cctests force fresh creation of heap constants, even though the cctest binary itself is an embedded snapshot build (i.e.: a snapshot blob exists, and a binary-embedded blob exists). This breaks a few assumptions, for example that off-heap builtins have a single, canonical off-heap code range. Unfortunately this isn't that easy to fix. I see a few alternatives: 1. In builtins setup, if an embedded blob exists, regenerate the builtins for their metadata (things like the safepoint table offset), and then replace them by off-heap trampolines. 2. As above, but deserialize the trampolines from the snapshot blob. 3. As above, but pack required metadata into the embedded blob and create trampolines from there. 4. Act as if the embedded blob does not exist. Alternative 1 does not work because the generated code can be slightly different at at runtime vs. mksnapshot-time. Alternative 2 is out because we do not have access to the snapshot blob in TestIsolate setup. Alternative 3 is probably the preferred option but would be a more involved change. This CL takes path 4. It's not an optimal solution, but it can be replace by alternative 3 later. TBR=ulan@chromium.org Bug: v8:7718, v8:7751 Change-Id: I36c024cb0179615011c886ed3978bc95f0d197ac Reviewed-on: https://chromium-review.googlesource.com/1098924 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#53886}
2018-06-20 08:55:51 +00:00
const bool kEnableSerializer = true;
const bool kGenerateHeap = true;
const bool kIsShared = false;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::Isolate* v8_isolate =
NewIsolate(kEnableSerializer, kGenerateHeap, kIsShared);
v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->Init(nullptr, nullptr, nullptr, false);
return v8_isolate;
}
// Wraps v8::Isolate::New, but with a test isolate under the hood.
// Allows flexibility to bootstrap with or without snapshot even when
// the production Isolate class has one or the other behavior baked in.
static v8::Isolate* NewIsolate(const v8::Isolate::CreateParams& params) {
[builtins] Properly handle cctest heap creation in embedded builds Some cctests force fresh creation of heap constants, even though the cctest binary itself is an embedded snapshot build (i.e.: a snapshot blob exists, and a binary-embedded blob exists). This breaks a few assumptions, for example that off-heap builtins have a single, canonical off-heap code range. Unfortunately this isn't that easy to fix. I see a few alternatives: 1. In builtins setup, if an embedded blob exists, regenerate the builtins for their metadata (things like the safepoint table offset), and then replace them by off-heap trampolines. 2. As above, but deserialize the trampolines from the snapshot blob. 3. As above, but pack required metadata into the embedded blob and create trampolines from there. 4. Act as if the embedded blob does not exist. Alternative 1 does not work because the generated code can be slightly different at at runtime vs. mksnapshot-time. Alternative 2 is out because we do not have access to the snapshot blob in TestIsolate setup. Alternative 3 is probably the preferred option but would be a more involved change. This CL takes path 4. It's not an optimal solution, but it can be replace by alternative 3 later. TBR=ulan@chromium.org Bug: v8:7718, v8:7751 Change-Id: I36c024cb0179615011c886ed3978bc95f0d197ac Reviewed-on: https://chromium-review.googlesource.com/1098924 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#53886}
2018-06-20 08:55:51 +00:00
const bool kEnableSerializer = false;
const bool kGenerateHeap = params.snapshot_blob == nullptr;
const bool kIsShared = false;
v8::Isolate* v8_isolate =
NewIsolate(kEnableSerializer, kGenerateHeap, kIsShared);
v8::Isolate::Initialize(v8_isolate, params);
return v8_isolate;
}
static v8::Isolate* NewIsolateFromBlob(const StartupBlobs& blobs) {
SnapshotData startup_snapshot(blobs.startup);
SnapshotData read_only_snapshot(blobs.read_only);
SnapshotData shared_space_snapshot(blobs.shared_space);
const bool kEnableSerializer = false;
const bool kGenerateHeap = false;
const bool kIsShared = false;
v8::Isolate* v8_isolate =
NewIsolate(kEnableSerializer, kGenerateHeap, kIsShared);
v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->Init(&startup_snapshot, &read_only_snapshot,
&shared_space_snapshot, false);
return v8_isolate;
}
static void InitializeProcessWideSharedIsolateFromBlob(
const StartupBlobs& blobs) {
base::MutexGuard guard(
i::Isolate::process_wide_shared_isolate_mutex_.Pointer());
CHECK_NULL(i::Isolate::process_wide_shared_isolate_);
SnapshotData startup_snapshot(blobs.startup);
SnapshotData read_only_snapshot(blobs.read_only);
SnapshotData shared_space_snapshot(blobs.shared_space);
const bool kEnableSerializer = false;
const bool kGenerateHeap = false;
const bool kIsShared = true;
v8::Isolate* v8_isolate =
NewIsolate(kEnableSerializer, kGenerateHeap, kIsShared);
v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->Init(&startup_snapshot, &read_only_snapshot,
&shared_space_snapshot, false);
i::Isolate::process_wide_shared_isolate_ = isolate;
}
static void DeleteProcessWideSharedIsolate() {
i::Isolate::DeleteProcessWideSharedIsolate();
}
private:
// Creates an Isolate instance configured for testing.
static v8::Isolate* NewIsolate(bool with_serializer, bool generate_heap,
bool is_shared) {
i::Isolate* isolate;
if (is_shared) {
isolate = i::Isolate::Allocate(true);
} else {
isolate = i::Isolate::New();
}
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
if (with_serializer) isolate->enable_serializer();
isolate->set_array_buffer_allocator(CcTest::array_buffer_allocator());
isolate->setup_delegate_ = new SetupIsolateDelegateForTests(generate_heap);
return v8_isolate;
}
};
static base::Vector<const byte> WritePayload(
const base::Vector<const byte>& payload) {
int length = payload.length();
byte* blob = NewArray<byte>(length);
memcpy(blob, payload.begin(), length);
return base::Vector<const byte>(const_cast<const byte*>(blob), length);
}
namespace {
// Convenience wrapper around the convenience wrapper.
v8::StartupData CreateSnapshotDataBlob(const char* embedded_source) {
v8::StartupData data = CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling::kClear, embedded_source);
return data;
}
} // namespace
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
static StartupBlobs Serialize(v8::Isolate* isolate) {
// We have to create one context. One reason for this is so that the builtins
// can be loaded from self hosted JS builtins and their addresses can be
// processed. This will clear the pending fixups array, which would otherwise
// contain GC roots that would confuse the serialization/deserialization
// process.
v8::Isolate::Scope isolate_scope(isolate);
{
v8::HandleScope scope(isolate);
v8::Context::New(isolate);
}
Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
CcTest::CollectAllAvailableGarbage(i_isolate);
IsolateSafepointScope safepoint(i_isolate->heap());
HandleScope scope(i_isolate);
DisallowGarbageCollection no_gc;
ReadOnlySerializer read_only_serializer(i_isolate,
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
Snapshot::kDefaultSerializerFlags);
read_only_serializer.SerializeReadOnlyRoots();
SharedHeapSerializer shared_space_serializer(
i_isolate, Snapshot::kDefaultSerializerFlags, &read_only_serializer);
StartupSerializer ser(i_isolate, Snapshot::kDefaultSerializerFlags,
&read_only_serializer, &shared_space_serializer);
ser.SerializeStrongReferences(no_gc);
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
ser.SerializeWeakReferencesAndDeferred();
shared_space_serializer.FinalizeSerialization();
read_only_serializer.FinalizeSerialization();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
SnapshotData startup_snapshot(&ser);
SnapshotData read_only_snapshot(&read_only_serializer);
SnapshotData shared_space_snapshot(&shared_space_serializer);
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
return {WritePayload(startup_snapshot.RawData()),
WritePayload(read_only_snapshot.RawData()),
WritePayload(shared_space_snapshot.RawData())};
}
base::Vector<const char> ConstructSource(base::Vector<const char> head,
base::Vector<const char> body,
base::Vector<const char> tail,
int repeats) {
size_t source_length = head.size() + body.size() * repeats + tail.size();
char* source = NewArray<char>(source_length);
CopyChars(source, head.begin(), head.length());
for (int i = 0; i < repeats; i++) {
CopyChars(source + head.length() + i * body.length(), body.begin(),
body.length());
}
CopyChars(source + head.length() + repeats * body.length(), tail.begin(),
tail.length());
return base::VectorOf(source, source_length);
}
static v8::Isolate* Deserialize(const StartupBlobs& blobs) {
v8::Isolate* isolate = TestSerializer::NewIsolateFromBlob(blobs);
CHECK(isolate);
return isolate;
}
static void SanityCheck(v8::Isolate* v8_isolate) {
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
v8::HandleScope scope(v8_isolate);
#ifdef VERIFY_HEAP
HeapVerifier::VerifyHeap(isolate->heap());
#endif
CHECK(isolate->global_object()->IsJSObject());
CHECK(isolate->native_context()->IsContext());
isolate->factory()->InternalizeString(base::StaticCharVector("Empty"));
}
void TestStartupSerializerOnceImpl() {
v8::Isolate* isolate = TestSerializer::NewIsolateInitialized();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
StartupBlobs blobs = Serialize(isolate);
isolate->Dispose();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
isolate = Deserialize(blobs);
{
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();
blobs.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(StartupSerializerOnce) {
DisableAlwaysOpt();
TestStartupSerializerOnceImpl();
}
UNINITIALIZED_TEST(StartupSerializerTwice) {
DisableAlwaysOpt();
v8::Isolate* isolate = TestSerializer::NewIsolateInitialized();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
StartupBlobs blobs1 = Serialize(isolate);
StartupBlobs blobs2 = Serialize(isolate);
isolate->Dispose();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
blobs1.Dispose();
isolate = Deserialize(blobs2);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> env = v8::Context::New(isolate);
env->Enter();
SanityCheck(isolate);
}
isolate->Dispose();
blobs2.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(StartupSerializerOnceRunScript) {
DisableAlwaysOpt();
v8::Isolate* isolate = TestSerializer::NewIsolateInitialized();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
StartupBlobs blobs = Serialize(isolate);
isolate->Dispose();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
isolate = Deserialize(blobs);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> env = v8::Context::New(isolate);
env->Enter();
const char* c_source = "\"1234\".length";
v8::Local<v8::Script> script = v8_compile(c_source);
v8::Maybe<int32_t> result = script->Run(isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(isolate->GetCurrentContext());
CHECK_EQ(4, result.FromJust());
}
isolate->Dispose();
blobs.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(StartupSerializerTwiceRunScript) {
DisableAlwaysOpt();
v8::Isolate* isolate = TestSerializer::NewIsolateInitialized();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
StartupBlobs blobs1 = Serialize(isolate);
StartupBlobs blobs2 = Serialize(isolate);
isolate->Dispose();
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
blobs1.Dispose();
isolate = Deserialize(blobs2);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> env = v8::Context::New(isolate);
env->Enter();
const char* c_source = "\"1234\".length";
v8::Local<v8::Script> script = v8_compile(c_source);
v8::Maybe<int32_t> result = script->Run(isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(isolate->GetCurrentContext());
CHECK_EQ(4, result.FromJust());
}
isolate->Dispose();
blobs2.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
static void SerializeContext(base::Vector<const byte>* startup_blob_out,
base::Vector<const byte>* read_only_blob_out,
base::Vector<const byte>* shared_space_blob_out,
base::Vector<const byte>* context_blob_out) {
v8::Isolate* v8_isolate = TestSerializer::NewIsolateInitialized();
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
Heap* heap = isolate->heap();
{
v8::Isolate::Scope isolate_scope(v8_isolate);
v8::Persistent<v8::Context> env;
{
HandleScope scope(isolate);
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
}
CHECK(!env.IsEmpty());
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
}
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of env.
CcTest::CollectAllAvailableGarbage(isolate);
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
}
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
HandleScope scope(isolate);
i::Context raw_context = i::Context::cast(*v8::Utils::OpenPersistent(env));
env.Reset();
IsolateSafepointScope safepoint(heap);
DisallowGarbageCollection no_gc;
SnapshotByteSink read_only_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
ReadOnlySerializer read_only_serializer(isolate,
Snapshot::kDefaultSerializerFlags);
read_only_serializer.SerializeReadOnlyRoots();
SharedHeapSerializer shared_space_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &read_only_serializer);
SnapshotByteSink startup_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
StartupSerializer startup_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &read_only_serializer,
&shared_space_serializer);
startup_serializer.SerializeStrongReferences(no_gc);
SnapshotByteSink context_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
ContextSerializer context_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &startup_serializer,
v8::SerializeInternalFieldsCallback());
context_serializer.Serialize(&raw_context, no_gc);
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
startup_serializer.SerializeWeakReferencesAndDeferred();
shared_space_serializer.FinalizeSerialization();
read_only_serializer.FinalizeSerialization();
SnapshotData read_only_snapshot(&read_only_serializer);
SnapshotData shared_space_snapshot(&shared_space_serializer);
SnapshotData startup_snapshot(&startup_serializer);
SnapshotData context_snapshot(&context_serializer);
*context_blob_out = WritePayload(context_snapshot.RawData());
*startup_blob_out = WritePayload(startup_snapshot.RawData());
*read_only_blob_out = WritePayload(read_only_snapshot.RawData());
*shared_space_blob_out = WritePayload(shared_space_snapshot.RawData());
}
v8_isolate->Dispose();
}
#ifdef SNAPSHOT_COMPRESSION
UNINITIALIZED_TEST(SnapshotCompression) {
DisableAlwaysOpt();
base::Vector<const byte> startup_blob;
base::Vector<const byte> read_only_blob;
base::Vector<const byte> shared_space_blob;
base::Vector<const byte> context_blob;
SerializeContext(&startup_blob, &read_only_blob, &shared_space_blob,
&context_blob);
SnapshotData original_snapshot_data(context_blob);
SnapshotData compressed =
i::SnapshotCompression::Compress(&original_snapshot_data);
SnapshotData decompressed =
i::SnapshotCompression::Decompress(compressed.RawData());
CHECK_EQ(context_blob, decompressed.RawData());
startup_blob.Dispose();
read_only_blob.Dispose();
shared_space_blob.Dispose();
context_blob.Dispose();
}
#endif // SNAPSHOT_COMPRESSION
UNINITIALIZED_TEST(ContextSerializerContext) {
DisableAlwaysOpt();
base::Vector<const byte> startup_blob;
base::Vector<const byte> read_only_blob;
base::Vector<const byte> shared_space_blob;
base::Vector<const byte> context_blob;
SerializeContext(&startup_blob, &read_only_blob, &shared_space_blob,
&context_blob);
StartupBlobs blobs = {startup_blob, read_only_blob, shared_space_blob};
v8::Isolate* v8_isolate = TestSerializer::NewIsolateFromBlob(blobs);
CHECK(v8_isolate);
{
v8::Isolate::Scope isolate_scope(v8_isolate);
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
HandleScope handle_scope(isolate);
Handle<Object> root;
Handle<JSGlobalProxy> global_proxy =
isolate->factory()->NewUninitializedJSGlobalProxy(
JSGlobalProxy::SizeWithEmbedderFields(0));
{
SnapshotData snapshot_data(context_blob);
root = ContextDeserializer::DeserializeContext(
isolate, &snapshot_data, false, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
}
Handle<Object> root2;
{
SnapshotData snapshot_data(context_blob);
root2 = ContextDeserializer::DeserializeContext(
isolate, &snapshot_data, false, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2));
}
context_blob.Dispose();
}
v8_isolate->Dispose();
blobs.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
static void SerializeCustomContext(
base::Vector<const byte>* startup_blob_out,
base::Vector<const byte>* read_only_blob_out,
base::Vector<const byte>* shared_space_blob_out,
base::Vector<const byte>* context_blob_out) {
v8::Isolate* v8_isolate = TestSerializer::NewIsolateInitialized();
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
{
v8::Isolate::Scope isolate_scope(v8_isolate);
v8::Persistent<v8::Context> env;
{
HandleScope scope(isolate);
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
}
CHECK(!env.IsEmpty());
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
// After execution, e's function context refers to the global object.
CompileRun(
"var e;"
"(function() {"
" e = function(s) { return eval (s); }"
"})();"
"var o = this;"
"var r = Math.random();"
"var c = Math.sin(0) + Math.cos(0);"
"var f = (function(a, b) { return a + b; }).bind(1, 2, 3);"
"var s = parseInt('12345');"
"var p = 0;"
"(async ()=>{ p = await 42; })();");
base::Vector<const char> source = ConstructSource(
base::StaticCharVector("function g() { return [,"),
base::StaticCharVector("1,"),
base::StaticCharVector("];} a = g(); b = g(); b.push(1);"), 100000);
v8::MaybeLocal<v8::String> source_str =
v8::String::NewFromUtf8(v8_isolate, source.begin(),
v8::NewStringType::kNormal, source.length());
CompileRun(source_str.ToLocalChecked());
source.Dispose();
}
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of env.
CcTest::CollectAllAvailableGarbage(isolate);
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
}
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
HandleScope scope(isolate);
i::Context raw_context = i::Context::cast(*v8::Utils::OpenPersistent(env));
env.Reset();
IsolateSafepointScope safepoint(isolate->heap());
DisallowGarbageCollection no_gc;
SnapshotByteSink read_only_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
ReadOnlySerializer read_only_serializer(isolate,
Snapshot::kDefaultSerializerFlags);
read_only_serializer.SerializeReadOnlyRoots();
SharedHeapSerializer shared_space_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &read_only_serializer);
SnapshotByteSink startup_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
StartupSerializer startup_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &read_only_serializer,
&shared_space_serializer);
startup_serializer.SerializeStrongReferences(no_gc);
SnapshotByteSink context_sink;
Reland "[snapshot] Expose the serializer through %SerializeDeserializeNow" This is a reland of ad5b005e38e78275a1bb8962ecb6cc048481ac82 Original change's description: > [snapshot] Expose the serializer through %SerializeDeserializeNow > > ... in order to exercise the snapshot/ component from mjsunit tests > and fuzzers. > > * Since the serializer and deserializer can now be called at any time > instead of only in a tightly controlled environment, several > assumptions (such as an empty execution stack, no microtasks, no > handles) no longer hold and had to be made configurable through > SerializerFlags. > > * Root iteration now skips more root categories which were previously > guaranteed to be empty (e.g. the stack, microtask queue, handles). > > * The %SerializeDeserializeNow runtime function triggers > serialization, deserialization, and heap verification on the current > isolate and native context. > > Support is not yet complete and will be extended in future work. Once > all mjsunit tests successfully run, we can add a new test mode to > stress serialization. > > Bug: v8:10416 > Change-Id: Ie7ff441a761257dd7f256d0a33e73227850074ac > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2159495 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#67423} Tbr: delphick@chromium.org,ulan@chromium.org Bug: v8:10416 Change-Id: Ibed04c0f0b72fabcf811d8b18a1479391a11568b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2170090 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67426}
2020-04-28 09:53:18 +00:00
ContextSerializer context_serializer(
isolate, Snapshot::kDefaultSerializerFlags, &startup_serializer,
v8::SerializeInternalFieldsCallback());
context_serializer.Serialize(&raw_context, no_gc);
Reland "[snapshot] Move builtins to dedicated snapshot area" This is a reland of 49e3bfd572dcc60f2c97c732bcc4c918cbc3fd9f Original change's description: > [snapshot] Move builtins to dedicated snapshot area > > As a first step towards lazy builtin deserialization, this CL moves > builtins to their own dedicated area in the snapshot blob, physically > located after startup data and before context-specific data. > > The startup- and partial serializers now serialize all seen builtins as > references, i.e. they only encode the relevant builtin id (taking care > to preserve special behavior around the interpreter trampoline and > CompileLazy). Builtins are later fully serialized by the > BuiltinSerializer. The separate blobs are finally glued together by > CreateSnapshotBlob. > > Deserialization takes the same steps: when we see builtin reference > bytecodes before builtins have been deserialized, we push to a list of > deferred builtin references. After builtin deserialization, this list is > iterated and all builtin references are fixed up. > > Bug: v8:6624 > Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng > Change-Id: Idee42fa9c92bdbe8d5b8c4b8bf3ca9dd39634004 > Reviewed-on: https://chromium-review.googlesource.com/610225 > Reviewed-by: Michael Lippautz <mlippautz@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#47596} Bug: v8:6624 Change-Id: I8bfac56c482d992987c270bf0fea7acd9e4ca0c7 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/638271 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#47705}
2017-08-28 15:49:54 +00:00
startup_serializer.SerializeWeakReferencesAndDeferred();
shared_space_serializer.FinalizeSerialization();
read_only_serializer.FinalizeSerialization();
SnapshotData read_only_snapshot(&read_only_serializer);
SnapshotData shared_space_snapshot(&shared_space_serializer);
SnapshotData startup_snapshot(&startup_serializer);
SnapshotData context_snapshot(&context_serializer);
*context_blob_out = WritePayload(context_snapshot.RawData());
*startup_blob_out = WritePayload(startup_snapshot.RawData());
*read_only_blob_out = WritePayload(read_only_snapshot.RawData());
*shared_space_blob_out = WritePayload(shared_space_snapshot.RawData());
}
v8_isolate->Dispose();
}
UNINITIALIZED_TEST(ContextSerializerCustomContext) {
DisableAlwaysOpt();
base::Vector<const byte> startup_blob;
base::Vector<const byte> read_only_blob;
base::Vector<const byte> shared_space_blob;
base::Vector<const byte> context_blob;
SerializeCustomContext(&startup_blob, &read_only_blob, &shared_space_blob,
&context_blob);
StartupBlobs blobs = {startup_blob, read_only_blob, shared_space_blob};
v8::Isolate* v8_isolate = TestSerializer::NewIsolateFromBlob(blobs);
CHECK(v8_isolate);
{
v8::Isolate::Scope isolate_scope(v8_isolate);
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
HandleScope handle_scope(isolate);
Handle<Object> root;
Handle<JSGlobalProxy> global_proxy =
isolate->factory()->NewUninitializedJSGlobalProxy(
JSGlobalProxy::SizeWithEmbedderFields(0));
{
SnapshotData snapshot_data(context_blob);
root = ContextDeserializer::DeserializeContext(
isolate, &snapshot_data, false, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
// Add context to the weak native context list
context->set(Context::NEXT_CONTEXT_LINK,
isolate->heap()->native_contexts_list(),
UPDATE_WRITE_BARRIER);
isolate->heap()->set_native_contexts_list(*context);
CHECK(context->global_proxy() == *global_proxy);
Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o");
Handle<JSObject> global_object(context->global_object(), isolate);
Handle<Object> property =
JSReceiver::GetDataProperty(isolate, global_object, o);
CHECK(property.is_identical_to(global_proxy));
v8::Local<v8::Context> v8_context = v8::Utils::ToLocal(context);
v8::Context::Scope context_scope(v8_context);
double r = CompileRun("r")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Value();
CHECK(0.0 <= r && r < 1.0);
// Math.random still works.
double random = CompileRun("Math.random()")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Value();
CHECK(0.0 <= random && random < 1.0);
double c = CompileRun("c")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Value();
CHECK_EQ(1, c);
int f = CompileRun("f()")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(v8_isolate->GetCurrentContext())
.FromJust();
CHECK_EQ(5, f);
f = CompileRun("e('f()')")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(v8_isolate->GetCurrentContext())
.FromJust();
CHECK_EQ(5, f);
v8::Local<v8::String> s = CompileRun("s")
->ToString(v8_isolate->GetCurrentContext())
.ToLocalChecked();
CHECK(s->Equals(v8_isolate->GetCurrentContext(), v8_str("12345"))
.FromJust());
v8::Local<v8::String> p = CompileRun("p")
->ToString(v8_isolate->GetCurrentContext())
.ToLocalChecked();
CHECK(
p->Equals(v8_isolate->GetCurrentContext(), v8_str("42")).FromJust());
int a = CompileRun("a.length")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(v8_isolate->GetCurrentContext())
.FromJust();
CHECK_EQ(100001, a);
int b = CompileRun("b.length")
->ToNumber(v8_isolate->GetCurrentContext())
.ToLocalChecked()
->Int32Value(v8_isolate->GetCurrentContext())
.FromJust();
CHECK_EQ(100002, b);
}
context_blob.Dispose();
}
v8_isolate->Dispose();
blobs.Dispose();
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlob1) {
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate1 = TestSerializer::NewIsolate(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result =
CompileRun("f()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(42, result.FromJust());
CHECK(CompileRun("this.g")->IsUndefined());
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
static void UnreachableCallback(const FunctionCallbackInfo<Value>& args) {
UNREACHABLE();
}
UNINITIALIZED_TEST(CustomSnapshotDataBlobOverwriteGlobal) {
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test that the snapshot overwrites the object template when there are
// duplicate global properties.
v8::Isolate* isolate1 = TestSerializer::NewIsolate(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate1);
global_template->Set(
isolate1, "f",
v8::FunctionTemplate::New(isolate1, UnreachableCallback));
v8::Local<v8::Context> context =
v8::Context::New(isolate1, nullptr, global_template);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result =
CompileRun("f()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(42, result.FromJust());
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(CustomSnapshotDataBlobStringNotInternalized) {
DisableAlwaysOpt();
const char* source1 =
R"javascript(
Reland "[heap] pre-populate the single_character_string_cache" This is a reland of commit 07e11a64e4394de038722be84bea3ec51812ce24. The original change removed the fill_thehole_and_call_runtime bailout in StringBuiltinsAssembler::StringToArray() so when the string is external and cannot be unpacked, the FixedArray won't be filled with holes before we call into the runtime, thus failing a heap verification if a GC happens before the array is filled. This reland adds back the bailout for this case. Bug: v8:12718, chromium:1330410 Original change's description: > [heap] pre-populate the single_character_string_cache > > This simplifies the code and removes the runtime overhead of > spontaneously adding strings to the cache. > > Bug: v8:12718 > Change-Id: I2ed49bd82e3baf2563eeb8f463be72c0308c52c5 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3616553 > Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> > Reviewed-by: Tobias Tebbi <tebbi@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#80803} Change-Id: I25e8724d511a8d0d971fa2a9b6ba8a0eafce4413 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3793525 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#82082}
2022-07-29 10:35:23 +00:00
// String would be internalized if it came from a literal so create "AB"
// via a function call.
Reland "[heap] pre-populate the single_character_string_cache" This is a reland of commit 07e11a64e4394de038722be84bea3ec51812ce24. The original change removed the fill_thehole_and_call_runtime bailout in StringBuiltinsAssembler::StringToArray() so when the string is external and cannot be unpacked, the FixedArray won't be filled with holes before we call into the runtime, thus failing a heap verification if a GC happens before the array is filled. This reland adds back the bailout for this case. Bug: v8:12718, chromium:1330410 Original change's description: > [heap] pre-populate the single_character_string_cache > > This simplifies the code and removes the runtime overhead of > spontaneously adding strings to the cache. > > Bug: v8:12718 > Change-Id: I2ed49bd82e3baf2563eeb8f463be72c0308c52c5 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3616553 > Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> > Reviewed-by: Tobias Tebbi <tebbi@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#80803} Change-Id: I25e8724d511a8d0d971fa2a9b6ba8a0eafce4413 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3793525 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#82082}
2022-07-29 10:35:23 +00:00
var global = String.fromCharCode(65, 66);
function f() { return global; }
)javascript";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate1 = TestSerializer::NewIsolate(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope c_scope(context);
v8::Local<v8::Value> result = CompileRun("f()").As<v8::Value>();
CHECK(result->IsString());
i::String str = *v8::Utils::OpenHandle(*result.As<v8::String>());
Reland "[heap] pre-populate the single_character_string_cache" This is a reland of commit 07e11a64e4394de038722be84bea3ec51812ce24. The original change removed the fill_thehole_and_call_runtime bailout in StringBuiltinsAssembler::StringToArray() so when the string is external and cannot be unpacked, the FixedArray won't be filled with holes before we call into the runtime, thus failing a heap verification if a GC happens before the array is filled. This reland adds back the bailout for this case. Bug: v8:12718, chromium:1330410 Original change's description: > [heap] pre-populate the single_character_string_cache > > This simplifies the code and removes the runtime overhead of > spontaneously adding strings to the cache. > > Bug: v8:12718 > Change-Id: I2ed49bd82e3baf2563eeb8f463be72c0308c52c5 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3616553 > Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> > Reviewed-by: Tobias Tebbi <tebbi@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#80803} Change-Id: I25e8724d511a8d0d971fa2a9b6ba8a0eafce4413 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3793525 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#82082}
2022-07-29 10:35:23 +00:00
CHECK_EQ(std::string(str.ToCString().get()), "AB");
CHECK(!str.IsInternalizedString());
CHECK(!i::ReadOnlyHeap::Contains(str));
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.
FreeCurrentEmbeddedBlob();
}
namespace {
void TestCustomSnapshotDataBlobWithIrregexpCode(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling) {
DisableAlwaysOpt();
const char* source =
"var re1 = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//;\n"
"function f() { return '/* a comment */'.search(re1); }\n"
"function g() { return 'not a comment'.search(re1); }\n"
"function h() { return '// this is a comment'.search(re1); }\n"
"var re2 = /a/;\n"
"function i() { return '/* a comment */'.search(re2); }\n"
"f(); f(); g(); g(); h(); h(); i(); i();\n";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 =
CreateSnapshotDataBlobInternal(function_code_handling, source);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate1 = TestSerializer::NewIsolate(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope c_scope(context);
{
// Check that compiled irregexp code has not been flushed prior to
// serialization.
i::Handle<i::JSRegExp> re =
Utils::OpenHandle(*CompileRun("re1").As<v8::RegExp>());
CHECK_EQ(re->HasCompiledCode(),
function_code_handling ==
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
{
v8::Maybe<int32_t> result =
CompileRun("f()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(0, result.FromJust());
}
{
v8::Maybe<int32_t> result =
CompileRun("g()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(-1, result.FromJust());
}
{
v8::Maybe<int32_t> result =
CompileRun("h()")->Int32Value(isolate1->GetCurrentContext());
CHECK_EQ(-1, result.FromJust());
}
{
// Check that ATOM regexp remains valid.
i::Handle<i::JSRegExp> re =
Utils::OpenHandle(*CompileRun("re2").As<v8::RegExp>());
CHECK_EQ(re->type_tag(), JSRegExp::ATOM);
CHECK(!re->HasCompiledCode());
}
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.
FreeCurrentEmbeddedBlob();
}
} // namespace
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithIrregexpCodeKeepCode) {
TestCustomSnapshotDataBlobWithIrregexpCode(
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithIrregexpCodeClearCode) {
TestCustomSnapshotDataBlobWithIrregexpCode(
v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(SnapshotChecksum) {
Reland "[snapshot] add checksum to startup snapshot" This is a reland of bcb8d49b2c655a3faf8aa45a29db53793fcfae4b TBR=petermarshall@chromium.org Original change's description: > [snapshot] add checksum to startup snapshot > > We already had checksumming for code cache data. We now extend > checksumming to the startup snapshot to catch data corruption early. > > The performance impact for deserialization is a regression of 1-2%, > which should be acceptable. > > Sample output for the included test with --profile-deserialization: > > [Verifying snapshot checksum took 0.023 ms] > [Deserializing isolate (134348 bytes) took 1.891 ms] > [Verifying snapshot checksum took 0.024 ms] > [Deserializing isolate (134348 bytes) took 1.654 ms] > [Deserializing context #0 (47208 bytes) took 0.331 ms] > Deserialization will reserve: > 208168 bytes per isolate > 123368 bytes per context #0 > Snapshot blob consists of: > 134492 bytes in 6 chunks for startup > 115272 bytes for builtins > 47152 bytes in 31 chunks for context #0 > [Verifying snapshot checksum took 0.048 ms] > [Verifying snapshot checksum took 0.043 ms] > > R=peria@chromium.org, petermarshall@chromium.org > > Bug: chromium:881417 > Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng > Change-Id: Ibc57520d459c86be8972f731aa35045b5e3751d7 > Reviewed-on: https://chromium-review.googlesource.com/1241874 > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Commit-Queue: Yang Guo <yangguo@chromium.org> > Cr-Commit-Position: refs/heads/master@{#56217} Bug: chromium:881417 Change-Id: I037f378fc2d45c3e0fa670bf538df68cbba5c53c Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/1243191 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#56224}
2018-09-25 09:19:30 +00:00
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
Reland "[snapshot] add checksum to startup snapshot" This is a reland of bcb8d49b2c655a3faf8aa45a29db53793fcfae4b TBR=petermarshall@chromium.org Original change's description: > [snapshot] add checksum to startup snapshot > > We already had checksumming for code cache data. We now extend > checksumming to the startup snapshot to catch data corruption early. > > The performance impact for deserialization is a regression of 1-2%, > which should be acceptable. > > Sample output for the included test with --profile-deserialization: > > [Verifying snapshot checksum took 0.023 ms] > [Deserializing isolate (134348 bytes) took 1.891 ms] > [Verifying snapshot checksum took 0.024 ms] > [Deserializing isolate (134348 bytes) took 1.654 ms] > [Deserializing context #0 (47208 bytes) took 0.331 ms] > Deserialization will reserve: > 208168 bytes per isolate > 123368 bytes per context #0 > Snapshot blob consists of: > 134492 bytes in 6 chunks for startup > 115272 bytes for builtins > 47152 bytes in 31 chunks for context #0 > [Verifying snapshot checksum took 0.048 ms] > [Verifying snapshot checksum took 0.043 ms] > > R=peria@chromium.org, petermarshall@chromium.org > > Bug: chromium:881417 > Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng > Change-Id: Ibc57520d459c86be8972f731aa35045b5e3751d7 > Reviewed-on: https://chromium-review.googlesource.com/1241874 > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Commit-Queue: Yang Guo <yangguo@chromium.org> > Cr-Commit-Position: refs/heads/master@{#56217} Bug: chromium:881417 Change-Id: I037f378fc2d45c3e0fa670bf538df68cbba5c53c Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/1243191 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#56224}
2018-09-25 09:19:30 +00:00
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
CHECK(i::Snapshot::VerifyChecksum(&data1));
const_cast<char*>(data1.data)[142] = data1.data[142] ^ 4; // Flip a bit.
CHECK(!i::Snapshot::VerifyChecksum(&data1));
delete[] data1.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
Reland "[snapshot] add checksum to startup snapshot" This is a reland of bcb8d49b2c655a3faf8aa45a29db53793fcfae4b TBR=petermarshall@chromium.org Original change's description: > [snapshot] add checksum to startup snapshot > > We already had checksumming for code cache data. We now extend > checksumming to the startup snapshot to catch data corruption early. > > The performance impact for deserialization is a regression of 1-2%, > which should be acceptable. > > Sample output for the included test with --profile-deserialization: > > [Verifying snapshot checksum took 0.023 ms] > [Deserializing isolate (134348 bytes) took 1.891 ms] > [Verifying snapshot checksum took 0.024 ms] > [Deserializing isolate (134348 bytes) took 1.654 ms] > [Deserializing context #0 (47208 bytes) took 0.331 ms] > Deserialization will reserve: > 208168 bytes per isolate > 123368 bytes per context #0 > Snapshot blob consists of: > 134492 bytes in 6 chunks for startup > 115272 bytes for builtins > 47152 bytes in 31 chunks for context #0 > [Verifying snapshot checksum took 0.048 ms] > [Verifying snapshot checksum took 0.043 ms] > > R=peria@chromium.org, petermarshall@chromium.org > > Bug: chromium:881417 > Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng > Change-Id: Ibc57520d459c86be8972f731aa35045b5e3751d7 > Reviewed-on: https://chromium-review.googlesource.com/1241874 > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Commit-Queue: Yang Guo <yangguo@chromium.org> > Cr-Commit-Position: refs/heads/master@{#56217} Bug: chromium:881417 Change-Id: I037f378fc2d45c3e0fa670bf538df68cbba5c53c Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Reviewed-on: https://chromium-review.googlesource.com/1243191 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#56224}
2018-09-25 09:19:30 +00:00
}
struct InternalFieldData {
uint32_t data;
};
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
void* data) {
if (data == reinterpret_cast<void*>(2000)) {
// Used for SnapshotCreatorTemplates test. We check that none of the fields
// have been cleared yet.
CHECK_NOT_NULL(holder->GetAlignedPointerFromInternalField(1));
} else {
CHECK_EQ(reinterpret_cast<void*>(2016), data);
}
if (index != 1) return {nullptr, 0};
InternalFieldData* embedder_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index));
if (embedder_field == nullptr) return {nullptr, 0};
int size = sizeof(*embedder_field);
char* payload = new char[size];
// We simply use memcpy to serialize the content.
memcpy(payload, embedder_field, size);
return {payload, size};
}
std::vector<InternalFieldData*> deserialized_data;
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
v8::StartupData payload, void* data) {
if (payload.raw_size == 0) {
holder->SetAlignedPointerInInternalField(index, nullptr);
return;
}
CHECK_EQ(reinterpret_cast<void*>(2017), data);
InternalFieldData* embedder_field = new InternalFieldData{0};
memcpy(embedder_field, payload.data, payload.raw_size);
holder->SetAlignedPointerInInternalField(index, embedder_field);
deserialized_data.push_back(embedder_field);
}
using Int32Expectations = std::vector<std::tuple<const char*, int32_t>>;
void TestInt32Expectations(const Int32Expectations& expectations) {
for (const auto& e : expectations) {
ExpectInt32(std::get<0>(e), std::get<1>(e));
}
}
void TypedArrayTestHelper(
const char* code, const Int32Expectations& expectations,
const char* code_to_run_after_restore = nullptr,
const Int32Expectations& after_restore_expectations = Int32Expectations(),
v8::ArrayBuffer::Allocator* allocator = nullptr) {
DisableAlwaysOpt();
i::v8_flags.allow_natives_syntax = true;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(code);
TestInt32Expectations(expectations);
creator.SetDefaultContext(
context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, reinterpret_cast<void*>(2016)));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator =
allocator != nullptr ? allocator : CcTest::array_buffer_allocator();
v8::Isolate* isolate = TestSerializer::NewIsolate(create_params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(
isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(),
v8::MaybeLocal<v8::Value>(),
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields,
reinterpret_cast<void*>(2017)));
CHECK(deserialized_data.empty()); // We do not expect any embedder data.
v8::Context::Scope c_scope(context);
TestInt32Expectations(expectations);
if (code_to_run_after_restore) {
CompileRun(code_to_run_after_restore);
}
TestInt32Expectations(after_restore_expectations);
}
isolate->Dispose();
delete[] blob.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithOffHeapTypedArray) {
const char* code =
"var x = new Uint8Array(128);"
"x[0] = 12;"
"var arr = new Array(17);"
"arr[1] = 24;"
"var y = new Uint32Array(arr);"
"var buffer = new ArrayBuffer(128);"
"var z = new Int16Array(buffer);"
"z[0] = 48;";
Int32Expectations expectations = {std::make_tuple("x[0]", 12),
std::make_tuple("y[1]", 24),
std::make_tuple("z[0]", 48)};
TypedArrayTestHelper(code, expectations);
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobSharedArrayBuffer) {
const char* code =
"var x = new Int32Array([12, 24, 48, 96]);"
"var y = new Uint8Array(x.buffer)";
Int32Expectations expectations = {
std::make_tuple("x[0]", 12),
std::make_tuple("x[1]", 24),
#if !V8_TARGET_BIG_ENDIAN
std::make_tuple("y[0]", 12),
std::make_tuple("y[1]", 0),
std::make_tuple("y[2]", 0),
std::make_tuple("y[3]", 0),
std::make_tuple("y[4]", 24)
#else
std::make_tuple("y[3]", 12),
std::make_tuple("y[2]", 0),
std::make_tuple("y[1]", 0),
std::make_tuple("y[0]", 0),
std::make_tuple("y[7]", 24)
#endif
};
TypedArrayTestHelper(code, expectations);
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobArrayBufferWithOffset) {
const char* code =
"var x = new Int32Array([12, 24, 48, 96]);"
"var y = new Int32Array(x.buffer, 4, 2)";
Int32Expectations expectations = {
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
std::make_tuple("x[1]", 24),
std::make_tuple("x[2]", 48),
std::make_tuple("y[0]", 24),
std::make_tuple("y[1]", 48),
};
// Verify that the typed arrays use the same buffer (not independent copies).
const char* code_to_run_after_restore = "x[2] = 57; y[0] = 42;";
Int32Expectations after_restore_expectations = {
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
std::make_tuple("x[1]", 42),
std::make_tuple("y[1]", 57),
};
TypedArrayTestHelper(code, expectations, code_to_run_after_restore,
after_restore_expectations);
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobDataView) {
const char* code =
"var x = new Int8Array([1, 2, 3, 4]);"
"var v = new DataView(x.buffer)";
Int32Expectations expectations = {std::make_tuple("v.getInt8(0)", 1),
std::make_tuple("v.getInt8(1)", 2),
std::make_tuple("v.getInt16(0)", 258),
std::make_tuple("v.getInt16(1)", 515)};
TypedArrayTestHelper(code, expectations);
}
namespace {
class AlternatingArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
AlternatingArrayBufferAllocator()
: allocation_fails_(false),
allocator_(v8::ArrayBuffer::Allocator::NewDefaultAllocator()) {}
~AlternatingArrayBufferAllocator() { delete allocator_; }
void* Allocate(size_t length) override {
allocation_fails_ = !allocation_fails_;
if (allocation_fails_) return nullptr;
return allocator_->Allocate(length);
}
void* AllocateUninitialized(size_t length) override {
return this->Allocate(length);
}
void Free(void* data, size_t size) override { allocator_->Free(data, size); }
void* Reallocate(void* data, size_t old_length, size_t new_length) override {
return allocator_->Reallocate(data, old_length, new_length);
}
private:
bool allocation_fails_;
v8::ArrayBuffer::Allocator* allocator_;
};
} // anonymous namespace
UNINITIALIZED_TEST(CustomSnapshotManyArrayBuffers) {
const char* code =
"var buffers = [];"
"for (let i = 0; i < 70; i++) buffers.push(new Uint8Array(1000));";
Int32Expectations expectations = {std::make_tuple("buffers.length", 70)};
std::unique_ptr<v8::ArrayBuffer::Allocator> allocator(
new AlternatingArrayBufferAllocator());
TypedArrayTestHelper(code, expectations, nullptr, Int32Expectations(),
allocator.get());
}
UNINITIALIZED_TEST(CustomSnapshotDataBlobDetachedArrayBuffer) {
const char* code =
"var x = new Int16Array([12, 24, 48]);"
"%ArrayBufferDetach(x.buffer);";
Int32Expectations expectations = {std::make_tuple("x.buffer.byteLength", 0),
std::make_tuple("x.length", 0)};
DisableAlwaysOpt();
i::v8_flags.allow_natives_syntax = true;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(code);
TestInt32Expectations(expectations);
creator.SetDefaultContext(
context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, reinterpret_cast<void*>(2016)));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = TestSerializer::NewIsolate(create_params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(
isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(),
v8::MaybeLocal<v8::Value>(),
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields,
reinterpret_cast<void*>(2017)));
v8::Context::Scope c_scope(context);
TestInt32Expectations(expectations);
v8::Local<v8::Value> x = CompileRun("x");
CHECK(x->IsTypedArray());
i::Handle<i::JSTypedArray> array =
i::Handle<i::JSTypedArray>::cast(v8::Utils::OpenHandle(*x));
CHECK(array->WasDetached());
}
isolate->Dispose();
delete[] blob.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
i::Handle<i::JSArrayBuffer> GetBufferFromTypedArray(
v8::Local<v8::Value> typed_array) {
CHECK(typed_array->IsTypedArray());
i::Handle<i::JSArrayBufferView> view = i::Handle<i::JSArrayBufferView>::cast(
v8::Utils::OpenHandle(*typed_array));
return i::handle(i::JSArrayBuffer::cast(view->buffer()), view->GetIsolate());
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobOnOrOffHeapTypedArray) {
const char* code =
"var x = new Uint8Array(8);"
"x[0] = 12;"
"x[7] = 24;"
"var y = new Int16Array([12, 24, 48]);"
"var z = new Int32Array(64);"
"z[0] = 96;";
Int32Expectations expectations = {
std::make_tuple("x[0]", 12), std::make_tuple("x[7]", 24),
std::make_tuple("y[2]", 48), std::make_tuple("z[0]", 96)};
DisableAlwaysOpt();
i::v8_flags.allow_natives_syntax = true;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(code);
TestInt32Expectations(expectations);
i::Handle<i::JSArrayBuffer> buffer =
GetBufferFromTypedArray(CompileRun("x"));
// The resulting buffer should be on-heap.
ArrayBuffer refactoring in preparation for CagedPointers The main changes of this CL are: It should no longer be assumed that an empty ArrayBuffer has a nullptr backing store. This is in preparation for the move to caged pointers, which cannot represent nullptr, and will instead likely provide a EmptyBackingStore constant pointing inside the virtual memory cage. For that reason, a new JSArrayBuffer::IsEmpty() helper is introduced, which should be used instead of checking against nullptr. CodeStubAssembler::GetTypedArrayBuffer now checks for on-heap TypedArrays instead of comparing the backing store pointer to nullptr. This is consistent with the implementation in JSTypedArray::GetBuffer. v8::ArrayBufferView::CopyContents now uses JSTypedArray::DataPtr instead of relying on nullptr backing stores to handle on-heap TypedArrays. The serializer and deserializer now check for IsEmpty() and use the kEmptyBackingStoreRefSentinel value to serialize empty backing stores. Empty ArrayBuffers allocated for on-heap TypedArrays now have a byte_length of zero. This allows removing the allocation_length() (and allocation_buffer()) methods, which were only (incorrectly, as they don't account for GSABs) used for memory measurements. Bug: chromium:1218005 Change-Id: Ib889ccf855f68525f7a614f3963e46ea56865fa3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3297709 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Samuel Groß <saelo@chromium.org> Cr-Commit-Position: refs/heads/main@{#78069}
2021-11-23 18:11:23 +00:00
CHECK(buffer->IsEmpty());
creator.SetDefaultContext(
context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, reinterpret_cast<void*>(2016)));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = TestSerializer::NewIsolate(create_params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(
isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(),
v8::MaybeLocal<v8::Value>(),
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields,
reinterpret_cast<void*>(2017)));
v8::Context::Scope c_scope(context);
TestInt32Expectations(expectations);
i::Handle<i::JSArrayBuffer> buffer =
GetBufferFromTypedArray(CompileRun("x"));
// The resulting buffer should be on-heap.
ArrayBuffer refactoring in preparation for CagedPointers The main changes of this CL are: It should no longer be assumed that an empty ArrayBuffer has a nullptr backing store. This is in preparation for the move to caged pointers, which cannot represent nullptr, and will instead likely provide a EmptyBackingStore constant pointing inside the virtual memory cage. For that reason, a new JSArrayBuffer::IsEmpty() helper is introduced, which should be used instead of checking against nullptr. CodeStubAssembler::GetTypedArrayBuffer now checks for on-heap TypedArrays instead of comparing the backing store pointer to nullptr. This is consistent with the implementation in JSTypedArray::GetBuffer. v8::ArrayBufferView::CopyContents now uses JSTypedArray::DataPtr instead of relying on nullptr backing stores to handle on-heap TypedArrays. The serializer and deserializer now check for IsEmpty() and use the kEmptyBackingStoreRefSentinel value to serialize empty backing stores. Empty ArrayBuffers allocated for on-heap TypedArrays now have a byte_length of zero. This allows removing the allocation_length() (and allocation_buffer()) methods, which were only (incorrectly, as they don't account for GSABs) used for memory measurements. Bug: chromium:1218005 Change-Id: Ib889ccf855f68525f7a614f3963e46ea56865fa3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3297709 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Samuel Groß <saelo@chromium.org> Cr-Commit-Position: refs/heads/main@{#78069}
2021-11-23 18:11:23 +00:00
CHECK(buffer->IsEmpty());
buffer = GetBufferFromTypedArray(CompileRun("y"));
ArrayBuffer refactoring in preparation for CagedPointers The main changes of this CL are: It should no longer be assumed that an empty ArrayBuffer has a nullptr backing store. This is in preparation for the move to caged pointers, which cannot represent nullptr, and will instead likely provide a EmptyBackingStore constant pointing inside the virtual memory cage. For that reason, a new JSArrayBuffer::IsEmpty() helper is introduced, which should be used instead of checking against nullptr. CodeStubAssembler::GetTypedArrayBuffer now checks for on-heap TypedArrays instead of comparing the backing store pointer to nullptr. This is consistent with the implementation in JSTypedArray::GetBuffer. v8::ArrayBufferView::CopyContents now uses JSTypedArray::DataPtr instead of relying on nullptr backing stores to handle on-heap TypedArrays. The serializer and deserializer now check for IsEmpty() and use the kEmptyBackingStoreRefSentinel value to serialize empty backing stores. Empty ArrayBuffers allocated for on-heap TypedArrays now have a byte_length of zero. This allows removing the allocation_length() (and allocation_buffer()) methods, which were only (incorrectly, as they don't account for GSABs) used for memory measurements. Bug: chromium:1218005 Change-Id: Ib889ccf855f68525f7a614f3963e46ea56865fa3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3297709 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Samuel Groß <saelo@chromium.org> Cr-Commit-Position: refs/heads/main@{#78069}
2021-11-23 18:11:23 +00:00
CHECK(buffer->IsEmpty());
buffer = GetBufferFromTypedArray(CompileRun("z"));
// The resulting buffer should be off-heap.
ArrayBuffer refactoring in preparation for CagedPointers The main changes of this CL are: It should no longer be assumed that an empty ArrayBuffer has a nullptr backing store. This is in preparation for the move to caged pointers, which cannot represent nullptr, and will instead likely provide a EmptyBackingStore constant pointing inside the virtual memory cage. For that reason, a new JSArrayBuffer::IsEmpty() helper is introduced, which should be used instead of checking against nullptr. CodeStubAssembler::GetTypedArrayBuffer now checks for on-heap TypedArrays instead of comparing the backing store pointer to nullptr. This is consistent with the implementation in JSTypedArray::GetBuffer. v8::ArrayBufferView::CopyContents now uses JSTypedArray::DataPtr instead of relying on nullptr backing stores to handle on-heap TypedArrays. The serializer and deserializer now check for IsEmpty() and use the kEmptyBackingStoreRefSentinel value to serialize empty backing stores. Empty ArrayBuffers allocated for on-heap TypedArrays now have a byte_length of zero. This allows removing the allocation_length() (and allocation_buffer()) methods, which were only (incorrectly, as they don't account for GSABs) used for memory measurements. Bug: chromium:1218005 Change-Id: Ib889ccf855f68525f7a614f3963e46ea56865fa3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3297709 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Samuel Groß <saelo@chromium.org> Cr-Commit-Position: refs/heads/main@{#78069}
2021-11-23 18:11:23 +00:00
CHECK(!buffer->IsEmpty());
}
isolate->Dispose();
delete[] blob.data; // We can dispose of the snapshot blob now.
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(CustomSnapshotDataBlobTypedArrayNoEmbedderFieldCallback) {
const char* code = "var x = new Uint8Array(8);";
DisableAlwaysOpt();
i::v8_flags.allow_natives_syntax = true;
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(code);
creator.SetDefaultContext(context, v8::SerializeInternalFieldsCallback());
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = TestSerializer::NewIsolate(create_params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(
isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(),
v8::MaybeLocal<v8::Value>(), v8::DeserializeInternalFieldsCallback());
v8::Context::Scope c_scope(context);
}
isolate->Dispose();
delete[] blob.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlob2) {
DisableAlwaysOpt();
const char* source2 =
"function f() { return g() * 2; }"
"function g() { return 43; }"
"/./.test('a')";
DisableEmbeddedBlobRefcounting();
v8::StartupData data2 = CreateSnapshotDataBlob(source2);
v8::Isolate::CreateParams params2;
params2.snapshot_blob = &data2;
params2.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate2 = TestSerializer::NewIsolate(params2);
{
v8::Isolate::Scope i_scope(isolate2);
v8::HandleScope h_scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result =
CompileRun("f()")->Int32Value(isolate2->GetCurrentContext());
CHECK_EQ(86, result.FromJust());
result = CompileRun("g()")->Int32Value(isolate2->GetCurrentContext());
CHECK_EQ(43, result.FromJust());
}
isolate2->Dispose();
delete[] data2.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
static void SerializationFunctionTemplate(
const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(args[0]);
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobOutdatedContextWithOverflow) {
DisableAlwaysOpt();
const char* source1 =
"var o = {};"
"(function() {"
" function f1(x) { return f2(x) instanceof Array; }"
" function f2(x) { return foo.bar(x); }"
" o.a = f2.bind(null);"
" o.b = 1;"
" o.c = 2;"
" o.d = 3;"
" o.e = 4;"
"})();\n";
const char* source2 = "o.a(42)";
DisableEmbeddedBlobRefcounting();
v8::StartupData data = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params;
params.snapshot_blob = &data;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
v8::Local<v8::ObjectTemplate> property = v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> function =
v8::FunctionTemplate::New(isolate, SerializationFunctionTemplate);
property->Set(isolate, "bar", function);
global->Set(isolate, "foo", property);
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
v8::Context::Scope c_scope(context);
v8::Local<v8::Value> result = CompileRun(source2);
v8::Maybe<bool> compare =
v8_str("42")->Equals(isolate->GetCurrentContext(), result);
CHECK(compare.FromJust());
}
isolate->Dispose();
delete[] data.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithLocker) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate0 = v8::Isolate::New(create_params);
{
v8::Locker locker(isolate0);
v8::Isolate::Scope i_scope(isolate0);
v8::HandleScope h_scope(isolate0);
v8::Local<v8::Context> context = v8::Context::New(isolate0);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result =
CompileRun("Math.cos(0)")->Int32Value(isolate0->GetCurrentContext());
CHECK_EQ(1, result.FromJust());
}
isolate0->Dispose();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate1 = TestSerializer::NewIsolate(params1);
{
v8::Locker locker(isolate1);
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result = CompileRun("f()")->Int32Value(context);
CHECK_EQ(42, result.FromJust());
}
isolate1->Dispose();
delete[] data1.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobStackOverflow) {
DisableAlwaysOpt();
const char* source =
"var a = [0];"
"var b = a;"
"for (var i = 0; i < 10000; i++) {"
" var c = [i];"
" b.push(c);"
" b.push(c);"
" b = c;"
"}";
DisableEmbeddedBlobRefcounting();
v8::StartupData data = CreateSnapshotDataBlob(source);
v8::Isolate::CreateParams params;
params.snapshot_blob = &data;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope c_scope(context);
const char* test =
"var sum = 0;"
"while (a) {"
" sum += a[0];"
" a = a[1];"
"}"
"sum";
v8::Maybe<int32_t> result =
CompileRun(test)->Int32Value(isolate->GetCurrentContext());
CHECK_EQ(9999 * 5000, result.FromJust());
}
isolate->Dispose();
delete[] data.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
bool IsCompiled(const char* name) {
return i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*CompileRun(name)))
->shared()
.is_compiled();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(SnapshotDataBlobWithWarmup) {
DisableAlwaysOpt();
const char* warmup = "Math.abs(1); Math.random = 1;";
DisableEmbeddedBlobRefcounting();
v8::StartupData cold = CreateSnapshotDataBlob(nullptr);
v8::StartupData warm = WarmUpSnapshotDataBlobInternal(cold, warmup);
delete[] cold.data;
v8::Isolate::CreateParams params;
params.snapshot_blob = &warm;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope c_scope(context);
// Running the warmup script has effect on whether functions are
// pre-compiled, but does not pollute the context.
CHECK(IsCompiled("Math.abs"));
CHECK(IsCompiled("String.raw"));
CHECK(CompileRun("Math.random")->IsFunction());
}
isolate->Dispose();
delete[] warm.data;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithWarmup) {
DisableAlwaysOpt();
const char* source =
"function f() { return Math.abs(1); }\n"
"function g() { return String.raw(1); }\n"
"Object.valueOf(1);"
"var a = 5";
const char* warmup = "a = f()";
DisableEmbeddedBlobRefcounting();
v8::StartupData cold = CreateSnapshotDataBlob(source);
v8::StartupData warm = WarmUpSnapshotDataBlobInternal(cold, warmup);
delete[] cold.data;
v8::Isolate::CreateParams params;
params.snapshot_blob = &warm;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope c_scope(context);
// Running the warmup script has effect on whether functions are
// pre-compiled, but does not pollute the context.
CHECK(IsCompiled("f"));
CHECK(IsCompiled("Math.abs"));
CHECK(!IsCompiled("g"));
CHECK(IsCompiled("String.raw"));
CHECK(IsCompiled("Array.prototype.lastIndexOf"));
CHECK_EQ(5, CompileRun("a")->Int32Value(context).FromJust());
}
isolate->Dispose();
delete[] warm.data;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
namespace {
v8::StartupData CreateCustomSnapshotWithKeep() {
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(
"function f() { return Math.abs(1); }\n"
"function g() { return String.raw(1); }");
v8::ScriptOrigin origin(isolate, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
CompileRun(isolate->GetCurrentContext(), &source,
v8::ScriptCompiler::kEagerCompile);
creator.SetDefaultContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
} // namespace
UNINITIALIZED_TEST(CustomSnapshotDataBlobWithKeep) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotWithKeep();
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CHECK(IsCompiled("f"));
CHECK(IsCompiled("g"));
}
isolate->Dispose();
}
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
UNINITIALIZED_TEST(CustomSnapshotDataBlobImmortalImmovableRoots) {
DisableAlwaysOpt();
// Flood the startup snapshot with shared function infos. If they are
// serialized before the immortal immovable root, the root will no longer end
// up on the first page.
base::Vector<const char> source =
ConstructSource(base::StaticCharVector("var a = [];"),
base::StaticCharVector("a.push(function() {return 7});"),
base::StaticCharVector("\0"), 10000);
DisableEmbeddedBlobRefcounting();
v8::StartupData data = CreateSnapshotDataBlob(source.begin());
v8::Isolate::CreateParams params;
params.snapshot_blob = &data;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope c_scope(context);
CHECK_EQ(7, CompileRun("a[0]()")->Int32Value(context).FromJust());
}
isolate->Dispose();
source.Dispose();
delete[] data.data; // We can dispose of the snapshot blob now.
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
TEST(TestThatAlwaysSucceeds) {}
TEST(TestThatAlwaysFails) {
bool ArtificialFailure = false;
CHECK(ArtificialFailure);
}
int CountBuiltins() {
// Check that we have not deserialized any additional builtin.
HeapObjectIterator iterator(CcTest::heap());
DisallowGarbageCollection no_gc;
int counter = 0;
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
if (obj.IsCode() && Code::cast(obj).kind() == CodeKind::BUILTIN) counter++;
}
return counter;
}
static Handle<SharedFunctionInfo> CompileScript(
Isolate* isolate, Handle<String> source,
const ScriptDetails& script_details, AlignedCachedData* cached_data,
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
v8::ScriptCompiler::CompileOptions options) {
return Compiler::GetSharedFunctionInfoForScriptWithCachedData(
isolate, source, script_details, cached_data, options,
ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE)
.ToHandleChecked();
}
static Handle<SharedFunctionInfo> CompileScriptAndProduceCache(
Isolate* isolate, Handle<String> source,
const ScriptDetails& script_details, AlignedCachedData** out_cached_data,
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
v8::ScriptCompiler::CompileOptions options) {
Handle<SharedFunctionInfo> sfi =
Compiler::GetSharedFunctionInfoForScript(
isolate, source, script_details, options,
ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE)
.ToHandleChecked();
std::unique_ptr<ScriptCompiler::CachedData> cached_data(
ScriptCompiler::CreateCodeCache(ToApiHandle<UnboundScript>(sfi)));
uint8_t* buffer = NewArray<uint8_t>(cached_data->length);
MemCopy(buffer, cached_data->data, cached_data->length);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
*out_cached_data = new i::AlignedCachedData(buffer, cached_data->length);
(*out_cached_data)->AcquireDataOwnership();
return sfi;
}
TEST(CodeSerializerWithProfiler) {
v8_flags.enable_lazy_source_positions = true;
v8_flags.stress_lazy_source_positions = false;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
const char* source = "1 + 1";
Handle<String> orig_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
Handle<String> copy_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
CHECK(!orig_source.is_identical_to(copy_source));
CHECK(orig_source->Equals(*copy_source));
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
ScriptDetails default_script_details;
Handle<SharedFunctionInfo> orig = CompileScriptAndProduceCache(
isolate, orig_source, default_script_details, &cache,
v8::ScriptCompiler::kNoCompileOptions);
CHECK(!orig->GetBytecodeArray(isolate).HasSourcePositionTable());
isolate->SetIsProfiling(true);
// This does not assert that no compilation can happen as source position
// collection could trigger it.
Handle<SharedFunctionInfo> copy =
CompileScript(isolate, copy_source, default_script_details, cache,
v8::ScriptCompiler::kConsumeCodeCache);
// Since the profiler is now enabled, source positions should be collected
// after deserialization.
CHECK(copy->GetBytecodeArray(isolate).HasSourcePositionTable());
delete cache;
}
void TestCodeSerializerOnePlusOneImpl(bool verify_builtins_count = true) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
const char* source = "1 + 1";
Handle<String> orig_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
Handle<String> copy_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
CHECK(!orig_source.is_identical_to(copy_source));
CHECK(orig_source->Equals(*copy_source));
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
ScriptDetails default_script_details;
Handle<SharedFunctionInfo> orig = CompileScriptAndProduceCache(
isolate, orig_source, default_script_details, &cache,
v8::ScriptCompiler::kNoCompileOptions);
int builtins_count = CountBuiltins();
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, copy_source, default_script_details, cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
Change ScriptCompiler::CompileOptions to allow for two 'cache' modes (parser or code) and to be explicit about cache consumption or production (rather than making presence of cached_data imply one or the other.) Also add a --cache flag to d8, to allow testing the functionality. ----------------------------- API change Reason: Currently, V8 supports a 'parser cache' for repeatedly executing the same script. We'd like to add a 2nd mode that would cache code, and would like to let the embedder decide which mode they chose (if any). Note: Previously, the 'use cached data' property was implied by the presence of the cached data itself. (That is, kNoCompileOptions and source->cached_data != NULL.) That is no longer sufficient, since the presence of data is no longer sufficient to determine /which kind/ of data is present. Changes from old behaviour: - If you previously didn't use caching, nothing changes. Example: v8::CompileUnbound(isolate, source, kNoCompileOptions); - If you previously used caching, it worked like this: - 1st run: v8::CompileUnbound(isolate, source, kProduceToCache); Then, source->cached_data would contain the data-to-be cached. This remains the same, except you need to tell V8 which type of data you want. v8::CompileUnbound(isolate, source, kProduceParserCache); - 2nd run: v8::CompileUnbound(isolate, source, kNoCompileOptions); with source->cached_data set to the data you received in the first run. This will now ignore the cached data, and you need to explicitly tell V8 to use it: v8::CompileUnbound(isolate, source, kConsumeParserCache); ----------------------------- BUG= R=marja@chromium.org, yangguo@chromium.org Review URL: https://codereview.chromium.org/389573006 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22431 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-07-16 12:18:33 +00:00
CHECK_NE(*orig, *copy);
CHECK(Script::cast(copy->script()).source() == *copy_source);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<JSObject> global(isolate->context().global_object(), isolate);
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK_EQ(2, Handle<Smi>::cast(copy_result)->value());
if (verify_builtins_count) CHECK_EQ(builtins_count, CountBuiltins());
delete cache;
}
TEST(CodeSerializerOnePlusOne) { TestCodeSerializerOnePlusOneImpl(); }
// See bug v8:9122
TEST(CodeSerializerOnePlusOneWithInterpretedFramesNativeStack) {
v8_flags.interpreted_frames_native_stack = true;
// We pass false because this test will create IET copies (which are
// builtins).
TestCodeSerializerOnePlusOneImpl(false);
}
TEST(CodeSerializerOnePlusOneWithDebugger) {
v8::HandleScope scope(CcTest::isolate());
static v8::debug::DebugDelegate dummy_delegate;
v8::debug::SetDebugDelegate(CcTest::isolate(), &dummy_delegate);
TestCodeSerializerOnePlusOneImpl();
}
TEST(CodeSerializerPromotedToCompilationCache) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
v8::HandleScope scope(CcTest::isolate());
const char* source = "1 + 1";
Handle<String> src = isolate->factory()->NewStringFromAsciiChecked(source);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<FixedArray> default_host_defined_options =
isolate->factory()->NewFixedArray(2);
default_host_defined_options->set(0, Smi::FromInt(0));
const char* default_host_defined_option_1_string = "custom string";
Handle<String> default_host_defined_option_1 =
isolate->factory()->NewStringFromAsciiChecked(
default_host_defined_option_1_string);
default_host_defined_options->set(1, *default_host_defined_option_1);
ScriptDetails default_script_details(src);
default_script_details.host_defined_options = default_host_defined_options;
CompileScriptAndProduceCache(isolate, src, default_script_details, &cache,
v8::ScriptCompiler::kNoCompileOptions);
Reland "Allow lookup of matching scripts in Isolate compilation cache" This is a reland of commit c443858fa91d2528c30f2b008d47cfc2e21d4992 The original version included an operation which could left-shift signed values, which is undefined behavior; the updated version masks the value first to avoid the problem. Original change's description: > Allow lookup of matching scripts in Isolate compilation cache > > Currently, if the same script text is compiled multiple times with > differing details (such as name, line number, or host-defined options), > then multiple copies of that script are added to the Isolate's > compilation cache. However, any attempt to look up those scripts can > find only the first instance. This change makes the script compilation > cache behave more consistently by checking the details while searching > the hash table for a match, rather than after a potential match has been > found. > > Bug: v8:12808 > Change-Id: Ic9da0bf74f359d4f1c88af89d585404f173056ee > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3671615 > Reviewed-by: Camillo Bruni <cbruni@chromium.org> > Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> > Cr-Commit-Position: refs/heads/main@{#80919} Bug: v8:12808 Change-Id: I494c3c9cc520b79f34247aab6618c40c854b9edc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687070 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#81007}
2022-06-02 17:46:17 +00:00
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, src, default_script_details, cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
{
ScriptDetails script_details(src);
script_details.host_defined_options =
default_script_details.host_defined_options;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK_EQ(*lookup_result.toplevel_sfi().ToHandleChecked(), *copy);
}
{
// Lookup with strictly equal host_defined_options should succeed:
ScriptDetails script_details(src);
Handle<FixedArray> host_defined_options =
isolate->factory()->NewFixedArray(2);
host_defined_options->set(0, default_host_defined_options->get(0));
Handle<String> host_defined_option_1 =
isolate->factory()->NewStringFromAsciiChecked(
default_host_defined_option_1_string);
host_defined_options->set(1, *host_defined_option_1);
script_details.host_defined_options = host_defined_options;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK_EQ(*lookup_result.toplevel_sfi().ToHandleChecked(), *copy);
}
{
// Lookup with different string with same contents should succeed:
ScriptDetails script_details(
isolate->factory()->NewStringFromAsciiChecked(source));
script_details.host_defined_options =
default_script_details.host_defined_options;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK_EQ(*lookup_result.toplevel_sfi().ToHandleChecked(), *copy);
}
{
// Lookup with different name string should fail:
ScriptDetails script_details(
isolate->factory()->NewStringFromAsciiChecked("other"));
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
{
// Lookup with different position should fail:
ScriptDetails script_details(src);
script_details.line_offset = 0xFF;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
{
// Lookup with different position should fail:
ScriptDetails script_details(src);
script_details.column_offset = 0xFF;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
{
// Lookup with different language mode should fail:
ScriptDetails script_details(src);
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kStrict);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
{
// Lookup with different script_options should fail
ScriptOriginOptions origin_options(false, true);
CHECK_NE(ScriptOriginOptions().Flags(), origin_options.Flags());
ScriptDetails script_details(src, origin_options);
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
{
// Lookup with different host_defined_options should fail:
ScriptDetails script_details(src);
script_details.host_defined_options = isolate->factory()->NewFixedArray(5);
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK(lookup_result.script().is_null() &&
lookup_result.toplevel_sfi().is_null());
}
Reland "Allow lookup of matching scripts in Isolate compilation cache" This is a reland of commit c443858fa91d2528c30f2b008d47cfc2e21d4992 The original version included an operation which could left-shift signed values, which is undefined behavior; the updated version masks the value first to avoid the problem. Original change's description: > Allow lookup of matching scripts in Isolate compilation cache > > Currently, if the same script text is compiled multiple times with > differing details (such as name, line number, or host-defined options), > then multiple copies of that script are added to the Isolate's > compilation cache. However, any attempt to look up those scripts can > find only the first instance. This change makes the script compilation > cache behave more consistently by checking the details while searching > the hash table for a match, rather than after a potential match has been > found. > > Bug: v8:12808 > Change-Id: Ic9da0bf74f359d4f1c88af89d585404f173056ee > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3671615 > Reviewed-by: Camillo Bruni <cbruni@chromium.org> > Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> > Cr-Commit-Position: refs/heads/main@{#80919} Bug: v8:12808 Change-Id: I494c3c9cc520b79f34247aab6618c40c854b9edc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687070 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#81007}
2022-06-02 17:46:17 +00:00
// Compile the script again with different options.
ScriptDetails alternative_script_details(src);
Handle<SharedFunctionInfo> alternative_toplevel_sfi =
Compiler::GetSharedFunctionInfoForScript(
isolate, src, alternative_script_details,
ScriptCompiler::kNoCompileOptions, ScriptCompiler::kNoCacheNoReason,
NOT_NATIVES_CODE)
.ToHandleChecked();
CHECK_NE(*copy, *alternative_toplevel_sfi);
{
// The original script can still be found.
ScriptDetails script_details(src);
script_details.host_defined_options =
default_script_details.host_defined_options;
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK_EQ(*lookup_result.toplevel_sfi().ToHandleChecked(), *copy);
Reland "Allow lookup of matching scripts in Isolate compilation cache" This is a reland of commit c443858fa91d2528c30f2b008d47cfc2e21d4992 The original version included an operation which could left-shift signed values, which is undefined behavior; the updated version masks the value first to avoid the problem. Original change's description: > Allow lookup of matching scripts in Isolate compilation cache > > Currently, if the same script text is compiled multiple times with > differing details (such as name, line number, or host-defined options), > then multiple copies of that script are added to the Isolate's > compilation cache. However, any attempt to look up those scripts can > find only the first instance. This change makes the script compilation > cache behave more consistently by checking the details while searching > the hash table for a match, rather than after a potential match has been > found. > > Bug: v8:12808 > Change-Id: Ic9da0bf74f359d4f1c88af89d585404f173056ee > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3671615 > Reviewed-by: Camillo Bruni <cbruni@chromium.org> > Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> > Cr-Commit-Position: refs/heads/main@{#80919} Bug: v8:12808 Change-Id: I494c3c9cc520b79f34247aab6618c40c854b9edc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687070 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#81007}
2022-06-02 17:46:17 +00:00
}
{
// The new script can also be found.
ScriptDetails script_details(src);
auto lookup_result = isolate->compilation_cache()->LookupScript(
src, script_details, LanguageMode::kSloppy);
CHECK_EQ(*lookup_result.toplevel_sfi().ToHandleChecked(),
*alternative_toplevel_sfi);
Reland "Allow lookup of matching scripts in Isolate compilation cache" This is a reland of commit c443858fa91d2528c30f2b008d47cfc2e21d4992 The original version included an operation which could left-shift signed values, which is undefined behavior; the updated version masks the value first to avoid the problem. Original change's description: > Allow lookup of matching scripts in Isolate compilation cache > > Currently, if the same script text is compiled multiple times with > differing details (such as name, line number, or host-defined options), > then multiple copies of that script are added to the Isolate's > compilation cache. However, any attempt to look up those scripts can > find only the first instance. This change makes the script compilation > cache behave more consistently by checking the details while searching > the hash table for a match, rather than after a potential match has been > found. > > Bug: v8:12808 > Change-Id: Ic9da0bf74f359d4f1c88af89d585404f173056ee > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3671615 > Reviewed-by: Camillo Bruni <cbruni@chromium.org> > Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> > Cr-Commit-Position: refs/heads/main@{#80919} Bug: v8:12808 Change-Id: I494c3c9cc520b79f34247aab6618c40c854b9edc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687070 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#81007}
2022-06-02 17:46:17 +00:00
}
delete cache;
}
TEST(CodeSerializerInternalizedString) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
const char* source = "'string1'";
Handle<String> orig_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
Handle<String> copy_source = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
CHECK(!orig_source.is_identical_to(copy_source));
CHECK(orig_source->Equals(*copy_source));
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
i::AlignedCachedData* cached_data = nullptr;
Handle<SharedFunctionInfo> orig = CompileScriptAndProduceCache(
isolate, orig_source, ScriptDetails(), &cached_data,
v8::ScriptCompiler::kNoCompileOptions);
Handle<JSFunction> orig_fun =
Factory::JSFunctionBuilder{isolate, orig, isolate->native_context()}
.Build();
Handle<Object> orig_result =
Execution::CallScript(isolate, orig_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK(orig_result->IsInternalizedString());
int builtins_count = CountBuiltins();
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, copy_source, ScriptDetails(), cached_data,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
CHECK(Script::cast(copy->script()).source() == *copy_source);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
CHECK_NE(*orig_fun, *copy_fun);
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK(orig_result.is_identical_to(copy_result));
Handle<String> expected =
isolate->factory()->NewStringFromAsciiChecked("string1");
CHECK(Handle<String>::cast(copy_result)->Equals(*expected));
CHECK_EQ(builtins_count, CountBuiltins());
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
delete cached_data;
}
TEST(CodeSerializerLargeCodeObject) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
// The serializer only tests the shared code, which is always the unoptimized
// code. Don't even bother generating optimized code to avoid timeouts.
v8_flags.always_turbofan = false;
base::Vector<const char> source = ConstructSource(
base::StaticCharVector("var j=1; if (j == 0) {"),
base::StaticCharVector(
"for (let i of Object.prototype) for (let k = 0; k < 0; ++k);"),
base::StaticCharVector("} j=7; j"), 2000);
Handle<String> source_str =
isolate->factory()->NewStringFromUtf8(source).ToHandleChecked();
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig =
CompileScriptAndProduceCache(isolate, source_str, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
CHECK(isolate->heap()->InSpace(orig->abstract_code(isolate), LO_SPACE));
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_str, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
int result_int;
CHECK(copy_result->ToInt32(&result_int));
CHECK_EQ(7, result_int);
delete cache;
source.Dispose();
}
TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) {
if (!v8_flags.incremental_marking) return;
if (!v8_flags.compact) return;
ManualGCScope manual_gc_scope;
v8_flags.always_turbofan = false;
const char* filter_flag = "--turbo-filter=NOTHING";
FlagList::SetFlagsFromString(filter_flag, strlen(filter_flag));
v8_flags.manual_evacuation_candidates_selection = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
base::Vector<const char> source = ConstructSource(
base::StaticCharVector("var j=1; if (j == 0) {"),
base::StaticCharVector("for (var i = 0; i < Object.prototype; i++);"),
base::StaticCharVector("} j=7; var s = 'happy_hippo'; j"), 20000);
Handle<String> source_str =
isolate->factory()->NewStringFromUtf8(source).ToHandleChecked();
// Create a string on an evacuation candidate in old space.
Handle<String> moving_object;
Page* ec_page;
{
AlwaysAllocateScopeForTesting always_allocate(heap);
heap::SimulateFullSpace(heap->old_space());
moving_object = isolate->factory()->InternalizeString(
isolate->factory()->NewStringFromAsciiChecked("happy_hippo"));
ec_page = Page::FromHeapObject(*moving_object);
}
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig =
CompileScriptAndProduceCache(isolate, source_str, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
CHECK(heap->InSpace(orig->abstract_code(isolate), LO_SPACE));
// Pretend that incremental marking is on when deserialization begins.
heap::ForceEvacuationCandidate(ec_page);
heap::SimulateIncrementalMarking(heap, false);
IncrementalMarking* marking = heap->incremental_marking();
CHECK(marking->black_allocation());
CHECK(marking->IsCompacting());
CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*moving_object));
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_str, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
// We should have missed a write barrier. Complete incremental marking
// to flush out the bug.
heap::SimulateIncrementalMarking(heap, true);
CcTest::CollectAllGarbage();
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
int result_int;
CHECK(copy_result->ToInt32(&result_int));
CHECK_EQ(7, result_int);
delete cache;
source.Dispose();
}
TEST(CodeSerializerLargeStrings) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* f = isolate->factory();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
base::Vector<const char> source_s = ConstructSource(
base::StaticCharVector("var s = \""), base::StaticCharVector("abcdef"),
base::StaticCharVector("\";"), 1000000);
base::Vector<const char> source_t = ConstructSource(
base::StaticCharVector("var t = \""), base::StaticCharVector("uvwxyz"),
base::StaticCharVector("\"; s + t"), 999999);
Handle<String> source_str =
f->NewConsString(f->NewStringFromUtf8(source_s).ToHandleChecked(),
f->NewStringFromUtf8(source_t).ToHandleChecked())
.ToHandleChecked();
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig =
CompileScriptAndProduceCache(isolate, source_str, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_str, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK_EQ(6 * 1999999, Handle<String>::cast(copy_result)->length());
Handle<Object> property = JSReceiver::GetDataProperty(
isolate, isolate->global_object(), f->NewStringFromAsciiChecked("s"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
property = JSReceiver::GetDataProperty(isolate, isolate->global_object(),
f->NewStringFromAsciiChecked("t"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
// Make sure we do not serialize too much, e.g. include the source string.
CHECK_LT(cache->length(), 13000000);
delete cache;
source_s.Dispose();
source_t.Dispose();
}
TEST(CodeSerializerThreeBigStrings) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* f = isolate->factory();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
const int32_t length_of_a = kMaxRegularHeapObjectSize * 2;
const int32_t length_of_b = kMaxRegularHeapObjectSize / 2;
const int32_t length_of_c = kMaxRegularHeapObjectSize / 2;
base::Vector<const char> source_a = ConstructSource(
base::StaticCharVector("var a = \""), base::StaticCharVector("a"),
base::StaticCharVector("\";"), length_of_a);
Handle<String> source_a_str =
f->NewStringFromUtf8(source_a).ToHandleChecked();
base::Vector<const char> source_b = ConstructSource(
base::StaticCharVector("var b = \""), base::StaticCharVector("b"),
base::StaticCharVector("\";"), length_of_b);
Handle<String> source_b_str =
f->NewStringFromUtf8(source_b).ToHandleChecked();
base::Vector<const char> source_c = ConstructSource(
base::StaticCharVector("var c = \""), base::StaticCharVector("c"),
base::StaticCharVector("\";"), length_of_c);
Handle<String> source_c_str =
f->NewStringFromUtf8(source_c).ToHandleChecked();
Handle<String> source_str =
f->NewConsString(
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
f->NewConsString(source_a_str, source_b_str).ToHandleChecked(),
source_c_str)
.ToHandleChecked();
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig =
CompileScriptAndProduceCache(isolate, source_str, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_str, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
USE(Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array()));
v8::Maybe<int32_t> result =
CompileRun("(a + b).length")
->Int32Value(CcTest::isolate()->GetCurrentContext());
CHECK_EQ(length_of_a + length_of_b, result.FromJust());
result = CompileRun("(b + c).length")
->Int32Value(CcTest::isolate()->GetCurrentContext());
CHECK_EQ(length_of_b + length_of_c, result.FromJust());
Heap* heap = isolate->heap();
v8::Local<v8::String> result_str =
CompileRun("a")
->ToString(CcTest::isolate()->GetCurrentContext())
.ToLocalChecked();
CHECK(heap->InSpace(*v8::Utils::OpenHandle(*result_str), LO_SPACE));
result_str = CompileRun("b")
->ToString(CcTest::isolate()->GetCurrentContext())
.ToLocalChecked();
CHECK(heap->InSpace(*v8::Utils::OpenHandle(*result_str), OLD_SPACE));
result_str = CompileRun("c")
->ToString(CcTest::isolate()->GetCurrentContext())
.ToLocalChecked();
CHECK(heap->InSpace(*v8::Utils::OpenHandle(*result_str), OLD_SPACE));
delete cache;
source_a.Dispose();
source_b.Dispose();
source_c.Dispose();
}
class SerializerOneByteResource
: public v8::String::ExternalOneByteStringResource {
public:
SerializerOneByteResource(const char* data, size_t length)
: data_(data), length_(length), dispose_count_(0) {}
const char* data() const override { return data_; }
size_t length() const override { return length_; }
void Dispose() override { dispose_count_++; }
int dispose_count() { return dispose_count_; }
private:
const char* data_;
size_t length_;
int dispose_count_;
};
class SerializerTwoByteResource : public v8::String::ExternalStringResource {
public:
SerializerTwoByteResource(const char* data, size_t length)
: data_(AsciiToTwoByteString(data)), length_(length), dispose_count_(0) {}
~SerializerTwoByteResource() override { DeleteArray<const uint16_t>(data_); }
const uint16_t* data() const override { return data_; }
size_t length() const override { return length_; }
void Dispose() override { dispose_count_++; }
int dispose_count() { return dispose_count_; }
private:
const uint16_t* data_;
size_t length_;
int dispose_count_;
};
TEST(CodeSerializerExternalString) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
// Obtain external internalized one-byte string.
SerializerOneByteResource one_byte_resource("one_byte", 8);
Handle<String> one_byte_string =
isolate->factory()->NewStringFromAsciiChecked("one_byte");
one_byte_string = isolate->factory()->InternalizeString(one_byte_string);
one_byte_string->MakeExternal(&one_byte_resource);
CHECK(one_byte_string->IsExternalOneByteString());
CHECK(one_byte_string->IsInternalizedString());
// Obtain external internalized two-byte string.
SerializerTwoByteResource two_byte_resource("two_byte", 8);
Handle<String> two_byte_string =
isolate->factory()->NewStringFromAsciiChecked("two_byte");
two_byte_string = isolate->factory()->InternalizeString(two_byte_string);
two_byte_string->MakeExternal(&two_byte_resource);
CHECK(two_byte_string->IsExternalTwoByteString());
CHECK(two_byte_string->IsInternalizedString());
const char* source =
"var o = {} \n"
"o.one_byte = 7; \n"
"o.two_byte = 8; \n"
"o.one_byte + o.two_byte; \n";
Handle<String> source_string =
isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig = CompileScriptAndProduceCache(
isolate, source_string, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_string, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK_EQ(15.0, copy_result->Number());
// This avoids the GC from trying to free stack allocated resources.
i::Handle<i::ExternalOneByteString>::cast(one_byte_string)
->SetResource(isolate, nullptr);
i::Handle<i::ExternalTwoByteString>::cast(two_byte_string)
->SetResource(isolate, nullptr);
delete cache;
}
TEST(CodeSerializerLargeExternalString) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
Factory* f = isolate->factory();
v8::HandleScope scope(CcTest::isolate());
// Create a huge external internalized string to use as variable name.
base::Vector<const char> string = ConstructSource(
base::StaticCharVector(""), base::StaticCharVector("abcdef"),
base::StaticCharVector(""), 999999);
Handle<String> name = f->NewStringFromUtf8(string).ToHandleChecked();
SerializerOneByteResource one_byte_resource(
reinterpret_cast<const char*>(string.begin()), string.length());
name = f->InternalizeString(name);
name->MakeExternal(&one_byte_resource);
CHECK(name->IsExternalOneByteString());
CHECK(name->IsInternalizedString());
CHECK(isolate->heap()->InSpace(*name, LO_SPACE));
// Create the source, which is "var <literal> = 42; <literal>".
Handle<String> source_str =
f->NewConsString(
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
f->NewConsString(f->NewStringFromAsciiChecked("var "), name)
.ToHandleChecked(),
f->NewConsString(f->NewStringFromAsciiChecked(" = 42; "), name)
.ToHandleChecked())
.ToHandleChecked();
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig =
CompileScriptAndProduceCache(isolate, source_str, ScriptDetails(), &cache,
v8::ScriptCompiler::kNoCompileOptions);
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_str, ScriptDetails(), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK_EQ(42.0, copy_result->Number());
// This avoids the GC from trying to free stack allocated resources.
i::Handle<i::ExternalOneByteString>::cast(name)->SetResource(isolate,
nullptr);
delete cache;
string.Dispose();
}
TEST(CodeSerializerExternalScriptName) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
Factory* f = isolate->factory();
v8::HandleScope scope(CcTest::isolate());
const char* source =
"var a = [1, 2, 3, 4];"
"a.reduce(function(x, y) { return x + y }, 0)";
Handle<String> source_string =
f->NewStringFromUtf8(base::CStrVector(source)).ToHandleChecked();
const SerializerOneByteResource one_byte_resource("one_byte", 8);
Handle<String> name =
f->NewExternalStringFromOneByte(&one_byte_resource).ToHandleChecked();
CHECK(name->IsExternalOneByteString());
CHECK(!name->IsInternalizedString());
Handle<JSObject> global(isolate->context().global_object(), isolate);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
Handle<SharedFunctionInfo> orig = CompileScriptAndProduceCache(
isolate, source_string, ScriptDetails(name), &cache,
v8::ScriptCompiler::kNoCompileOptions);
Handle<SharedFunctionInfo> copy;
{
DisallowCompilation no_compile_expected(isolate);
copy = CompileScript(isolate, source_string, ScriptDetails(name), cache,
v8::ScriptCompiler::kConsumeCodeCache);
}
CHECK_NE(*orig, *copy);
Handle<JSFunction> copy_fun =
Factory::JSFunctionBuilder{isolate, copy, isolate->native_context()}
.Build();
Handle<Object> copy_result =
Execution::CallScript(isolate, copy_fun, global,
isolate->factory()->empty_fixed_array())
.ToHandleChecked();
CHECK_EQ(10.0, copy_result->Number());
// This avoids the GC from trying to free stack allocated resources.
i::Handle<i::ExternalOneByteString>::cast(name)->SetResource(isolate,
nullptr);
delete cache;
}
static bool toplevel_test_code_event_found = false;
static void SerializerLogEventListener(const v8::JitCodeEvent* event) {
if (event->type == v8::JitCodeEvent::CODE_ADDED &&
(memcmp(event->name.str, "Script:~ test", 13) == 0 ||
memcmp(event->name.str, "Script: test", 12) == 0)) {
toplevel_test_code_event_found = true;
}
}
v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
const char* js_source, CodeCacheType cacheType = CodeCacheType::kLazy) {
v8::ScriptCompiler::CachedData* cache;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
{
v8::Isolate::Scope iscope(isolate1);
v8::HandleScope scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate1, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
v8::ScriptCompiler::CompileOptions options;
switch (cacheType) {
case CodeCacheType::kEager:
options = v8::ScriptCompiler::kEagerCompile;
break;
case CodeCacheType::kLazy:
case CodeCacheType::kAfterExecute:
options = v8::ScriptCompiler::kNoCompileOptions;
break;
default:
UNREACHABLE();
}
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(isolate1, &source, options)
.ToLocalChecked();
if (cacheType != CodeCacheType::kAfterExecute) {
cache = ScriptCompiler::CreateCodeCache(script);
}
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate1->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_string =
result->ToString(isolate1->GetCurrentContext()).ToLocalChecked();
CHECK(result_string->Equals(isolate1->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
if (cacheType == CodeCacheType::kAfterExecute) {
cache = ScriptCompiler::CreateCodeCache(script);
}
CHECK(cache);
}
isolate1->Dispose();
return cache;
}
TEST(CodeSerializerIsolates) {
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = CompileRunAndProduceCache(js_source);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
isolate2->SetJitCodeEventHandler(v8::kJitCodeEventDefault,
SerializerLogEventListener);
toplevel_test_code_event_found = false;
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> script;
{
DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK(!cache->rejected);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
CHECK(result->ToString(isolate2->GetCurrentContext())
.ToLocalChecked()
->Equals(isolate2->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
}
CHECK(toplevel_test_code_event_found);
isolate2->Dispose();
}
TEST(CodeSerializerIsolatesEager) {
const char* js_source =
"function f() {"
" return function g() {"
" return 'abc';"
" }"
"}"
"f()() + 'def'";
v8::ScriptCompiler::CachedData* cache =
CompileRunAndProduceCache(js_source, CodeCacheType::kEager);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
isolate2->SetJitCodeEventHandler(v8::kJitCodeEventDefault,
SerializerLogEventListener);
toplevel_test_code_event_found = false;
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> script;
{
DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK(!cache->rejected);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
CHECK(result->ToString(isolate2->GetCurrentContext())
.ToLocalChecked()
->Equals(isolate2->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
}
CHECK(toplevel_test_code_event_found);
isolate2->Dispose();
}
TEST(CodeSerializerAfterExecute) {
// We test that no compilations happen when running this code. Forcing
// to always optimize breaks this test.
bool prev_always_turbofan_value = v8_flags.always_turbofan;
v8_flags.always_turbofan = false;
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache =
CompileRunAndProduceCache(js_source, CodeCacheType::kAfterExecute);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> script;
{
DisallowCompilation no_compile_expected(i_isolate2);
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK(!cache->rejected);
Handle<SharedFunctionInfo> sfi = v8::Utils::OpenHandle(*script);
CHECK(sfi->HasBytecodeArray());
{
DisallowCompilation no_compile_expected(i_isolate2);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_string =
result->ToString(isolate2->GetCurrentContext()).ToLocalChecked();
CHECK(
result_string->Equals(isolate2->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
}
}
isolate2->Dispose();
// Restore the flags.
v8_flags.always_turbofan = prev_always_turbofan_value;
}
TEST(CodeSerializerFlagChange) {
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = CompileRunAndProduceCache(js_source);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
v8_flags.allow_natives_syntax =
true; // Flag change should trigger cache reject.
FlagList::EnforceFlagImplications();
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
CHECK(cache->rejected);
}
isolate2->Dispose();
}
TEST(CodeSerializerBitFlip) {
i::v8_flags.verify_snapshot_checksum = true;
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = CompileRunAndProduceCache(js_source);
// Arbitrary bit flip.
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
int arbitrary_spot = 237;
CHECK_LT(arbitrary_spot, cache->length);
const_cast<uint8_t*>(cache->data)[arbitrary_spot] ^= 0x40;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
CHECK(cache->rejected);
}
isolate2->Dispose();
}
TEST(CodeSerializerWithHarmonyScoping) {
const char* source1 = "'use strict'; let x = 'X'";
const char* source2 = "'use strict'; let y = 'Y'";
const char* source3 = "'use strict'; x + y";
v8::ScriptCompiler::CachedData* cache;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
{
v8::Isolate::Scope iscope(isolate1);
v8::HandleScope scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope context_scope(context);
CompileRun(source1);
CompileRun(source2);
v8::Local<v8::String> source_str = v8_str(source3);
v8::ScriptOrigin origin(isolate1, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(
isolate1, &source, v8::ScriptCompiler::kNoCompileOptions)
.ToLocalChecked();
cache = v8::ScriptCompiler::CreateCodeCache(script);
CHECK(cache);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate1->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_str =
result->ToString(isolate1->GetCurrentContext()).ToLocalChecked();
CHECK(result_str->Equals(isolate1->GetCurrentContext(), v8_str("XY"))
.FromJust());
}
isolate1->Dispose();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
// Reverse order of prior running scripts.
CompileRun(source2);
CompileRun(source1);
v8::Local<v8::String> source_str = v8_str(source3);
v8::ScriptOrigin origin(isolate2, v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> script;
{
DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_str =
result->ToString(isolate2->GetCurrentContext()).ToLocalChecked();
CHECK(result_str->Equals(isolate2->GetCurrentContext(), v8_str("XY"))
.FromJust());
}
isolate2->Dispose();
}
TEST(Regress503552) {
if (!v8_flags.incremental_marking) return;
// Test that the code serializer can deal with weak cells that form a linked
// list during incremental marking.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
Handle<String> source = isolate->factory()->NewStringFromAsciiChecked(
"function f() {} function g() {}");
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cached_data = nullptr;
Handle<SharedFunctionInfo> shared = CompileScriptAndProduceCache(
isolate, source, ScriptDetails(), &cached_data,
v8::ScriptCompiler::kNoCompileOptions);
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
delete cached_data;
heap::SimulateIncrementalMarking(isolate->heap());
v8::ScriptCompiler::CachedData* cache_data =
CodeSerializer::Serialize(shared);
delete cache_data;
}
UNINITIALIZED_TEST(SnapshotCreatorBlobNotCreated) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::TryCatch try_catch(isolate);
v8::Local<v8::String> code = v8_str("throw new Error('test');");
CHECK(v8::Script::Compile(context, code)
.ToLocalChecked()
->Run(context)
.IsEmpty());
CHECK(try_catch.HasCaught());
}
// SnapshotCreator should be destroyed just fine even when no
// blob is created.
}
FreeCurrentEmbeddedBlob();
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorMultipleContexts) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun("var f = function() { return 1; }");
creator.SetDefaultContext(context);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun("var f = function() { return 2; }");
CHECK_EQ(0u, creator.AddContext(context));
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK_EQ(1u, creator.AddContext(context));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 1);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 2);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 1).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectUndefined("this.f");
}
}
isolate->Dispose();
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
static int serialized_static_field = 314;
static void SerializedCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Data()->IsExternal()) {
CHECK_EQ(args.Data().As<v8::External>()->Value(),
static_cast<void*>(&serialized_static_field));
int* value =
reinterpret_cast<int*>(args.Data().As<v8::External>()->Value());
(*value)++;
}
args.GetReturnValue().Set(v8_num(42));
}
static void SerializedCallbackReplacement(
const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(v8_num(1337));
}
static void NamedPropertyGetterForSerialization(
v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
if (name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("x"))
.FromJust()) {
info.GetReturnValue().Set(v8_num(2016));
}
}
static void AccessorForSerialization(
v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(v8_num(2017));
}
static SerializerOneByteResource serializable_one_byte_resource("one_byte", 8);
static SerializerTwoByteResource serializable_two_byte_resource("two_byte", 8);
intptr_t original_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallback),
reinterpret_cast<intptr_t>(&serialized_static_field),
reinterpret_cast<intptr_t>(&NamedPropertyGetterForSerialization),
reinterpret_cast<intptr_t>(&AccessorForSerialization),
reinterpret_cast<intptr_t>(&serialized_static_field), // duplicate entry
reinterpret_cast<intptr_t>(&serializable_one_byte_resource),
reinterpret_cast<intptr_t>(&serializable_two_byte_resource),
0};
intptr_t replaced_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallbackReplacement),
reinterpret_cast<intptr_t>(&serialized_static_field),
reinterpret_cast<intptr_t>(&NamedPropertyGetterForSerialization),
reinterpret_cast<intptr_t>(&AccessorForSerialization),
reinterpret_cast<intptr_t>(&serialized_static_field),
reinterpret_cast<intptr_t>(&serializable_one_byte_resource),
reinterpret_cast<intptr_t>(&serializable_two_byte_resource),
0};
intptr_t short_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallbackReplacement), 0};
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorExternalReferences) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
v8::Local<v8::Value> function =
callback->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
CHECK(context->Global()
->Set(context, v8_str("one_byte"),
v8::String::NewExternalOneByte(
isolate, &serializable_one_byte_resource)
.ToLocalChecked())
.FromJust());
CHECK(context->Global()
->Set(context, v8_str("two_byte"),
v8::String::NewExternalTwoByte(
isolate, &serializable_two_byte_resource)
.ToLocalChecked())
.FromJust());
ExpectInt32("f()", 42);
ExpectString("one_byte", "one_byte");
ExpectString("two_byte", "two_byte");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
CHECK_EQ(1, serializable_one_byte_resource.dispose_count());
CHECK_EQ(1, serializable_two_byte_resource.dispose_count());
// Deserialize with the original external reference.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = original_external_references;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
ExpectString("one_byte", "one_byte");
ExpectString("two_byte", "two_byte");
v8::Local<v8::String> one_byte = CompileRun("one_byte").As<v8::String>();
v8::Local<v8::String> two_byte = CompileRun("two_byte").As<v8::String>();
CHECK(one_byte->IsExternalOneByte());
CHECK(!one_byte->IsExternalTwoByte());
CHECK(!two_byte->IsExternalOneByte());
CHECK(two_byte->IsExternalTwoByte());
}
isolate->Dispose();
}
CHECK_EQ(2, serializable_one_byte_resource.dispose_count());
CHECK_EQ(2, serializable_two_byte_resource.dispose_count());
// Deserialize with some other external reference.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = replaced_external_references;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 1337);
}
isolate->Dispose();
}
CHECK_EQ(3, serializable_one_byte_resource.dispose_count());
CHECK_EQ(3, serializable_two_byte_resource.dispose_count());
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorShortExternalReferences) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
v8::Local<v8::Value> function =
callback->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
ExpectInt32("f()", 42);
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = short_external_references;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 1337);
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
v8::StartupData CreateSnapshotWithDefaultAndCustom() {
v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun("function f() { return 41; }");
creator.SetDefaultContext(context);
ExpectInt32("f()", 41);
}
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::FunctionTemplate> function_template =
v8::FunctionTemplate::New(isolate, SerializedCallback);
v8::Local<v8::Value> function =
function_template->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
v8::Local<v8::ObjectTemplate> object_template =
v8::ObjectTemplate::New(isolate);
object_template->SetAccessor(v8_str("x"), AccessorForSerialization);
v8::Local<v8::Object> object =
object_template->NewInstance(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("o"), object).FromJust());
ExpectInt32("f()", 42);
ExpectInt32("o.x", 2017);
creator.AddContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorNoExternalReferencesDefault) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateSnapshotWithDefaultAndCustom();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = nullptr;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 41);
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
v8::StartupData CreateCustomSnapshotWithPreparseDataAndNoOuterScope() {
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"var foo = {\n"
" // This function is not top-level, but also has no outer scope.\n"
" bar: function(){\n"
" // Add an inner function so that the outer one has preparse\n"
" // scope data.\n"
" return function(){}\n"
" }\n"
"};\n");
creator.SetDefaultContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorPreparseDataAndNoOuterScope) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotWithPreparseDataAndNoOuterScope();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
v8::StartupData CreateCustomSnapshotArrayJoinWithKeep() {
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"[].join('');\n"
"function g() { return String([1,2,3]); }\n");
ExpectString("g()", "1,2,3");
creator.SetDefaultContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorArrayJoinWithKeep) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotArrayJoinWithKeep();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectString("g()", "1,2,3");
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
v8::StartupData CreateCustomSnapshotWithDuplicateFunctions() {
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"function f() { return (() => 'a'); }\n"
"let g1 = f();\n"
"let g2 = f();\n");
ExpectString("g1()", "a");
ExpectString("g2()", "a");
creator.SetDefaultContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
UNINITIALIZED_TEST(SnapshotCreatorDuplicateFunctions) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotWithDuplicateFunctions();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectString("g1()", "a");
ExpectString("g2()", "a");
}
isolate->Dispose();
}
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
#ifndef V8_SHARED_RO_HEAP
// We do not support building multiple snapshots when read-only heap is shared.
TEST(SnapshotCreatorNoExternalReferencesCustomFail1) {
DisableAlwaysOpt();
v8::StartupData blob = CreateSnapshotWithDefaultAndCustom();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = nullptr;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
}
isolate->Dispose();
}
delete[] blob.data;
}
TEST(SnapshotCreatorNoExternalReferencesCustomFail2) {
DisableAlwaysOpt();
v8::StartupData blob = CreateSnapshotWithDefaultAndCustom();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = nullptr;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("o.x", 2017);
}
isolate->Dispose();
}
delete[] blob.data;
}
#endif // V8_SHARED_RO_HEAP
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorUnknownExternalReferences) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
v8::Local<v8::Value> function =
callback->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
ExpectInt32("f()", 42);
creator.SetDefaultContext(context);
}
v8::StartupData blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorTemplates) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
InternalFieldData* a1 = new InternalFieldData{11};
InternalFieldData* b1 = new InternalFieldData{20};
InternalFieldData* c1 = new InternalFieldData{30};
v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::ExtensionConfiguration* no_extension = nullptr;
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
v8::Local<v8::External> external =
v8::External::New(isolate, &serialized_static_field);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback, external);
global_template->Set(isolate, "f", callback);
v8::Local<v8::Context> context =
v8::Context::New(isolate, no_extension, global_template);
creator.SetDefaultContext(context);
context = v8::Context::New(isolate, no_extension, global_template);
v8::Local<v8::ObjectTemplate> object_template =
v8::ObjectTemplate::New(isolate);
object_template->SetInternalFieldCount(3);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
CHECK_EQ(315, serialized_static_field);
v8::Local<v8::Object> a =
object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::Object> b =
object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::Object> c =
object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::External> resource_external =
v8::External::New(isolate, &serializable_one_byte_resource);
v8::Local<v8::External> field_external =
v8::External::New(isolate, &serialized_static_field);
a->SetInternalField(0, b);
b->SetInternalField(0, c);
a->SetAlignedPointerInInternalField(1, a1);
b->SetAlignedPointerInInternalField(1, b1);
c->SetAlignedPointerInInternalField(1, c1);
a->SetInternalField(2, resource_external);
b->SetInternalField(2, field_external);
c->SetInternalField(2, v8_num(35));
CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust());
CHECK_EQ(0u,
creator.AddContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields,
reinterpret_cast<void*>(2000))));
CHECK_EQ(0u, creator.AddData(callback));
CHECK_EQ(1u, creator.AddData(global_template));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
delete a1;
delete b1;
delete c1;
}
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = original_external_references;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
{
// Create a new context without a new object template.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
CHECK_EQ(316, serialized_static_field);
// Retrieve the snapshotted object template.
v8::Local<v8::ObjectTemplate> obj_template =
isolate->GetDataFromSnapshotOnce<v8::ObjectTemplate>(1)
.ToLocalChecked();
CHECK(!obj_template.IsEmpty());
v8::Local<v8::Object> object =
obj_template->NewInstance(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("o"), object).FromJust());
ExpectInt32("o.f()", 42);
CHECK_EQ(317, serialized_static_field);
// Check that it instantiates to the same prototype.
ExpectTrue("o.f.prototype === f.prototype");
// Retrieve the snapshotted function template.
v8::Local<v8::FunctionTemplate> fun_template =
isolate->GetDataFromSnapshotOnce<v8::FunctionTemplate>(0)
.ToLocalChecked();
CHECK(!fun_template.IsEmpty());
v8::Local<v8::Function> fun =
fun_template->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("g"), fun).FromJust());
ExpectInt32("g()", 42);
// Check that it instantiates to the same prototype.
ExpectTrue("g.prototype === f.prototype");
// Retrieve embedder fields.
v8::Local<v8::Object> a = context->Global()
->Get(context, v8_str("a"))
.ToLocalChecked()
->ToObject(context)
.ToLocalChecked();
v8::Local<v8::Object> b =
a->GetInternalField(0)->ToObject(context).ToLocalChecked();
v8::Local<v8::Object> c =
b->GetInternalField(0)->ToObject(context).ToLocalChecked();
InternalFieldData* a1 = reinterpret_cast<InternalFieldData*>(
a->GetAlignedPointerFromInternalField(1));
v8::Local<v8::Value> a2 = a->GetInternalField(2);
InternalFieldData* b1 = reinterpret_cast<InternalFieldData*>(
b->GetAlignedPointerFromInternalField(1));
v8::Local<v8::Value> b2 = b->GetInternalField(2);
v8::Local<v8::Value> c0 = c->GetInternalField(0);
InternalFieldData* c1 = reinterpret_cast<InternalFieldData*>(
c->GetAlignedPointerFromInternalField(1));
v8::Local<v8::Value> c2 = c->GetInternalField(2);
CHECK(c0->IsUndefined());
CHECK_EQ(11u, a1->data);
CHECK_EQ(20u, b1->data);
CHECK_EQ(30u, c1->data);
CHECK(a2->IsExternal());
CHECK_EQ(static_cast<void*>(&serializable_one_byte_resource),
v8::Local<v8::External>::Cast(a2)->Value());
CHECK(b2->IsExternal());
CHECK_EQ(static_cast<void*>(&serialized_static_field),
v8::Local<v8::External>::Cast(b2)->Value());
CHECK(c2->IsInt32() && c2->Int32Value(context).FromJust() == 35);
// Calling GetDataFromSnapshotOnce again returns an empty MaybeLocal.
CHECK(
isolate->GetDataFromSnapshotOnce<v8::ObjectTemplate>(1).IsEmpty());
CHECK(isolate->GetDataFromSnapshotOnce<v8::FunctionTemplate>(0)
.IsEmpty());
CHECK(v8::Context::FromSnapshot(isolate, 1).IsEmpty());
for (auto data : deserialized_data) delete data;
deserialized_data.clear();
}
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
MaybeLocal<v8::Module> ResolveCallback(Local<v8::Context> context,
Local<v8::String> specifier,
Local<v8::FixedArray> import_assertions,
Local<v8::Module> referrer) {
return {};
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorAddData) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
// i::PerformCastCheck(Data*) should compile and be no-op
{
v8::Local<v8::Data> data;
i::PerformCastCheck(*data);
}
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
v8::Eternal<v8::Value> eternal_number;
v8::Persistent<v8::Value> persistent_number_1;
v8::Persistent<v8::Value> persistent_number_2;
v8::Persistent<v8::Context> persistent_context;
{
v8::HandleScope handle_scope(isolate);
eternal_number.Set(isolate, v8_num(2017));
persistent_number_1.Reset(isolate, v8_num(2018));
persistent_number_2.Reset(isolate, v8_num(2019));
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK_EQ(0u, creator.AddData(context, persistent_number_2.Get(isolate)));
creator.SetDefaultContext(context);
context = v8::Context::New(isolate);
persistent_context.Reset(isolate, context);
v8::Context::Scope context_scope(context);
v8::Local<v8::Object> object = CompileRun("({ p: 12 })").As<v8::Object>();
v8::Local<v8::ObjectTemplate> object_template =
v8::ObjectTemplate::New(isolate);
object_template->SetInternalFieldCount(3);
v8::Local<v8::Private> private_symbol =
v8::Private::ForApi(isolate, v8_str("private_symbol"));
v8::Local<v8::Signature> signature =
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
v8::Signature::New(isolate, v8::FunctionTemplate::New(isolate));
v8::ScriptOrigin origin(isolate, v8_str(""), {}, {}, {}, {}, {}, {}, {},
true);
v8::ScriptCompiler::Source source(
v8::String::NewFromUtf8Literal(
isolate, "export let a = 42; globalThis.a = {};"),
origin);
v8::Local<v8::Module> module =
v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
module->InstantiateModule(context, ResolveCallback).ToChecked();
module->Evaluate(context).ToLocalChecked();
CHECK_EQ(0u, creator.AddData(context, object));
CHECK_EQ(1u, creator.AddData(context, v8_str("context-dependent")));
CHECK_EQ(2u, creator.AddData(context, persistent_number_1.Get(isolate)));
CHECK_EQ(3u, creator.AddData(context, object_template));
CHECK_EQ(4u, creator.AddData(context, persistent_context.Get(isolate)));
CHECK_EQ(5u, creator.AddData(context, module));
creator.AddContext(context);
CHECK_EQ(0u, creator.AddData(v8_str("context-independent")));
CHECK_EQ(1u, creator.AddData(eternal_number.Get(isolate)));
CHECK_EQ(2u, creator.AddData(object_template));
CHECK_EQ(3u, creator.AddData(v8::FunctionTemplate::New(isolate)));
CHECK_EQ(4u, creator.AddData(private_symbol));
CHECK_EQ(5u, creator.AddData(signature));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
// Check serialized data on the context.
v8::Local<v8::Object> object =
context->GetDataFromSnapshotOnce<v8::Object>(0).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::Object>(0).IsEmpty());
CHECK_EQ(12, object->Get(context, v8_str("p"))
.ToLocalChecked()
->Int32Value(context)
.FromJust());
v8::Local<v8::String> string =
context->GetDataFromSnapshotOnce<v8::String>(1).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::String>(1).IsEmpty());
CHECK(string->Equals(context, v8_str("context-dependent")).FromJust());
v8::Local<v8::Number> number =
context->GetDataFromSnapshotOnce<v8::Number>(2).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::Number>(2).IsEmpty());
CHECK_EQ(2018, number->Int32Value(context).FromJust());
v8::Local<v8::ObjectTemplate> templ =
context->GetDataFromSnapshotOnce<v8::ObjectTemplate>(3)
.ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::ObjectTemplate>(3).IsEmpty());
CHECK_EQ(3, templ->InternalFieldCount());
v8::Local<v8::Context> serialized_context =
context->GetDataFromSnapshotOnce<v8::Context>(4).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::Context>(4).IsEmpty());
CHECK_EQ(*v8::Utils::OpenHandle(*serialized_context),
*v8::Utils::OpenHandle(*context));
v8::Local<v8::Module> serialized_module =
context->GetDataFromSnapshotOnce<v8::Module>(5).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::Context>(5).IsEmpty());
{
v8::Context::Scope context_scope(context);
v8::Local<v8::Object> mod_ns =
serialized_module->GetModuleNamespace().As<v8::Object>();
CHECK(mod_ns->Get(context, v8_str("a"))
.ToLocalChecked()
->StrictEquals(v8_num(42.0)));
}
CHECK(context->GetDataFromSnapshotOnce<v8::Value>(6).IsEmpty());
// Check serialized data on the isolate.
string = isolate->GetDataFromSnapshotOnce<v8::String>(0).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::String>(0).IsEmpty());
CHECK(string->Equals(context, v8_str("context-independent")).FromJust());
number = isolate->GetDataFromSnapshotOnce<v8::Number>(1).ToLocalChecked();
CHECK(isolate->GetDataFromSnapshotOnce<v8::Number>(1).IsEmpty());
CHECK_EQ(2017, number->Int32Value(context).FromJust());
templ = isolate->GetDataFromSnapshotOnce<v8::ObjectTemplate>(2)
.ToLocalChecked();
CHECK(isolate->GetDataFromSnapshotOnce<v8::ObjectTemplate>(2).IsEmpty());
CHECK_EQ(3, templ->InternalFieldCount());
isolate->GetDataFromSnapshotOnce<v8::FunctionTemplate>(3)
.ToLocalChecked();
CHECK(
isolate->GetDataFromSnapshotOnce<v8::FunctionTemplate>(3).IsEmpty());
isolate->GetDataFromSnapshotOnce<v8::Private>(4).ToLocalChecked();
Reland^4 "[serializer] Allocate during deserialization" This relands commit 3f4e9bbe43650862884b9719494b216635f3b8c2. which was a reland of c4a062a9588b24a844a30358ac40f811d0020e0b which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a The change had an issue that embedders implementing heap tracing (e.g. Unified Heap with Blink) could be passed an uninitialized pointer if marking happened during deserialization of an object containing such a pointer. Because of the 0xdeadbed0 uninitialized filler value, these embedders would then receive the value 0xdeadbed0deadbed0 as the 'pointer', and crash on dereference. There is, however, special handling already for null pointers in heap tracing, also for dealing with not-yet initialized values. So, we can make the uninitialized Smi filler be 0x00000000, and that will make such embedded fields have a nullptr representation, making them follow the normal uninitialized value bailouts. In addition, it relands the following dependent changes, which are relanding unchanged and are followup performance improvements. Relanding them in the same change should allow for cleaner reverts should they be needed. This relands commit 76ad3ab59732a0ac400874b5143eb18697813cf3 [identity-map] Change resize heuristic This relands commit 77cc96aa48a4ec2841b4c1fffd63f2a69c3f59d0 [identity-map] Cache the calculated Hash This relands commit bee5b996aae018acf87ece5fda74e07678f3bba1 [serializer] Remove Deserializer::Initialize This relands commit c8f73f22662a8db351123a20761d48006545af37 [serializer] Cache instance type in PostProcessNewObject This relands commit 4e7c99abdab608ce63c7dcff5a2f891f695d529c [identity-map] Remove double-lookups in IdentityMap Original change's description: > Reland^3 "[serializer] Allocate during deserialization" > > This is a reland of c4a062a9588b24a844a30358ac40f811d0020e0b > which was a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > Fixes TSAN errors from non-atomic writes in the deserializer. Now all > writes are (relaxed) atomic. > > Original change's description: > > Reland^2 "[serializer] Allocate during deserialization" > > > > This is a reland of 28a30c578c1d690b320b602d6c90e7fe1996c7f4 > > which was a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > The crashes were from calling RegisterDeserializerFinished on a null > > Isolate pointer, for a deserializer that was never initialised > > (specifically, ReadOnlyDeserializer when ROHeap is shared). > > > > Original change's description: > > > Reland "[serializer] Allocate during deserialization" > > > > > > This is a reland of 5d7a29c90e85476edf44c9e9e495630cf395086a > > > > > > This reland shuffles around the order of checks in Heap::AllocateRawWith > > > to not check the new space addresses until it's known that this is a new > > > space allocation. This fixes an UBSan failure during read-only space > > > deserialization, which happens before the new space is initialized. > > > > > > It also fixes some issues discovered by --stress-snapshot, around > > > serializing ThinStrings (which are now elided as part of serialization), > > > handle counts (I bumped the maximum handle count in that check), and > > > clearing map transitions (the map backpointer field needed a Smi > > > uninitialized value check). > > > > > > Original change's description: > > > > [serializer] Allocate during deserialization > > > > > > > > This patch removes the concept of reservations and a specialized > > > > deserializer allocator, and instead makes the deserializer allocate > > > > directly with the Heap's Allocate method. > > > > > > > > The major consequence of this is that the GC can now run during > > > > deserialization, which means that: > > > > > > > > a) Deserialized objects are visible to the GC, and > > > > b) Objects that the deserializer/deserialized objects point to can > > > > move. > > > > > > > > Point a) is mostly not a problem due to previous work in making > > > > deserialized objects "GC valid", i.e. making sure that they have a valid > > > > size before any subsequent allocation/safepoint. We now additionally > > > > have to initialize the allocated space with a valid tagged value -- this > > > > is a magic Smi value to keep "uninitialized" checks simple. > > > > > > > > Point b) is solved by Handlifying the deserializer. This involves > > > > changing any vectors of objects into vectors of Handles, and any object > > > > keyed map into an IdentityMap (we can't use Handles as keys because > > > > the object's address is no longer a stable hash). > > > > > > > > Back-references can no longer be direct chunk offsets, so instead the > > > > deserializer stores a Handle to each deserialized object, and the > > > > backreference is an index into this handle array. This encoding could > > > > be optimized in the future with e.g. a second pass over the serialized > > > > array which emits a different bytecode for objects that are and aren't > > > > back-referenced. > > > > > > > > Additionally, the slot-walk over objects to initialize them can no > > > > longer use absolute slot offsets, as again an object may move and its > > > > slot address would become invalid. Now, slots are walked as relative > > > > offsets to a Handle to the object, or as absolute slots for the case of > > > > root pointers. A concept of "slot accessor" is introduced to share the > > > > code between these two modes, and writing the slot (including write > > > > barriers) is abstracted into this accessor. > > > > > > > > Finally, the Code body walk is modified to deserialize all objects > > > > referred to by RelocInfos before doing the RelocInfo walk itself. This > > > > is because RelocInfoIterator uses raw pointers, so we cannot allocate > > > > during a RelocInfo walk. > > > > > > > > As a drive-by, the VariableRawData bytecode is tweaked to use tagged > > > > size rather than byte size -- the size is expected to be tagged-aligned > > > > anyway, so now we get an extra few bits in the size encoding. > > > > > > > > Bug: chromium:1075999 > > > > Change-Id: I672c42f553f2669888cc5e35d692c1b8ece1845e > > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2404451 > > > > Commit-Queue: Leszek Swirski <leszeks@chromium.org> > > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > > > > Cr-Commit-Position: refs/heads/master@{#70229} Bug: chromium:1075999 Change-Id: Ib514a4ef16bd02bfb60d046ecbf8fae1ead64a98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2452689 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#70366}
2020-10-07 07:31:16 +00:00
CHECK(isolate->GetDataFromSnapshotOnce<v8::Private>(4).IsEmpty());
isolate->GetDataFromSnapshotOnce<v8::Signature>(5).ToLocalChecked();
CHECK(isolate->GetDataFromSnapshotOnce<v8::Signature>(5).IsEmpty());
CHECK(isolate->GetDataFromSnapshotOnce<v8::Value>(7).IsEmpty());
}
isolate->Dispose();
}
{
SnapshotCreator creator(nullptr, &blob);
v8::Isolate* isolate = creator.GetIsolate();
{
// Adding data to a snapshot replaces the list of existing data.
v8::HandleScope hscope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
creator.SetDefaultContext(context);
context = v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Local<v8::String> string =
context->GetDataFromSnapshotOnce<v8::String>(1).ToLocalChecked();
CHECK(context->GetDataFromSnapshotOnce<v8::String>(1).IsEmpty());
CHECK(string->Equals(context, v8_str("context-dependent")).FromJust());
v8::Local<v8::Number> number =
isolate->GetDataFromSnapshotOnce<v8::Number>(1).ToLocalChecked();
CHECK(isolate->GetDataFromSnapshotOnce<v8::Number>(1).IsEmpty());
CHECK_EQ(2017, number->Int32Value(context).FromJust());
CHECK_EQ(0u, creator.AddData(context, v8_num(2016)));
CHECK_EQ(0u, creator.AddContext(context));
CHECK_EQ(0u, creator.AddData(v8_str("stuff")));
}
delete[] blob.data;
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
// Context where we did not re-add data no longer has data.
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(context->GetDataFromSnapshotOnce<v8::Object>(0).IsEmpty());
// Context where we re-added data has completely new ones.
context = v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Local<v8::Value> value =
context->GetDataFromSnapshotOnce<v8::Value>(0).ToLocalChecked();
CHECK_EQ(2016, value->Int32Value(context).FromJust());
CHECK(context->GetDataFromSnapshotOnce<v8::Value>(1).IsEmpty());
// Ditto for the isolate.
v8::Local<v8::String> string =
isolate->GetDataFromSnapshotOnce<v8::String>(0).ToLocalChecked();
CHECK(string->Equals(context, v8_str("stuff")).FromJust());
CHECK(context->GetDataFromSnapshotOnce<v8::String>(1).IsEmpty());
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
TEST(SnapshotCreatorUnknownHandles) {
DisableAlwaysOpt();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
v8::Eternal<v8::Value> eternal_number;
v8::Persistent<v8::Value> persistent_number;
{
v8::HandleScope handle_scope(isolate);
eternal_number.Set(isolate, v8_num(2017));
persistent_number.Reset(isolate, v8_num(2018));
v8::Local<v8::Context> context = v8::Context::New(isolate);
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
delete[] blob.data;
}
UNINITIALIZED_TEST(SnapshotAccessorDescriptors) {
const char* source1 =
"var bValue = 38;\n"
"Object.defineProperty(this, 'property1', {\n"
" get() { return bValue; },\n"
" set(newValue) { bValue = newValue; },\n"
"});";
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope c_scope(context);
ExpectInt32("this.property1", 38);
}
isolate1->Dispose();
delete[] data1.data;
}
UNINITIALIZED_TEST(SnapshotObjectDefinePropertyWhenNewGlobalTemplate) {
const char* source1 =
"Object.defineProperty(this, 'property1', {\n"
" value: 42,\n"
" writable: false\n"
"});\n"
"var bValue = 38;\n"
"Object.defineProperty(this, 'property2', {\n"
" get() { return bValue; },\n"
" set(newValue) { bValue = newValue; }\n"
"});";
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate1);
v8::Local<v8::Context> context =
v8::Context::New(isolate1, nullptr, global_template);
v8::Context::Scope c_scope(context);
ExpectInt32("this.property1", 42);
ExpectInt32("this.property2", 38);
}
isolate1->Dispose();
delete[] data1.data;
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate();
{
// Set default context. This context implicitly does *not* serialize
// the global proxy, and upon deserialization one has to be created
// in the bootstrapper from the global object template.
// Side effects from extensions are persisted though.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
global_template->Set(isolate, "f", callback);
global_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
NamedPropertyGetterForSerialization));
v8::Local<v8::Context> context =
v8::Context::New(isolate, nullptr, global_template);
v8::Context::Scope context_scope(context);
CompileRun(
"function h() { return 13; };"
"function i() { return 14; };"
"var o = { p: 7 };");
ExpectInt32("f()", 42);
ExpectInt32("h()", 13);
ExpectInt32("o.p", 7);
ExpectInt32("x", 2016);
creator.SetDefaultContext(context);
}
{
// Add additional context. This context implicitly *does* serialize
// the global proxy, and upon deserialization one has to be created
// in the bootstrapper from the global object template.
// Side effects from extensions are persisted.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
global_template->SetInternalFieldCount(3);
global_template->Set(isolate, "f", callback);
global_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
NamedPropertyGetterForSerialization));
global_template->SetAccessor(v8_str("y"), AccessorForSerialization);
v8::Local<v8::Private> priv =
v8::Private::ForApi(isolate, v8_str("cached"));
global_template->SetAccessorProperty(
v8_str("cached"),
v8::FunctionTemplate::NewWithCache(isolate, SerializedCallback, priv,
v8::Local<v8::Value>()));
v8::Local<v8::Context> context =
v8::Context::New(isolate, nullptr, global_template);
v8::Context::Scope context_scope(context);
CHECK(context->Global()
->SetPrivate(context, priv, v8_str("cached string"))
.FromJust());
v8::Local<v8::Private> hidden =
v8::Private::ForApi(isolate, v8_str("hidden"));
CHECK(context->Global()
->SetPrivate(context, hidden, v8_str("hidden string"))
.FromJust());
ExpectInt32("f()", 42);
ExpectInt32("x", 2016);
ExpectInt32("y", 2017);
CHECK(v8_str("hidden string")
->Equals(context, context->Global()
->GetPrivate(context, hidden)
.ToLocalChecked())
.FromJust());
CHECK_EQ(0u,
creator.AddContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields,
reinterpret_cast<void*>(2016))));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = original_external_references;
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
// We can introduce new extensions, which could override functions already
// in the snapshot.
auto extension =
std::make_unique<v8::Extension>("new extension",
"function i() { return 24; }"
"function j() { return 25; }"
"let a = 26;"
"try {"
" if (o.p == 7) o.p++;"
"} catch {}");
extension->set_auto_enable(true);
v8::RegisterExtension(std::move(extension));
{
// Create a new context from default context snapshot. This will also
// deserialize its global object with interceptor.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
ExpectInt32("h()", 13);
ExpectInt32("i()", 24);
ExpectInt32("j()", 25);
ExpectInt32("o.p", 8);
ExpectInt32("a", 26);
ExpectInt32("x", 2016);
}
{
// Create a new context from first additional context snapshot. This
// will use the global object from the snapshot, including interceptor.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked();
{
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
ExpectInt32("i()", 24);
ExpectInt32("j()", 25);
ExpectInt32("x", 2016);
v8::Local<v8::Private> hidden =
v8::Private::ForApi(isolate, v8_str("hidden"));
CHECK(v8_str("hidden string")
->Equals(context, context->Global()
->GetPrivate(context, hidden)
.ToLocalChecked())
.FromJust());
ExpectString("cached", "cached string");
}
v8::Local<v8::Object> global = context->Global();
CHECK_EQ(3, global->InternalFieldCount());
context->DetachGlobal();
// New context, but reuse global proxy.
v8::ExtensionConfiguration* no_extensions = nullptr;
v8::Local<v8::Context> context2 =
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)),
no_extensions, global)
.ToLocalChecked();
{
v8::Context::Scope context_scope(context2);
ExpectInt32("f()", 42);
ExpectInt32("i()", 24);
ExpectInt32("j()", 25);
ExpectInt32("x", 2016);
v8::Local<v8::Private> hidden =
v8::Private::ForApi(isolate, v8_str("hidden"));
CHECK(v8_str("hidden string")
->Equals(context2, context2->Global()
->GetPrivate(context2, hidden)
.ToLocalChecked())
.FromJust());
// Set cached accessor property again.
v8::Local<v8::Private> priv =
v8::Private::ForApi(isolate, v8_str("cached"));
CHECK(context2->Global()
->SetPrivate(context2, priv, v8_str("cached string 1"))
.FromJust());
ExpectString("cached", "cached string 1");
}
CHECK(context2->Global()->Equals(context2, global).FromJust());
}
}
isolate->Dispose();
}
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ReinitializeHashSeedJSCollectionRehashable) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
// Create an object with an ordered hash table.
CompileRun(
"var m = new Map();"
"m.set('a', 1);"
"m.set('b', 2);"
"var s = new Set();"
"s.add(1);"
"s.add(globalThis);");
ExpectInt32("m.get('b')", 2);
ExpectTrue("s.has(1)");
ExpectTrue("s.has(globalThis)");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
CHECK(blob.CanBeRehashed());
}
i::v8_flags.hash_seed = 1337;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
// Check that rehashing has been performed.
CHECK_EQ(static_cast<uint64_t>(1337),
HashSeed(reinterpret_cast<i::Isolate*>(isolate)));
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectInt32("m.get('b')", 2);
ExpectTrue("s.has(1)");
ExpectTrue("s.has(globalThis)");
}
isolate->Dispose();
delete[] blob.data;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ReinitializeHashSeedRehashable) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
// Create dictionary mode object.
CompileRun(
"var a = new Array(10000);"
"%NormalizeElements(a);"
"a[133] = 1;"
"a[177] = 2;"
"a[971] = 3;"
"a[7997] = 4;"
"a[2111] = 5;"
"var o = {};"
"%OptimizeObjectForAddingMultipleProperties(o, 3);"
"o.a = 1;"
"o.b = 2;"
"o.c = 3;"
"var p = { foo: 1 };" // Test rehashing of transition arrays.
"p = JSON.parse('{\"foo\": {\"x\": 1}}');");
i::Handle<i::Object> i_a = v8::Utils::OpenHandle(*CompileRun("a"));
i::Handle<i::Object> i_o = v8::Utils::OpenHandle(*CompileRun("o"));
CHECK(i_a->IsJSArray());
CHECK(i_a->IsJSObject());
CHECK(!i::Handle<i::JSArray>::cast(i_a)->HasFastElements());
CHECK(!i::Handle<i::JSObject>::cast(i_o)->HasFastProperties());
ExpectInt32("a[2111]", 5);
ExpectInt32("o.c", 3);
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
CHECK(blob.CanBeRehashed());
}
i::v8_flags.hash_seed = 1337;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
// Check that rehashing has been performed.
CHECK_EQ(static_cast<uint64_t>(1337),
HashSeed(reinterpret_cast<i::Isolate*>(isolate)));
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
i::Handle<i::Object> i_a = v8::Utils::OpenHandle(*CompileRun("a"));
i::Handle<i::Object> i_o = v8::Utils::OpenHandle(*CompileRun("o"));
CHECK(i_a->IsJSArray());
CHECK(i_a->IsJSObject());
CHECK(!i::Handle<i::JSArray>::cast(i_a)->HasFastElements());
CHECK(!i::Handle<i::JSObject>::cast(i_o)->HasFastProperties());
ExpectInt32("a[2111]", 5);
ExpectInt32("o.c", 3);
}
isolate->Dispose();
delete[] blob.data;
Reland "[builtins] Support embedded builtins in nosnapshot builds" This is a reland of bf2f0a0227c1233cd42e6e0a928bf968acaf713e Original change's description: > [builtins] Support embedded builtins in nosnapshot builds > > This CL adds support for embedded builtins in nosnap builds by creating > and setting an 'embedded blob' after builtin generation. Unlike > snapshot builds, the blob is not embedded into the .text section but > located on the C++ heap. > > This makes nosnap builds more consistent with mksnapshot, and allows us > to simplify there and in serializer cctests. > > Complications arise from the different workflows we need to support: > > 1. the standard mksnapshot build process, > 2. nosnap builds (which reuse the blob created by the first Isolate), > 2. and tests with various complicated serialization workflows. > > To cover all of these cases, this CL introduces two knobs to twiddle: > > 1. A 'sticky' embedded blob which overrides compiled-in default > embedded blobs at Isolate setup. > 2. The blob lifecycle can be managed manually or through refcounting. > > These are described in more detail in isolate.cc. > > Tbr: ulan@chromium.org > Bug: v8:6666, v8:8350 > Change-Id: I3842e40cdaf45d2cadd05c6eb1ec2f5e3d83568d > Reviewed-on: https://chromium-review.googlesource.com/c/1310195 > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Yang Guo <yangguo@chromium.org> > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#57523} Tbr: ulan@chromium.org,yangguo@chromium.org Bug: v8:6666, v8:8350 Change-Id: I13b523c9e7406b39a3cd28465c06f17f1744a738 Reviewed-on: https://chromium-review.googlesource.com/c/1337578 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#57540}
2018-11-15 12:49:20 +00:00
FreeCurrentEmbeddedBlob();
}
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
UNINITIALIZED_TEST(ClassFields) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class ClassWithFieldInitializer {"
" #field = 1;"
" constructor(val) {"
" this.#field = val;"
" }"
" get field() {"
" return this.#field;"
" }"
"}"
"class ClassWithDefaultConstructor {"
" #field = 42;"
" get field() {"
" return this.#field;"
" }"
"}"
"class ClassWithFieldDeclaration {"
" #field;"
" constructor(val) {"
" this.#field = val;"
" }"
" get field() {"
" return this.#field;"
" }"
"}"
"class ClassWithPublicField {"
" field = 1;"
" constructor(val) {"
" this.field = val;"
" }"
"}"
"class ClassWithFunctionField {"
" field = 123;"
" func = () => { return this.field; }"
"}"
"class ClassWithThisInInitializer {"
" #field = 123;"
" field = this.#field;"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectInt32("(new ClassWithFieldInitializer(123)).field", 123);
ExpectInt32("(new ClassWithDefaultConstructor()).field", 42);
ExpectInt32("(new ClassWithFieldDeclaration(123)).field", 123);
ExpectInt32("(new ClassWithPublicField(123)).field", 123);
ExpectInt32("(new ClassWithFunctionField()).func()", 123);
ExpectInt32("(new ClassWithThisInInitializer()).field", 123);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsReferencePrivateInInitializer) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class A {"
" #a = 42;"
" a = this.#a;"
"}"
"let str;"
"class ClassWithEval {"
" field = eval(str);"
"}"
"class ClassWithPrivateAndEval {"
" #field = 42;"
" field = eval(str);"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectInt32("(new A()).a", 42);
v8::TryCatch try_catch(isolate);
CompileRun("str = 'this.#nonexistent'; (new ClassWithEval()).field");
CHECK(try_catch.HasCaught());
ExpectInt32("str = 'this.#field'; (new ClassWithPrivateAndEval()).field",
42);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsReferenceClassVariable) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class PrivateFieldClass {"
" #consturctor = PrivateFieldClass;"
" func() {"
" return this.#consturctor;"
" }"
"}"
"class PublicFieldClass {"
" ctor = PublicFieldClass;"
" func() {"
" return this.ctor;"
" }"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectTrue("new PrivateFieldClass().func() === PrivateFieldClass");
ExpectTrue("new PublicFieldClass().func() === PublicFieldClass");
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsNested) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class Outer {"
" #odata = 42;"
" #inner;"
" static getInner() {"
" class Inner {"
" #idata = 42;"
" #outer;"
" constructor(outer) {"
" this.#outer = outer;"
" outer.#inner = this;"
" }"
" check() {"
" return this.#idata === this.#outer.#odata &&"
" this === this.#outer.#inner;"
" }"
" }"
" return Inner;"
" }"
" check() {"
" return this.#inner.check();"
" }"
"}"
"const Inner = Outer.getInner();");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectTrue("(new Inner(new Outer)).check()");
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassPrivateMethods) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class JustPrivateMethods {"
" #method() { return this.val; }"
" get #accessor() { return this.val; };"
" set #accessor(val) { this.val = val; }"
" method() { return this.#method(); } "
" getter() { return this.#accessor; } "
" setter(val) { this.#accessor = val } "
"}"
"class PrivateMethodsAndFields {"
" #val = 1;"
" #method() { return this.#val; }"
" get #accessor() { return this.#val; };"
" set #accessor(val) { this.#val = val; }"
" method() { return this.#method(); } "
" getter() { return this.#accessor; } "
" setter(val) { this.#accessor = val } "
"}"
"class Nested {"
" #val = 42;"
" static #method(obj) { return obj.#val; }"
" getInner() {"
" class Inner {"
" runEval(obj, str) {"
" return eval(str);"
" }"
" }"
" return Inner;"
" }"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
CompileRun("const a = new JustPrivateMethods(); a.setter(42);");
ExpectInt32("a.method()", 42);
ExpectInt32("a.getter()", 42);
CompileRun("const b = new PrivateMethodsAndFields(); b.setter(42);");
ExpectInt32("b.method()", 42);
ExpectInt32("b.getter()", 42);
CompileRun("const c = new (new Nested().getInner());");
ExpectInt32("c.runEval(new Nested(), 'Nested.#method(obj)')", 42);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsWithInheritance) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"class Base {"
" #a = 'test';"
" getA() { return this.#a; }"
"}"
"class Derived extends Base {"
" #b = 1;"
" constructor() {"
" super();"
" this.#b = this.getA();"
" }"
" check() {"
" return this.#b === this.getA();"
" }"
"}"
"class DerivedDefaultConstructor extends Base {"
" #b = 1;"
" check() {"
" return this.#b === 1;"
" }"
"}"
"class NestedSuper extends Base {"
" #b = 1;"
" constructor() {"
" const t = () => {"
" super();"
" };"
" t();"
" }"
" check() {"
" return this.#b === 1;"
" }"
"}"
"class EvaledSuper extends Base {"
" #b = 1;"
" constructor() {"
" eval('super()');"
" }"
" check() {"
" return this.#b === 1;"
" }"
"}"
"class NestedEvaledSuper extends Base {"
" #b = 1;"
" constructor() {"
" const t = () => {"
" eval('super()');"
" };"
" t();"
" }"
" check() {"
" return this.#b === 1;"
" }"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectBoolean("(new Derived()).check()", true);
ExpectBoolean("(new DerivedDefaultConstructor()).check()", true);
ExpectBoolean("(new NestedSuper()).check()", true);
ExpectBoolean("(new EvaledSuper()).check()", true);
ExpectBoolean("(new NestedEvaledSuper()).check()", true);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsRecalcPrivateNames) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"let heritageFn;"
"class Outer {"
" #f = 'Outer.#f';"
" static Inner = class Inner extends (heritageFn = function () {"
" return class Nested {"
" exfil(obj) { return obj.#f; }"
" exfilEval(obj) { return eval('obj.#f'); }"
" };"
" }) {"
" #f = 'Inner.#f';"
" };"
"};");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
CompileRun(
"const o = new Outer;"
"const c = new Outer.Inner;"
"const D = heritageFn();"
"const d = new D;"
"let error1;"
"let error2;");
ExpectString("d.exfil(o)", "Outer.#f");
ExpectString("d.exfilEval(o)", "Outer.#f");
CompileRun("try { d.exfil(c) } catch(e) { error1 = e; }");
ExpectBoolean("error1 instanceof TypeError", true);
CompileRun("try { d.exfilEval(c) } catch(e) { error2 = e; }");
ExpectBoolean("error2 instanceof TypeError", true);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(ClassFieldsWithBindings) {
DisableAlwaysOpt();
i::v8_flags.rehash_snapshot = true;
i::v8_flags.hash_seed = 42;
i::v8_flags.allow_natives_syntax = true;
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
DisableEmbeddedBlobRefcounting();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"function testVarBinding() {"
" function FuncWithVar() {"
" this.getPrivate = () => 'test';"
" }"
" class Derived extends FuncWithVar {"
" ['computed'] = FuncWithVar;"
" #private = FuncWithVar;"
" public = FuncWithVar;"
" constructor() {"
" super();"
" this.#private = this.getPrivate();"
" }"
" check() {"
" return this.#private === this.getPrivate() &&"
" this.computed === FuncWithVar &&"
" this.public === FuncWithVar;"
" }"
" }"
""
" return((new Derived()).check());"
"}"
"class ClassWithLet {"
" #private = 'test';"
" getPrivate() { return this.#private; }"
"}"
"function testLetBinding() {"
" class Derived extends ClassWithLet {"
" ['computed'] = ClassWithLet;"
" #private = ClassWithLet;"
" public = ClassWithLet;"
" constructor() {"
" super();"
" this.#private = this.getPrivate();"
" }"
" check() {"
" return this.#private === this.getPrivate() &&"
" this.computed === ClassWithLet &&"
" this.public === ClassWithLet;"
" }"
" }"
""
" return((new Derived()).check());"
"}"
"const ClassWithConst = class {"
" #private = 'test';"
" getPrivate() { return this.#private; }"
"};"
"function testConstBinding() {"
" class Derived extends ClassWithConst {"
" ['computed'] = ClassWithConst;"
" #private = ClassWithConst;"
" public = ClassWithConst;"
" constructor() {"
" super();"
" this.#private = this.getPrivate();"
" }"
" check() {"
" return this.#private === this.getPrivate() &&"
" this.computed === ClassWithConst &&"
" this.public === ClassWithConst;"
" }"
" }"
""
" return((new Derived()).check());"
"}");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.snapshot_blob = &blob;
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
ExpectBoolean("testVarBinding()", true);
ExpectBoolean("testLetBinding()", true);
ExpectBoolean("testConstBinding()", true);
}
isolate->Dispose();
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
void CheckSFIsAreWeak(WeakFixedArray sfis, Isolate* isolate) {
CHECK_GT(sfis.length(), 0);
int no_of_weak = 0;
for (int i = 0; i < sfis.length(); ++i) {
MaybeObject maybe_object = sfis.Get(i);
HeapObject heap_object;
CHECK(maybe_object->IsWeakOrCleared() ||
(maybe_object->GetHeapObjectIfStrong(&heap_object) &&
heap_object.IsUndefined(isolate)));
if (maybe_object->IsWeak()) {
++no_of_weak;
}
}
CHECK_GT(no_of_weak, 0);
}
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
UNINITIALIZED_TEST(WeakArraySerializationInSnapshot) {
const char* code = "var my_func = function() { }";
DisableAlwaysOpt();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
DisableEmbeddedBlobRefcounting();
i::v8_flags.allow_natives_syntax = true;
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(code);
creator.SetDefaultContext(
context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, reinterpret_cast<void*>(2016)));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
}
v8::Isolate::CreateParams create_params;
create_params.snapshot_blob = &blob;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = TestSerializer::NewIsolate(create_params);
{
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(
isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(),
v8::MaybeLocal<v8::Value>(),
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields,
reinterpret_cast<void*>(2017)));
v8::Context::Scope c_scope(context);
v8::Local<v8::Value> x = CompileRun("my_func");
CHECK(x->IsFunction());
Handle<JSFunction> function =
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*x));
// Verify that the pointers in shared_function_infos are weak.
WeakFixedArray sfis =
Script::cast(function->shared().script()).shared_function_infos();
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
CheckSFIsAreWeak(sfis, reinterpret_cast<i::Isolate*>(isolate));
}
isolate->Dispose();
delete[] blob.data;
Reland "Reland "[builtins] Verify Isolate compatibility with the embedded blob"" This is a reland of 1e3582b5aecfeb0ffdca4bda3f1fd66d433236f6 Original change's description: > Reland "[builtins] Verify Isolate compatibility with the embedded blob" > > This is a reland of b022e825bd9f45279bb0c493a9081804f17455ae > > Original change's description: > > [builtins] Verify Isolate compatibility with the embedded blob > > > > Embedded builtins (= the embedded blob) have a few dependencies on the > > snapshot state. For instance, they require that metadata stored on > > builtin Code objects as well as the builtins constant table remain > > unchanged from mksnapshot-time. Embedders may violate these > > assumptions by accident, e.g. by loading a snapshot generated with > > different build flags, leading to seemingly unrelated failures later > > on. > > > > This CL introduces an Isolate hash stored in the embedded blob which > > hashes relevant parts of builtin Code objects and the builtins > > constant table. It's verified in Isolate::Init in debug builds. > > > > Bug: v8:8723 > > Change-Id: Ifc9bdbe6f56ea67d8984f162afa73a3572cfbba8 > > Reviewed-on: https://chromium-review.googlesource.com/c/1442641 > > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#59177} > > Tbr: yangguo@chromium.org,sigurds@chromium.org > Bug: v8:8723 > Change-Id: I1dd001783f0f1fae21a9809c8639e40f55b8f663 > Reviewed-on: https://chromium-review.googlesource.com/c/1445985 > Commit-Queue: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > Cr-Commit-Position: refs/heads/master@{#59236} Tbr: yangguo@chromium.org,sigurds@chromium.org Bug: v8:8723 Change-Id: I8e4ae2f09d16b693c1fb814477d8487385046ee4 Reviewed-on: https://chromium-review.googlesource.com/c/1448312 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#59250}
2019-01-31 13:48:53 +00:00
FreeCurrentEmbeddedBlob();
}
TEST(WeakArraySerializationInCodeCache) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->DisableScriptAndEval();
v8::HandleScope scope(CcTest::isolate());
const char* source = "function foo() { }";
Handle<String> src = isolate->factory()
->NewStringFromUtf8(base::CStrVector(source))
.ToHandleChecked();
[api] Add API for off-thread code cache deserialization To consume a code cache off-thread 1. The embedder creates a CachedData object wrapping the data blob. 2. The embedder calls ScriptCompiler::StartConsumingCodeCache with the CachedData, and receives a ScriptCompiler::CodeCacheConsumeTask which takes ownership of the CachedData. 3. The embedder calls ScriptCompiler::CodeCacheConsumeTask::Run on a different thread. 4. Once this completes, the embedded passes the completed task as an optional argument into Source constructor, and calls Compile as before. This is roughly similar to how streaming compilation works, with the QoL improvement that Source owns the CodeCacheConsumeTask and therefore we can reuse the same Compile method and do the off-thread finalization behind the scenes inside Compile. On the v8::internal side, ScriptCompiler::CodeCacheConsumeTask wraps a v8::internal::BackgroundDeserializeTask, which has a Run and a Finish method. The Run creates a LocalIsolate (again, similar to BackgroundCompileTask), calls some helpers on CodeSerializer, and stores the pre-finalization result in a OffThreadDeserializeData structure. This stores Persistent Handles to the off-thread initialized SFI and a vector of Scripts needing fixing up, and it owns the PersistentHandles object which owns those Handles. Finally, the Finish method consumes this OffThreadDeserializeData structure, fixes up Scripts, moves the SFI Handle into the caller HandleScope, and that's it. Since we don't yet have the source at off-thread deserialization time, the various code cache sanity checks are done without the source hash when deserializing, and the Finish method re-does them now that the source is available. Bug: chromium:1075999 Change-Id: If1faf35ba3ef840fa4e735581d0b29c96c1d5fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067322 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#76155}
2021-08-06 13:53:48 +00:00
AlignedCachedData* cache = nullptr;
ScriptDetails script_details(src);
CompileScriptAndProduceCache(isolate, src, script_details, &cache,
v8::ScriptCompiler::kNoCompileOptions);
DisallowCompilation no_compile_expected(isolate);
Handle<SharedFunctionInfo> copy =
CompileScript(isolate, src, script_details, cache,
v8::ScriptCompiler::kConsumeCodeCache);
// Verify that the pointers in shared_function_infos are weak.
WeakFixedArray sfis = Script::cast(copy->script()).shared_function_infos();
CheckSFIsAreWeak(sfis, isolate);
delete cache;
}
TEST(CachedCompileFunction) {
DisableAlwaysOpt();
LocalContext env;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()
->DisableScriptAndEval(); // Disable same-isolate code cache.
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::String> source = v8_str("return x*x;");
v8::Local<v8::String> arg_str = v8_str("x");
ScriptCompiler::CachedData* cache;
{
v8::ScriptCompiler::Source script_source(source);
v8::Local<v8::Function> fun =
v8::ScriptCompiler::CompileFunction(env.local(), &script_source, 1,
&arg_str, 0, nullptr,
v8::ScriptCompiler::kEagerCompile)
.ToLocalChecked();
cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun);
}
{
DisallowCompilation no_compile_expected(isolate);
v8::ScriptCompiler::Source script_source(source, cache);
v8::Local<v8::Function> fun =
v8::ScriptCompiler::CompileFunction(
env.local(), &script_source, 1, &arg_str, 0, nullptr,
v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
v8::Local<v8::Value> arg = v8_num(3);
v8::Local<v8::Value> result =
fun->Call(env.local(), v8::Undefined(CcTest::isolate()), 1, &arg)
.ToLocalChecked();
CHECK_EQ(9, result->Int32Value(env.local()).FromJust());
}
}
UNINITIALIZED_TEST(SnapshotCreatorAnonClassWithKeep) {
DisableAlwaysOpt();
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"function Foo() { return class {}; } \n"
"class Bar extends Foo() {}\n"
"Foo()\n");
creator.SetDefaultContext(context);
}
}
v8::StartupData blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
delete[] blob.data;
}
UNINITIALIZED_TEST(SnapshotCreatorDontDeferByteArrayForTypedArray) {
DisableAlwaysOpt();
v8::StartupData blob;
{
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"const z = new Uint8Array(1);\n"
"class A { \n"
" static x() { \n"
" } \n"
"} \n"
"class B extends A {} \n"
"B.foo = ''; \n"
"class C extends B {} \n"
"class D extends C {} \n"
"class E extends B {} \n"
"function F() {} \n"
"Object.setPrototypeOf(F, D); \n");
creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
CHECK(blob.raw_size > 0 && blob.data != nullptr);
}
{
SnapshotCreator creator(nullptr, &blob);
v8::Isolate* isolate = creator.GetIsolate();
v8::HandleScope scope(isolate);
USE(v8::Context::New(isolate));
}
delete[] blob.data;
}
class V8_NODISCARD DisableLazySourcePositionScope {
public:
DisableLazySourcePositionScope()
: backup_value_(v8_flags.enable_lazy_source_positions) {
v8_flags.enable_lazy_source_positions = false;
}
~DisableLazySourcePositionScope() {
v8_flags.enable_lazy_source_positions = backup_value_;
}
private:
bool backup_value_;
};
UNINITIALIZED_TEST(NoStackFrameCacheSerialization) {
// Checks that exceptions caught are not cached in the
// stack frame cache during serialization. The individual frames
// can point to JSFunction objects, which need to be stored in a
// context snapshot, *not* isolate snapshot.
DisableAlwaysOpt();
DisableLazySourcePositionScope lazy_scope;
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
isolate->SetCaptureStackTraceForUncaughtExceptions(true);
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::TryCatch try_catch(isolate);
CompileRun(R"(
function foo() { throw new Error('bar'); }
function bar() {
foo();
}
bar();
)");
creator.SetDefaultContext(context);
}
}
v8::StartupData blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
delete[] blob.data;
}
namespace {
void CheckObjectsAreInSharedHeap(Isolate* isolate) {
Heap* heap = isolate->heap();
HeapObjectIterator iterator(heap);
DisallowGarbageCollection no_gc;
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
const bool expected_in_shared_old =
heap->MustBeInSharedOldSpace(obj) ||
(obj.IsString() && String::IsInPlaceInternalizable(String::cast(obj)));
if (expected_in_shared_old) {
CHECK(obj.InSharedHeap());
}
}
}
} // namespace
UNINITIALIZED_TEST(SharedStrings) {
// Test that deserializing with --shared-string-table deserializes into the
// shared Isolate.
if (!V8_CAN_CREATE_SHARED_HEAP_BOOL) return;
// Make all the flags that require a shared heap false before creating the
// isolate to serialize.
v8_flags.shared_string_table = false;
v8_flags.harmony_struct = false;
v8::Isolate* isolate_to_serialize = TestSerializer::NewIsolateInitialized();
StartupBlobs blobs = Serialize(isolate_to_serialize);
isolate_to_serialize->Dispose();
v8_flags.shared_string_table = true;
if (!v8_flags.shared_space) {
TestSerializer::InitializeProcessWideSharedIsolateFromBlob(blobs);
}
v8::Isolate* isolate1 = TestSerializer::NewIsolateFromBlob(blobs);
v8::Isolate* isolate2 = TestSerializer::NewIsolateFromBlob(blobs);
Isolate* i_isolate1 = reinterpret_cast<Isolate*>(isolate1);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
CHECK_EQ(i_isolate1->string_table(), i_isolate2->string_table());
{
ParkedScope parked(i_isolate2->main_thread_local_heap());
CheckObjectsAreInSharedHeap(i_isolate1);
}
{
ParkedScope parked(i_isolate1->main_thread_local_heap());
CheckObjectsAreInSharedHeap(i_isolate2);
}
{
// Because both isolate1 and isolate2 are considered running on the main
// thread, one must be parked to avoid deadlock in the shared heap
// verification that may happen on client heap disposal.
ParkedScope parked(i_isolate1->main_thread_local_isolate());
isolate2->Dispose();
}
isolate1->Dispose();
if (!v8_flags.shared_space) {
TestSerializer::DeleteProcessWideSharedIsolate();
}
blobs.Dispose();
FreeCurrentEmbeddedBlob();
}
} // namespace internal
} // namespace v8