| Index: test/cctest/compiler/test-run-native-calls.cc
|
| diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc
|
| index 791b0d7ae5868e82534b0ba60af91e9621906ebe..e51d25635f9b643d5e092e901fd1d6952b5a80fc 100644
|
| --- a/test/cctest/compiler/test-run-native-calls.cc
|
| +++ b/test/cctest/compiler/test-run-native-calls.cc
|
| @@ -1157,6 +1157,86 @@ TEST(MixedParams_1) { MixedParamTest(1); }
|
| TEST(MixedParams_2) { MixedParamTest(2); }
|
| TEST(MixedParams_3) { MixedParamTest(3); }
|
|
|
| +template <typename T>
|
| +void TestStackSlot(MachineType slot_type, T expected) {
|
| + // Test: Generate with a function f which reserves a stack slot, call an inner
|
| + // function g from f which writes into the stack slot of f.
|
| +
|
| + if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->num_double_registers() < 2)
|
| + return;
|
| +
|
| + Isolate* isolate = CcTest::InitIsolateOnce();
|
| +
|
| + // Lots of code to generate the build descriptor for the inner function.
|
| + int parray_gp[] = {
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableGeneralCode(0),
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableGeneralCode(1)};
|
| + int rarray_gp[] = {
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableGeneralCode(0)};
|
| + int parray_fp[] = {
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableDoubleCode(0),
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableDoubleCode(1)};
|
| + int rarray_fp[] = {
|
| + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
| + ->GetAllocatableDoubleCode(0)};
|
| + Allocator palloc(parray_gp, 2, parray_fp, 2);
|
| + Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
|
| + RegisterConfig config(palloc, ralloc);
|
| +
|
| + Zone zone;
|
| + HandleScope scope(isolate);
|
| + MachineSignature::Builder builder(&zone, 1, 12);
|
| + builder.AddReturn(MachineType::Int32());
|
| + for (int i = 0; i < 10; i++) {
|
| + builder.AddParam(MachineType::Int32());
|
| + }
|
| + builder.AddParam(slot_type);
|
| + builder.AddParam(MachineType::Pointer());
|
| + MachineSignature* sig = builder.Build();
|
| + CallDescriptor* desc = config.Create(&zone, sig);
|
| +
|
| + // Create inner function g. g has lots of parameters so that they are passed
|
| + // over the stack.
|
| + Handle<Code> inner;
|
| + Graph graph(&zone);
|
| + RawMachineAssembler g(isolate, &graph, desc);
|
| +
|
| + g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10),
|
| + WriteBarrierKind::kNoWriteBarrier);
|
| + g.Return(g.Parameter(9));
|
| + inner = CompileGraph("Compute", desc, &graph, g.Export());
|
| +
|
| + // Create function f with a stack slot which calls the inner function g.
|
| + BufferedRawMachineAssemblerTester<T> f(slot_type);
|
| + Node* target = f.HeapConstant(inner);
|
| + Node* stack_slot = f.StackSlot(slot_type.representation());
|
| + Node* args[12];
|
| + for (int i = 0; i < 10; i++) {
|
| + args[i] = f.Int32Constant(i);
|
| + }
|
| + args[10] = f.Parameter(0);
|
| + args[11] = stack_slot;
|
| +
|
| + f.CallN(desc, target, args);
|
| + f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));
|
| +
|
| + CHECK_EQ(expected, f.Call(expected));
|
| +}
|
| +
|
| +TEST(RunStackSlotInt32) { TestStackSlot(MachineType::Int32(), 0x12345678); }
|
| +#if !V8_TARGET_ARCH_32_BIT
|
| +TEST(RunStackSlotInt64) {
|
| + TestStackSlot(MachineType::Int64(), 0x123456789abcdef0);
|
| +}
|
| +#endif
|
| +TEST(RunStackSlotFloat32) { TestStackSlot(MachineType::Float32(), 1234.125f); }
|
| +TEST(RunStackSlotFloat64) { TestStackSlot(MachineType::Float64(), 3456.375); }
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|