Skip to content

Commit

Permalink
deps: patch V8 to 10.2.154.19
Browse files Browse the repository at this point in the history
Refs: v8/v8@10.2.154.15...10.2.154.19
PR-URL: #45229
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
  • Loading branch information
targos authored and danielleadams committed Jan 3, 2023
1 parent 39cf8b4 commit 5c0fcc1
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 13 deletions.
2 changes: 1 addition & 1 deletion deps/v8/include/v8-version.h
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 10
#define V8_MINOR_VERSION 2
#define V8_BUILD_NUMBER 154
#define V8_PATCH_LEVEL 15
#define V8_PATCH_LEVEL 19

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
12 changes: 9 additions & 3 deletions deps/v8/src/compiler/access-info.cc
Expand Up @@ -454,9 +454,15 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
map, descriptor, details_representation));
} else if (details_representation.IsHeapObject()) {
if (descriptors_field_type->IsNone()) {
// Store is not safe if the field type was cleared.
if (access_mode == AccessMode::kStore) {
return Invalid();
switch (access_mode) {
case AccessMode::kStore:
case AccessMode::kStoreInLiteral:
case AccessMode::kDefine:
// Store is not safe if the field type was cleared.
return Invalid();
case AccessMode::kLoad:
case AccessMode::kHas:
break;
}

// The field type was cleared by the GC, so we don't know anything
Expand Down
45 changes: 44 additions & 1 deletion deps/v8/src/compiler/compilation-dependencies.cc
Expand Up @@ -35,7 +35,8 @@ namespace compiler {
V(Protector) \
V(PrototypeProperty) \
V(StableMap) \
V(Transition)
V(Transition) \
V(ObjectSlotValue)

CompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
Zone* zone)
Expand Down Expand Up @@ -863,6 +864,42 @@ class ProtectorDependency final : public CompilationDependency {
const PropertyCellRef cell_;
};

// Check that an object slot will not change during compilation.
class ObjectSlotValueDependency final : public CompilationDependency {
public:
explicit ObjectSlotValueDependency(const HeapObjectRef& object, int offset,
const ObjectRef& value)
: CompilationDependency(kObjectSlotValue),
object_(object.object()),
offset_(offset),
value_(value.object()) {}

bool IsValid() const override {
PtrComprCageBase cage_base = GetPtrComprCageBase(*object_);
Object current_value =
offset_ == HeapObject::kMapOffset
? object_->map()
: TaggedField<Object>::Relaxed_Load(cage_base, *object_, offset_);
return *value_ == current_value;
}
void Install(PendingDependencies* deps) const override {}

private:
size_t Hash() const override {
return base::hash_combine(object_.address(), offset_, value_.address());
}

bool Equals(const CompilationDependency* that) const override {
const ObjectSlotValueDependency* const zat = that->AsObjectSlotValue();
return object_->address() == zat->object_->address() &&
offset_ == zat->offset_ && value_.address() == zat->value_.address();
}

Handle<HeapObject> object_;
int offset_;
Handle<Object> value_;
};

class ElementsKindDependency final : public CompilationDependency {
public:
ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
Expand Down Expand Up @@ -1110,6 +1147,12 @@ void CompilationDependencies::DependOnElementsKind(
}
}

void CompilationDependencies::DependOnObjectSlotValue(
const HeapObjectRef& object, int offset, const ObjectRef& value) {
RecordDependency(
zone_->New<ObjectSlotValueDependency>(object, offset, value));
}

void CompilationDependencies::DependOnOwnConstantElement(
const JSObjectRef& holder, uint32_t index, const ObjectRef& element) {
RecordDependency(
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/compiler/compilation-dependencies.h
Expand Up @@ -93,6 +93,10 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
// Record the assumption that {site}'s {ElementsKind} doesn't change.
void DependOnElementsKind(const AllocationSiteRef& site);

// Check that an object slot will not change during compilation.
void DependOnObjectSlotValue(const HeapObjectRef& object, int offset,
const ObjectRef& value);

void DependOnOwnConstantElement(const JSObjectRef& holder, uint32_t index,
const ObjectRef& element);

Expand Down
12 changes: 12 additions & 0 deletions deps/v8/src/compiler/js-create-lowering.cc
Expand Up @@ -1677,6 +1677,10 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(

// Now that we hold the migration lock, get the current map.
MapRef boilerplate_map = boilerplate.map();
// Protect against concurrent changes to the boilerplate object by checking
// for an identical value at the end of the compilation.
dependencies()->DependOnObjectSlotValue(boilerplate, HeapObject::kMapOffset,
boilerplate_map);
{
base::Optional<MapRef> current_boilerplate_map =
boilerplate.map_direct_read();
Expand Down Expand Up @@ -1841,10 +1845,18 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
boilerplate.elements(kRelaxedLoad);
if (!maybe_boilerplate_elements.has_value()) return {};
FixedArrayBaseRef boilerplate_elements = maybe_boilerplate_elements.value();
// Protect against concurrent changes to the boilerplate object by checking
// for an identical value at the end of the compilation.
dependencies()->DependOnObjectSlotValue(
boilerplate, JSObject::kElementsOffset, boilerplate_elements);

// Empty or copy-on-write elements just store a constant.
int const elements_length = boilerplate_elements.length();
MapRef elements_map = boilerplate_elements.map();
// Protect against concurrent changes to the boilerplate object by checking
// for an identical value at the end of the compilation.
dependencies()->DependOnObjectSlotValue(boilerplate_elements,
HeapObject::kMapOffset, elements_map);
if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
if (allocation == AllocationType::kOld &&
!boilerplate.IsElementsTenured(boilerplate_elements)) {
Expand Down
54 changes: 50 additions & 4 deletions deps/v8/src/objects/value-serializer.cc
Expand Up @@ -64,6 +64,17 @@ static const uint32_t kLatestVersion = 15;
static_assert(kLatestVersion == v8::CurrentValueSerializerFormatVersion(),
"Exported format version must match latest version.");

namespace {
// For serializing JSArrayBufferView flags. Instead of serializing /
// deserializing the flags directly, we serialize them bit by bit. This is for
// ensuring backwards compatilibity in the case where the representation
// changes. Note that the ValueSerializer data can be stored on disk.
using JSArrayBufferViewIsLengthTracking = base::BitField<bool, 0, 1>;
using JSArrayBufferViewIsBackedByRab =
JSArrayBufferViewIsLengthTracking::Next<bool, 1>;

} // namespace

template <typename T>
static size_t BytesNeededForVarint(T value) {
static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
Expand Down Expand Up @@ -922,6 +933,8 @@ Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
if (byte_length > std::numeric_limits<uint32_t>::max()) {
return ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer);
}
// TODO(v8:11111): Support RAB / GSAB. The wire version will need to be
// bumped.
WriteTag(SerializationTag::kArrayBuffer);
WriteVarint<uint32_t>(byte_length);
WriteRawBytes(array_buffer->backing_store(), byte_length);
Expand Down Expand Up @@ -950,7 +963,10 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView view) {
WriteVarint(static_cast<uint8_t>(tag));
WriteVarint(static_cast<uint32_t>(view.byte_offset()));
WriteVarint(static_cast<uint32_t>(view.byte_length()));
WriteVarint(static_cast<uint32_t>(view.bit_field()));
uint32_t flags =
JSArrayBufferViewIsLengthTracking::encode(view.is_length_tracking()) |
JSArrayBufferViewIsBackedByRab::encode(view.is_backed_by_rab());
WriteVarint(flags);
return ThrowIfOutOfMemory();
}

Expand Down Expand Up @@ -1979,7 +1995,7 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() {

MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
Handle<JSArrayBuffer> buffer) {
uint32_t buffer_byte_length = static_cast<uint32_t>(buffer->byte_length());
uint32_t buffer_byte_length = static_cast<uint32_t>(buffer->GetByteLength());
uint8_t tag = 0;
uint32_t byte_offset = 0;
uint32_t byte_length = 0;
Expand All @@ -2004,7 +2020,9 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
Handle<JSDataView> data_view =
isolate_->factory()->NewJSDataView(buffer, byte_offset, byte_length);
AddObjectWithID(id, data_view);
data_view->set_bit_field(flags);
if (!ValidateAndSetJSArrayBufferViewFlags(*data_view, *buffer, flags)) {
return MaybeHandle<JSArrayBufferView>();
}
return data_view;
}
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
Expand All @@ -2021,11 +2039,39 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
}
Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray(
external_array_type, buffer, byte_offset, byte_length / element_size);
typed_array->set_bit_field(flags);
if (!ValidateAndSetJSArrayBufferViewFlags(*typed_array, *buffer, flags)) {
return MaybeHandle<JSArrayBufferView>();
}
AddObjectWithID(id, typed_array);
return typed_array;
}

bool ValueDeserializer::ValidateAndSetJSArrayBufferViewFlags(
JSArrayBufferView view, JSArrayBuffer buffer, uint32_t serialized_flags) {
bool is_length_tracking =
JSArrayBufferViewIsLengthTracking::decode(serialized_flags);
bool is_backed_by_rab =
JSArrayBufferViewIsBackedByRab::decode(serialized_flags);

// TODO(marja): When the version number is bumped the next time, check that
// serialized_flags doesn't contain spurious 1-bits.

if (is_backed_by_rab || is_length_tracking) {
if (!FLAG_harmony_rab_gsab) {
return false;
}
if (!buffer.is_resizable()) {
return false;
}
if (is_backed_by_rab && buffer.is_shared()) {
return false;
}
}
view.set_is_length_tracking(is_length_tracking);
view.set_is_backed_by_rab(is_backed_by_rab);
return true;
}

MaybeHandle<Object> ValueDeserializer::ReadJSError() {
uint32_t id = next_id_++;

Expand Down
3 changes: 3 additions & 0 deletions deps/v8/src/objects/value-serializer.h
Expand Up @@ -295,6 +295,9 @@ class ValueDeserializer {
V8_WARN_UNUSED_RESULT;
MaybeHandle<JSArrayBufferView> ReadJSArrayBufferView(
Handle<JSArrayBuffer> buffer) V8_WARN_UNUSED_RESULT;
bool ValidateAndSetJSArrayBufferViewFlags(
JSArrayBufferView view, JSArrayBuffer buffer,
uint32_t serialized_flags) V8_WARN_UNUSED_RESULT;
MaybeHandle<Object> ReadJSError() V8_WARN_UNUSED_RESULT;
#if V8_ENABLE_WEBASSEMBLY
MaybeHandle<JSObject> ReadWasmModuleTransfer() V8_WARN_UNUSED_RESULT;
Expand Down
12 changes: 8 additions & 4 deletions deps/v8/src/wasm/baseline/liftoff-compiler.cc
Expand Up @@ -1417,9 +1417,11 @@ class LiftoffCompiler {
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ emit_jump(c->label.get());
}
// Merge the else state into the end state.
// Merge the else state into the end state. Set this state as the current
// state first so helper functions know which registers are in use.
__ bind(c->else_state->label.get());
__ MergeFullStackWith(c->label_state, c->else_state->state);
__ cache_state()->Steal(c->else_state->state);
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ cache_state()->Steal(c->label_state);
} else if (c->reachable()) {
// No merge yet at the end of the if, but we need to create a merge for
Expand All @@ -1431,9 +1433,11 @@ class LiftoffCompiler {
c->stack_depth + c->num_exceptions);
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ emit_jump(c->label.get());
// Merge the else state into the end state.
// Merge the else state into the end state. Set this state as the current
// state first so helper functions know which registers are in use.
__ bind(c->else_state->label.get());
__ MergeFullStackWith(c->label_state, c->else_state->state);
__ cache_state()->Steal(c->else_state->state);
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ cache_state()->Steal(c->label_state);
} else {
// No merge needed, just continue with the else state.
Expand Down
17 changes: 17 additions & 0 deletions deps/v8/test/mjsunit/rab-gsab-valueserializer.js
@@ -0,0 +1,17 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --harmony-rab-gsab

"use strict";

(function FlagMismatch() {
// Length tracking TA, buffer not resizable.
const data1 = new Uint8Array([255, 15, 66, 4, 3, 5, 7, 11, 86, 66, 1, 2, 1]);
assertThrows(() => { d8.serializer.deserialize(data1.buffer); });

// RAB backed TA, buffer not resizable.
const data2 = new Uint8Array([255, 15, 66, 4, 3, 5, 7, 11, 86, 66, 1, 2, 2]);
assertThrows(() => { d8.serializer.deserialize(data2.buffer); });
})();

0 comments on commit 5c0fcc1

Please sign in to comment.