diff options
Diffstat (limited to 'deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc | 119 |
1 files changed, 116 insertions, 3 deletions
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc index 57e82ecde3..b78cc71037 100644 --- a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc +++ b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/arm64/macro-assembler-arm64-inl.h" -#include "src/macro-assembler.h" -#include "src/simulator.h" +#include "src/codegen/arm64/macro-assembler-arm64-inl.h" +#include "src/codegen/macro-assembler.h" +#include "src/execution/simulator.h" +#include "src/utils/ostreams.h" #include "test/common/assembler-tester.h" #include "test/unittests/test-utils.h" #include "testing/gtest-support.h" @@ -69,6 +70,118 @@ TEST_F(TurboAssemblerTest, TestCheck) { ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, ERROR_MESSAGE("abort: no reason")); } +struct MoveObjectAndSlotTestCase { + const char* comment; + Register dst_object; + Register dst_slot; + Register object; + Register offset_register = no_reg; +}; + +const MoveObjectAndSlotTestCase kMoveObjectAndSlotTestCases[] = { + {"no overlap", x0, x1, x2}, + {"no overlap", x0, x1, x2, x3}, + + {"object == dst_object", x2, x1, x2}, + {"object == dst_object", x2, x1, x2, x3}, + + {"object == dst_slot", x1, x2, x2}, + {"object == dst_slot", x1, x2, x2, x3}, + + {"offset == dst_object", x0, x1, x2, x0}, + + {"offset == dst_object && object == dst_slot", x0, x1, x1, x0}, + + {"offset == dst_slot", x0, x1, x2, x1}, + + {"offset == dst_slot && object == dst_object", x0, x1, x0, x1}}; + +// Make sure we include offsets that cannot be encoded in an add instruction. +const int kOffsets[] = {0, 42, kMaxRegularHeapObjectSize, 0x101001}; + +template <typename T> +class TurboAssemblerTestWithParam : public TurboAssemblerTest, + public ::testing::WithParamInterface<T> {}; + +using TurboAssemblerTestMoveObjectAndSlot = + TurboAssemblerTestWithParam<MoveObjectAndSlotTestCase>; + +TEST_P(TurboAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) { + const MoveObjectAndSlotTestCase test_case = GetParam(); + TRACED_FOREACH(int32_t, offset, kOffsets) { + auto buffer = AllocateAssemblerBuffer(); + TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo, + buffer->CreateView()); + + __ Push(x0, padreg); + __ Mov(test_case.object, x1); + + Register src_object = test_case.object; + Register dst_object = test_case.dst_object; + Register dst_slot = test_case.dst_slot; + + Operand offset_operand(0); + if (test_case.offset_register.Is(no_reg)) { + offset_operand = Operand(offset); + } else { + __ Mov(test_case.offset_register, Operand(offset)); + offset_operand = Operand(test_case.offset_register); + } + + std::stringstream comment; + comment << "-- " << test_case.comment << ": MoveObjectAndSlot(" + << dst_object << ", " << dst_slot << ", " << src_object << ", "; + if (test_case.offset_register.Is(no_reg)) { + comment << "#" << offset; + } else { + comment << test_case.offset_register; + } + comment << ") --"; + __ RecordComment(comment.str().c_str()); + __ MoveObjectAndSlot(dst_object, dst_slot, src_object, offset_operand); + __ RecordComment("--"); + + // The `result` pointer was saved on the stack. + UseScratchRegisterScope temps(&tasm); + Register scratch = temps.AcquireX(); + __ Pop(padreg, scratch); + __ Str(dst_object, MemOperand(scratch)); + __ Str(dst_slot, MemOperand(scratch, kSystemPointerSize)); + + __ Ret(); + + CodeDesc desc; + tasm.GetCode(nullptr, &desc); + if (FLAG_print_code) { + Handle<Code> code = + Factory::CodeBuilder(isolate(), desc, Code::STUB).Build(); + StdoutStream os; + code->Print(os); + } + + buffer->MakeExecutable(); + // We need an isolate here to execute in the simulator. + auto f = GeneratedCode<void, byte**, byte*>::FromBuffer(isolate(), + buffer->start()); + + byte* object = new byte[offset]; + byte* result[] = {nullptr, nullptr}; + + f.Call(result, object); + + // The first element must be the address of the object, and the second the + // slot addressed by `offset`. + EXPECT_EQ(result[0], &object[0]); + EXPECT_EQ(result[1], &object[offset]); + + delete[] object; + } +} + +INSTANTIATE_TEST_SUITE_P(TurboAssemblerTest, + TurboAssemblerTestMoveObjectAndSlot, + ::testing::ValuesIn(kMoveObjectAndSlotTestCases)); + #undef __ #undef ERROR_MESSAGE |