Commit e210b196 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[csa][cleanup] TNodify Atomic Compare Exchange.

Splits the 64bit operation to a seperate function since there are different
return types depending upon whether the architecture is 64-bit or 32-bit.

BUG=v8:6949,v8:11074

Change-Id: I47c84a0104f71ec8865f12cbfa201f2f76cf08bc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2529911
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71128}
parent 8d611a87
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
using compiler::Node;
class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler { class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
public: public:
explicit SharedArrayBufferBuiltinsAssembler( explicit SharedArrayBufferBuiltinsAssembler(
...@@ -47,8 +45,8 @@ class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler { ...@@ -47,8 +45,8 @@ class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
// Create a BigInt from the result of a 64-bit atomic operation, using // Create a BigInt from the result of a 64-bit atomic operation, using
// projections on 32-bit platforms. // projections on 32-bit platforms.
TNode<BigInt> BigIntFromSigned64(SloppyTNode<AtomicInt64> signed64); TNode<BigInt> BigIntFromSigned64(TNode<AtomicInt64> signed64);
TNode<BigInt> BigIntFromUnsigned64(SloppyTNode<AtomicUint64> unsigned64); TNode<BigInt> BigIntFromUnsigned64(TNode<AtomicUint64> unsigned64);
}; };
// https://tc39.es/ecma262/#sec-validateintegertypedarray // https://tc39.es/ecma262/#sec-validateintegertypedarray
...@@ -146,7 +144,7 @@ void SharedArrayBufferBuiltinsAssembler::DebugCheckAtomicIndex( ...@@ -146,7 +144,7 @@ void SharedArrayBufferBuiltinsAssembler::DebugCheckAtomicIndex(
} }
TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64( TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64(
SloppyTNode<AtomicInt64> signed64) { TNode<AtomicInt64> signed64) {
#if defined(V8_HOST_ARCH_32_BIT) #if defined(V8_HOST_ARCH_32_BIT)
TNode<IntPtrT> low = Projection<0>(signed64); TNode<IntPtrT> low = Projection<0>(signed64);
TNode<IntPtrT> high = Projection<1>(signed64); TNode<IntPtrT> high = Projection<1>(signed64);
...@@ -157,7 +155,7 @@ TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64( ...@@ -157,7 +155,7 @@ TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64(
} }
TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromUnsigned64( TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromUnsigned64(
SloppyTNode<AtomicUint64> unsigned64) { TNode<AtomicUint64> unsigned64) {
#if defined(V8_HOST_ARCH_32_BIT) #if defined(V8_HOST_ARCH_32_BIT)
TNode<UintPtrT> low = Projection<0>(unsigned64); TNode<UintPtrT> low = Projection<0>(unsigned64);
TNode<UintPtrT> high = Projection<1>(unsigned64); TNode<UintPtrT> high = Projection<1>(unsigned64);
...@@ -559,34 +557,34 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) { ...@@ -559,34 +557,34 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
arraysize(case_labels)); arraysize(case_labels));
BIND(&i8); BIND(&i8);
Return(SmiFromInt32(AtomicCompareExchange(MachineType::Int8(), backing_store, Return(SmiFromInt32(Signed(
index_word, old_value_word32, AtomicCompareExchange(MachineType::Int8(), backing_store, index_word,
new_value_word32))); old_value_word32, new_value_word32))));
BIND(&u8); BIND(&u8);
Return(SmiFromInt32(AtomicCompareExchange(MachineType::Uint8(), backing_store, Return(SmiFromInt32(Signed(
index_word, old_value_word32, AtomicCompareExchange(MachineType::Uint8(), backing_store, index_word,
new_value_word32))); old_value_word32, new_value_word32))));
BIND(&i16); BIND(&i16);
Return(SmiFromInt32(AtomicCompareExchange( Return(SmiFromInt32(Signed(AtomicCompareExchange(
MachineType::Int16(), backing_store, WordShl(index_word, 1), MachineType::Int16(), backing_store, WordShl(index_word, 1),
old_value_word32, new_value_word32))); old_value_word32, new_value_word32))));
BIND(&u16); BIND(&u16);
Return(SmiFromInt32(AtomicCompareExchange( Return(SmiFromInt32(Signed(AtomicCompareExchange(
MachineType::Uint16(), backing_store, WordShl(index_word, 1), MachineType::Uint16(), backing_store, WordShl(index_word, 1),
old_value_word32, new_value_word32))); old_value_word32, new_value_word32))));
BIND(&i32); BIND(&i32);
Return(ChangeInt32ToTagged(AtomicCompareExchange( Return(ChangeInt32ToTagged(Signed(AtomicCompareExchange(
MachineType::Int32(), backing_store, WordShl(index_word, 2), MachineType::Int32(), backing_store, WordShl(index_word, 2),
old_value_word32, new_value_word32))); old_value_word32, new_value_word32))));
BIND(&u32); BIND(&u32);
Return(ChangeUint32ToTagged(AtomicCompareExchange( Return(ChangeUint32ToTagged(Unsigned(AtomicCompareExchange(
MachineType::Uint32(), backing_store, WordShl(index_word, 2), MachineType::Uint32(), backing_store, WordShl(index_word, 2),
old_value_word32, new_value_word32))); old_value_word32, new_value_word32))));
BIND(&big); BIND(&big);
// 4. If typedArray.[[ContentType]] is BigInt, then // 4. If typedArray.[[ContentType]] is BigInt, then
...@@ -616,14 +614,14 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) { ...@@ -616,14 +614,14 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
// This uses Uint64() intentionally: AtomicCompareExchange is not implemented // This uses Uint64() intentionally: AtomicCompareExchange is not implemented
// for Int64(), which is fine because the machine instruction only cares // for Int64(), which is fine because the machine instruction only cares
// about words. // about words.
Return(BigIntFromSigned64(AtomicCompareExchange( Return(BigIntFromSigned64(AtomicCompareExchange64<AtomicInt64>(
MachineType::Uint64(), backing_store, WordShl(index_word, 3), backing_store, WordShl(index_word, 3), var_old_low.value(),
var_old_low.value(), var_new_low.value(), old_high, new_high))); var_new_low.value(), old_high, new_high)));
BIND(&u64); BIND(&u64);
Return(BigIntFromUnsigned64(AtomicCompareExchange( Return(BigIntFromUnsigned64(AtomicCompareExchange64<AtomicUint64>(
MachineType::Uint64(), backing_store, WordShl(index_word, 3), backing_store, WordShl(index_word, 3), var_old_low.value(),
var_old_low.value(), var_new_low.value(), old_high, new_high))); var_new_low.value(), old_high, new_high)));
// This shouldn't happen, we've already validated the type. // This shouldn't happen, we've already validated the type.
BIND(&other); BIND(&other);
......
...@@ -843,15 +843,37 @@ ATOMIC_FUNCTION(Xor) ...@@ -843,15 +843,37 @@ ATOMIC_FUNCTION(Xor)
ATOMIC_FUNCTION(Exchange) ATOMIC_FUNCTION(Exchange)
#undef ATOMIC_FUNCTION #undef ATOMIC_FUNCTION
Node* CodeAssembler::AtomicCompareExchange(MachineType type, Node* base, TNode<Word32T> CodeAssembler::AtomicCompareExchange(MachineType type,
Node* offset, Node* old_value, TNode<RawPtrT> base,
Node* new_value, TNode<WordT> offset,
Node* old_value_high, TNode<Word32T> old_value,
Node* new_value_high) { TNode<Word32T> new_value) {
return raw_assembler()->AtomicCompareExchange( return UncheckedCast<Word32T>(raw_assembler()->AtomicCompareExchange(
type, base, offset, old_value, old_value_high, new_value, new_value_high); type, base, offset, old_value, new_value));
} }
template <class Type>
TNode<Type> CodeAssembler::AtomicCompareExchange64(
TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
TNode<UintPtrT> new_value_high) {
// This uses Uint64() intentionally: AtomicCompareExchange is not implemented
// for Int64(), which is fine because the machine instruction only cares
// about words.
return UncheckedCast<Type>(raw_assembler()->AtomicCompareExchange64(
base, offset, old_value, old_value_high, new_value, new_value_high));
}
template TNode<AtomicInt64> CodeAssembler::AtomicCompareExchange64<AtomicInt64>(
TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
TNode<UintPtrT> new_value_high);
template TNode<AtomicUint64>
CodeAssembler::AtomicCompareExchange64<AtomicUint64>(
TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
TNode<UintPtrT> new_value_high);
Node* CodeAssembler::StoreRoot(RootIndex root_index, Node* value) { Node* CodeAssembler::StoreRoot(RootIndex root_index, Node* value) {
DCHECK(!RootsTable::IsImmortalImmovable(root_index)); DCHECK(!RootsTable::IsImmortalImmovable(root_index));
TNode<ExternalReference> isolate_root = TNode<ExternalReference> isolate_root =
......
...@@ -844,10 +844,18 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -844,10 +844,18 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<UintPtrT> value_high); TNode<UintPtrT> value_high);
// Compare and Exchange value at raw memory location // Compare and Exchange value at raw memory location
Node* AtomicCompareExchange(MachineType type, Node* base, Node* offset, TNode<Word32T> AtomicCompareExchange(MachineType type, TNode<RawPtrT> base,
Node* old_value, Node* new_value, TNode<WordT> offset,
Node* old_value_high = nullptr, TNode<Word32T> old_value,
Node* new_value_high = nullptr); TNode<Word32T> new_value);
template <class Type>
TNode<Type> AtomicCompareExchange64(TNode<RawPtrT> base, TNode<WordT> offset,
TNode<UintPtrT> old_value,
TNode<UintPtrT> new_value,
TNode<UintPtrT> old_value_high,
TNode<UintPtrT> new_value_high);
// Store a value to the root array. // Store a value to the root array.
Node* StoreRoot(RootIndex root_index, Node* value); Node* StoreRoot(RootIndex root_index, Node* value);
......
...@@ -286,26 +286,30 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { ...@@ -286,26 +286,30 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
#undef VALUE_HALVES #undef VALUE_HALVES
Node* AtomicCompareExchange(MachineType type, Node* base, Node* index, Node* AtomicCompareExchange(MachineType type, Node* base, Node* index,
Node* old_value, Node* old_value_high, Node* old_value, Node* new_value) {
Node* new_value, Node* new_value_high) { DCHECK_NE(type.representation(), MachineRepresentation::kWord64);
if (type.representation() == MachineRepresentation::kWord64) {
if (machine()->Is64()) {
DCHECK_NULL(old_value_high);
DCHECK_NULL(new_value_high);
return AddNode(machine()->Word64AtomicCompareExchange(type), base,
index, old_value, new_value);
} else {
return AddNode(machine()->Word32AtomicPairCompareExchange(), base,
index, old_value, old_value_high, new_value,
new_value_high);
}
}
DCHECK_NULL(old_value_high);
DCHECK_NULL(new_value_high);
return AddNode(machine()->Word32AtomicCompareExchange(type), base, index, return AddNode(machine()->Word32AtomicCompareExchange(type), base, index,
old_value, new_value); old_value, new_value);
} }
Node* AtomicCompareExchange64(Node* base, Node* index, Node* old_value,
Node* old_value_high, Node* new_value,
Node* new_value_high) {
if (machine()->Is64()) {
DCHECK_NULL(old_value_high);
DCHECK_NULL(new_value_high);
// This uses Uint64() intentionally: AtomicCompareExchange is not
// implemented for Int64(), which is fine because the machine instruction
// only cares about words.
return AddNode(
machine()->Word64AtomicCompareExchange(MachineType::Uint64()), base,
index, old_value, new_value);
} else {
return AddNode(machine()->Word32AtomicPairCompareExchange(), base, index,
old_value, old_value_high, new_value, new_value_high);
}
}
// Arithmetic Operations. // Arithmetic Operations.
Node* WordAnd(Node* a, Node* b) { Node* WordAnd(Node* a, Node* b) {
return AddNode(machine()->WordAnd(), a, b); return AddNode(machine()->WordAnd(), a, b);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment