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

Side by Side Diff: test/cctest/wasm/wasm-run-utils.h

Issue 1702023002: [wasm] Replace the BufferedRawMachineAssemblerTester in the WasmRunner. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Code cleanup. Created 4 years, 10 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 unified diff | Download patch
« no previous file with comments | « test/cctest/wasm/test-run-wasm-js.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #ifndef WASM_RUN_UTILS_H 5 #ifndef WASM_RUN_UTILS_H
6 #define WASM_RUN_UTILS_H 6 #define WASM_RUN_UTILS_H
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <string.h> 10 #include <string.h>
11 11
12 #include "src/base/utils/random-number-generator.h" 12 #include "src/base/utils/random-number-generator.h"
13 13
14 #include "src/compiler/graph-visualizer.h" 14 #include "src/compiler/graph-visualizer.h"
15 #include "src/compiler/int64-lowering.h" 15 #include "src/compiler/int64-lowering.h"
16 #include "src/compiler/js-graph.h" 16 #include "src/compiler/js-graph.h"
17 #include "src/compiler/node.h"
18 #include "src/compiler/pipeline.h"
17 #include "src/compiler/wasm-compiler.h" 19 #include "src/compiler/wasm-compiler.h"
18 20
19 #include "src/wasm/ast-decoder.h" 21 #include "src/wasm/ast-decoder.h"
20 #include "src/wasm/wasm-js.h" 22 #include "src/wasm/wasm-js.h"
21 #include "src/wasm/wasm-module.h" 23 #include "src/wasm/wasm-module.h"
22 #include "src/wasm/wasm-opcodes.h" 24 #include "src/wasm/wasm-opcodes.h"
23 25
26 #include "src/zone.h"
27
24 #include "test/cctest/cctest.h" 28 #include "test/cctest/cctest.h"
25 #include "test/cctest/compiler/codegen-tester.h" 29 #include "test/cctest/compiler/call-tester.h"
26 #include "test/cctest/compiler/graph-builder-tester.h" 30 #include "test/cctest/compiler/graph-builder-tester.h"
27 31
28 // TODO(titzer): pull WASM_64 up to a common header. 32 // TODO(titzer): pull WASM_64 up to a common header.
29 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 33 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
30 #define WASM_64 1 34 #define WASM_64 1
31 #else 35 #else
32 #define WASM_64 0 36 #define WASM_64 0
33 #endif 37 #endif
34 38
35 // TODO(titzer): check traps more robustly in tests. 39 // TODO(titzer): check traps more robustly in tests.
36 // Currently, in tests, we just return 0xdeadbeef from the function in which 40 // Currently, in tests, we just return 0xdeadbeef from the function in which
37 // the trap occurs if the runtime context is not available to throw a JavaScript 41 // the trap occurs if the runtime context is not available to throw a JavaScript
38 // exception. 42 // exception.
39 #define CHECK_TRAP32(x) \ 43 #define CHECK_TRAP32(x) \
40 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) 44 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF)
41 #define CHECK_TRAP64(x) \ 45 #define CHECK_TRAP64(x) \
42 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) 46 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
43 #define CHECK_TRAP(x) CHECK_TRAP32(x) 47 #define CHECK_TRAP(x) CHECK_TRAP32(x)
44 48
49 #define WASM_WRAPPER_RETURN_VALUE 8754
50
45 namespace { 51 namespace {
46 using namespace v8::base; 52 using namespace v8::base;
47 using namespace v8::internal; 53 using namespace v8::internal;
48 using namespace v8::internal::compiler; 54 using namespace v8::internal::compiler;
49 using namespace v8::internal::wasm; 55 using namespace v8::internal::wasm;
50 56
51 inline void init_env(FunctionEnv* env, FunctionSig* sig) { 57 inline void init_env(FunctionEnv* env, FunctionSig* sig) {
52 env->module = nullptr; 58 env->module = nullptr;
53 env->sig = sig; 59 env->sig = sig;
54 env->local_i32_count = 0; 60 env->local_i32_count = 0;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 str << ", msg = " << result.error_msg.get(); 245 str << ", msg = " << result.error_msg.get();
240 FATAL(str.str().c_str()); 246 FATAL(str.str().c_str());
241 } 247 }
242 builder.Int64LoweringForTesting(); 248 builder.Int64LoweringForTesting();
243 if (FLAG_trace_turbo_graph) { 249 if (FLAG_trace_turbo_graph) {
244 OFStream os(stdout); 250 OFStream os(stdout);
245 os << AsRPO(*jsgraph->graph()); 251 os << AsRPO(*jsgraph->graph());
246 } 252 }
247 } 253 }
248 254
255 template <typename ReturnType>
256 class WasmFunctionWrapper : public HandleAndZoneScope,
257 private GraphAndBuilders {
258 public:
259 WasmFunctionWrapper()
260 : GraphAndBuilders(main_zone()),
261 inner_code_node_(nullptr),
262 signature_(nullptr) {
263 Signature<MachineType>::Builder sig_builder(zone(), 1, 5);
264
265 sig_builder.AddReturn(MachineType::Int32());
266 for (int i = 0; i < 5; i++) {
267 sig_builder.AddParam(MachineType::Pointer());
268 }
269 signature_ = sig_builder.Build();
270 }
271
272 void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(),
273 MachineType p1 = MachineType::None(),
274 MachineType p2 = MachineType::None(),
275 MachineType p3 = MachineType::None()) {
276 // Create the TF graph for the wrapper. The wrapper always takes four
277 // pointers as parameters, but may not pass the values of all pointers to
278 // the actual test function.
279
280 // Function, effect, and control.
281 Node** parameters = zone()->template NewArray<Node*>(4 + 3);
282 graph()->SetStart(graph()->NewNode(common()->Start(6)));
283 Node* effect = graph()->start();
284 int parameter_count = 0;
285
286 // Dummy node which gets replaced in SetInnerCode.
287 inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
288 parameters[parameter_count++] = inner_code_node_;
289
290 if (p0 != MachineType::None()) {
291 parameters[parameter_count] = graph()->NewNode(
292 machine()->Load(p0),
293 graph()->NewNode(common()->Parameter(0), graph()->start()),
294 graph()->NewNode(common()->Int32Constant(0)), effect,
295 graph()->start());
296 effect = parameters[parameter_count++];
297 }
298 if (p1 != MachineType::None()) {
299 parameters[parameter_count] = graph()->NewNode(
300 machine()->Load(p0),
301 graph()->NewNode(common()->Parameter(1), graph()->start()),
302 graph()->NewNode(common()->Int32Constant(0)), effect,
303 graph()->start());
304 effect = parameters[parameter_count++];
305 }
306 if (p2 != MachineType::None()) {
307 parameters[parameter_count] = graph()->NewNode(
308 machine()->Load(p0),
309 graph()->NewNode(common()->Parameter(2), graph()->start()),
310 graph()->NewNode(common()->Int32Constant(0)), effect,
311 graph()->start());
312 effect = parameters[parameter_count++];
313 }
314 if (p3 != MachineType::None()) {
315 parameters[parameter_count] = graph()->NewNode(
316 machine()->Load(p0),
317 graph()->NewNode(common()->Parameter(3), graph()->start()),
318 graph()->NewNode(common()->Int32Constant(0)), effect,
319 graph()->start());
320 effect = parameters[parameter_count++];
321 }
322
323 parameters[parameter_count++] = effect;
324 parameters[parameter_count++] = graph()->start();
325 Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count,
326 parameters);
327
328 effect = graph()->NewNode(
329 machine()->Store(
330 StoreRepresentation(MachineTypeForC<ReturnType>().representation(),
331 WriteBarrierKind::kNoWriteBarrier)),
332 graph()->NewNode(common()->Parameter(4), graph()->start()),
333 graph()->NewNode(common()->Int32Constant(0)), call, effect,
334 graph()->start());
335 Node* r = graph()->NewNode(
336 common()->Return(),
337 graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
338 effect, graph()->start());
339 graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start()));
340 }
341
342 void SetInnerCode(Handle<Code> code_handle) {
343 NodeProperties::ChangeOp(inner_code_node_,
344 common()->HeapConstant(code_handle));
345 }
346
347 Handle<Code> GetWrapperCode() {
348 if (code_.is_null()) {
349 Isolate* isolate = CcTest::InitIsolateOnce();
350
351 CallDescriptor* descriptor =
352 Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
353
354 CompilationInfo info("testing", isolate, graph()->zone());
355 code_ =
356 Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr);
357 CHECK(!code_.is_null());
358 #ifdef ENABLE_DISASSEMBLER
359 if (FLAG_print_opt_code) {
360 OFStream os(stdout);
361 code_->Disassemble("wasm wrapper", os);
362 }
363 #endif
364 }
365
366 return code_;
367 }
368
369 Signature<MachineType>* signature() const { return signature_; }
370
371 private:
372 Node* inner_code_node_;
373 Handle<Code> code_;
374 Signature<MachineType>* signature_;
375 };
249 376
250 // A helper for compiling functions that are only internally callable WASM code. 377 // A helper for compiling functions that are only internally callable WASM code.
251 class WasmFunctionCompiler : public HandleAndZoneScope, 378 class WasmFunctionCompiler : public HandleAndZoneScope,
252 private GraphAndBuilders { 379 private GraphAndBuilders {
253 public: 380 public:
254 explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr) 381 explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr)
255 : GraphAndBuilders(main_zone()), 382 : GraphAndBuilders(main_zone()),
256 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, 383 jsgraph(this->isolate(), this->graph(), this->common(), nullptr,
257 nullptr, this->machine()), 384 nullptr, this->machine()),
258 descriptor_(nullptr) { 385 descriptor_(nullptr) {
259 init_env(&env, sig); 386 init_env(&env, sig);
260 env.module = module; 387 env.module = module;
261 } 388 }
262 389
263 JSGraph jsgraph; 390 JSGraph jsgraph;
264 FunctionEnv env; 391 FunctionEnv env;
265 // The call descriptor is initialized when the function is compiled. 392 // The call descriptor is initialized when the function is compiled.
266 CallDescriptor* descriptor_; 393 CallDescriptor* descriptor_;
267 394
268 Isolate* isolate() { return main_isolate(); } 395 Isolate* isolate() { return main_isolate(); }
269 Graph* graph() const { return main_graph_; } 396 Graph* graph() const { return main_graph_; }
270 Zone* zone() const { return graph()->zone(); } 397 Zone* zone() const { return graph()->zone(); }
271 CommonOperatorBuilder* common() { return &main_common_; } 398 CommonOperatorBuilder* common() { return &main_common_; }
272 MachineOperatorBuilder* machine() { return &main_machine_; } 399 MachineOperatorBuilder* machine() { return &main_machine_; }
400 void InitializeDescriptor() {
401 if (descriptor_ == nullptr) {
402 descriptor_ = env.module->GetWasmCallDescriptor(main_zone(), env.sig);
403 }
404 }
273 CallDescriptor* descriptor() { return descriptor_; } 405 CallDescriptor* descriptor() { return descriptor_; }
274 406
275 void Build(const byte* start, const byte* end) { 407 void Build(const byte* start, const byte* end) {
276 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); 408 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end);
277 } 409 }
278 410
279 byte AllocateLocal(LocalType type) { 411 byte AllocateLocal(LocalType type) {
280 int result = static_cast<int>(env.total_locals); 412 int result = static_cast<int>(env.total_locals);
281 env.AddLocals(type, 1); 413 env.AddLocals(type, 1);
282 byte b = static_cast<byte>(result); 414 byte b = static_cast<byte>(result);
283 CHECK_EQ(result, b); 415 CHECK_EQ(result, b);
284 return b; 416 return b;
285 } 417 }
286 418
287 Handle<Code> Compile(ModuleEnv* module) { 419 Handle<Code> Compile(ModuleEnv* module) {
288 descriptor_ = module->GetWasmCallDescriptor(this->zone(), env.sig); 420 InitializeDescriptor();
289 CompilationInfo info("wasm compile", this->isolate(), this->zone()); 421 CompilationInfo info("wasm compile", this->isolate(), this->zone());
290 Handle<Code> result = 422 Handle<Code> result =
291 Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph()); 423 Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph());
292 #ifdef ENABLE_DISASSEMBLER 424 #ifdef ENABLE_DISASSEMBLER
293 if (!result.is_null() && FLAG_print_opt_code) { 425 if (!result.is_null() && FLAG_print_opt_code) {
294 OFStream os(stdout); 426 OFStream os(stdout);
295 result->Disassemble("wasm code", os); 427 result->Disassemble("wasm code", os);
296 } 428 }
297 #endif 429 #endif
298 430
(...skipping 17 matching lines...) Expand all
316 template <typename ReturnType> 448 template <typename ReturnType>
317 class WasmRunner { 449 class WasmRunner {
318 public: 450 public:
319 WasmRunner(MachineType p0 = MachineType::None(), 451 WasmRunner(MachineType p0 = MachineType::None(),
320 MachineType p1 = MachineType::None(), 452 MachineType p1 = MachineType::None(),
321 MachineType p2 = MachineType::None(), 453 MachineType p2 = MachineType::None(),
322 MachineType p3 = MachineType::None()) 454 MachineType p3 = MachineType::None())
323 : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1, 455 : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
324 GetParameterCount(p0, p1, p2, p3), storage_), 456 GetParameterCount(p0, p1, p2, p3), storage_),
325 compiler_(&signature_), 457 compiler_(&signature_),
326 call_wrapper_(p0, p1, p2, p3),
327 compilation_done_(false) { 458 compilation_done_(false) {
328 int index = 0; 459 int index = 0;
329 MachineType ret = MachineTypeForC<ReturnType>(); 460 MachineType ret = MachineTypeForC<ReturnType>();
330 if (ret != MachineType::None()) { 461 if (ret != MachineType::None()) {
331 storage_[index++] = WasmOpcodes::LocalTypeFor(ret); 462 storage_[index++] = WasmOpcodes::LocalTypeFor(ret);
332 } 463 }
333 if (p0 != MachineType::None()) 464 if (p0 != MachineType::None())
334 storage_[index++] = WasmOpcodes::LocalTypeFor(p0); 465 storage_[index++] = WasmOpcodes::LocalTypeFor(p0);
335 if (p1 != MachineType::None()) 466 if (p1 != MachineType::None())
336 storage_[index++] = WasmOpcodes::LocalTypeFor(p1); 467 storage_[index++] = WasmOpcodes::LocalTypeFor(p1);
337 if (p2 != MachineType::None()) 468 if (p2 != MachineType::None())
338 storage_[index++] = WasmOpcodes::LocalTypeFor(p2); 469 storage_[index++] = WasmOpcodes::LocalTypeFor(p2);
339 if (p3 != MachineType::None()) 470 if (p3 != MachineType::None())
340 storage_[index++] = WasmOpcodes::LocalTypeFor(p3); 471 storage_[index++] = WasmOpcodes::LocalTypeFor(p3);
472
473 compiler_.InitializeDescriptor();
474 wrapper_.Init(compiler_.descriptor(), p0, p1, p2, p3);
341 } 475 }
342 476
343 477
344 FunctionEnv* env() { return &compiler_.env; } 478 FunctionEnv* env() { return &compiler_.env; }
345 479
346 480
347 // Builds a graph from the given Wasm code, and generates the machine 481 // Builds a graph from the given Wasm code, and generates the machine
348 // code and call wrapper for that graph. This method must not be called 482 // code and call wrapper for that graph. This method must not be called
349 // more than once. 483 // more than once.
350 void Build(const byte* start, const byte* end) { 484 void Build(const byte* start, const byte* end) {
351 DCHECK(!compilation_done_); 485 DCHECK(!compilation_done_);
352 compilation_done_ = true; 486 compilation_done_ = true;
353 // Build the TF graph. 487 // Build the TF graph.
354 compiler_.Build(start, end); 488 compiler_.Build(start, end);
355 // Generate code. 489 // Generate code.
356 Handle<Code> code = compiler_.Compile(env()->module); 490 Handle<Code> code = compiler_.Compile(env()->module);
357 491
358 // Construct the call wrapper. 492 wrapper_.SetInnerCode(code);
359 Node* inputs[5];
360 int input_count = 0;
361 inputs[input_count++] = call_wrapper_.HeapConstant(code);
362 for (size_t i = 0; i < signature_.parameter_count(); i++) {
363 inputs[input_count++] = call_wrapper_.Parameter(i);
364 }
365
366 call_wrapper_.Return(call_wrapper_.AddNode(
367 call_wrapper_.common()->Call(compiler_.descriptor()), input_count,
368 inputs));
369 } 493 }
370 494
371 ReturnType Call() { return call_wrapper_.Call(); } 495 ReturnType Call() { return Call(nullptr, nullptr, nullptr, nullptr); }
372 496
373 template <typename P0> 497 template <typename P0>
374 ReturnType Call(P0 p0) { 498 ReturnType Call(P0 p0) {
375 return call_wrapper_.Call(p0); 499 return Call(p0, nullptr, nullptr, nullptr);
376 } 500 }
377 501
378 template <typename P0, typename P1> 502 template <typename P0, typename P1>
379 ReturnType Call(P0 p0, P1 p1) { 503 ReturnType Call(P0 p0, P1 p1) {
380 return call_wrapper_.Call(p0, p1); 504 return Call(p0, p1, nullptr, nullptr);
381 } 505 }
382 506
383 template <typename P0, typename P1, typename P2> 507 template <typename P0, typename P1, typename P2>
384 ReturnType Call(P0 p0, P1 p1, P2 p2) { 508 ReturnType Call(P0 p0, P1 p1, P2 p2) {
385 return call_wrapper_.Call(p0, p1, p2); 509 return Call(p0, p1, p2, nullptr);
386 } 510 }
387 511
388 template <typename P0, typename P1, typename P2, typename P3> 512 template <typename P0, typename P1, typename P2, typename P3>
389 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { 513 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
390 return call_wrapper_.Call(p0, p1, p2, p3); 514 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
515 wrapper_.GetWrapperCode(), wrapper_.signature());
516 ReturnType return_value;
517 int32_t result = runner.Call<void*, void*, void*, void*, void*>(
518 &p0, &p1, &p2, &p3, &return_value);
519 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
520 return return_value;
391 } 521 }
392 522
393 byte AllocateLocal(LocalType type) { 523 byte AllocateLocal(LocalType type) {
394 int result = static_cast<int>(env()->total_locals); 524 int result = static_cast<int>(env()->total_locals);
395 env()->AddLocals(type, 1); 525 env()->AddLocals(type, 1);
396 byte b = static_cast<byte>(result); 526 byte b = static_cast<byte>(result);
397 CHECK_EQ(result, b); 527 CHECK_EQ(result, b);
398 return b; 528 return b;
399 } 529 }
400 530
401 private: 531 private:
402 LocalType storage_[5]; 532 LocalType storage_[5];
403 FunctionSig signature_; 533 FunctionSig signature_;
404 WasmFunctionCompiler compiler_; 534 WasmFunctionCompiler compiler_;
405 BufferedRawMachineAssemblerTester<ReturnType> call_wrapper_; 535 WasmFunctionWrapper<ReturnType> wrapper_;
406 bool compilation_done_; 536 bool compilation_done_;
407 537
408 static size_t GetParameterCount(MachineType p0, MachineType p1, 538 static size_t GetParameterCount(MachineType p0, MachineType p1,
409 MachineType p2, MachineType p3) { 539 MachineType p2, MachineType p3) {
410 if (p0 == MachineType::None()) return 0; 540 if (p0 == MachineType::None()) return 0;
411 if (p1 == MachineType::None()) return 1; 541 if (p1 == MachineType::None()) return 1;
412 if (p2 == MachineType::None()) return 2; 542 if (p2 == MachineType::None()) return 2;
413 if (p3 == MachineType::None()) return 3; 543 if (p3 == MachineType::None()) return 3;
414 return 4; 544 return 4;
415 } 545 }
416 }; 546 };
417 547
418 } // namespace 548 } // namespace
419 549
420 #endif 550 #endif
OLDNEW
« no previous file with comments | « test/cctest/wasm/test-run-wasm-js.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698