[CSA]: Fix ElementOffsetFromIndex for dynamic SMIs

Non-constant SMIs were being shifted to the right with SHR instead of SAR,
which caused corruption of negative offsets.

Add tests for SMI access to arguments using CodeStubArguments.

Change-Id: I6cc4fc0a5dd0018524f5ff4f16f9e9a21866363f
Reviewed-on: https://chromium-review.googlesource.com/854055
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50506}
This commit is contained in:
Dan Elphick 2018-01-10 08:47:56 +00:00 committed by Commit Bot
parent 63aaa83370
commit 9dd2b20350
2 changed files with 88 additions and 1 deletions

View File

@ -7350,7 +7350,7 @@ Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
? index_node
: ((element_size_shift > 0)
? WordShl(index_node, IntPtrConstant(element_size_shift))
: WordShr(index_node, IntPtrConstant(-element_size_shift)));
: WordSar(index_node, IntPtrConstant(-element_size_shift)));
return IntPtrAdd(IntPtrConstant(base_size), shifted_index);
}

View File

@ -1717,6 +1717,93 @@ TEST(Arguments) {
CHECK_EQ(*isolate->factory()->undefined_value(), *result);
}
TEST(ArgumentsWithSmiConstantIndices) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr,
CodeStubAssembler::SMI_PARAMETERS);
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(m.SmiConstant(0),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(12))));
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(m.SmiConstant(1),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(13))));
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(m.SmiConstant(2),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(14))));
m.Return(arguments.GetReceiver());
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
Handle<Smi>(Smi::FromInt(12), isolate),
Handle<Smi>(Smi::FromInt(13), isolate),
Handle<Smi>(Smi::FromInt(14), isolate))
.ToHandleChecked();
CHECK_EQ(*isolate->factory()->undefined_value(), *result);
}
TNode<Smi> NonConstantSmi(CodeStubAssembler* m, int value) {
// Generate a SMI with the given value and feed it through a Phi so it can't
// be inferred to be constant.
Variable var(m, MachineRepresentation::kTagged, m->SmiConstant(value));
Label dummy_done(m);
// Even though the Goto always executes, it will taint the variable and thus
// make it appear non-constant when used later.
m->GotoIf(m->Int32Constant(1), &dummy_done);
var.Bind(m->SmiConstant(value));
m->Goto(&dummy_done);
m->BIND(&dummy_done);
// Ensure that the above hackery actually created a non-constant SMI.
Smi* smi_constant;
CHECK(!m->ToSmiConstant(var.value(), smi_constant));
return m->UncheckedCast<Smi>(var.value());
}
TEST(ArgumentsWithSmiIndices) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr,
CodeStubAssembler::SMI_PARAMETERS);
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 0),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(12))));
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 1),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(13))));
CSA_ASSERT(&m,
m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 2),
CodeStubAssembler::SMI_PARAMETERS),
m.SmiConstant(Smi::FromInt(14))));
m.Return(arguments.GetReceiver());
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
Handle<Smi>(Smi::FromInt(12), isolate),
Handle<Smi>(Smi::FromInt(13), isolate),
Handle<Smi>(Smi::FromInt(14), isolate))
.ToHandleChecked();
CHECK_EQ(*isolate->factory()->undefined_value(), *result);
}
TEST(ArgumentsForEach) {
Isolate* isolate(CcTest::InitIsolateOnce());