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

Side by Side Diff: test/cctest/compiler/test-code-assembler.cc

Issue 2570213002: [stubs] Enable machine graph verification for CodeStubAssembler and friends by default in debug mode (Closed)
Patch Set: Created 4 years 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 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 "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/compiler/code-assembler.h" 6 #include "src/compiler/code-assembler.h"
7 #include "src/isolate.h" 7 #include "src/isolate.h"
8 #include "test/cctest/compiler/code-assembler-tester.h" 8 #include "test/cctest/compiler/code-assembler-tester.h"
9 #include "test/cctest/compiler/function-tester.h" 9 #include "test/cctest/compiler/function-tester.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 namespace compiler { 13 namespace compiler {
14 14
15 namespace { 15 namespace {
16 16
17 Node* SmiTag(CodeAssembler& m, Node* value) { 17 Node* SmiTag(CodeAssembler& m, Node* value) {
18 int32_t constant_value; 18 int32_t constant_value;
19 if (m.ToInt32Constant(value, constant_value) && 19 if (m.ToInt32Constant(value, constant_value) &&
20 Smi::IsValid(constant_value)) { 20 Smi::IsValid(constant_value)) {
21 return m.SmiConstant(Smi::FromInt(constant_value)); 21 return m.SmiConstant(Smi::FromInt(constant_value));
22 } 22 }
23 return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize)); 23 return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize));
24 } 24 }
25 25
26 Node* UndefinedConstant(CodeAssembler& m) { 26 Node* UndefinedConstant(CodeAssembler& m) {
27 return m.LoadRoot(Heap::kUndefinedValueRootIndex); 27 return m.LoadRoot(Heap::kUndefinedValueRootIndex);
28 } 28 }
29 29
30 Node* SmiFromWord32(CodeAssembler& m, Node* value) {
31 value = m.ChangeInt32ToIntPtr(value);
32 return m.BitcastWordToTaggedSigned(
33 m.WordShl(value, kSmiShiftSize + kSmiTagSize));
34 }
35
30 Node* LoadObjectField(CodeAssembler& m, Node* object, int offset, 36 Node* LoadObjectField(CodeAssembler& m, Node* object, int offset,
31 MachineType rep = MachineType::AnyTagged()) { 37 MachineType rep = MachineType::AnyTagged()) {
32 return m.Load(rep, object, m.IntPtrConstant(offset - kHeapObjectTag)); 38 return m.Load(rep, object, m.IntPtrConstant(offset - kHeapObjectTag));
33 } 39 }
34 40
41 Node* LoadMap(CodeAssembler& m, Node* object) {
42 return LoadObjectField(m, object, JSObject::kMapOffset);
43 }
44
35 } // namespace 45 } // namespace
36 46
37 TEST(SimpleSmiReturn) { 47 TEST(SimpleSmiReturn) {
38 Isolate* isolate(CcTest::InitIsolateOnce()); 48 Isolate* isolate(CcTest::InitIsolateOnce());
39 CodeAssemblerTester data(isolate); 49 CodeAssemblerTester data(isolate);
40 CodeAssembler m(data.state()); 50 CodeAssembler m(data.state());
41 m.Return(SmiTag(m, m.Int32Constant(37))); 51 m.Return(SmiTag(m, m.Int32Constant(37)));
42 Handle<Code> code = data.GenerateCode(); 52 Handle<Code> code = data.GenerateCode();
43 FunctionTester ft(code); 53 FunctionTester ft(code);
44 MaybeHandle<Object> result = ft.Call(); 54 MaybeHandle<Object> result = ft.Call();
45 CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value()); 55 CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value());
46 } 56 }
47 57
48 TEST(SimpleIntPtrReturn) { 58 TEST(SimpleIntPtrReturn) {
49 Isolate* isolate(CcTest::InitIsolateOnce()); 59 Isolate* isolate(CcTest::InitIsolateOnce());
50 CodeAssemblerTester data(isolate); 60 CodeAssemblerTester data(isolate);
51 CodeAssembler m(data.state()); 61 CodeAssembler m(data.state());
52 int test; 62 int test;
53 m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))); 63 m.Return(m.BitcastWordToTagged(
64 m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))));
54 Handle<Code> code = data.GenerateCode(); 65 Handle<Code> code = data.GenerateCode();
55 FunctionTester ft(code); 66 FunctionTester ft(code);
56 MaybeHandle<Object> result = ft.Call(); 67 MaybeHandle<Object> result = ft.Call();
57 CHECK_EQ(reinterpret_cast<intptr_t>(&test), 68 CHECK_EQ(reinterpret_cast<intptr_t>(&test),
58 reinterpret_cast<intptr_t>(*result.ToHandleChecked())); 69 reinterpret_cast<intptr_t>(*result.ToHandleChecked()));
59 } 70 }
60 71
61 TEST(SimpleDoubleReturn) { 72 TEST(SimpleDoubleReturn) {
62 Isolate* isolate(CcTest::InitIsolateOnce()); 73 Isolate* isolate(CcTest::InitIsolateOnce());
63 CodeAssemblerTester data(isolate); 74 CodeAssemblerTester data(isolate);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 a = UndefinedConstant(m); 386 a = UndefinedConstant(m);
376 CHECK(!m.ToInt32Constant(a, value32)); 387 CHECK(!m.ToInt32Constant(a, value32));
377 CHECK(!m.ToInt64Constant(a, value64)); 388 CHECK(!m.ToInt64Constant(a, value64));
378 389
379 a = UndefinedConstant(m); 390 a = UndefinedConstant(m);
380 CHECK(!m.ToInt32Constant(a, value32)); 391 CHECK(!m.ToInt32Constant(a, value32));
381 CHECK(!m.ToInt64Constant(a, value64)); 392 CHECK(!m.ToInt64Constant(a, value64));
382 } 393 }
383 394
384 TEST(DeferredCodePhiHints) { 395 TEST(DeferredCodePhiHints) {
385 typedef compiler::Node Node;
386 typedef CodeAssemblerLabel Label; 396 typedef CodeAssemblerLabel Label;
387 typedef CodeAssemblerVariable Variable; 397 typedef CodeAssemblerVariable Variable;
388 Isolate* isolate(CcTest::InitIsolateOnce()); 398 Isolate* isolate(CcTest::InitIsolateOnce());
389 CodeAssemblerTester data(isolate); 399 CodeAssemblerTester data(isolate);
390 CodeAssembler m(data.state()); 400 CodeAssembler m(data.state());
391 Label block1(&m, Label::kDeferred); 401 Label block1(&m, Label::kDeferred);
392 m.Goto(&block1); 402 m.Goto(&block1);
393 m.Bind(&block1); 403 m.Bind(&block1);
394 { 404 {
395 Variable var_object(&m, MachineRepresentation::kTagged); 405 Variable var_object(&m, MachineRepresentation::kTagged);
396 Label loop(&m, &var_object); 406 Label loop(&m, &var_object);
397 var_object.Bind(m.IntPtrConstant(0)); 407 var_object.Bind(m.SmiConstant(0));
398 m.Goto(&loop); 408 m.Goto(&loop);
399 m.Bind(&loop); 409 m.Bind(&loop);
400 { 410 {
401 Node* map = LoadObjectField(m, var_object.value(), JSObject::kMapOffset); 411 Node* map = LoadMap(m, var_object.value());
402 var_object.Bind(map); 412 var_object.Bind(map);
403 m.Goto(&loop); 413 m.Goto(&loop);
404 } 414 }
405 } 415 }
406 CHECK(!data.GenerateCode().is_null()); 416 CHECK(!data.GenerateCode().is_null());
407 } 417 }
408 418
409 TEST(TestOutOfScopeVariable) { 419 TEST(TestOutOfScopeVariable) {
410 typedef CodeAssemblerLabel Label; 420 typedef CodeAssemblerLabel Label;
411 typedef CodeAssemblerVariable Variable; 421 typedef CodeAssemblerVariable Variable;
(...skipping 16 matching lines...) Expand all
428 m.Goto(&block1); 438 m.Goto(&block1);
429 439
430 m.Bind(&block3); 440 m.Bind(&block3);
431 var_object.Bind(m.IntPtrConstant(66)); 441 var_object.Bind(m.IntPtrConstant(66));
432 m.Goto(&block1); 442 m.Goto(&block1);
433 } 443 }
434 m.Bind(&block1); 444 m.Bind(&block1);
435 CHECK(!data.GenerateCode().is_null()); 445 CHECK(!data.GenerateCode().is_null());
436 } 446 }
437 447
448 TEST(GotoIfException) {
449 typedef CodeAssemblerLabel Label;
450 typedef CodeAssemblerVariable Variable;
451 Isolate* isolate(CcTest::InitIsolateOnce());
452
453 const int kNumParams = 1;
454 CodeAssemblerTester data(isolate, kNumParams);
455 CodeAssembler m(data.state());
456
457 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
458 Node* to_string_tag =
459 m.HeapConstant(isolate->factory()->to_string_tag_symbol());
460 Variable exception(&m, MachineRepresentation::kTagged);
461
462 Label exception_handler(&m);
463 Callable to_string = CodeFactory::ToString(isolate);
464 Node* string = m.CallStub(to_string, context, to_string_tag);
465 m.GotoIfException(string, &exception_handler, &exception);
466 m.Return(string);
467
468 m.Bind(&exception_handler);
469 m.Return(exception.value());
470
471 Handle<Code> code = data.GenerateCode();
472 CHECK(!code.is_null());
473
474 FunctionTester ft(code, kNumParams);
475 Handle<Object> result = ft.Call().ToHandleChecked();
476
477 // Should be a TypeError.
478 CHECK(result->IsJSObject());
479
480 Handle<Object> constructor =
481 Object::GetPropertyOrElement(result,
482 isolate->factory()->constructor_string())
483 .ToHandleChecked();
484 CHECK(constructor->SameValue(*isolate->type_error_function()));
485 }
486
487 TEST(GotoIfExceptionMultiple) {
488 typedef CodeAssemblerLabel Label;
489 typedef CodeAssemblerVariable Variable;
490 Isolate* isolate(CcTest::InitIsolateOnce());
491
492 const int kNumParams = 4; // receiver, first, second, third
493 CodeAssemblerTester data(isolate, kNumParams);
494 CodeAssembler m(data.state());
495
496 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
497 Node* first_value = m.Parameter(0);
498 Node* second_value = m.Parameter(1);
499 Node* third_value = m.Parameter(2);
500
501 Label exception_handler1(&m);
502 Label exception_handler2(&m);
503 Label exception_handler3(&m);
504 Variable return_value(&m, MachineRepresentation::kWord32);
505 Variable error(&m, MachineRepresentation::kTagged);
506
507 return_value.Bind(m.Int32Constant(0));
508
509 // try { return ToString(param1) } catch (e) { ... }
510 Callable to_string = CodeFactory::ToString(isolate);
511 Node* string = m.CallStub(to_string, context, first_value);
512 m.GotoIfException(string, &exception_handler1, &error);
513 m.Return(string);
514
515 // try { ToString(param2); return 7 } catch (e) { ... }
516 m.Bind(&exception_handler1);
517 return_value.Bind(m.Int32Constant(7));
518 error.Bind(UndefinedConstant(m));
519 string = m.CallStub(to_string, context, second_value);
520 m.GotoIfException(string, &exception_handler2, &error);
521 m.Return(SmiFromWord32(m, return_value.value()));
522
523 // try { ToString(param3); return 7 & ~2; } catch (e) { return e; }
524 m.Bind(&exception_handler2);
525 // Return returnValue & ~2
526 error.Bind(UndefinedConstant(m));
527 string = m.CallStub(to_string, context, third_value);
528 m.GotoIfException(string, &exception_handler3, &error);
529 m.Return(SmiFromWord32(
530 m, m.Word32And(return_value.value(),
531 m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1)))));
532
533 m.Bind(&exception_handler3);
534 m.Return(error.value());
535
536 Handle<Code> code = data.GenerateCode();
537 CHECK(!code.is_null());
538
539 FunctionTester ft(code, kNumParams);
540
541 Handle<Object> result;
542 // First handler does not throw, returns result of first value.
543 result = ft.Call(isolate->factory()->undefined_value(),
544 isolate->factory()->to_string_tag_symbol())
545 .ToHandleChecked();
546 CHECK(String::cast(*result)->IsOneByteEqualTo(OneByteVector("undefined")));
547
548 // First handler returns a number.
549 result = ft.Call(isolate->factory()->to_string_tag_symbol(),
550 isolate->factory()->undefined_value())
551 .ToHandleChecked();
552 CHECK_EQ(7, Smi::cast(*result)->value());
553
554 // First handler throws, second handler returns a number.
555 result = ft.Call(isolate->factory()->to_string_tag_symbol(),
556 isolate->factory()->to_primitive_symbol())
557 .ToHandleChecked();
558 CHECK_EQ(7 & ~2, Smi::cast(*result)->value());
559
560 // First handler throws, second handler throws, third handler returns thrown
561 // value.
562 result = ft.Call(isolate->factory()->to_string_tag_symbol(),
563 isolate->factory()->to_primitive_symbol(),
564 isolate->factory()->unscopables_symbol())
565 .ToHandleChecked();
566
567 // Should be a TypeError.
568 CHECK(result->IsJSObject());
569
570 Handle<Object> constructor =
571 Object::GetPropertyOrElement(result,
572 isolate->factory()->constructor_string())
573 .ToHandleChecked();
574 CHECK(constructor->SameValue(*isolate->type_error_function()));
575 }
576
438 } // namespace compiler 577 } // namespace compiler
439 } // namespace internal 578 } // namespace internal
440 } // namespace v8 579 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698