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

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: Avoid null pointer in Windows. 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
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.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 str << ", msg = " << result.error_msg.get(); 243 str << ", msg = " << result.error_msg.get();
240 FATAL(str.str().c_str()); 244 FATAL(str.str().c_str());
241 } 245 }
242 builder.Int64LoweringForTesting(); 246 builder.Int64LoweringForTesting();
243 if (FLAG_trace_turbo_graph) { 247 if (FLAG_trace_turbo_graph) {
244 OFStream os(stdout); 248 OFStream os(stdout);
245 os << AsRPO(*jsgraph->graph()); 249 os << AsRPO(*jsgraph->graph());
246 } 250 }
247 } 251 }
248 252
253 template <typename ReturnType>
254 class WasmFunctionWrapper : public HandleAndZoneScope,
255 private GraphAndBuilders {
256 public:
257 WasmFunctionWrapper()
258 : GraphAndBuilders(main_zone()),
259 inner_code_node_(nullptr),
260 signature_(nullptr) {
261 Signature<MachineType>::Builder sig_builder(zone(), 1, 5);
262
263 sig_builder.AddReturn(MachineType::Int32());
264 for (int i = 0; i < 5; i++) {
265 sig_builder.AddParam(MachineType::Pointer());
266 }
267 signature_ = sig_builder.Build();
268 }
269
270 void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(),
271 MachineType p1 = MachineType::None(),
272 MachineType p2 = MachineType::None(),
273 MachineType p3 = MachineType::None()) {
274 // Create the TF graph for the wrapper. The wrapper always takes four
275 // pointers as parameters, but may not pass the values of all pointers to
276 // the actual test function.
277
278 // Function, effect, and control.
279 Node** parameters = zone()->template NewArray<Node*>(4 + 3);
280 graph()->SetStart(graph()->NewNode(common()->Start(6)));
281 Node* effect = graph()->start();
282 int parameter_count = 0;
283
284 // Dummy node which gets replaced in SetInnerCode.
285 inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
286 parameters[parameter_count++] = inner_code_node_;
287
288 if (p0 != MachineType::None()) {
289 parameters[parameter_count] = graph()->NewNode(
290 machine()->Load(p0),
291 graph()->NewNode(common()->Parameter(0), graph()->start()),
292 graph()->NewNode(common()->Int32Constant(0)), effect,
293 graph()->start());
294 effect = parameters[parameter_count++];
295 }
296 if (p1 != MachineType::None()) {
297 parameters[parameter_count] = graph()->NewNode(
298 machine()->Load(p0),
299 graph()->NewNode(common()->Parameter(1), graph()->start()),
300 graph()->NewNode(common()->Int32Constant(0)), effect,
301 graph()->start());
302 effect = parameters[parameter_count++];
303 }
304 if (p2 != MachineType::None()) {
305 parameters[parameter_count] = graph()->NewNode(
306 machine()->Load(p0),
307 graph()->NewNode(common()->Parameter(2), graph()->start()),
308 graph()->NewNode(common()->Int32Constant(0)), effect,
309 graph()->start());
310 effect = parameters[parameter_count++];
311 }
312 if (p3 != MachineType::None()) {
313 parameters[parameter_count] = graph()->NewNode(
314 machine()->Load(p0),
315 graph()->NewNode(common()->Parameter(3), graph()->start()),
316 graph()->NewNode(common()->Int32Constant(0)), effect,
317 graph()->start());
318 effect = parameters[parameter_count++];
319 }
320
321 parameters[parameter_count++] = effect;
322 parameters[parameter_count++] = graph()->start();
323 Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count,
324 parameters);
325
326 effect = graph()->NewNode(
327 machine()->Store(
328 StoreRepresentation(MachineTypeForC<ReturnType>().representation(),
329 WriteBarrierKind::kNoWriteBarrier)),
330 graph()->NewNode(common()->Parameter(4), graph()->start()),
331 graph()->NewNode(common()->Int32Constant(0)), call, effect,
332 graph()->start());
333 Node* r = graph()->NewNode(common()->Return(),
334 graph()->NewNode(common()->Int32Constant(7654)),
335 effect, graph()->start());
336 graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start()));
337 }
338
339 void SetInnerCode(Handle<Code> code_handle) {
340 NodeProperties::ChangeOp(inner_code_node_,
341 common()->HeapConstant(code_handle));
342 }
343
344 Handle<Code> GetWrapperCode() {
345 if (code_.is_null()) {
346 Isolate* isolate = CcTest::InitIsolateOnce();
347
348 CallDescriptor* descriptor =
349 Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
350
351 CompilationInfo info("testing", isolate, graph()->zone());
352 code_ =
353 Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr);
354 CHECK(!code_.is_null());
355 #ifdef ENABLE_DISASSEMBLER
356 if (FLAG_print_opt_code) {
357 OFStream os(stdout);
358 code_->Disassemble("wasm wrapper", os);
359 }
360 #endif
361 }
362
363 return code_;
364 }
365
366 Signature<MachineType>* signature() const { return signature_; }
367
368 private:
369 Node* inner_code_node_;
370 Handle<Code> code_;
371 Signature<MachineType>* signature_;
372 };
249 373
250 // A helper for compiling functions that are only internally callable WASM code. 374 // A helper for compiling functions that are only internally callable WASM code.
251 class WasmFunctionCompiler : public HandleAndZoneScope, 375 class WasmFunctionCompiler : public HandleAndZoneScope,
252 private GraphAndBuilders { 376 private GraphAndBuilders {
253 public: 377 public:
254 explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr) 378 explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr)
255 : GraphAndBuilders(main_zone()), 379 : GraphAndBuilders(main_zone()),
256 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, 380 jsgraph(this->isolate(), this->graph(), this->common(), nullptr,
257 nullptr, this->machine()), 381 nullptr, this->machine()),
258 descriptor_(nullptr) { 382 descriptor_(nullptr) {
259 init_env(&env, sig); 383 init_env(&env, sig);
260 env.module = module; 384 env.module = module;
261 } 385 }
262 386
263 JSGraph jsgraph; 387 JSGraph jsgraph;
264 FunctionEnv env; 388 FunctionEnv env;
265 // The call descriptor is initialized when the function is compiled. 389 // The call descriptor is initialized when the function is compiled.
266 CallDescriptor* descriptor_; 390 CallDescriptor* descriptor_;
267 391
268 Isolate* isolate() { return main_isolate(); } 392 Isolate* isolate() { return main_isolate(); }
269 Graph* graph() const { return main_graph_; } 393 Graph* graph() const { return main_graph_; }
270 Zone* zone() const { return graph()->zone(); } 394 Zone* zone() const { return graph()->zone(); }
271 CommonOperatorBuilder* common() { return &main_common_; } 395 CommonOperatorBuilder* common() { return &main_common_; }
272 MachineOperatorBuilder* machine() { return &main_machine_; } 396 MachineOperatorBuilder* machine() { return &main_machine_; }
397 void InitializeDescriptor() {
398 if (descriptor_ == nullptr) {
399 descriptor_ = env.module->GetWasmCallDescriptor(main_zone(), env.sig);
400 }
401 }
273 CallDescriptor* descriptor() { return descriptor_; } 402 CallDescriptor* descriptor() { return descriptor_; }
274 403
275 void Build(const byte* start, const byte* end) { 404 void Build(const byte* start, const byte* end) {
276 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); 405 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end);
277 } 406 }
278 407
279 byte AllocateLocal(LocalType type) { 408 byte AllocateLocal(LocalType type) {
280 int result = static_cast<int>(env.total_locals); 409 int result = static_cast<int>(env.total_locals);
281 env.AddLocals(type, 1); 410 env.AddLocals(type, 1);
282 byte b = static_cast<byte>(result); 411 byte b = static_cast<byte>(result);
283 CHECK_EQ(result, b); 412 CHECK_EQ(result, b);
284 return b; 413 return b;
285 } 414 }
286 415
287 Handle<Code> Compile(ModuleEnv* module) { 416 Handle<Code> Compile(ModuleEnv* module) {
288 descriptor_ = module->GetWasmCallDescriptor(this->zone(), env.sig); 417 InitializeDescriptor();
289 CompilationInfo info("wasm compile", this->isolate(), this->zone()); 418 CompilationInfo info("wasm compile", this->isolate(), this->zone());
290 Handle<Code> result = 419 Handle<Code> result =
291 Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph()); 420 Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph());
292 #ifdef ENABLE_DISASSEMBLER 421 #ifdef ENABLE_DISASSEMBLER
293 if (!result.is_null() && FLAG_print_opt_code) { 422 if (!result.is_null() && FLAG_print_opt_code) {
294 OFStream os(stdout); 423 OFStream os(stdout);
295 result->Disassemble("wasm code", os); 424 result->Disassemble("wasm code", os);
296 } 425 }
297 #endif 426 #endif
298 427
(...skipping 17 matching lines...) Expand all
316 template <typename ReturnType> 445 template <typename ReturnType>
317 class WasmRunner { 446 class WasmRunner {
318 public: 447 public:
319 WasmRunner(MachineType p0 = MachineType::None(), 448 WasmRunner(MachineType p0 = MachineType::None(),
320 MachineType p1 = MachineType::None(), 449 MachineType p1 = MachineType::None(),
321 MachineType p2 = MachineType::None(), 450 MachineType p2 = MachineType::None(),
322 MachineType p3 = MachineType::None()) 451 MachineType p3 = MachineType::None())
323 : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1, 452 : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
324 GetParameterCount(p0, p1, p2, p3), storage_), 453 GetParameterCount(p0, p1, p2, p3), storage_),
325 compiler_(&signature_), 454 compiler_(&signature_),
326 call_wrapper_(p0, p1, p2, p3),
327 compilation_done_(false) { 455 compilation_done_(false) {
328 int index = 0; 456 int index = 0;
329 MachineType ret = MachineTypeForC<ReturnType>(); 457 MachineType ret = MachineTypeForC<ReturnType>();
330 if (ret != MachineType::None()) { 458 if (ret != MachineType::None()) {
331 storage_[index++] = WasmOpcodes::LocalTypeFor(ret); 459 storage_[index++] = WasmOpcodes::LocalTypeFor(ret);
332 } 460 }
333 if (p0 != MachineType::None()) 461 if (p0 != MachineType::None())
334 storage_[index++] = WasmOpcodes::LocalTypeFor(p0); 462 storage_[index++] = WasmOpcodes::LocalTypeFor(p0);
335 if (p1 != MachineType::None()) 463 if (p1 != MachineType::None())
336 storage_[index++] = WasmOpcodes::LocalTypeFor(p1); 464 storage_[index++] = WasmOpcodes::LocalTypeFor(p1);
337 if (p2 != MachineType::None()) 465 if (p2 != MachineType::None())
338 storage_[index++] = WasmOpcodes::LocalTypeFor(p2); 466 storage_[index++] = WasmOpcodes::LocalTypeFor(p2);
339 if (p3 != MachineType::None()) 467 if (p3 != MachineType::None())
340 storage_[index++] = WasmOpcodes::LocalTypeFor(p3); 468 storage_[index++] = WasmOpcodes::LocalTypeFor(p3);
469
470 compiler_.InitializeDescriptor();
471 wrapper_.Init(compiler_.descriptor(), p0, p1, p2, p3);
341 } 472 }
342 473
343 474
344 FunctionEnv* env() { return &compiler_.env; } 475 FunctionEnv* env() { return &compiler_.env; }
345 476
346 477
347 // Builds a graph from the given Wasm code, and generates the machine 478 // 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 479 // code and call wrapper for that graph. This method must not be called
349 // more than once. 480 // more than once.
350 void Build(const byte* start, const byte* end) { 481 void Build(const byte* start, const byte* end) {
351 DCHECK(!compilation_done_); 482 DCHECK(!compilation_done_);
352 compilation_done_ = true; 483 compilation_done_ = true;
353 // Build the TF graph. 484 // Build the TF graph.
354 compiler_.Build(start, end); 485 compiler_.Build(start, end);
355 // Generate code. 486 // Generate code.
356 Handle<Code> code = compiler_.Compile(env()->module); 487 Handle<Code> code = compiler_.Compile(env()->module);
357 488
358 // Construct the call wrapper. 489 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 } 490 }
370 491
371 ReturnType Call() { return call_wrapper_.Call(); } 492 ReturnType Call() { return Call(nullptr, nullptr, nullptr, nullptr); }
372 493
373 template <typename P0> 494 template <typename P0>
374 ReturnType Call(P0 p0) { 495 ReturnType Call(P0 p0) {
375 return call_wrapper_.Call(p0); 496 return Call(p0, nullptr, nullptr, nullptr);
376 } 497 }
377 498
378 template <typename P0, typename P1> 499 template <typename P0, typename P1>
379 ReturnType Call(P0 p0, P1 p1) { 500 ReturnType Call(P0 p0, P1 p1) {
380 return call_wrapper_.Call(p0, p1); 501 return Call(p0, p1, nullptr, nullptr);
381 } 502 }
382 503
383 template <typename P0, typename P1, typename P2> 504 template <typename P0, typename P1, typename P2>
384 ReturnType Call(P0 p0, P1 p1, P2 p2) { 505 ReturnType Call(P0 p0, P1 p1, P2 p2) {
385 return call_wrapper_.Call(p0, p1, p2); 506 return Call(p0, p1, p2, nullptr);
386 } 507 }
387 508
388 template <typename P0, typename P1, typename P2, typename P3> 509 template <typename P0, typename P1, typename P2, typename P3>
389 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { 510 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
390 return call_wrapper_.Call(p0, p1, p2, p3); 511 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
512 wrapper_.GetWrapperCode(), wrapper_.signature());
513 ReturnType return_value;
514 int32_t result = runner.Call<void*, void*, void*, void*, void*>(
515 &p0, &p1, &p2, &p3, &return_value);
516 CHECK_EQ(7654, result);
titzer 2016/02/18 08:18:49 Pull this constant out somewhere.
ahaas 2016/02/18 09:10:57 Done.
517 return return_value;
391 } 518 }
392 519
393 byte AllocateLocal(LocalType type) { 520 byte AllocateLocal(LocalType type) {
394 int result = static_cast<int>(env()->total_locals); 521 int result = static_cast<int>(env()->total_locals);
395 env()->AddLocals(type, 1); 522 env()->AddLocals(type, 1);
396 byte b = static_cast<byte>(result); 523 byte b = static_cast<byte>(result);
397 CHECK_EQ(result, b); 524 CHECK_EQ(result, b);
398 return b; 525 return b;
399 } 526 }
400 527
401 private: 528 private:
402 LocalType storage_[5]; 529 LocalType storage_[5];
403 FunctionSig signature_; 530 FunctionSig signature_;
404 WasmFunctionCompiler compiler_; 531 WasmFunctionCompiler compiler_;
405 BufferedRawMachineAssemblerTester<ReturnType> call_wrapper_; 532 WasmFunctionWrapper<ReturnType> wrapper_;
406 bool compilation_done_; 533 bool compilation_done_;
407 534
408 static size_t GetParameterCount(MachineType p0, MachineType p1, 535 static size_t GetParameterCount(MachineType p0, MachineType p1,
409 MachineType p2, MachineType p3) { 536 MachineType p2, MachineType p3) {
410 if (p0 == MachineType::None()) return 0; 537 if (p0 == MachineType::None()) return 0;
411 if (p1 == MachineType::None()) return 1; 538 if (p1 == MachineType::None()) return 1;
412 if (p2 == MachineType::None()) return 2; 539 if (p2 == MachineType::None()) return 2;
413 if (p3 == MachineType::None()) return 3; 540 if (p3 == MachineType::None()) return 3;
414 return 4; 541 return 4;
415 } 542 }
416 }; 543 };
417 544
418 } // namespace 545 } // namespace
419 546
420 #endif 547 #endif
OLDNEW
« test/cctest/wasm/test-run-wasm-js.cc ('K') | « 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