Commit 515cc07d authored by jgruber's avatar jgruber Committed by Commit Bot

[csa] Ensure the requested allocation size fits in a Smi

In CSA::AllocateRaw, ensure that the given allocation size fits into a
Smi.

Bug: chromium:848672
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I4e74791296163188b1ca77cae8226a9833fba8ef
Reviewed-on: https://chromium-review.googlesource.com/1084930Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53495}
parent 3348ed0b
......@@ -534,6 +534,18 @@ TNode<Smi> CodeStubAssembler::SmiFromInt32(SloppyTNode<Int32T> value) {
WordShl(value_intptr, SmiShiftBitsConstant()));
}
TNode<BoolT> CodeStubAssembler::IsValidPositiveSmi(TNode<IntPtrT> value) {
intptr_t constant_value;
if (ToIntPtrConstant(value, constant_value)) {
return (static_cast<uintptr_t>(constant_value) <=
static_cast<uintptr_t>(Smi::kMaxValue))
? Int32TrueConstant()
: Int32FalseConstant();
}
return UintPtrLessThanOrEqual(value, IntPtrConstant(Smi::kMaxValue));
}
TNode<Smi> CodeStubAssembler::SmiTag(SloppyTNode<IntPtrT> value) {
int32_t constant_value;
if (ToInt32Constant(value, constant_value) && Smi::IsValid(constant_value)) {
......@@ -1024,6 +1036,19 @@ void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) {
Node* CodeStubAssembler::AllocateRaw(Node* size_in_bytes, AllocationFlags flags,
Node* top_address, Node* limit_address) {
// TODO(jgruber, chromium:848672): TNodeify AllocateRaw.
// TODO(jgruber, chromium:848672): Call FatalProcessOutOfMemory if this fails.
{
intptr_t constant_value;
if (ToIntPtrConstant(size_in_bytes, constant_value)) {
CHECK(Internals::IsValidSmi(constant_value));
CHECK_GT(constant_value, 0);
} else {
CSA_CHECK(this,
IsValidPositiveSmi(UncheckedCast<IntPtrT>(size_in_bytes)));
}
}
Node* top = Load(MachineType::Pointer(), top_address);
Node* limit = Load(MachineType::Pointer(), limit_address);
......
......@@ -274,6 +274,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<Object> index,
TNode<IntPtrT> length);
// Returns true iff the given value fits into smi range and is >= 0.
TNode<BoolT> IsValidPositiveSmi(TNode<IntPtrT> value);
// Tag an IntPtr as a Smi value.
TNode<Smi> SmiTag(SloppyTNode<IntPtrT> value);
// Untag a Smi value as an IntPtr.
......
......@@ -209,6 +209,49 @@ TEST(ToUint32) {
ft.CheckThrows(factory->match_symbol());
}
namespace {
void IsValidPositiveSmiCase(Isolate* isolate, intptr_t value, bool expected) {
const int kNumParams = 0;
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
m.Return(
m.SelectBooleanConstant(m.IsValidPositiveSmi(m.IntPtrConstant(value))));
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
MaybeHandle<Object> maybe_handle = ft.Call();
if (expected) {
CHECK(maybe_handle.ToHandleChecked()->IsTrue(isolate));
} else {
CHECK(maybe_handle.ToHandleChecked()->IsFalse(isolate));
}
}
} // namespace
TEST(IsValidPositiveSmi) {
Isolate* isolate(CcTest::InitIsolateOnce());
IsValidPositiveSmiCase(isolate, -1, false);
IsValidPositiveSmiCase(isolate, 0, true);
IsValidPositiveSmiCase(isolate, 1, true);
#ifdef V8_TARGET_ARCH_32_BIT
IsValidPositiveSmiCase(isolate, 0x3FFFFFFFU, true);
IsValidPositiveSmiCase(isolate, 0xC0000000U, false);
IsValidPositiveSmiCase(isolate, 0x40000000U, false);
IsValidPositiveSmiCase(isolate, 0xBFFFFFFFU, false);
#else
typedef std::numeric_limits<int32_t> int32_limits;
IsValidPositiveSmiCase(isolate, int32_limits::max(), true);
IsValidPositiveSmiCase(isolate, int32_limits::min(), false);
IsValidPositiveSmiCase(isolate,
static_cast<intptr_t>(int32_limits::max()) + 1, false);
IsValidPositiveSmiCase(isolate,
static_cast<intptr_t>(int32_limits::min()) - 1, false);
#endif
}
TEST(FixedArrayAccessSmiIndex) {
Isolate* isolate(CcTest::InitIsolateOnce());
CodeAssemblerTester asm_tester(isolate);
......
......@@ -4,7 +4,7 @@
[
# Only test for default mode x64.
['variant != default or arch != x64', {
['variant != default or arch != x64 or asan == True', {
'*': [SKIP],
}], # variant != default or arch != x64
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment