OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "src/base/utils/random-number-generator.h" | 9 #include "src/base/utils/random-number-generator.h" |
10 | 10 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 if (module == nullptr) { | 190 if (module == nullptr) { |
191 module = new WasmModule(); | 191 module = new WasmModule(); |
192 module->globals = nullptr; | 192 module->globals = nullptr; |
193 module->functions = nullptr; | 193 module->functions = nullptr; |
194 module->data_segments = nullptr; | 194 module->data_segments = nullptr; |
195 } | 195 } |
196 } | 196 } |
197 }; | 197 }; |
198 | 198 |
199 | 199 |
200 static void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, FunctionEnv* env, | |
201 const byte* start, const byte* end) { | |
202 compiler::WasmGraphBuilder builder(zone, jsgraph, env->sig); | |
203 TreeResult result = BuildTFGraph(&builder, env, start, end); | |
204 if (result.failed()) { | |
205 ptrdiff_t pc = result.error_pc - result.start; | |
206 ptrdiff_t pt = result.error_pt - result.start; | |
207 std::ostringstream str; | |
208 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
209 if (result.error_pt) str << ", pt = +" << pt; | |
210 str << ", msg = " << result.error_msg.get(); | |
211 FATAL(str.str().c_str()); | |
212 } | |
213 if (FLAG_trace_turbo_graph) { | |
214 OFStream os(stdout); | |
215 os << AsRPO(*jsgraph->graph()); | |
216 } | |
217 } | |
218 | |
219 | |
200 // A helper for compiling functions that are only internally callable WASM code. | 220 // A helper for compiling functions that are only internally callable WASM code. |
201 class WasmFunctionCompiler : public HandleAndZoneScope, | 221 class WasmFunctionCompiler : public HandleAndZoneScope, |
202 private GraphAndBuilders { | 222 private GraphAndBuilders { |
203 public: | 223 public: |
204 explicit WasmFunctionCompiler(FunctionSig* sig) | 224 explicit WasmFunctionCompiler(FunctionSig* sig) |
205 : GraphAndBuilders(main_zone()), | 225 : GraphAndBuilders(main_zone()), |
206 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, | 226 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, |
207 nullptr, this->machine()), | 227 nullptr, this->machine()), |
208 descriptor_(nullptr) { | 228 descriptor_(nullptr) { |
209 init_env(&env, sig); | 229 init_env(&env, sig); |
210 } | 230 } |
211 | 231 |
212 JSGraph jsgraph; | 232 JSGraph jsgraph; |
213 FunctionEnv env; | 233 FunctionEnv env; |
214 // The call descriptor is initialized when the function is compiled. | 234 // The call descriptor is initialized when the function is compiled. |
215 CallDescriptor* descriptor_; | 235 CallDescriptor* descriptor_; |
216 | 236 |
217 Isolate* isolate() { return main_isolate(); } | 237 Isolate* isolate() { return main_isolate(); } |
218 Graph* graph() const { return main_graph_; } | 238 Graph* graph() const { return main_graph_; } |
219 Zone* zone() const { return graph()->zone(); } | 239 Zone* zone() const { return graph()->zone(); } |
220 CommonOperatorBuilder* common() { return &main_common_; } | 240 CommonOperatorBuilder* common() { return &main_common_; } |
221 MachineOperatorBuilder* machine() { return &main_machine_; } | 241 MachineOperatorBuilder* machine() { return &main_machine_; } |
222 CallDescriptor* descriptor() { return descriptor_; } | 242 CallDescriptor* descriptor() { return descriptor_; } |
223 | 243 |
224 void Build(const byte* start, const byte* end) { | 244 void Build(const byte* start, const byte* end) { |
225 compiler::WasmGraphBuilder builder(main_zone(), &jsgraph, env.sig); | 245 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); |
226 TreeResult result = BuildTFGraph(&builder, &env, start, end); | |
227 if (result.failed()) { | |
228 ptrdiff_t pc = result.error_pc - result.start; | |
229 ptrdiff_t pt = result.error_pt - result.start; | |
230 std::ostringstream str; | |
231 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
232 if (result.error_pt) str << ", pt = +" << pt; | |
233 str << ", msg = " << result.error_msg.get(); | |
234 FATAL(str.str().c_str()); | |
235 } | |
236 if (FLAG_trace_turbo_graph) { | |
237 OFStream os(stdout); | |
238 os << AsRPO(*jsgraph.graph()); | |
239 } | |
240 } | 246 } |
241 | 247 |
242 byte AllocateLocal(LocalType type) { | 248 byte AllocateLocal(LocalType type) { |
243 int result = static_cast<int>(env.total_locals); | 249 int result = static_cast<int>(env.total_locals); |
244 env.AddLocals(type, 1); | 250 env.AddLocals(type, 1); |
245 byte b = static_cast<byte>(result); | 251 byte b = static_cast<byte>(result); |
246 CHECK_EQ(result, b); | 252 CHECK_EQ(result, b); |
247 return b; | 253 return b; |
248 } | 254 } |
249 | 255 |
(...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2288 | 2294 |
2289 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { | 2295 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { |
2290 WasmRunner<int32_t> r(MachineType::Int32()); | 2296 WasmRunner<int32_t> r(MachineType::Int32()); |
2291 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), | 2297 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), |
2292 WASM_INFINITE_LOOP)); | 2298 WASM_INFINITE_LOOP)); |
2293 // Run the code, but don't go into the infinite loop. | 2299 // Run the code, but don't go into the infinite loop. |
2294 CHECK_EQ(45, r.Call(1)); | 2300 CHECK_EQ(45, r.Call(1)); |
2295 } | 2301 } |
2296 | 2302 |
2297 | 2303 |
2298 // TODO(titzer): Fix for nosee4 and re-enable. | 2304 static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { |
2299 #if 0 | 2305 if (!WasmOpcodes::IsSupported(opcode)) return; |
2300 | 2306 |
2301 static void TestBuildGraphForUnop(WasmOpcode opcode, FunctionSig* sig) { | 2307 Zone zone; |
2302 WasmRunner<int32_t> r(MachineType::Int32()); | 2308 Isolate* isolate = CcTest::InitIsolateOnce(); |
2303 init_env(r.env(), sig); | 2309 HandleScope scope(isolate); |
2304 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0); | 2310 // Enable all optional operators. |
2305 } | 2311 CommonOperatorBuilder common(&zone); |
2312 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), | |
2313 MachineOperatorBuilder::kAllOptionalOps); | |
2314 Graph graph(&zone); | |
2315 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | |
2316 FunctionEnv env; | |
2317 FunctionSig* sig = WasmOpcodes::Signature(opcode); | |
2318 init_env(&env, sig); | |
2306 | 2319 |
2307 | 2320 if (sig->parameter_count() == 1) { |
2308 static void TestBuildGraphForBinop(WasmOpcode opcode, FunctionSig* sig) { | 2321 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0}; |
2309 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); | 2322 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); |
2310 init_env(r.env(), sig); | 2323 } else { |
Michael Starzinger
2016/01/07 14:44:34
suggestion: Would a DCHECK_EQ(2, sig->parameter_co
| |
2311 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, 1); | 2324 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, |
2325 1}; | |
2326 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); | |
2327 } | |
2312 } | 2328 } |
2313 | 2329 |
2314 | 2330 |
2315 TEST(Build_Wasm_SimpleExprs) { | 2331 TEST(Build_Wasm_SimpleExprs) { |
2316 // Test that the decoder can build a graph for all supported simple expressions. | 2332 // Test that the decoder can build a graph for all supported simple expressions. |
2317 #define GRAPH_BUILD_TEST(name, opcode, sig) \ | 2333 #define GRAPH_BUILD_TEST(name, opcode, sig) \ |
2318 if (WasmOpcodes::IsSupported(kExpr##name)) { \ | 2334 TestBuildGraphForSimpleExpression(kExpr##name); |
2319 FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \ | |
2320 printf("expression: " #name "\n"); \ | |
2321 if (sig->parameter_count() == 1) { \ | |
2322 TestBuildGraphForUnop(kExpr##name, sig); \ | |
2323 } else { \ | |
2324 TestBuildGraphForBinop(kExpr##name, sig); \ | |
2325 } \ | |
2326 } | |
2327 | 2335 |
2328 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); | 2336 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); |
2329 | 2337 |
2330 #undef GRAPH_BUILD_TEST | 2338 #undef GRAPH_BUILD_TEST |
2331 } | 2339 } |
2332 | 2340 |
2333 #endif | |
2334 | |
2335 | 2341 |
2336 TEST(Run_Wasm_Int32LoadInt8_signext) { | 2342 TEST(Run_Wasm_Int32LoadInt8_signext) { |
2337 TestingModule module; | 2343 TestingModule module; |
2338 const int kNumElems = 16; | 2344 const int kNumElems = 16; |
2339 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); | 2345 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); |
2340 module.RandomizeMemory(); | 2346 module.RandomizeMemory(); |
2341 memory[0] = -1; | 2347 memory[0] = -1; |
2342 WasmRunner<int32_t> r(MachineType::Int32()); | 2348 WasmRunner<int32_t> r(MachineType::Int32()); |
2343 r.env()->module = &module; | 2349 r.env()->module = &module; |
2344 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); | 2350 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3567 TEST(Run_Wasm_F32CopySign) { | 3573 TEST(Run_Wasm_F32CopySign) { |
3568 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); | 3574 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); |
3569 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 3575 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
3570 | 3576 |
3571 FOR_FLOAT32_INPUTS(i) { | 3577 FOR_FLOAT32_INPUTS(i) { |
3572 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } | 3578 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } |
3573 } | 3579 } |
3574 } | 3580 } |
3575 | 3581 |
3576 #endif | 3582 #endif |
OLD | NEW |