[shared-struct] Fix in/out-of-object property storage
In a few places, shared structs currently incorrectly assume all storage is in-object. This CL fixes those and rename CSA::StoreJSSharedStructInObjectField to CSA::StoreSharedObjectField to reflect the genericity. Bug: v8:12547 Change-Id: I7c155b6bc584fbdcdbd484fda38f9f8a1940953d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3997700 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Shu-yu Guo <syg@chromium.org> Cr-Commit-Position: refs/heads/main@{#84022}
This commit is contained in:
parent
103c34991b
commit
381b8f55e9
@ -85,7 +85,12 @@ BUILTIN(SharedStructTypeConstructor) {
|
||||
|
||||
instance_map->InitializeDescriptors(isolate, *descriptors);
|
||||
// Structs have fixed layout ahead of time, so there's no slack.
|
||||
instance_map->SetInObjectUnusedPropertyFields(0);
|
||||
int out_of_object_properties = num_properties - in_object_properties;
|
||||
if (out_of_object_properties == 0) {
|
||||
instance_map->SetInObjectUnusedPropertyFields(0);
|
||||
} else {
|
||||
instance_map->SetOutOfObjectUnusedPropertyFields(0);
|
||||
}
|
||||
instance_map->set_is_extensible(false);
|
||||
JSFunction::SetInitialMap(isolate, constructor, instance_map,
|
||||
factory->null_value());
|
||||
|
@ -3104,9 +3104,14 @@ void CodeStubAssembler::UnsafeStoreObjectFieldNoWriteBarrier(
|
||||
object, offset, value);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::StoreJSSharedStructInObjectField(
|
||||
TNode<HeapObject> object, TNode<IntPtrT> offset, TNode<Object> value) {
|
||||
CSA_DCHECK(this, IsJSSharedStruct(object));
|
||||
void CodeStubAssembler::StoreSharedObjectField(TNode<HeapObject> object,
|
||||
TNode<IntPtrT> offset,
|
||||
TNode<Object> value) {
|
||||
CSA_DCHECK(
|
||||
this,
|
||||
WordNotEqual(WordAnd(LoadBasicMemoryChunkFlags(object),
|
||||
IntPtrConstant(BasicMemoryChunk::IN_SHARED_HEAP)),
|
||||
IntPtrConstant(0)));
|
||||
// JSSharedStructs are allocated in the shared old space, which is currently
|
||||
// collected by stopping the world, so the incremental write barrier is not
|
||||
// needed. They can only store Smis and other HeapObjects in the shared old
|
||||
|
@ -1860,9 +1860,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
|
||||
int additional_offset = 0);
|
||||
|
||||
void StoreJSSharedStructInObjectField(TNode<HeapObject> object,
|
||||
TNode<IntPtrT> offset,
|
||||
TNode<Object> value);
|
||||
void StoreSharedObjectField(TNode<HeapObject> object, TNode<IntPtrT> offset,
|
||||
TNode<Object> value);
|
||||
|
||||
void StoreJSSharedStructPropertyArrayElement(TNode<PropertyArray> array,
|
||||
TNode<IntPtrT> index,
|
||||
|
@ -561,6 +561,7 @@ void Map::MapVerify(Isolate* isolate) {
|
||||
if (maybe_cell.IsCell()) CHECK(maybe_cell.InSharedHeap());
|
||||
CHECK(!is_extensible());
|
||||
CHECK(!is_prototype_map());
|
||||
CHECK(OnlyHasSimpleProperties());
|
||||
CHECK(instance_descriptors(isolate).InSharedHeap());
|
||||
if (IsJSSharedArrayMap()) {
|
||||
CHECK(has_shared_array_elements());
|
||||
@ -1268,7 +1269,6 @@ void JSSharedStruct::JSSharedStructVerify(Isolate* isolate) {
|
||||
CHECK(details.representation().IsTagged());
|
||||
FieldIndex field_index = FieldIndex::ForDescriptor(struct_map, i);
|
||||
CHECK(RawFastPropertyAt(field_index).IsShared());
|
||||
CHECK(field_index.is_inobject());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1231,8 +1231,7 @@ void AccessorAssembler::HandleStoreICSmiHandlerJSSharedStructFieldCase(
|
||||
DecodeWordFromWord32<StoreHandler::FieldIndexBits>(handler_word);
|
||||
TNode<IntPtrT> offset = Signed(TimesTaggedSize(index));
|
||||
|
||||
StoreJSSharedStructInObjectField(property_storage, offset,
|
||||
shared_value.value());
|
||||
StoreSharedObjectField(property_storage, offset, shared_value.value());
|
||||
|
||||
// Return the original value.
|
||||
Return(value);
|
||||
@ -1758,8 +1757,7 @@ void AccessorAssembler::StoreJSSharedStructField(
|
||||
BIND(&inobject);
|
||||
{
|
||||
TNode<IntPtrT> field_offset = Signed(TimesTaggedSize(field_index));
|
||||
StoreJSSharedStructInObjectField(shared_struct, field_offset,
|
||||
shared_value.value());
|
||||
StoreSharedObjectField(shared_struct, field_offset, shared_value.value());
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
@ -1768,7 +1766,10 @@ void AccessorAssembler::StoreJSSharedStructField(
|
||||
TNode<IntPtrT> backing_store_index =
|
||||
Signed(IntPtrSub(field_index, instance_size_in_words));
|
||||
|
||||
Label tagged_rep(this), double_rep(this);
|
||||
CSA_DCHECK(
|
||||
this,
|
||||
Word32Equal(DecodeWord32<PropertyDetails::RepresentationField>(details),
|
||||
Int32Constant(Representation::kTagged)));
|
||||
TNode<PropertyArray> properties =
|
||||
CAST(LoadFastProperties(CAST(shared_struct)));
|
||||
StoreJSSharedStructPropertyArrayElement(properties, backing_store_index,
|
||||
|
23
test/mjsunit/shared-memory/shared-struct-property-storage.js
Normal file
23
test/mjsunit/shared-memory/shared-struct-property-storage.js
Normal file
@ -0,0 +1,23 @@
|
||||
// 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: --shared-string-table --harmony-struct
|
||||
|
||||
'use strict';
|
||||
|
||||
let fieldNames = [];
|
||||
for (let i = 0; i < 999; i++) {
|
||||
fieldNames.push('field' + i);
|
||||
}
|
||||
let s = new (new SharedStructType(fieldNames));
|
||||
|
||||
// Write to an out-of-object field.
|
||||
(function storeOutOfObject() {
|
||||
for (let i = 0; i < 100; i++) s.field998 = i;
|
||||
})();
|
||||
|
||||
// Write to an in-object field.
|
||||
(function storeInObject() {
|
||||
for (let i = 0; i < 100; i++) s.field0 = i;
|
||||
})();
|
@ -49,11 +49,13 @@ let S = new SharedStructType(['field']);
|
||||
})();
|
||||
|
||||
(function TestTooManyFields() {
|
||||
let field_names = [];
|
||||
let fieldNames = [];
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
field_names.push('field' + i);
|
||||
fieldNames.push('field' + i);
|
||||
}
|
||||
assertThrows(() => { new SharedStructType(field_names); });
|
||||
assertThrows(() => {
|
||||
new SharedStructType(fieldNames);
|
||||
});
|
||||
})();
|
||||
|
||||
(function TestOwnPropertyEnumeration() {
|
||||
|
Loading…
Reference in New Issue
Block a user