Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. Use of this |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // found in the LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include <cmath> | 5 #include <cmath> |
| 6 #include <functional> | 6 #include <functional> |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/utils/random-number-generator.h" | 10 #include "src/base/utils/random-number-generator.h" |
| 11 #include "src/codegen.h" | 11 #include "src/codegen.h" |
| 12 #include "src/compiler/raw-machine-assembler.h" | |
| 13 #include "src/simulator.h" | |
| 12 #include "test/cctest/cctest.h" | 14 #include "test/cctest/cctest.h" |
| 13 #include "test/cctest/compiler/codegen-tester.h" | 15 #include "test/cctest/compiler/codegen-tester.h" |
| 14 #include "test/cctest/compiler/value-helper.h" | 16 #include "test/cctest/compiler/value-helper.h" |
| 15 | 17 |
| 16 using namespace v8::base; | 18 using namespace v8::base; |
| 17 using namespace v8::internal; | 19 using namespace v8::internal; |
| 18 using namespace v8::internal::compiler; | 20 using namespace v8::internal::compiler; |
| 19 | 21 |
| 20 typedef RawMachineAssembler::Label MLabel; | 22 typedef RawMachineAssembler::Label MLabel; |
| 21 | 23 |
| (...skipping 5476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5498 m.Return(m.Int32Constant(11)); | 5500 m.Return(m.Int32Constant(11)); |
| 5499 FOR_INT32_INPUTS(i) { | 5501 FOR_INT32_INPUTS(i) { |
| 5500 input = *i; | 5502 input = *i; |
| 5501 CHECK_EQ(11, m.Call()); | 5503 CHECK_EQ(11, m.Call()); |
| 5502 float expected = bit_cast<float>(input); | 5504 float expected = bit_cast<float>(input); |
| 5503 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output)); | 5505 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output)); |
| 5504 } | 5506 } |
| 5505 } | 5507 } |
| 5506 | 5508 |
| 5507 | 5509 |
| 5510 Handle<Code> GenerateCode(RawMachineAssembler* r) { | |
|
titzer
2015/10/26 21:58:30
You shouldn't need to duplicate this code here. E.
ahaas
2015/10/27 00:13:39
Done.
| |
| 5511 Schedule* schedule = r->Export(); | |
| 5512 CallDescriptor* call_descriptor = r->call_descriptor(); | |
| 5513 Graph* graph = r->graph(); | |
| 5514 CompilationInfo info("testing", r->isolate(), r->zone()); | |
| 5515 MaybeHandle<Code> code = | |
| 5516 Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph, schedule); | |
| 5517 | |
| 5518 return code.ToHandleChecked(); | |
| 5519 } | |
| 5520 | |
| 5521 | |
| 5522 int32_t ExecuteCode(Handle<Code> code) { | |
|
titzer
2015/10/26 21:58:30
You shouldn't need to inline this code here. You c
ahaas
2015/10/27 00:13:39
Done.
| |
| 5523 typedef int32_t V8_CDECL FType(); | |
| 5524 | |
| 5525 FType* function = FUNCTION_CAST<FType*>(code->entry()); | |
| 5526 | |
| 5527 | |
| 5528 #if USE_SIMULATOR && V8_TARGET_ARCH_ARM64 | |
| 5529 Simulator::CallArgument args[] = {Simulator::CallArgument::End()}; | |
| 5530 return CastReturnValue<int32_t>(CallSimulator(FUNCTION_ADDR(function), args)); | |
| 5531 #elif USE_SIMULATOR && \ | |
| 5532 (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_ARM || \ | |
| 5533 V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_PPC) | |
| 5534 return CastReturnValue<int32_t>(CallSimulator(FUNCTION_ADDR(function))); | |
| 5535 #else | |
| 5536 return function(); | |
| 5537 #endif | |
| 5538 } | |
| 5539 | |
| 5540 | |
| 5541 int32_t ExecuteCode(Handle<Code> code, int32_t parameter) { | |
| 5542 typedef int32_t V8_CDECL FType(int32_t); | |
| 5543 | |
| 5544 FType* function = FUNCTION_CAST<FType*>(code->entry()); | |
| 5545 | |
| 5546 #if USE_SIMULATOR && V8_TARGET_ARCH_ARM64 | |
| 5547 Simulator::CallArgument args[] = {Simulator::CallArgument(parameter), | |
| 5548 Simulator::CallArgument::End()}; | |
| 5549 return CastReturnValue<int32_t>(CallSimulator(FUNCTION_ADDR(function), args)); | |
| 5550 #elif USE_SIMULATOR && \ | |
| 5551 (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_ARM || \ | |
| 5552 V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_PPC) | |
| 5553 return CastReturnValue<int32_t>(CallSimulator( | |
| 5554 FUNCTION_ADDR(function), ParameterTraits<int32_t>::Cast(parameter))); | |
| 5555 #else | |
| 5556 return function(parameter); | |
| 5557 #endif | |
| 5558 } | |
| 5559 | |
| 5560 | |
| 5508 TEST(RunComputedCodeObject) { | 5561 TEST(RunComputedCodeObject) { |
| 5509 RawMachineAssemblerTester<int32_t> a; | 5562 i::Isolate* main_isolate = CcTest::InitIsolateOnce(); |
| 5563 i::HandleScope handle_scope(main_isolate); | |
| 5564 | |
| 5565 i::Zone main_zone_a; | |
| 5566 RawMachineAssembler a( | |
| 5567 main_isolate, new (&main_zone_a) Graph(&main_zone_a), | |
| 5568 Linkage::GetSimplifiedCDescriptor( | |
| 5569 &main_zone_a, CSignature::New(&main_zone_a, kMachInt32)), | |
| 5570 kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); | |
| 5571 | |
| 5510 a.Return(a.Int32Constant(33)); | 5572 a.Return(a.Int32Constant(33)); |
| 5511 CHECK_EQ(33, a.Call()); | |
| 5512 | 5573 |
| 5513 RawMachineAssemblerTester<int32_t> b; | 5574 Handle<Code> code_a = GenerateCode(&a); |
| 5575 CHECK_EQ(33, ExecuteCode(code_a)); | |
| 5576 | |
| 5577 i::Zone main_zone_b; | |
| 5578 RawMachineAssembler b( | |
| 5579 main_isolate, new (&main_zone_b) Graph(&main_zone_b), | |
| 5580 Linkage::GetSimplifiedCDescriptor( | |
| 5581 &main_zone_b, CSignature::New(&main_zone_b, kMachInt32)), | |
| 5582 kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); | |
| 5583 | |
| 5514 b.Return(b.Int32Constant(44)); | 5584 b.Return(b.Int32Constant(44)); |
| 5515 CHECK_EQ(44, b.Call()); | |
| 5516 | 5585 |
| 5517 RawMachineAssemblerTester<int32_t> r(kMachInt32); | 5586 Handle<Code> code_b = GenerateCode(&b); |
| 5587 CHECK_EQ(44, ExecuteCode(code_b)); | |
| 5588 | |
| 5589 i::Zone main_zone_r; | |
| 5590 RawMachineAssembler r( | |
| 5591 main_isolate, new (&main_zone_r) Graph(&main_zone_r), | |
| 5592 Linkage::GetSimplifiedCDescriptor( | |
| 5593 &main_zone_r, CSignature::New(&main_zone_r, kMachInt32, kMachInt32)), | |
| 5594 kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); | |
| 5595 | |
| 5518 RawMachineAssembler::Label tlabel; | 5596 RawMachineAssembler::Label tlabel; |
| 5519 RawMachineAssembler::Label flabel; | 5597 RawMachineAssembler::Label flabel; |
| 5520 RawMachineAssembler::Label merge; | 5598 RawMachineAssembler::Label merge; |
| 5521 r.Branch(r.Parameter(0), &tlabel, &flabel); | 5599 r.Branch(r.Parameter(0), &tlabel, &flabel); |
| 5522 r.Bind(&tlabel); | 5600 r.Bind(&tlabel); |
| 5523 Node* fa = r.HeapConstant(a.GetCode()); | 5601 Node* fa = r.HeapConstant(code_a); |
| 5524 r.Goto(&merge); | 5602 r.Goto(&merge); |
| 5525 r.Bind(&flabel); | 5603 r.Bind(&flabel); |
| 5526 Node* fb = r.HeapConstant(b.GetCode()); | 5604 Node* fb = r.HeapConstant(code_b); |
| 5527 r.Goto(&merge); | 5605 r.Goto(&merge); |
| 5528 r.Bind(&merge); | 5606 r.Bind(&merge); |
| 5529 Node* phi = r.Phi(kMachInt32, fa, fb); | 5607 Node* phi = r.Phi(kMachInt32, fa, fb); |
| 5530 | 5608 |
| 5531 // TODO(titzer): all this descriptor hackery is just to call the above | 5609 // TODO(titzer): all this descriptor hackery is just to call the above |
| 5532 // functions as code objects instead of direct addresses. | 5610 // functions as code objects instead of direct addresses. |
| 5533 CSignature0<int32_t> sig; | 5611 CSignature0<int32_t> sig; |
| 5534 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig); | 5612 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig); |
| 5535 LinkageLocation ret[] = {c->GetReturnLocation(0)}; | 5613 LinkageLocation ret[] = {c->GetReturnLocation(0)}; |
| 5536 Signature<LinkageLocation> loc(1, 0, ret); | 5614 Signature<LinkageLocation> loc(1, 0, ret); |
| 5537 CallDescriptor* desc = new (r.zone()) CallDescriptor( // -- | 5615 CallDescriptor* desc = new (r.zone()) CallDescriptor( // -- |
| 5538 CallDescriptor::kCallCodeObject, // kind | 5616 CallDescriptor::kCallCodeObject, // kind |
| 5539 kMachAnyTagged, // target_type | 5617 kMachAnyTagged, // target_type |
| 5540 c->GetInputLocation(0), // target_loc | 5618 c->GetInputLocation(0), // target_loc |
| 5541 &sig, // machine_sig | 5619 &sig, // machine_sig |
| 5542 &loc, // location_sig | 5620 &loc, // location_sig |
| 5543 0, // stack count | 5621 0, // stack count |
| 5544 Operator::kNoProperties, // properties | 5622 Operator::kNoProperties, // properties |
| 5545 c->CalleeSavedRegisters(), // callee saved | 5623 c->CalleeSavedRegisters(), // callee saved |
| 5546 c->CalleeSavedFPRegisters(), // callee saved FP | 5624 c->CalleeSavedFPRegisters(), // callee saved FP |
| 5547 CallDescriptor::kNoFlags, // flags | 5625 CallDescriptor::kNoFlags, // flags |
| 5548 "c-call-as-code"); | 5626 "c-call-as-code"); |
| 5549 Node* call = r.AddNode(r.common()->Call(desc), phi); | 5627 Node* call = r.AddNode(r.common()->Call(desc), phi); |
| 5550 r.Return(call); | 5628 r.Return(call); |
| 5551 | 5629 Handle<Code> code_r = GenerateCode(&r); |
| 5552 CHECK_EQ(33, r.Call(1)); | 5630 CHECK_EQ(33, ExecuteCode(code_r, 1)); |
| 5553 CHECK_EQ(44, r.Call(0)); | 5631 CHECK_EQ(44, ExecuteCode(code_r, 0)); |
| 5554 } | 5632 } |
| OLD | NEW |