[shared-struct] Fix shared barrier for always shared objects
Currently the shared value barrier manually fast paths instance types for objects that are always in the shared heap. This CL makes a common superclass, AlwaysSharedSpaceJSObject, and uses that for the fast path. Bug: chromium:1402920, v8:12547 Fixed: chromium:1402920 Change-Id: I84421802791a4dc72925341eeb0cfc5949b8938a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4134475 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Shu-yu Guo <syg@chromium.org> Cr-Commit-Position: refs/heads/main@{#85192}
This commit is contained in:
parent
59657281c2
commit
b0be4f8ddb
@ -435,8 +435,8 @@ void BaseCollectionsAssembler::GotoIfCannotBeHeldWeakly(
|
||||
// TODO(v8:12547) Shared structs and arrays should only be able to point
|
||||
// to shared values in weak collections. For now, disallow them as weak
|
||||
// collection keys.
|
||||
GotoIf(IsJSSharedStructInstanceType(instance_type), if_cannot_be_held_weakly);
|
||||
GotoIf(IsJSSharedArrayInstanceType(instance_type), if_cannot_be_held_weakly);
|
||||
GotoIf(IsAlwaysSharedSpaceJSObjectInstanceType(instance_type),
|
||||
if_cannot_be_held_weakly);
|
||||
Goto(&end);
|
||||
Bind(&check_symbol_key);
|
||||
GotoIfNot(HasHarmonySymbolAsWeakmapKeyFlag(), if_cannot_be_held_weakly);
|
||||
|
@ -6817,6 +6817,12 @@ TNode<BoolT> CodeStubAssembler::IsJSArrayIterator(TNode<HeapObject> object) {
|
||||
return HasInstanceType(object, JS_ARRAY_ITERATOR_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsAlwaysSharedSpaceJSObjectInstanceType(
|
||||
TNode<Int32T> instance_type) {
|
||||
return IsInRange(instance_type, FIRST_ALWAYS_SHARED_SPACE_JS_OBJECT_TYPE,
|
||||
LAST_ALWAYS_SHARED_SPACE_JS_OBJECT_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsJSSharedArrayInstanceType(
|
||||
TNode<Int32T> instance_type) {
|
||||
return InstanceTypeEqual(instance_type, JS_SHARED_ARRAY_TYPE);
|
||||
@ -16828,9 +16834,9 @@ void CodeStubAssembler::SharedValueBarrier(
|
||||
TNode<Uint16T> value_instance_type =
|
||||
LoadMapInstanceType(LoadMap(CAST(value)));
|
||||
GotoIf(IsSharedStringInstanceType(value_instance_type), &skip_barrier);
|
||||
GotoIf(IsJSSharedStructInstanceType(value_instance_type), &skip_barrier);
|
||||
GotoIf(IsAlwaysSharedSpaceJSObjectInstanceType(value_instance_type),
|
||||
&skip_barrier);
|
||||
GotoIf(IsHeapNumberInstanceType(value_instance_type), &check_in_shared_heap);
|
||||
GotoIf(IsJSSharedArrayInstanceType(value_instance_type), &skip_barrier);
|
||||
Goto(&slow);
|
||||
|
||||
BIND(&check_in_shared_heap);
|
||||
|
@ -2590,6 +2590,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<BoolT> InstanceTypeEqual(TNode<Int32T> instance_type, int type);
|
||||
TNode<BoolT> IsNoElementsProtectorCellInvalid();
|
||||
TNode<BoolT> IsMegaDOMProtectorCellInvalid();
|
||||
TNode<BoolT> IsAlwaysSharedSpaceJSObjectInstanceType(
|
||||
TNode<Int32T> instance_type);
|
||||
TNode<BoolT> IsArrayIteratorProtectorCellInvalid();
|
||||
TNode<BoolT> IsBigIntInstanceType(TNode<Int32T> instance_type);
|
||||
TNode<BoolT> IsBigInt(TNode<HeapObject> object);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/common/globals.h"
|
||||
#include "src/heap/heap-write-barrier-inl.h"
|
||||
#include "src/objects/js-atomics-synchronization.h"
|
||||
#include "src/objects/js-struct-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/base/platform/time.h"
|
||||
#include "src/execution/thread-id.h"
|
||||
#include "src/objects/js-objects.h"
|
||||
#include "src/objects/js-struct.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
@ -26,7 +27,7 @@ class WaiterQueueNode;
|
||||
// Base class for JSAtomicsMutex and JSAtomicsCondition
|
||||
class JSSynchronizationPrimitive
|
||||
: public TorqueGeneratedJSSynchronizationPrimitive<
|
||||
JSSynchronizationPrimitive, JSObject> {
|
||||
JSSynchronizationPrimitive, AlwaysSharedSpaceJSObject> {
|
||||
public:
|
||||
// Synchronization only store raw data as state.
|
||||
static constexpr int kEndOfTaggedFieldsOffset = JSObject::kHeaderSize;
|
||||
@ -44,10 +45,10 @@ class JSSynchronizationPrimitive
|
||||
|
||||
inline std::atomic<StateT>* AtomicStatePtr();
|
||||
|
||||
using TorqueGeneratedJSSynchronizationPrimitive<JSSynchronizationPrimitive,
|
||||
JSObject>::state;
|
||||
using TorqueGeneratedJSSynchronizationPrimitive<JSSynchronizationPrimitive,
|
||||
JSObject>::set_state;
|
||||
using TorqueGeneratedJSSynchronizationPrimitive<
|
||||
JSSynchronizationPrimitive, AlwaysSharedSpaceJSObject>::state;
|
||||
using TorqueGeneratedJSSynchronizationPrimitive<
|
||||
JSSynchronizationPrimitive, AlwaysSharedSpaceJSObject>::set_state;
|
||||
};
|
||||
|
||||
// A non-recursive mutex that is exposed to JS.
|
||||
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
@abstract
|
||||
extern class JSSynchronizationPrimitive extends JSObject {
|
||||
extern class JSSynchronizationPrimitive extends AlwaysSharedSpaceJSObject {
|
||||
@if(TAGGED_SIZE_8_BYTES) state: uintptr;
|
||||
@ifnot(TAGGED_SIZE_8_BYTES) state: uint32;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/api/api-inl.h"
|
||||
#include "src/heap/heap-write-barrier-inl.h"
|
||||
#include "src/objects/js-shared-array.h"
|
||||
#include "src/objects/js-struct-inl.h"
|
||||
#include "src/objects/smi-inl.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define V8_OBJECTS_JS_SHARED_ARRAY_H_
|
||||
|
||||
#include "src/objects/js-objects.h"
|
||||
#include "src/objects/js-struct.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
@ -16,7 +17,8 @@ namespace internal {
|
||||
#include "torque-generated/src/objects/js-shared-array-tq.inc"
|
||||
|
||||
class JSSharedArray
|
||||
: public TorqueGeneratedJSSharedArray<JSSharedArray, JSObject> {
|
||||
: public TorqueGeneratedJSSharedArray<JSSharedArray,
|
||||
AlwaysSharedSpaceJSObject> {
|
||||
public:
|
||||
DECL_CAST(JSSharedArray)
|
||||
DECL_PRINTER(JSSharedArray)
|
||||
|
@ -2,4 +2,4 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
extern class JSSharedArray extends JSObject {}
|
||||
extern class JSSharedArray extends AlwaysSharedSpaceJSObject {}
|
||||
|
@ -18,6 +18,8 @@ namespace internal {
|
||||
|
||||
#include "torque-generated/src/objects/js-struct-tq-inl.inc"
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(AlwaysSharedSpaceJSObject)
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(JSSharedStruct)
|
||||
|
||||
CAST_ACCESSOR(JSSharedStruct)
|
||||
|
@ -15,8 +15,17 @@ namespace internal {
|
||||
|
||||
#include "torque-generated/src/objects/js-struct-tq.inc"
|
||||
|
||||
class AlwaysSharedSpaceJSObject
|
||||
: public TorqueGeneratedAlwaysSharedSpaceJSObject<AlwaysSharedSpaceJSObject,
|
||||
JSObject> {
|
||||
public:
|
||||
static_assert(kHeaderSize == JSObject::kHeaderSize);
|
||||
TQ_OBJECT_CONSTRUCTORS(AlwaysSharedSpaceJSObject)
|
||||
};
|
||||
|
||||
class JSSharedStruct
|
||||
: public TorqueGeneratedJSSharedStruct<JSSharedStruct, JSObject> {
|
||||
: public TorqueGeneratedJSSharedStruct<JSSharedStruct,
|
||||
AlwaysSharedSpaceJSObject> {
|
||||
public:
|
||||
DECL_CAST(JSSharedStruct)
|
||||
DECL_PRINTER(JSSharedStruct)
|
||||
|
@ -2,6 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
extern class JSSharedStruct extends JSObject {
|
||||
// escaped_local_thread: Smi;
|
||||
// AlwaysSharedSpaceJSObject are JSObjects that must always be allocated in the
|
||||
// shared space. Its instance type range is used to fast path the shared value
|
||||
// barrier.
|
||||
@abstract
|
||||
@highestInstanceTypeWithinParentClassRange
|
||||
extern class AlwaysSharedSpaceJSObject extends JSObject {
|
||||
}
|
||||
|
||||
extern class JSSharedStruct extends AlwaysSharedSpaceJSObject {}
|
||||
|
@ -78,6 +78,7 @@ class ZoneForwardList;
|
||||
V(AccessCheckNeeded) \
|
||||
V(AccessorInfo) \
|
||||
V(AllocationSite) \
|
||||
V(AlwaysSharedSpaceJSObject) \
|
||||
V(ArrayList) \
|
||||
V(BigInt) \
|
||||
V(BigIntBase) \
|
||||
|
@ -1233,13 +1233,14 @@ bool Object::IsShared() const {
|
||||
}
|
||||
|
||||
// Check if this object is already shared.
|
||||
switch (object.map().instance_type()) {
|
||||
InstanceType instance_type = object.map().instance_type();
|
||||
if (InstanceTypeChecker::IsAlwaysSharedSpaceJSObject(instance_type)) {
|
||||
DCHECK(object.InSharedHeap());
|
||||
return true;
|
||||
}
|
||||
switch (instance_type) {
|
||||
case SHARED_STRING_TYPE:
|
||||
case SHARED_ONE_BYTE_STRING_TYPE:
|
||||
case JS_SHARED_ARRAY_TYPE:
|
||||
case JS_SHARED_STRUCT_TYPE:
|
||||
case JS_ATOMICS_MUTEX_TYPE:
|
||||
case JS_ATOMICS_CONDITION_TYPE:
|
||||
DCHECK(object.InSharedHeap());
|
||||
return true;
|
||||
case INTERNALIZED_STRING_TYPE:
|
||||
|
@ -34,3 +34,10 @@ let cv = new Atomics.Condition;
|
||||
assertEquals(false, Atomics.Condition.wait(cv, mutex, 100));
|
||||
});
|
||||
})();
|
||||
|
||||
// Mutexes can be assigned to shared objects.
|
||||
(function TestConditionCanBeAssignedToSharedObjects() {
|
||||
const Box = new SharedStructType(["payload"]);
|
||||
const box = new Box;
|
||||
box.payload = cv;
|
||||
})();
|
||||
|
@ -44,3 +44,10 @@ assertThrowsEquals(() => {
|
||||
}, 42);
|
||||
Atomics.Mutex.tryLock(mutex, () => { locked_count++; });
|
||||
assertEquals(locked_count, 6);
|
||||
|
||||
// Mutexes can be assigned to shared objects.
|
||||
(function TestMutexCanBeAssignedToSharedObjects() {
|
||||
const Box = new SharedStructType(["payload"]);
|
||||
const box = new Box;
|
||||
box.payload = mutex;
|
||||
})();
|
||||
|
@ -236,60 +236,60 @@ INSTANCE_TYPES = {
|
||||
2098: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
|
||||
2099: "JS_MAP_TYPE",
|
||||
2100: "JS_SET_TYPE",
|
||||
2101: "JS_ATOMICS_CONDITION_TYPE",
|
||||
2102: "JS_ATOMICS_MUTEX_TYPE",
|
||||
2103: "JS_WEAK_MAP_TYPE",
|
||||
2104: "JS_WEAK_SET_TYPE",
|
||||
2105: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
2106: "JS_ARRAY_TYPE",
|
||||
2107: "JS_ARRAY_ITERATOR_TYPE",
|
||||
2108: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
2109: "JS_COLLATOR_TYPE",
|
||||
2110: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
2111: "JS_DATE_TYPE",
|
||||
2112: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
2113: "JS_DISPLAY_NAMES_TYPE",
|
||||
2114: "JS_DURATION_FORMAT_TYPE",
|
||||
2115: "JS_ERROR_TYPE",
|
||||
2116: "JS_EXTERNAL_OBJECT_TYPE",
|
||||
2117: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
2118: "JS_LIST_FORMAT_TYPE",
|
||||
2119: "JS_LOCALE_TYPE",
|
||||
2120: "JS_MESSAGE_OBJECT_TYPE",
|
||||
2121: "JS_NUMBER_FORMAT_TYPE",
|
||||
2122: "JS_PLURAL_RULES_TYPE",
|
||||
2123: "JS_RAW_JSON_TYPE",
|
||||
2124: "JS_REG_EXP_TYPE",
|
||||
2125: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
2126: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
2127: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
2128: "JS_SEGMENTER_TYPE",
|
||||
2129: "JS_SEGMENTS_TYPE",
|
||||
2130: "JS_SHADOW_REALM_TYPE",
|
||||
2131: "JS_SHARED_ARRAY_TYPE",
|
||||
2132: "JS_SHARED_STRUCT_TYPE",
|
||||
2133: "JS_STRING_ITERATOR_TYPE",
|
||||
2134: "JS_TEMPORAL_CALENDAR_TYPE",
|
||||
2135: "JS_TEMPORAL_DURATION_TYPE",
|
||||
2136: "JS_TEMPORAL_INSTANT_TYPE",
|
||||
2137: "JS_TEMPORAL_PLAIN_DATE_TYPE",
|
||||
2138: "JS_TEMPORAL_PLAIN_DATE_TIME_TYPE",
|
||||
2139: "JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE",
|
||||
2140: "JS_TEMPORAL_PLAIN_TIME_TYPE",
|
||||
2141: "JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE",
|
||||
2142: "JS_TEMPORAL_TIME_ZONE_TYPE",
|
||||
2143: "JS_TEMPORAL_ZONED_DATE_TIME_TYPE",
|
||||
2144: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
2145: "JS_WEAK_REF_TYPE",
|
||||
2146: "WASM_EXCEPTION_PACKAGE_TYPE",
|
||||
2147: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
2148: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
2149: "WASM_MEMORY_OBJECT_TYPE",
|
||||
2150: "WASM_MODULE_OBJECT_TYPE",
|
||||
2151: "WASM_SUSPENDER_OBJECT_TYPE",
|
||||
2152: "WASM_TABLE_OBJECT_TYPE",
|
||||
2153: "WASM_TAG_OBJECT_TYPE",
|
||||
2154: "WASM_VALUE_OBJECT_TYPE",
|
||||
2101: "JS_WEAK_MAP_TYPE",
|
||||
2102: "JS_WEAK_SET_TYPE",
|
||||
2103: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
2104: "JS_ARRAY_TYPE",
|
||||
2105: "JS_ARRAY_ITERATOR_TYPE",
|
||||
2106: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
2107: "JS_COLLATOR_TYPE",
|
||||
2108: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
2109: "JS_DATE_TYPE",
|
||||
2110: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
2111: "JS_DISPLAY_NAMES_TYPE",
|
||||
2112: "JS_DURATION_FORMAT_TYPE",
|
||||
2113: "JS_ERROR_TYPE",
|
||||
2114: "JS_EXTERNAL_OBJECT_TYPE",
|
||||
2115: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
2116: "JS_LIST_FORMAT_TYPE",
|
||||
2117: "JS_LOCALE_TYPE",
|
||||
2118: "JS_MESSAGE_OBJECT_TYPE",
|
||||
2119: "JS_NUMBER_FORMAT_TYPE",
|
||||
2120: "JS_PLURAL_RULES_TYPE",
|
||||
2121: "JS_RAW_JSON_TYPE",
|
||||
2122: "JS_REG_EXP_TYPE",
|
||||
2123: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
2124: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
2125: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
2126: "JS_SEGMENTER_TYPE",
|
||||
2127: "JS_SEGMENTS_TYPE",
|
||||
2128: "JS_SHADOW_REALM_TYPE",
|
||||
2129: "JS_STRING_ITERATOR_TYPE",
|
||||
2130: "JS_TEMPORAL_CALENDAR_TYPE",
|
||||
2131: "JS_TEMPORAL_DURATION_TYPE",
|
||||
2132: "JS_TEMPORAL_INSTANT_TYPE",
|
||||
2133: "JS_TEMPORAL_PLAIN_DATE_TYPE",
|
||||
2134: "JS_TEMPORAL_PLAIN_DATE_TIME_TYPE",
|
||||
2135: "JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE",
|
||||
2136: "JS_TEMPORAL_PLAIN_TIME_TYPE",
|
||||
2137: "JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE",
|
||||
2138: "JS_TEMPORAL_TIME_ZONE_TYPE",
|
||||
2139: "JS_TEMPORAL_ZONED_DATE_TIME_TYPE",
|
||||
2140: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
2141: "JS_WEAK_REF_TYPE",
|
||||
2142: "WASM_EXCEPTION_PACKAGE_TYPE",
|
||||
2143: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
2144: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
2145: "WASM_MEMORY_OBJECT_TYPE",
|
||||
2146: "WASM_MODULE_OBJECT_TYPE",
|
||||
2147: "WASM_SUSPENDER_OBJECT_TYPE",
|
||||
2148: "WASM_TABLE_OBJECT_TYPE",
|
||||
2149: "WASM_TAG_OBJECT_TYPE",
|
||||
2150: "WASM_VALUE_OBJECT_TYPE",
|
||||
2151: "JS_ATOMICS_CONDITION_TYPE",
|
||||
2152: "JS_ATOMICS_MUTEX_TYPE",
|
||||
2153: "JS_SHARED_ARRAY_TYPE",
|
||||
2154: "JS_SHARED_STRUCT_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -481,8 +481,8 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x03e95): (272, "WasmTypeInfoMap"),
|
||||
("read_only_space", 0x03ebd): (268, "WasmContinuationObjectMap"),
|
||||
("read_only_space", 0x03ee5): (274, "WeakCellMap"),
|
||||
("old_space", 0x0438d): (2116, "ExternalMap"),
|
||||
("old_space", 0x043b5): (2120, "JSMessageObjectMap"),
|
||||
("old_space", 0x0438d): (2114, "ExternalMap"),
|
||||
("old_space", 0x043b5): (2118, "JSMessageObjectMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
|
Loading…
Reference in New Issue
Block a user