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 |