Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Unified Diff: test/cctest/test-simulator-arm64.cc

Issue 2754543006: [arm64] Use exclusive instructions in exchange (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/arm64/decoder-arm64-inl.h ('K') | « test/cctest/test-disasm-arm64.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-simulator-arm64.cc
diff --git a/test/cctest/test-simulator-arm64.cc b/test/cctest/test-simulator-arm64.cc
index b852a46b0ed8cf10437050a60f0f537322b6308d..73dd75460710f1fccaac316c990a3d6e4f123d9d 100644
--- a/test/cctest/test-simulator-arm64.cc
+++ b/test/cctest/test-simulator-arm64.cc
@@ -49,8 +49,10 @@ struct MemoryAccess {
None,
Load,
LoadExcl,
+ LoadAcqExcl,
Store,
StoreExcl,
+ StoreRelExcl,
};
enum class Size {
@@ -109,6 +111,22 @@ static void AssembleMemoryAccess(MacroAssembler* assembler, MemoryAccess access,
case MemoryAccess::Kind::LoadExcl:
switch (access.size) {
case MemoryAccess::Size::Byte:
+ __ ldxrb(value_reg, addr_reg);
+ break;
+
+ case MemoryAccess::Size::HalfWord:
+ __ ldxrh(value_reg, addr_reg);
+ break;
+
+ case MemoryAccess::Size::Word:
+ __ ldxr(value_reg, addr_reg);
+ break;
+ }
+ break;
+
+ case MemoryAccess::Kind::LoadAcqExcl:
+ switch (access.size) {
+ case MemoryAccess::Size::Byte:
__ ldaxrb(value_reg, addr_reg);
break;
@@ -145,6 +163,25 @@ static void AssembleMemoryAccess(MacroAssembler* assembler, MemoryAccess access,
switch (access.size) {
case MemoryAccess::Size::Byte:
__ Mov(value_reg, Operand(access.value));
+ __ stxrb(dest_reg, value_reg, addr_reg);
+ break;
+
+ case MemoryAccess::Size::HalfWord:
+ __ Mov(value_reg, Operand(access.value));
+ __ stxrh(dest_reg, value_reg, addr_reg);
+ break;
+
+ case MemoryAccess::Size::Word:
+ __ Mov(value_reg, Operand(access.value));
+ __ stxr(dest_reg, value_reg, addr_reg);
+ break;
+ }
+ break;
+
+ case MemoryAccess::Kind::StoreRelExcl:
+ switch (access.size) {
+ case MemoryAccess::Size::Byte:
+ __ Mov(value_reg, Operand(access.value));
__ stlxrb(dest_reg, value_reg, addr_reg);
break;
@@ -164,14 +201,16 @@ static void AssembleMemoryAccess(MacroAssembler* assembler, MemoryAccess access,
static void AssembleLoadExcl(MacroAssembler* assembler, MemoryAccess access,
Register value_reg, Register addr_reg) {
- DCHECK(access.kind == MemoryAccess::Kind::LoadExcl);
+ DCHECK((access.kind == MemoryAccess::Kind::LoadExcl) ||
+ (access.kind == MemoryAccess::Kind::LoadAcqExcl));
AssembleMemoryAccess(assembler, access, no_reg, value_reg, addr_reg);
}
static void AssembleStoreExcl(MacroAssembler* assembler, MemoryAccess access,
Register dest_reg, Register value_reg,
Register addr_reg) {
- DCHECK(access.kind == MemoryAccess::Kind::StoreExcl);
+ DCHECK((access.kind == MemoryAccess::Kind::StoreExcl) ||
+ (access.kind == MemoryAccess::Kind::StoreRelExcl));
AssembleMemoryAccess(assembler, access, dest_reg, value_reg, addr_reg);
}
@@ -185,7 +224,7 @@ static void TestInvalidateExclusiveAccess(
AssembleLoadExcl(&masm, access1, w1, x1);
AssembleMemoryAccess(&masm, access2, w3, w2, x1);
AssembleStoreExcl(&masm, access3, w0, w3, x1);
- __ br(lr);
+ __ Br(lr);
CodeDesc desc;
masm.GetCode(&desc);
@@ -214,24 +253,25 @@ static void TestInvalidateExclusiveAccess(
}
}
-TEST(simulator_invalidate_exclusive_access) {
+TEST(simulator_invalidate_acquire_release_exclusive_access) {
using Kind = MemoryAccess::Kind;
using Size = MemoryAccess::Size;
- MemoryAccess ldaxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w));
- MemoryAccess stlxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7);
+ MemoryAccess ldaxr_w(Kind::LoadAcqExcl, Size::Word, offsetof(TestData, w));
+ MemoryAccess stlxr_w(Kind::StoreRelExcl, Size::Word, offsetof(TestData, w),
+ 7);
// Address mismatch.
TestInvalidateExclusiveAccess(
TestData(1), ldaxr_w,
- MemoryAccess(Kind::LoadExcl, Size::Word, offsetof(TestData, dummy)),
+ MemoryAccess(Kind::LoadAcqExcl, Size::Word, offsetof(TestData, dummy)),
stlxr_w, 1, TestData(1));
// Size mismatch.
- TestInvalidateExclusiveAccess(
- TestData(1), ldaxr_w, MemoryAccess(),
- MemoryAccess(Kind::StoreExcl, Size::HalfWord, offsetof(TestData, w), 7),
- 1, TestData(1));
+ TestInvalidateExclusiveAccess(TestData(1), ldaxr_w, MemoryAccess(),
+ MemoryAccess(Kind::StoreRelExcl, Size::HalfWord,
+ offsetof(TestData, w), 7),
+ 1, TestData(1));
// Load between ldaxr/stlxr.
TestInvalidateExclusiveAccess(
@@ -250,6 +290,42 @@ TEST(simulator_invalidate_exclusive_access) {
0, TestData(7));
}
+TEST(simulator_invalidate_exclusive_access) {
+ using Kind = MemoryAccess::Kind;
+ using Size = MemoryAccess::Size;
+
+ MemoryAccess ldxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w));
+ MemoryAccess stxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 42);
+
+ // Address mismatch.
+ TestInvalidateExclusiveAccess(
+ TestData(1), ldxr_w,
+ MemoryAccess(Kind::LoadExcl, Size::Word, offsetof(TestData, dummy)),
+ stxr_w, 1, TestData(1));
+
+ // Size mismatch.
+ TestInvalidateExclusiveAccess(
+ TestData(1), ldxr_w, MemoryAccess(),
+ MemoryAccess(Kind::StoreExcl, Size::HalfWord, offsetof(TestData, w), 42),
+ 1, TestData(1));
+
+ // Load between ldxr/stxr.
+ TestInvalidateExclusiveAccess(
+ TestData(1), ldxr_w,
+ MemoryAccess(Kind::Load, Size::Word, offsetof(TestData, dummy)), stxr_w,
+ 1, TestData(1));
+
+ // Store between ldxr/stxr.
+ TestInvalidateExclusiveAccess(
+ TestData(1), ldxr_w,
+ MemoryAccess(Kind::Store, Size::Word, offsetof(TestData, dummy)), stxr_w,
+ 1, TestData(1));
+
+ // Match
+ TestInvalidateExclusiveAccess(TestData(1), ldxr_w, MemoryAccess(), stxr_w, 0,
+ TestData(42));
+}
+
static int ExecuteMemoryAccess(Isolate* isolate, TestData* test_data,
MemoryAccess access) {
HandleScope scope(isolate);
@@ -331,7 +407,7 @@ class MemoryAccessThread : public v8::base::Thread {
v8::base::ConditionVariable did_request_cv_;
};
-TEST(simulator_invalidate_exclusive_access_threaded) {
+TEST(simulator_invalidate_acquire_release_exclusive_access_threaded) {
using Kind = MemoryAccess::Kind;
using Size = MemoryAccess::Size;
@@ -343,15 +419,16 @@ TEST(simulator_invalidate_exclusive_access_threaded) {
MemoryAccessThread thread;
thread.Start();
- MemoryAccess ldaxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w));
- MemoryAccess stlxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7);
+ MemoryAccess ldaxr_w(Kind::LoadAcqExcl, Size::Word, offsetof(TestData, w));
+ MemoryAccess stlxr_w(Kind::StoreRelExcl, Size::Word, offsetof(TestData, w),
+ 7);
// Exclusive store completed by another thread first.
test_data = TestData(1);
- thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word,
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadAcqExcl, Size::Word,
offsetof(TestData, w)));
ExecuteMemoryAccess(isolate, &test_data, ldaxr_w);
- thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word,
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreRelExcl, Size::Word,
offsetof(TestData, w), 5));
CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stlxr_w));
CHECK_EQ(5, test_data.w);
@@ -360,9 +437,9 @@ TEST(simulator_invalidate_exclusive_access_threaded) {
// to same
test_data = TestData(1);
ExecuteMemoryAccess(isolate, &test_data, ldaxr_w);
- thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word,
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadAcqExcl, Size::Word,
offsetof(TestData, dummy)));
- thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word,
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreRelExcl, Size::Word,
offsetof(TestData, dummy), 5));
CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stlxr_w));
CHECK_EQ(1, test_data.w);
@@ -379,6 +456,54 @@ TEST(simulator_invalidate_exclusive_access_threaded) {
thread.Join();
}
+TEST(simulator_invalidate_exclusive_access_threaded) {
+ using Kind = MemoryAccess::Kind;
+ using Size = MemoryAccess::Size;
+
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ TestData test_data(1);
+
+ MemoryAccessThread thread;
+ thread.Start();
+
+ MemoryAccess ldxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w));
+ MemoryAccess stxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7);
+
+ // Exclusive store completed by another thread first.
+ test_data = TestData(1);
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word,
+ offsetof(TestData, w)));
+ ExecuteMemoryAccess(isolate, &test_data, ldxr_w);
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word,
+ offsetof(TestData, w), 5));
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stxr_w));
+ CHECK_EQ(5, test_data.w);
+
+ // Exclusive store completed by another thread; different address, but masked
+ // to same
+ test_data = TestData(1);
+ ExecuteMemoryAccess(isolate, &test_data, ldxr_w);
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word,
+ offsetof(TestData, dummy)));
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word,
+ offsetof(TestData, dummy), 5));
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stxr_w));
+ CHECK_EQ(1, test_data.w);
+
+ // Test failure when store between ldxr/stxr.
+ test_data = TestData(1);
+ ExecuteMemoryAccess(isolate, &test_data, ldxr_w);
+ thread.NextAndWait(&test_data, MemoryAccess(Kind::Store, Size::Word,
+ offsetof(TestData, dummy)));
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stxr_w));
+ CHECK_EQ(1, test_data.w);
+
+ thread.Finish();
+ thread.Join();
+}
+
#undef __
#endif // USE_SIMULATOR
« src/arm64/decoder-arm64-inl.h ('K') | « test/cctest/test-disasm-arm64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698