Commit f74dd202 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

Fix BigInt builtins and TurboFan support after BigInt header layout change

broken by: [cleanup] Fix kPointerSize usages in src/objects/bigint.*

Bug: v8:8477, v8:8238
Change-Id: If1961ae42e1969d4ee807ea052a9c4cf4f072d0f
Reviewed-on: https://chromium-review.googlesource.com/c/1357046
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57997}
parent bf3cae9e
......@@ -346,9 +346,13 @@ extern runtime ReThrow(Context, Object): never;
extern runtime ThrowInvalidStringLength(Context): never;
extern operator '<' macro Int32LessThan(int32, int32): bool;
extern operator '<' macro Uint32LessThan(uint32, uint32): bool;
extern operator '>' macro Int32GreaterThan(int32, int32): bool;
extern operator '>' macro Uint32GreaterThan(uint32, uint32): bool;
extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bool;
extern operator '<=' macro Uint32LessThanOrEqual(uint32, uint32): bool;
extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bool;
extern operator '>=' macro Uint32GreaterThanOrEqual(uint32, uint32): bool;
extern operator '==' macro SmiEqual(Smi, Smi): bool;
extern operator '!=' macro SmiNotEqual(Smi, Smi): bool;
......
......@@ -37,19 +37,19 @@ class DataViewBuiltinsAssembler : public CodeStubAssembler {
return ElementsKindToByteSize(elements_kind);
}
TNode<IntPtrT> DataViewEncodeBigIntBits(bool sign, int32_t digits) {
return IntPtrConstant(BigInt::SignBits::encode(sign) |
BigInt::LengthBits::encode(digits));
TNode<Uint32T> DataViewEncodeBigIntBits(bool sign, int32_t digits) {
return Unsigned(Int32Constant(BigInt::SignBits::encode(sign) |
BigInt::LengthBits::encode(digits)));
}
TNode<UintPtrT> DataViewDecodeBigIntLength(TNode<BigInt> value) {
TNode<WordT> bitfield = LoadBigIntBitfield(value);
return DecodeWord<BigIntBase::LengthBits>(bitfield);
TNode<Uint32T> DataViewDecodeBigIntLength(TNode<BigInt> value) {
TNode<Word32T> bitfield = LoadBigIntBitfield(value);
return DecodeWord32<BigIntBase::LengthBits>(bitfield);
}
TNode<UintPtrT> DataViewDecodeBigIntSign(TNode<BigInt> value) {
TNode<WordT> bitfield = LoadBigIntBitfield(value);
return DecodeWord<BigIntBase::SignBits>(bitfield);
TNode<Uint32T> DataViewDecodeBigIntSign(TNode<BigInt> value) {
TNode<Word32T> bitfield = LoadBigIntBitfield(value);
return DecodeWord32<BigIntBase::SignBits>(bitfield);
}
};
......
......@@ -219,10 +219,10 @@ namespace data_view {
}
extern macro AllocateBigInt(intptr): BigInt;
extern macro StoreBigIntBitfield(BigInt, intptr): void;
extern macro StoreBigIntBitfield(BigInt, uint32): void;
extern macro StoreBigIntDigit(BigInt, constexpr int31, uintptr): void;
extern macro DataViewBuiltinsAssembler::DataViewEncodeBigIntBits(
constexpr bool, constexpr int31): intptr;
constexpr bool, constexpr int31): uint32;
const kPositiveBigInt: constexpr bool = false;
const kNegativeBigInt: constexpr bool = true;
......@@ -621,9 +621,9 @@ namespace data_view {
}
extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntLength(BigInt):
uintptr;
uint32;
extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntSign(BigInt):
uintptr;
uint32;
extern macro LoadBigIntDigit(BigInt, constexpr int31): uintptr;
// We might get here a BigInt that is bigger than 64 bits, but we're only
......@@ -632,8 +632,8 @@ namespace data_view {
macro StoreDataViewBigInt(
buffer: JSArrayBuffer, offset: uintptr, bigIntValue: BigInt,
requestedLittleEndian: bool) {
let length: uintptr = DataViewDecodeBigIntLength(bigIntValue);
let sign: uintptr = DataViewDecodeBigIntSign(bigIntValue);
let length: uint32 = DataViewDecodeBigIntLength(bigIntValue);
let sign: uint32 = DataViewDecodeBigIntSign(bigIntValue);
// The 32-bit words that will hold the BigInt's value in
// two's complement representation.
......
......@@ -2024,7 +2024,7 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt32Pair(TNode<IntPtrT> low,
TNode<IntPtrT> high) {
DCHECK(!Is64());
TVARIABLE(BigInt, var_result);
TVARIABLE(WordT, var_sign, IntPtrConstant(BigInt::SignBits::encode(false)));
TVARIABLE(Word32T, var_sign, Int32Constant(BigInt::SignBits::encode(false)));
TVARIABLE(IntPtrT, var_high, high);
TVARIABLE(IntPtrT, var_low, low);
Label high_zero(this), negative(this), allocate_one_digit(this),
......@@ -2040,7 +2040,7 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt32Pair(TNode<IntPtrT> low,
BIND(&negative);
{
var_sign = IntPtrConstant(BigInt::SignBits::encode(true));
var_sign = Int32Constant(BigInt::SignBits::encode(true));
// We must negate the value by computing "0 - (high|low)", performing
// both parts of the subtraction separately and manually taking care
// of the carry bit (which is 1 iff low != 0).
......@@ -2062,8 +2062,8 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt32Pair(TNode<IntPtrT> low,
{
var_result = AllocateRawBigInt(IntPtrConstant(1));
StoreBigIntBitfield(var_result.value(),
WordOr(var_sign.value(),
IntPtrConstant(BigInt::LengthBits::encode(1))));
Word32Or(var_sign.value(),
Int32Constant(BigInt::LengthBits::encode(1))));
StoreBigIntDigit(var_result.value(), 0, Unsigned(var_low.value()));
Goto(&done);
}
......@@ -2072,8 +2072,8 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt32Pair(TNode<IntPtrT> low,
{
var_result = AllocateRawBigInt(IntPtrConstant(2));
StoreBigIntBitfield(var_result.value(),
WordOr(var_sign.value(),
IntPtrConstant(BigInt::LengthBits::encode(2))));
Word32Or(var_sign.value(),
Int32Constant(BigInt::LengthBits::encode(2))));
StoreBigIntDigit(var_result.value(), 0, Unsigned(var_low.value()));
StoreBigIntDigit(var_result.value(), 1, Unsigned(var_high.value()));
Goto(&done);
......@@ -2099,8 +2099,8 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt64(TNode<IntPtrT> value) {
BIND(&if_positive);
{
StoreBigIntBitfield(var_result.value(),
IntPtrConstant(BigInt::SignBits::encode(false) |
BigInt::LengthBits::encode(1)));
Int32Constant(BigInt::SignBits::encode(false) |
BigInt::LengthBits::encode(1)));
StoreBigIntDigit(var_result.value(), 0, Unsigned(value));
Goto(&done);
}
......@@ -2108,8 +2108,8 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt64(TNode<IntPtrT> value) {
BIND(&if_negative);
{
StoreBigIntBitfield(var_result.value(),
IntPtrConstant(BigInt::SignBits::encode(true) |
BigInt::LengthBits::encode(1)));
Int32Constant(BigInt::SignBits::encode(true) |
BigInt::LengthBits::encode(1)));
StoreBigIntDigit(var_result.value(), 0,
Unsigned(IntPtrSub(IntPtrConstant(0), value)));
Goto(&done);
......@@ -3045,7 +3045,9 @@ TNode<MutableHeapNumber> CodeStubAssembler::AllocateMutableHeapNumberWithValue(
TNode<BigInt> CodeStubAssembler::AllocateBigInt(TNode<IntPtrT> length) {
TNode<BigInt> result = AllocateRawBigInt(length);
StoreBigIntBitfield(result, WordShl(length, BigInt::LengthBits::kShift));
StoreBigIntBitfield(result,
Word32Shl(TruncateIntPtrToInt32(length),
Int32Constant(BigInt::LengthBits::kShift)));
return result;
}
......@@ -3054,17 +3056,24 @@ TNode<BigInt> CodeStubAssembler::AllocateRawBigInt(TNode<IntPtrT> length) {
// applicability is required, a large-object check must be added.
CSA_ASSERT(this, UintPtrLessThan(length, IntPtrConstant(3)));
TNode<IntPtrT> size = IntPtrAdd(IntPtrConstant(BigInt::kHeaderSize),
Signed(WordShl(length, kPointerSizeLog2)));
TNode<IntPtrT> size =
IntPtrAdd(IntPtrConstant(BigInt::kHeaderSize),
Signed(WordShl(length, kSystemPointerSizeLog2)));
Node* raw_result = Allocate(size, kNone);
StoreMapNoWriteBarrier(raw_result, RootIndex::kBigIntMap);
if (FIELD_SIZE(BigInt::kOptionalPaddingOffset)) {
DCHECK_EQ(4, FIELD_SIZE(BigInt::kOptionalPaddingOffset));
StoreObjectFieldNoWriteBarrier(raw_result, BigInt::kOptionalPaddingOffset,
Int32Constant(0),
MachineRepresentation::kWord32);
}
return UncheckedCast<BigInt>(raw_result);
}
void CodeStubAssembler::StoreBigIntBitfield(TNode<BigInt> bigint,
TNode<WordT> bitfield) {
TNode<Word32T> bitfield) {
StoreObjectFieldNoWriteBarrier(bigint, BigInt::kBitfieldOffset, bitfield,
MachineType::PointerRepresentation());
MachineRepresentation::kWord32);
}
void CodeStubAssembler::StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
......@@ -3074,9 +3083,9 @@ void CodeStubAssembler::StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
UintPtrT::kMachineRepresentation);
}
TNode<WordT> CodeStubAssembler::LoadBigIntBitfield(TNode<BigInt> bigint) {
return UncheckedCast<WordT>(
LoadObjectField(bigint, BigInt::kBitfieldOffset, MachineType::UintPtr()));
TNode<Word32T> CodeStubAssembler::LoadBigIntBitfield(TNode<BigInt> bigint) {
return UncheckedCast<Word32T>(
LoadObjectField(bigint, BigInt::kBitfieldOffset, MachineType::Uint32()));
}
TNode<UintPtrT> CodeStubAssembler::LoadBigIntDigit(TNode<BigInt> bigint,
......@@ -10282,19 +10291,19 @@ void CodeStubAssembler::BigIntToRawBytes(TNode<BigInt> bigint,
Label done(this);
*var_low = Unsigned(IntPtrConstant(0));
*var_high = Unsigned(IntPtrConstant(0));
TNode<WordT> bitfield = LoadBigIntBitfield(bigint);
TNode<UintPtrT> length = DecodeWord<BigIntBase::LengthBits>(bitfield);
TNode<UintPtrT> sign = DecodeWord<BigIntBase::SignBits>(bitfield);
GotoIf(WordEqual(length, IntPtrConstant(0)), &done);
TNode<Word32T> bitfield = LoadBigIntBitfield(bigint);
TNode<Uint32T> length = DecodeWord32<BigIntBase::LengthBits>(bitfield);
TNode<Uint32T> sign = DecodeWord32<BigIntBase::SignBits>(bitfield);
GotoIf(Word32Equal(length, Int32Constant(0)), &done);
*var_low = LoadBigIntDigit(bigint, 0);
if (!Is64()) {
Label load_done(this);
GotoIf(WordEqual(length, IntPtrConstant(1)), &load_done);
GotoIf(Word32Equal(length, Int32Constant(1)), &load_done);
*var_high = LoadBigIntDigit(bigint, 1);
Goto(&load_done);
BIND(&load_done);
}
GotoIf(WordEqual(sign, IntPtrConstant(0)), &done);
GotoIf(Word32Equal(sign, Int32Constant(0)), &done);
// Negative value. Simulate two's complement.
if (!Is64()) {
*var_high = Unsigned(IntPtrSub(IntPtrConstant(0), var_high->value()));
......
......@@ -1288,10 +1288,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BigInt> AllocateBigInt(TNode<IntPtrT> length);
// Like above, but allowing custom bitfield initialization.
TNode<BigInt> AllocateRawBigInt(TNode<IntPtrT> length);
void StoreBigIntBitfield(TNode<BigInt> bigint, TNode<WordT> bitfield);
void StoreBigIntBitfield(TNode<BigInt> bigint, TNode<Word32T> bitfield);
void StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
TNode<UintPtrT> digit);
TNode<WordT> LoadBigIntBitfield(TNode<BigInt> bigint);
TNode<Word32T> LoadBigIntBitfield(TNode<BigInt> bigint);
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
// Allocate a SeqOneByteString with the given length.
......
......@@ -60,7 +60,7 @@ FieldAccess AccessBuilder::ForHeapNumberValue() {
FieldAccess AccessBuilder::ForBigIntBitfield() {
FieldAccess access = {
kTaggedBase, BigInt::kBitfieldOffset, MaybeHandle<Name>(),
MaybeHandle<Map>(), TypeCache::Get().kInt32, MachineType::IntPtr(),
MaybeHandle<Map>(), TypeCache::Get().kInt32, MachineType::Uint32(),
kNoWriteBarrier};
return access;
}
......
......@@ -1297,9 +1297,9 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
__ Bind(&if_bigint);
{
Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value);
Node* length_is_zero = __ WordEqual(
__ WordAnd(bitfield, __ IntPtrConstant(BigInt::LengthBits::kMask)),
__ IntPtrConstant(0));
Node* length_is_zero = __ Word32Equal(
__ Word32And(bitfield, __ Int32Constant(BigInt::LengthBits::kMask)),
__ Int32Constant(0));
__ Goto(done, __ Word32Equal(length_is_zero, zero));
}
}
......
......@@ -184,18 +184,18 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
// Internal field setters. Non-mutable BigInts don't have these.
#include "src/objects/object-macros.h"
inline void set_sign(bool new_sign) {
intptr_t bitfield = RELAXED_READ_INTPTR_FIELD(this, kBitfieldOffset);
bitfield = SignBits::update(static_cast<uint32_t>(bitfield), new_sign);
RELAXED_WRITE_INTPTR_FIELD(this, kBitfieldOffset, bitfield);
int32_t bitfield = RELAXED_READ_INT32_FIELD(this, kBitfieldOffset);
bitfield = SignBits::update(bitfield, new_sign);
RELAXED_WRITE_INT32_FIELD(this, kBitfieldOffset, bitfield);
}
inline void synchronized_set_length(int new_length) {
intptr_t bitfield = RELAXED_READ_INTPTR_FIELD(this, kBitfieldOffset);
bitfield = LengthBits::update(static_cast<uint32_t>(bitfield), new_length);
RELEASE_WRITE_INTPTR_FIELD(this, kBitfieldOffset, bitfield);
int32_t bitfield = RELAXED_READ_INT32_FIELD(this, kBitfieldOffset);
bitfield = LengthBits::update(bitfield, new_length);
RELEASE_WRITE_INT32_FIELD(this, kBitfieldOffset, bitfield);
}
inline void initialize_bitfield(bool sign, int length) {
intptr_t bitfield = LengthBits::encode(length) | SignBits::encode(sign);
WRITE_INTPTR_FIELD(this, kBitfieldOffset, bitfield);
int32_t bitfield = LengthBits::encode(length) | SignBits::encode(sign);
WRITE_INT32_FIELD(this, kBitfieldOffset, bitfield);
}
inline void set_digit(int n, digit_t value) {
SLOW_DCHECK(0 <= n && n < length());
......
......@@ -81,7 +81,7 @@ class BigIntBase : public HeapObjectPtr {
// sign() == true means negative.
inline bool sign() const {
intptr_t bitfield = RELAXED_READ_INTPTR_FIELD(this, kBitfieldOffset);
int32_t bitfield = RELAXED_READ_INT32_FIELD(this, kBitfieldOffset);
return SignBits::decode(static_cast<uint32_t>(bitfield));
}
......
......@@ -473,6 +473,11 @@
reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
static_cast<base::Atomic32>(value));
#define RELEASE_WRITE_INT32_FIELD(p, offset, value) \
base::Release_Store( \
reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
static_cast<base::Atomic32>(value));
#define READ_FLOAT_FIELD(p, offset) \
(*reinterpret_cast<const float*>(FIELD_ADDR(p, offset)))
......
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