[shared-struct] Store length per-SharedArray instance
With shared space (instead of the shared isolate), the AccessorInfo implementation of SharedArray's length property is no longer threadsafe. Until AccessorInfos can be put into shared or RO space, go back to storing the length field as a per-instance in-object field, which is unfrotunately a little wasteful. Bug: v8:12547 Change-Id: I99c1cbf26047da48a4b4c11e14ab7def7d4e4f60 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4039309 Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Auto-Submit: Shu-yu Guo <syg@chromium.org> Commit-Queue: Shu-yu Guo <syg@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/main@{#84408}
This commit is contained in:
parent
96b83b8160
commit
bd5b3ae542
@ -230,25 +230,6 @@ Handle<AccessorInfo> Accessors::MakeArrayLengthInfo(Isolate* isolate) {
|
||||
&ArrayLengthGetter, &ArrayLengthSetter);
|
||||
}
|
||||
|
||||
//
|
||||
// Accessors::SharedArrayLength
|
||||
//
|
||||
|
||||
void Accessors::SharedArrayLengthGetter(
|
||||
v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
|
||||
DisallowGarbageCollection no_gc;
|
||||
HandleScope scope(isolate);
|
||||
auto holder = JSSharedArray::cast(*Utils::OpenHandle(*info.Holder()));
|
||||
Object result = Smi::FromInt(holder.elements().length());
|
||||
info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
|
||||
}
|
||||
|
||||
Handle<AccessorInfo> Accessors::MakeSharedArrayLengthInfo(Isolate* isolate) {
|
||||
return MakeAccessor(isolate, isolate->factory()->length_string(),
|
||||
&SharedArrayLengthGetter, nullptr);
|
||||
}
|
||||
|
||||
//
|
||||
// Accessors::ModuleNamespaceEntry
|
||||
//
|
||||
|
@ -44,8 +44,6 @@ class JavaScriptFrame;
|
||||
kHasSideEffectToReceiver) \
|
||||
V(_, function_prototype, FunctionPrototype, kHasNoSideEffect, \
|
||||
kHasSideEffectToReceiver) \
|
||||
V(_, shared_array_length, SharedArrayLength, kHasNoSideEffect, \
|
||||
kHasSideEffectToReceiver) \
|
||||
V(_, string_length, StringLength, kHasNoSideEffect, \
|
||||
kHasSideEffectToReceiver) \
|
||||
V(_, value_unavailable, ValueUnavailable, kHasNoSideEffect, \
|
||||
|
@ -3991,6 +3991,10 @@ Handle<JSSharedArray> Factory::NewJSSharedArray(Handle<JSFunction> constructor,
|
||||
Handle<JSSharedArray> instance = Handle<JSSharedArray>::cast(
|
||||
NewJSObject(constructor, AllocationType::kSharedOld));
|
||||
instance->set_elements(*storage);
|
||||
FieldIndex index = FieldIndex::ForDescriptor(
|
||||
constructor->initial_map(),
|
||||
InternalIndex(JSSharedArray::kLengthFieldIndex));
|
||||
instance->FastPropertyAtPut(index, Smi::FromInt(length), SKIP_WRITE_BARRIER);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -523,7 +523,7 @@ V8_NOINLINE Handle<JSFunction> InstallFunction(
|
||||
|
||||
V8_NOINLINE Handle<JSFunction> CreateSharedObjectConstructor(
|
||||
Isolate* isolate, Handle<String> name, InstanceType type, int instance_size,
|
||||
ElementsKind element_kind, Builtin builtin) {
|
||||
int inobject_properties, ElementsKind element_kind, Builtin builtin) {
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfoForBuiltin(
|
||||
name, builtin, FunctionKind::kNormalFunction);
|
||||
@ -532,9 +532,8 @@ V8_NOINLINE Handle<JSFunction> CreateSharedObjectConstructor(
|
||||
Factory::JSFunctionBuilder{isolate, info, isolate->native_context()}
|
||||
.set_map(isolate->strict_function_with_readonly_prototype_map())
|
||||
.Build();
|
||||
constexpr int in_object_properties = 0;
|
||||
Handle<Map> instance_map =
|
||||
factory->NewMap(type, instance_size, element_kind, in_object_properties,
|
||||
factory->NewMap(type, instance_size, element_kind, inobject_properties,
|
||||
AllocationType::kSharedMap);
|
||||
// Shared objects have fixed layout ahead of time, so there's no slack.
|
||||
instance_map->SetInObjectUnusedPropertyFields(0);
|
||||
@ -4686,8 +4685,8 @@ void Genesis::InitializeGlobal_harmony_struct() {
|
||||
Handle<String> shared_array_str =
|
||||
isolate()->factory()->InternalizeUtf8String("SharedArray");
|
||||
Handle<JSFunction> shared_array_fun = CreateSharedObjectConstructor(
|
||||
isolate(), shared_array_str, JS_SHARED_ARRAY_TYPE,
|
||||
JSSharedArray::kHeaderSize, SHARED_ARRAY_ELEMENTS,
|
||||
isolate(), shared_array_str, JS_SHARED_ARRAY_TYPE, JSSharedArray::kSize,
|
||||
JSSharedArray::kInObjectFieldCount, SHARED_ARRAY_ELEMENTS,
|
||||
Builtin::kSharedArrayConstructor);
|
||||
shared_array_fun->shared().set_internal_formal_parameter_count(
|
||||
JSParameterCount(0));
|
||||
@ -4697,14 +4696,12 @@ void Genesis::InitializeGlobal_harmony_struct() {
|
||||
Handle<DescriptorArray> descriptors =
|
||||
isolate()->factory()->NewDescriptorArray(1, 0,
|
||||
AllocationType::kSharedOld);
|
||||
Descriptor descriptor = Descriptor::AccessorConstant(
|
||||
Descriptor length_descriptor = Descriptor::DataField(
|
||||
isolate()->shared_heap_isolate()->factory()->length_string(),
|
||||
isolate()
|
||||
->shared_heap_isolate()
|
||||
->factory()
|
||||
->shared_array_length_accessor(),
|
||||
ALL_ATTRIBUTES_MASK);
|
||||
descriptors->Set(InternalIndex(0), &descriptor);
|
||||
JSSharedArray::kLengthFieldIndex, ALL_ATTRIBUTES_MASK,
|
||||
PropertyConstness::kConst, Representation::Smi(),
|
||||
MaybeObjectHandle(FieldType::Any(isolate())));
|
||||
descriptors->Set(InternalIndex(0), &length_descriptor);
|
||||
shared_array_fun->initial_map().InitializeDescriptors(isolate(),
|
||||
*descriptors);
|
||||
|
||||
@ -4721,7 +4718,7 @@ void Genesis::InitializeGlobal_harmony_struct() {
|
||||
isolate()->factory()->InternalizeUtf8String("Mutex");
|
||||
Handle<JSFunction> mutex_fun = CreateSharedObjectConstructor(
|
||||
isolate(), mutex_str, JS_ATOMICS_MUTEX_TYPE,
|
||||
JSAtomicsMutex::kHeaderSize, TERMINAL_FAST_ELEMENTS_KIND,
|
||||
JSAtomicsMutex::kHeaderSize, 0, TERMINAL_FAST_ELEMENTS_KIND,
|
||||
Builtin::kAtomicsMutexConstructor);
|
||||
mutex_fun->shared().set_internal_formal_parameter_count(
|
||||
JSParameterCount(0));
|
||||
@ -4741,7 +4738,7 @@ void Genesis::InitializeGlobal_harmony_struct() {
|
||||
isolate()->factory()->InternalizeUtf8String("Condition");
|
||||
Handle<JSFunction> condition_fun = CreateSharedObjectConstructor(
|
||||
isolate(), condition_str, JS_ATOMICS_CONDITION_TYPE,
|
||||
JSAtomicsCondition::kHeaderSize, TERMINAL_FAST_ELEMENTS_KIND,
|
||||
JSAtomicsCondition::kHeaderSize, 0, TERMINAL_FAST_ELEMENTS_KIND,
|
||||
Builtin::kAtomicsConditionConstructor);
|
||||
condition_fun->shared().set_internal_formal_parameter_count(
|
||||
JSParameterCount(0));
|
||||
|
@ -22,6 +22,18 @@ class JSSharedArray
|
||||
DECL_PRINTER(JSSharedArray)
|
||||
EXPORT_DECL_VERIFIER(JSSharedArray)
|
||||
|
||||
// In-object fields.
|
||||
enum {
|
||||
// The length field is constant and is equal to elements().length().
|
||||
//
|
||||
// TODO(v8:12547): We can save the space for this field by making it
|
||||
// possible to put AccessorInfo in shared or RO space.
|
||||
kLengthFieldIndex = 0,
|
||||
kInObjectFieldCount,
|
||||
};
|
||||
static constexpr int kSize =
|
||||
kHeaderSize + (kTaggedSize * kInObjectFieldCount);
|
||||
|
||||
class BodyDescriptor;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(JSSharedArray)
|
||||
|
@ -88,7 +88,7 @@
|
||||
let shared_array = new SharedArray(2);
|
||||
shared_array[0] = 42;
|
||||
|
||||
assertArrayEquals(shared_array.length, 10);
|
||||
assertEquals(2, shared_array.length);
|
||||
|
||||
let propDescs = Object.getOwnPropertyDescriptors(shared_array);
|
||||
let desc = propDescs[0];
|
||||
|
@ -463,8 +463,8 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x080dd): (138, "StoreHandler1Map"),
|
||||
("read_only_space", 0x08105): (138, "StoreHandler2Map"),
|
||||
("read_only_space", 0x0812d): (138, "StoreHandler3Map"),
|
||||
("old_space", 0x043a5): (2116, "ExternalMap"),
|
||||
("old_space", 0x043d5): (2120, "JSMessageObjectMap"),
|
||||
("old_space", 0x0438d): (2116, "ExternalMap"),
|
||||
("old_space", 0x043bd): (2120, "JSMessageObjectMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
@ -524,60 +524,59 @@ KNOWN_OBJECTS = {
|
||||
("old_space", 0x042e5): "FunctionNameAccessor",
|
||||
("old_space", 0x042fd): "FunctionLengthAccessor",
|
||||
("old_space", 0x04315): "FunctionPrototypeAccessor",
|
||||
("old_space", 0x0432d): "SharedArrayLengthAccessor",
|
||||
("old_space", 0x04345): "StringLengthAccessor",
|
||||
("old_space", 0x0435d): "ValueUnavailableAccessor",
|
||||
("old_space", 0x04375): "WrappedFunctionLengthAccessor",
|
||||
("old_space", 0x0438d): "WrappedFunctionNameAccessor",
|
||||
("old_space", 0x043a5): "ExternalMap",
|
||||
("old_space", 0x043cd): "InvalidPrototypeValidityCell",
|
||||
("old_space", 0x043d5): "JSMessageObjectMap",
|
||||
("old_space", 0x043fd): "EmptyScript",
|
||||
("old_space", 0x04441): "ManyClosuresCell",
|
||||
("old_space", 0x0444d): "ArrayConstructorProtector",
|
||||
("old_space", 0x04461): "NoElementsProtector",
|
||||
("old_space", 0x04475): "MegaDOMProtector",
|
||||
("old_space", 0x04489): "IsConcatSpreadableProtector",
|
||||
("old_space", 0x0449d): "ArraySpeciesProtector",
|
||||
("old_space", 0x044b1): "TypedArraySpeciesProtector",
|
||||
("old_space", 0x044c5): "PromiseSpeciesProtector",
|
||||
("old_space", 0x044d9): "RegExpSpeciesProtector",
|
||||
("old_space", 0x044ed): "StringLengthProtector",
|
||||
("old_space", 0x04501): "ArrayIteratorProtector",
|
||||
("old_space", 0x04515): "ArrayBufferDetachingProtector",
|
||||
("old_space", 0x04529): "PromiseHookProtector",
|
||||
("old_space", 0x0453d): "PromiseResolveProtector",
|
||||
("old_space", 0x04551): "MapIteratorProtector",
|
||||
("old_space", 0x04565): "PromiseThenProtector",
|
||||
("old_space", 0x04579): "SetIteratorProtector",
|
||||
("old_space", 0x0458d): "StringIteratorProtector",
|
||||
("old_space", 0x045a1): "StringSplitCache",
|
||||
("old_space", 0x049a9): "RegExpMultipleCache",
|
||||
("old_space", 0x04db1): "BuiltinsConstantsTable",
|
||||
("old_space", 0x05215): "AsyncFunctionAwaitRejectSharedFun",
|
||||
("old_space", 0x05239): "AsyncFunctionAwaitResolveSharedFun",
|
||||
("old_space", 0x0525d): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
("old_space", 0x05281): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
("old_space", 0x052a5): "AsyncGeneratorYieldWithAwaitResolveSharedFun",
|
||||
("old_space", 0x052c9): "AsyncGeneratorReturnResolveSharedFun",
|
||||
("old_space", 0x052ed): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
("old_space", 0x05311): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
("old_space", 0x05335): "AsyncIteratorValueUnwrapSharedFun",
|
||||
("old_space", 0x05359): "PromiseAllResolveElementSharedFun",
|
||||
("old_space", 0x0537d): "PromiseAllSettledResolveElementSharedFun",
|
||||
("old_space", 0x053a1): "PromiseAllSettledRejectElementSharedFun",
|
||||
("old_space", 0x053c5): "PromiseAnyRejectElementSharedFun",
|
||||
("old_space", 0x053e9): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
("old_space", 0x0540d): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
("old_space", 0x05431): "PromiseCatchFinallySharedFun",
|
||||
("old_space", 0x05455): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
("old_space", 0x05479): "PromiseThenFinallySharedFun",
|
||||
("old_space", 0x0549d): "PromiseThrowerFinallySharedFun",
|
||||
("old_space", 0x054c1): "PromiseValueThunkFinallySharedFun",
|
||||
("old_space", 0x054e5): "ProxyRevokeSharedFun",
|
||||
("old_space", 0x05509): "ShadowRealmImportValueFulfilledSFI",
|
||||
("old_space", 0x0552d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
("old_space", 0x05551): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
("old_space", 0x0432d): "StringLengthAccessor",
|
||||
("old_space", 0x04345): "ValueUnavailableAccessor",
|
||||
("old_space", 0x0435d): "WrappedFunctionLengthAccessor",
|
||||
("old_space", 0x04375): "WrappedFunctionNameAccessor",
|
||||
("old_space", 0x0438d): "ExternalMap",
|
||||
("old_space", 0x043b5): "InvalidPrototypeValidityCell",
|
||||
("old_space", 0x043bd): "JSMessageObjectMap",
|
||||
("old_space", 0x043e5): "EmptyScript",
|
||||
("old_space", 0x04429): "ManyClosuresCell",
|
||||
("old_space", 0x04435): "ArrayConstructorProtector",
|
||||
("old_space", 0x04449): "NoElementsProtector",
|
||||
("old_space", 0x0445d): "MegaDOMProtector",
|
||||
("old_space", 0x04471): "IsConcatSpreadableProtector",
|
||||
("old_space", 0x04485): "ArraySpeciesProtector",
|
||||
("old_space", 0x04499): "TypedArraySpeciesProtector",
|
||||
("old_space", 0x044ad): "PromiseSpeciesProtector",
|
||||
("old_space", 0x044c1): "RegExpSpeciesProtector",
|
||||
("old_space", 0x044d5): "StringLengthProtector",
|
||||
("old_space", 0x044e9): "ArrayIteratorProtector",
|
||||
("old_space", 0x044fd): "ArrayBufferDetachingProtector",
|
||||
("old_space", 0x04511): "PromiseHookProtector",
|
||||
("old_space", 0x04525): "PromiseResolveProtector",
|
||||
("old_space", 0x04539): "MapIteratorProtector",
|
||||
("old_space", 0x0454d): "PromiseThenProtector",
|
||||
("old_space", 0x04561): "SetIteratorProtector",
|
||||
("old_space", 0x04575): "StringIteratorProtector",
|
||||
("old_space", 0x04589): "StringSplitCache",
|
||||
("old_space", 0x04991): "RegExpMultipleCache",
|
||||
("old_space", 0x04d99): "BuiltinsConstantsTable",
|
||||
("old_space", 0x051fd): "AsyncFunctionAwaitRejectSharedFun",
|
||||
("old_space", 0x05221): "AsyncFunctionAwaitResolveSharedFun",
|
||||
("old_space", 0x05245): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
("old_space", 0x05269): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
("old_space", 0x0528d): "AsyncGeneratorYieldWithAwaitResolveSharedFun",
|
||||
("old_space", 0x052b1): "AsyncGeneratorReturnResolveSharedFun",
|
||||
("old_space", 0x052d5): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
("old_space", 0x052f9): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
("old_space", 0x0531d): "AsyncIteratorValueUnwrapSharedFun",
|
||||
("old_space", 0x05341): "PromiseAllResolveElementSharedFun",
|
||||
("old_space", 0x05365): "PromiseAllSettledResolveElementSharedFun",
|
||||
("old_space", 0x05389): "PromiseAllSettledRejectElementSharedFun",
|
||||
("old_space", 0x053ad): "PromiseAnyRejectElementSharedFun",
|
||||
("old_space", 0x053d1): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
("old_space", 0x053f5): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
("old_space", 0x05419): "PromiseCatchFinallySharedFun",
|
||||
("old_space", 0x0543d): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
("old_space", 0x05461): "PromiseThenFinallySharedFun",
|
||||
("old_space", 0x05485): "PromiseThrowerFinallySharedFun",
|
||||
("old_space", 0x054a9): "PromiseValueThunkFinallySharedFun",
|
||||
("old_space", 0x054cd): "ProxyRevokeSharedFun",
|
||||
("old_space", 0x054f1): "ShadowRealmImportValueFulfilledSFI",
|
||||
("old_space", 0x05515): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
("old_space", 0x05539): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
}
|
||||
|
||||
# Lower 32 bits of first page addresses for various heap spaces.
|
||||
|
Loading…
Reference in New Issue
Block a user