OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. |
| 4 |
| 5 #include <cmath> |
| 6 #include <functional> |
| 7 #include <limits> |
| 8 |
| 9 #include "src/base/bits.h" |
| 10 #include "src/base/utils/random-number-generator.h" |
| 11 #include "src/codegen.h" |
| 12 #include "test/cctest/cctest.h" |
| 13 #include "test/cctest/compiler/codegen-tester.h" |
| 14 #include "test/cctest/compiler/graph-builder-tester.h" |
| 15 #include "test/cctest/compiler/value-helper.h" |
| 16 |
| 17 using namespace v8::internal; |
| 18 using namespace v8::internal::compiler; |
| 19 |
| 20 static void UpdateMemoryReferences(Handle<Code> code, Address old_base, |
| 21 Address new_base, size_t old_size, |
| 22 size_t new_size) { |
| 23 Isolate* isolate = CcTest::i_isolate(); |
| 24 bool modified = false; |
| 25 int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE); |
| 26 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { |
| 27 RelocInfo::Mode mode = it.rinfo()->rmode(); |
| 28 if (RelocInfo::IsWasmMemoryReference(mode)) { |
| 29 // Patch addresses with change in memory start address |
| 30 it.rinfo()->update_wasm_memory_reference(old_base, new_base, old_size, |
| 31 new_size); |
| 32 modified = true; |
| 33 } |
| 34 } |
| 35 if (modified) { |
| 36 Assembler::FlushICache(isolate, code->instruction_start(), |
| 37 code->instruction_size()); |
| 38 } |
| 39 } |
| 40 |
| 41 template <typename CType> |
| 42 static void RunLoadStoreRelocation(MachineType rep) { |
| 43 const int kNumElems = 2; |
| 44 CType buffer[kNumElems]; |
| 45 CType new_buffer[kNumElems]; |
| 46 byte* raw = reinterpret_cast<byte*>(buffer); |
| 47 byte* new_raw = reinterpret_cast<byte*>(new_buffer); |
| 48 for (size_t i = 0; i < sizeof(buffer); i++) { |
| 49 raw[i] = static_cast<byte>((i + sizeof(CType)) ^ 0xAA); |
| 50 new_raw[i] = static_cast<byte>((i + sizeof(CType)) ^ 0xAA); |
| 51 } |
| 52 int32_t OK = 0x29000; |
| 53 RawMachineAssemblerTester<uint32_t> m; |
| 54 Node* base = m.RelocatableIntPtrConstant(reinterpret_cast<intptr_t>(raw), |
| 55 RelocInfo::WASM_MEMORY_REFERENCE); |
| 56 Node* base1 = m.RelocatableIntPtrConstant( |
| 57 reinterpret_cast<intptr_t>(raw + sizeof(CType)), |
| 58 RelocInfo::WASM_MEMORY_REFERENCE); |
| 59 Node* index = m.Int32Constant(0); |
| 60 Node* load = m.Load(rep, base, index); |
| 61 m.Store(rep.representation(), base1, index, load, kNoWriteBarrier); |
| 62 m.Return(m.Int32Constant(OK)); |
| 63 CHECK(buffer[0] != buffer[1]); |
| 64 CHECK_EQ(OK, m.Call()); |
| 65 CHECK(buffer[0] == buffer[1]); |
| 66 m.GenerateCode(); |
| 67 Handle<Code> code = m.GetCode(); |
| 68 UpdateMemoryReferences(code, raw, new_raw, sizeof(buffer), |
| 69 sizeof(new_buffer)); |
| 70 CHECK(new_buffer[0] != new_buffer[1]); |
| 71 CHECK_EQ(OK, m.Call()); |
| 72 CHECK(new_buffer[0] == new_buffer[1]); |
| 73 } |
| 74 |
| 75 TEST(RunLoadStoreRelocation) { |
| 76 RunLoadStoreRelocation<int8_t>(MachineType::Int8()); |
| 77 RunLoadStoreRelocation<uint8_t>(MachineType::Uint8()); |
| 78 RunLoadStoreRelocation<int16_t>(MachineType::Int16()); |
| 79 RunLoadStoreRelocation<uint16_t>(MachineType::Uint16()); |
| 80 RunLoadStoreRelocation<int32_t>(MachineType::Int32()); |
| 81 RunLoadStoreRelocation<uint32_t>(MachineType::Uint32()); |
| 82 RunLoadStoreRelocation<void*>(MachineType::AnyTagged()); |
| 83 RunLoadStoreRelocation<float>(MachineType::Float32()); |
| 84 RunLoadStoreRelocation<double>(MachineType::Float64()); |
| 85 } |
| 86 |
| 87 template <typename CType> |
| 88 static void RunLoadStoreRelocationOffset(MachineType rep) { |
| 89 RawMachineAssemblerTester<int32_t> r(MachineType::Int32()); |
| 90 const int kNumElems = 4; |
| 91 CType buffer[kNumElems]; |
| 92 CType new_buffer[kNumElems + 1]; |
| 93 |
| 94 for (int32_t x = 0; x < kNumElems; x++) { |
| 95 int32_t y = kNumElems - x - 1; |
| 96 // initialize the buffer with raw data. |
| 97 byte* raw = reinterpret_cast<byte*>(buffer); |
| 98 for (size_t i = 0; i < sizeof(buffer); i++) { |
| 99 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); |
| 100 } |
| 101 |
| 102 RawMachineAssemblerTester<int32_t> m; |
| 103 int32_t OK = 0x29000 + x; |
| 104 Node* base = m.RelocatableIntPtrConstant(reinterpret_cast<intptr_t>(buffer), |
| 105 RelocInfo::WASM_MEMORY_REFERENCE); |
| 106 Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); |
| 107 Node* load = m.Load(rep, base, index0); |
| 108 Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); |
| 109 m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); |
| 110 m.Return(m.Int32Constant(OK)); |
| 111 |
| 112 CHECK(buffer[x] != buffer[y]); |
| 113 CHECK_EQ(OK, m.Call()); |
| 114 CHECK(buffer[x] == buffer[y]); |
| 115 m.GenerateCode(); |
| 116 |
| 117 // Initialize new buffer and set old_buffer to 0 |
| 118 byte* new_raw = reinterpret_cast<byte*>(new_buffer); |
| 119 for (size_t i = 0; i < sizeof(buffer); i++) { |
| 120 raw[i] = 0; |
| 121 new_raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); |
| 122 } |
| 123 |
| 124 // Perform relocation on generated code |
| 125 Handle<Code> code = m.GetCode(); |
| 126 UpdateMemoryReferences(code, raw, new_raw, sizeof(buffer), |
| 127 sizeof(new_buffer)); |
| 128 |
| 129 CHECK(new_buffer[x] != new_buffer[y]); |
| 130 CHECK_EQ(OK, m.Call()); |
| 131 CHECK(new_buffer[x] == new_buffer[y]); |
| 132 } |
| 133 } |
| 134 |
| 135 TEST(RunLoadStoreRelocationOffset) { |
| 136 RunLoadStoreRelocationOffset<int8_t>(MachineType::Int8()); |
| 137 RunLoadStoreRelocationOffset<uint8_t>(MachineType::Uint8()); |
| 138 RunLoadStoreRelocationOffset<int16_t>(MachineType::Int16()); |
| 139 RunLoadStoreRelocationOffset<uint16_t>(MachineType::Uint16()); |
| 140 RunLoadStoreRelocationOffset<int32_t>(MachineType::Int32()); |
| 141 RunLoadStoreRelocationOffset<uint32_t>(MachineType::Uint32()); |
| 142 RunLoadStoreRelocationOffset<void*>(MachineType::AnyTagged()); |
| 143 RunLoadStoreRelocationOffset<float>(MachineType::Float32()); |
| 144 RunLoadStoreRelocationOffset<double>(MachineType::Float64()); |
| 145 } |
OLD | NEW |