Commit 172ab5dc authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Port BigInt to the new design

Bug: v8:3770
Change-Id: I6ad84a663926fffc9e1acc590c13780c39461274
Reviewed-on: https://chromium-review.googlesource.com/c/1351248
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57952}
parent cb62c6ed
...@@ -2313,7 +2313,7 @@ Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length, ...@@ -2313,7 +2313,7 @@ Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length,
} }
HeapObject* result = AllocateRawWithImmortalMap(BigInt::SizeFor(length), HeapObject* result = AllocateRawWithImmortalMap(BigInt::SizeFor(length),
pretenure, *bigint_map()); pretenure, *bigint_map());
FreshlyAllocatedBigInt* bigint = FreshlyAllocatedBigInt::cast(result); FreshlyAllocatedBigInt bigint = FreshlyAllocatedBigInt::cast(result);
bigint->clear_padding(); bigint->clear_padding();
return handle(bigint, isolate()); return handle(bigint, isolate());
} }
......
...@@ -34,7 +34,7 @@ class WasmInstanceObject; ...@@ -34,7 +34,7 @@ class WasmInstanceObject;
#define TYPED_VISITOR_ID_LIST(V) \ #define TYPED_VISITOR_ID_LIST(V) \
V(AllocationSite, AllocationSite*) \ V(AllocationSite, AllocationSite*) \
V(BigInt, BigInt*) \ V(BigInt, BigInt) \
V(ByteArray, ByteArray) \ V(ByteArray, ByteArray) \
V(BytecodeArray, BytecodeArray) \ V(BytecodeArray, BytecodeArray) \
V(Cell, Cell*) \ V(Cell, Cell*) \
......
...@@ -508,11 +508,15 @@ NormalizedMapCache::NormalizedMapCache(Address ptr) : WeakFixedArray(ptr) { ...@@ -508,11 +508,15 @@ NormalizedMapCache::NormalizedMapCache(Address ptr) : WeakFixedArray(ptr) {
// OBJECT_CONSTRUCTORS_IMPL macro? // OBJECT_CONSTRUCTORS_IMPL macro?
} }
OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
// ------------------------------------ // ------------------------------------
// Cast operations // Cast operations
CAST_ACCESSOR(AccessorPair) CAST_ACCESSOR(AccessorPair)
CAST_ACCESSOR(BigInt) CAST_ACCESSOR2(BigInt)
CAST_ACCESSOR2(ObjectBoilerplateDescription) CAST_ACCESSOR2(ObjectBoilerplateDescription)
CAST_ACCESSOR(Cell) CAST_ACCESSOR(Cell)
CAST_ACCESSOR(ArrayBoilerplateDescription) CAST_ACCESSOR(ArrayBoilerplateDescription)
...@@ -1602,7 +1606,7 @@ int HeapObject::SizeFromMap(Map map) const { ...@@ -1602,7 +1606,7 @@ int HeapObject::SizeFromMap(Map map) const {
reinterpret_cast<const FeedbackVector*>(this)->length()); reinterpret_cast<const FeedbackVector*>(this)->length());
} }
if (instance_type == BIGINT_TYPE) { if (instance_type == BIGINT_TYPE) {
return BigInt::SizeFor(reinterpret_cast<const BigInt*>(this)->length()); return BigInt::SizeFor(BigInt::unchecked_cast(this)->length());
} }
if (instance_type == PRE_PARSED_SCOPE_DATA_TYPE) { if (instance_type == PRE_PARSED_SCOPE_DATA_TYPE) {
return PreParsedScopeData::SizeFor( return PreParsedScopeData::SizeFor(
...@@ -2063,9 +2067,9 @@ bool ScopeInfo::HasSimpleParameters() const { ...@@ -2063,9 +2067,9 @@ bool ScopeInfo::HasSimpleParameters() const {
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS) FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
#undef FIELD_ACCESSORS #undef FIELD_ACCESSORS
FreshlyAllocatedBigInt* FreshlyAllocatedBigInt::cast(Object* object) { FreshlyAllocatedBigInt FreshlyAllocatedBigInt::cast(Object* object) {
SLOW_DCHECK(object->IsBigInt()); SLOW_DCHECK(object->IsBigInt());
return reinterpret_cast<FreshlyAllocatedBigInt*>(object); return FreshlyAllocatedBigInt(object->ptr());
} }
} // namespace internal } // namespace internal
......
...@@ -34,8 +34,7 @@ namespace internal { ...@@ -34,8 +34,7 @@ namespace internal {
// Many of the functions in this class use arguments of type {BigIntBase}, // Many of the functions in this class use arguments of type {BigIntBase},
// indicating that they will be used in a read-only capacity, and both // indicating that they will be used in a read-only capacity, and both
// {BigInt} and {MutableBigInt} objects can be passed in. // {BigInt} and {MutableBigInt} objects can be passed in.
class MutableBigInt : public FreshlyAllocatedBigInt, class MutableBigInt : public FreshlyAllocatedBigInt {
public NeverReadOnlySpaceObject {
public: public:
// Bottleneck for converting MutableBigInts to BigInts. // Bottleneck for converting MutableBigInts to BigInts.
static MaybeHandle<BigInt> MakeImmutable(MaybeHandle<MutableBigInt> maybe); static MaybeHandle<BigInt> MakeImmutable(MaybeHandle<MutableBigInt> maybe);
...@@ -58,6 +57,9 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -58,6 +57,9 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
SLOW_DCHECK(bigint->IsBigInt()); SLOW_DCHECK(bigint->IsBigInt());
return Handle<MutableBigInt>::cast(bigint); return Handle<MutableBigInt>::cast(bigint);
} }
static MutableBigInt unchecked_cast(ObjectPtr o) {
return MutableBigInt(o.ptr());
}
// Internal helpers. // Internal helpers.
static MaybeHandle<MutableBigInt> BitwiseAnd(Isolate* isolate, static MaybeHandle<MutableBigInt> BitwiseAnd(Isolate* isolate,
...@@ -82,7 +84,7 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -82,7 +84,7 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
Handle<BigInt> y, bool result_sign); Handle<BigInt> y, bool result_sign);
static MaybeHandle<MutableBigInt> AbsoluteAddOne( static MaybeHandle<MutableBigInt> AbsoluteAddOne(
Isolate* isolate, Handle<BigIntBase> x, bool sign, Isolate* isolate, Handle<BigIntBase> x, bool sign,
MutableBigInt* result_storage = nullptr); MutableBigInt result_storage = MutableBigInt());
static Handle<MutableBigInt> AbsoluteSubOne(Isolate* isolate, static Handle<MutableBigInt> AbsoluteSubOne(Isolate* isolate,
Handle<BigIntBase> x); Handle<BigIntBase> x);
static MaybeHandle<MutableBigInt> AbsoluteSubOne(Isolate* isolate, static MaybeHandle<MutableBigInt> AbsoluteSubOne(Isolate* isolate,
...@@ -93,21 +95,21 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -93,21 +95,21 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
enum SymmetricOp { kSymmetric, kNotSymmetric }; enum SymmetricOp { kSymmetric, kNotSymmetric };
static inline Handle<MutableBigInt> AbsoluteBitwiseOp( static inline Handle<MutableBigInt> AbsoluteBitwiseOp(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage, ExtraDigitsHandling extra_digits, MutableBigInt result_storage, ExtraDigitsHandling extra_digits,
SymmetricOp symmetric, SymmetricOp symmetric,
const std::function<digit_t(digit_t, digit_t)>& op); const std::function<digit_t(digit_t, digit_t)>& op);
static Handle<MutableBigInt> AbsoluteAnd( static Handle<MutableBigInt> AbsoluteAnd(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage = nullptr); MutableBigInt result_storage = MutableBigInt());
static Handle<MutableBigInt> AbsoluteAndNot( static Handle<MutableBigInt> AbsoluteAndNot(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage = nullptr); MutableBigInt result_storage = MutableBigInt());
static Handle<MutableBigInt> AbsoluteOr( static Handle<MutableBigInt> AbsoluteOr(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage = nullptr); MutableBigInt result_storage = MutableBigInt());
static Handle<MutableBigInt> AbsoluteXor( static Handle<MutableBigInt> AbsoluteXor(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage = nullptr); MutableBigInt result_storage = MutableBigInt());
static int AbsoluteCompare(Handle<BigIntBase> x, Handle<BigIntBase> y); static int AbsoluteCompare(Handle<BigIntBase> x, Handle<BigIntBase> y);
...@@ -115,9 +117,8 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -115,9 +117,8 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
digit_t multiplier, digit_t multiplier,
Handle<MutableBigInt> accumulator, Handle<MutableBigInt> accumulator,
int accumulator_index); int accumulator_index);
static void InternalMultiplyAdd(BigIntBase* source, digit_t factor, static void InternalMultiplyAdd(BigIntBase source, digit_t factor,
digit_t summand, int n, digit_t summand, int n, MutableBigInt result);
MutableBigInt* result);
void InplaceMultiplyAdd(uintptr_t factor, uintptr_t summand); void InplaceMultiplyAdd(uintptr_t factor, uintptr_t summand);
// Specialized helpers for Divide/Remainder. // Specialized helpers for Divide/Remainder.
...@@ -167,7 +168,7 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -167,7 +168,7 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
// Returns the least significant 64 bits, simulating two's complement // Returns the least significant 64 bits, simulating two's complement
// representation. // representation.
static uint64_t GetRawBits(BigIntBase* x, bool* lossless); static uint64_t GetRawBits(BigIntBase x, bool* lossless);
// Digit arithmetic helpers. // Digit arithmetic helpers.
static inline digit_t digit_add(digit_t a, digit_t b, digit_t* carry); static inline digit_t digit_add(digit_t a, digit_t b, digit_t* carry);
...@@ -201,11 +202,21 @@ class MutableBigInt : public FreshlyAllocatedBigInt, ...@@ -201,11 +202,21 @@ class MutableBigInt : public FreshlyAllocatedBigInt,
Address address = FIELD_ADDR(this, kDigitsOffset + n * kDigitSize); Address address = FIELD_ADDR(this, kDigitsOffset + n * kDigitSize);
(*reinterpret_cast<digit_t*>(address)) = value; (*reinterpret_cast<digit_t*>(address)) = value;
} }
#include "src/objects/object-macros-undef.h"
void set_64_bits(uint64_t bits); void set_64_bits(uint64_t bits);
bool IsMutableBigInt() const { return IsBigInt(); }
NEVER_READ_ONLY_SPACE
OBJECT_CONSTRUCTORS(MutableBigInt, FreshlyAllocatedBigInt)
}; };
OBJECT_CONSTRUCTORS_IMPL(MutableBigInt, FreshlyAllocatedBigInt)
NEVER_READ_ONLY_SPACE_IMPL(MutableBigInt)
#include "src/objects/object-macros-undef.h"
MaybeHandle<MutableBigInt> MutableBigInt::New(Isolate* isolate, int length, MaybeHandle<MutableBigInt> MutableBigInt::New(Isolate* isolate, int length,
PretenureFlag pretenure) { PretenureFlag pretenure) {
if (length > BigInt::kMaxLength) { if (length > BigInt::kMaxLength) {
...@@ -318,9 +329,8 @@ Handle<MutableBigInt> MutableBigInt::Copy(Isolate* isolate, ...@@ -318,9 +329,8 @@ Handle<MutableBigInt> MutableBigInt::Copy(Isolate* isolate,
} }
void MutableBigInt::InitializeDigits(int length, byte value) { void MutableBigInt::InitializeDigits(int length, byte value) {
memset(reinterpret_cast<void*>(reinterpret_cast<Address>(this) + memset(reinterpret_cast<void*>(ptr() + kDigitsOffset - kHeapObjectTag), value,
kDigitsOffset - kHeapObjectTag), length * kDigitSize);
value, length * kDigitSize);
} }
MaybeHandle<BigInt> MutableBigInt::MakeImmutable( MaybeHandle<BigInt> MutableBigInt::MakeImmutable(
...@@ -623,7 +633,7 @@ ComparisonResult BigInt::CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y) { ...@@ -623,7 +633,7 @@ ComparisonResult BigInt::CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y) {
return ComparisonResult::kEqual; return ComparisonResult::kEqual;
} }
bool BigInt::EqualToBigInt(BigInt* x, BigInt* y) { bool BigInt::EqualToBigInt(BigInt x, BigInt y) {
if (x->sign() != y->sign()) return false; if (x->sign() != y->sign()) return false;
if (x->length() != y->length()) return false; if (x->length() != y->length()) return false;
for (int i = 0; i < x->length(); i++) { for (int i = 0; i < x->length(); i++) {
...@@ -1173,7 +1183,7 @@ Handle<BigInt> MutableBigInt::AbsoluteSub(Isolate* isolate, Handle<BigInt> x, ...@@ -1173,7 +1183,7 @@ Handle<BigInt> MutableBigInt::AbsoluteSub(Isolate* isolate, Handle<BigInt> x,
// modification. // modification.
MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteAddOne( MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteAddOne(
Isolate* isolate, Handle<BigIntBase> x, bool sign, Isolate* isolate, Handle<BigIntBase> x, bool sign,
MutableBigInt* result_storage) { MutableBigInt result_storage) {
int input_length = x->length(); int input_length = x->length();
// The addition will overflow into a new digit if all existing digits are // The addition will overflow into a new digit if all existing digits are
// at maximum. // at maximum.
...@@ -1186,7 +1196,7 @@ MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteAddOne( ...@@ -1186,7 +1196,7 @@ MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteAddOne(
} }
int result_length = input_length + will_overflow; int result_length = input_length + will_overflow;
Handle<MutableBigInt> result(result_storage, isolate); Handle<MutableBigInt> result(result_storage, isolate);
if (result_storage == nullptr) { if (result_storage.is_null()) {
if (!New(isolate, result_length).ToHandle(&result)) { if (!New(isolate, result_length).ToHandle(&result)) {
return MaybeHandle<MutableBigInt>(); return MaybeHandle<MutableBigInt>();
} }
...@@ -1261,7 +1271,7 @@ MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteSubOne(Isolate* isolate, ...@@ -1261,7 +1271,7 @@ MaybeHandle<MutableBigInt> MutableBigInt::AbsoluteSubOne(Isolate* isolate,
// result_storage: [ 0 ][ x3 ][ r2 ][ r1 ][ r0 ] // result_storage: [ 0 ][ x3 ][ r2 ][ r1 ][ r0 ]
inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp( inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage, ExtraDigitsHandling extra_digits, MutableBigInt result_storage, ExtraDigitsHandling extra_digits,
SymmetricOp symmetric, const std::function<digit_t(digit_t, digit_t)>& op) { SymmetricOp symmetric, const std::function<digit_t(digit_t, digit_t)>& op) {
int x_length = x->length(); int x_length = x->length();
int y_length = y->length(); int y_length = y->length();
...@@ -1276,7 +1286,7 @@ inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp( ...@@ -1276,7 +1286,7 @@ inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp(
DCHECK(num_pairs == Min(x_length, y_length)); DCHECK(num_pairs == Min(x_length, y_length));
Handle<MutableBigInt> result(result_storage, isolate); Handle<MutableBigInt> result(result_storage, isolate);
int result_length = extra_digits == kCopy ? x_length : num_pairs; int result_length = extra_digits == kCopy ? x_length : num_pairs;
if (result_storage == nullptr) { if (result_storage.is_null()) {
result = New(isolate, result_length).ToHandleChecked(); result = New(isolate, result_length).ToHandleChecked();
} else { } else {
DCHECK(result_storage->length() >= result_length); DCHECK(result_storage->length() >= result_length);
...@@ -1300,9 +1310,10 @@ inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp( ...@@ -1300,9 +1310,10 @@ inline Handle<MutableBigInt> MutableBigInt::AbsoluteBitwiseOp(
// If {result_storage} is non-nullptr, it will be used for the result, // If {result_storage} is non-nullptr, it will be used for the result,
// otherwise a new BigInt of appropriate length will be allocated. // otherwise a new BigInt of appropriate length will be allocated.
// {result_storage} may alias {x} or {y} for in-place modification. // {result_storage} may alias {x} or {y} for in-place modification.
Handle<MutableBigInt> MutableBigInt::AbsoluteAnd( Handle<MutableBigInt> MutableBigInt::AbsoluteAnd(Isolate* isolate,
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Handle<BigIntBase> x,
MutableBigInt* result_storage) { Handle<BigIntBase> y,
MutableBigInt result_storage) {
return AbsoluteBitwiseOp(isolate, x, y, result_storage, kSkip, kSymmetric, return AbsoluteBitwiseOp(isolate, x, y, result_storage, kSkip, kSymmetric,
[](digit_t a, digit_t b) { return a & b; }); [](digit_t a, digit_t b) { return a & b; });
} }
...@@ -1312,7 +1323,7 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteAnd( ...@@ -1312,7 +1323,7 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteAnd(
// {result_storage} may alias {x} or {y} for in-place modification. // {result_storage} may alias {x} or {y} for in-place modification.
Handle<MutableBigInt> MutableBigInt::AbsoluteAndNot( Handle<MutableBigInt> MutableBigInt::AbsoluteAndNot(
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y,
MutableBigInt* result_storage) { MutableBigInt result_storage) {
return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kNotSymmetric, return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kNotSymmetric,
[](digit_t a, digit_t b) { return a & ~b; }); [](digit_t a, digit_t b) { return a & ~b; });
} }
...@@ -1323,7 +1334,7 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteAndNot( ...@@ -1323,7 +1334,7 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteAndNot(
Handle<MutableBigInt> MutableBigInt::AbsoluteOr(Isolate* isolate, Handle<MutableBigInt> MutableBigInt::AbsoluteOr(Isolate* isolate,
Handle<BigIntBase> x, Handle<BigIntBase> x,
Handle<BigIntBase> y, Handle<BigIntBase> y,
MutableBigInt* result_storage) { MutableBigInt result_storage) {
return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kSymmetric, return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kSymmetric,
[](digit_t a, digit_t b) { return a | b; }); [](digit_t a, digit_t b) { return a | b; });
} }
...@@ -1331,9 +1342,10 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteOr(Isolate* isolate, ...@@ -1331,9 +1342,10 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteOr(Isolate* isolate,
// If {result_storage} is non-nullptr, it will be used for the result, // If {result_storage} is non-nullptr, it will be used for the result,
// otherwise a new BigInt of appropriate length will be allocated. // otherwise a new BigInt of appropriate length will be allocated.
// {result_storage} may alias {x} or {y} for in-place modification. // {result_storage} may alias {x} or {y} for in-place modification.
Handle<MutableBigInt> MutableBigInt::AbsoluteXor( Handle<MutableBigInt> MutableBigInt::AbsoluteXor(Isolate* isolate,
Isolate* isolate, Handle<BigIntBase> x, Handle<BigIntBase> y, Handle<BigIntBase> x,
MutableBigInt* result_storage) { Handle<BigIntBase> y,
MutableBigInt result_storage) {
return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kSymmetric, return AbsoluteBitwiseOp(isolate, x, y, result_storage, kCopy, kSymmetric,
[](digit_t a, digit_t b) { return a ^ b; }); [](digit_t a, digit_t b) { return a ^ b; });
} }
...@@ -1391,9 +1403,9 @@ void MutableBigInt::MultiplyAccumulate(Handle<BigIntBase> multiplicand, ...@@ -1391,9 +1403,9 @@ void MutableBigInt::MultiplyAccumulate(Handle<BigIntBase> multiplicand,
// Multiplies {source} with {factor} and adds {summand} to the result. // Multiplies {source} with {factor} and adds {summand} to the result.
// {result} and {source} may be the same BigInt for inplace modification. // {result} and {source} may be the same BigInt for inplace modification.
void MutableBigInt::InternalMultiplyAdd(BigIntBase* source, digit_t factor, void MutableBigInt::InternalMultiplyAdd(BigIntBase source, digit_t factor,
digit_t summand, int n, digit_t summand, int n,
MutableBigInt* result) { MutableBigInt result) {
DCHECK(source->length() >= n); DCHECK(source->length() >= n);
DCHECK(result->length() >= n); DCHECK(result->length() >= n);
digit_t carry = summand; digit_t carry = summand;
...@@ -1869,8 +1881,8 @@ int BigInt::DigitsByteLengthForBitfield(uint32_t bitfield) { ...@@ -1869,8 +1881,8 @@ int BigInt::DigitsByteLengthForBitfield(uint32_t bitfield) {
// The serialization format MUST NOT CHANGE without updating the format // The serialization format MUST NOT CHANGE without updating the format
// version in value-serializer.cc! // version in value-serializer.cc!
void BigInt::SerializeDigits(uint8_t* storage) { void BigInt::SerializeDigits(uint8_t* storage) {
void* digits = reinterpret_cast<void*>(reinterpret_cast<Address>(this) + void* digits =
kDigitsOffset - kHeapObjectTag); reinterpret_cast<void*>(ptr() + kDigitsOffset - kHeapObjectTag);
#if defined(V8_TARGET_LITTLE_ENDIAN) #if defined(V8_TARGET_LITTLE_ENDIAN)
int bytelength = length() * kDigitSize; int bytelength = length() * kDigitSize;
memcpy(storage, digits, bytelength); memcpy(storage, digits, bytelength);
...@@ -1897,8 +1909,8 @@ MaybeHandle<BigInt> BigInt::FromSerializedDigits( ...@@ -1897,8 +1909,8 @@ MaybeHandle<BigInt> BigInt::FromSerializedDigits(
Handle<MutableBigInt> result = Handle<MutableBigInt> result =
MutableBigInt::Cast(isolate->factory()->NewBigInt(length, pretenure)); MutableBigInt::Cast(isolate->factory()->NewBigInt(length, pretenure));
result->initialize_bitfield(sign, length); result->initialize_bitfield(sign, length);
void* digits = reinterpret_cast<void*>(reinterpret_cast<Address>(*result) + void* digits =
kDigitsOffset - kHeapObjectTag); reinterpret_cast<void*>(result->ptr() + kDigitsOffset - kHeapObjectTag);
#if defined(V8_TARGET_LITTLE_ENDIAN) #if defined(V8_TARGET_LITTLE_ENDIAN)
memcpy(digits, digits_storage.start(), bytelength); memcpy(digits, digits_storage.start(), bytelength);
void* padding_start = void* padding_start =
...@@ -2380,7 +2392,7 @@ void BigInt::ToWordsArray64(int* sign_bit, int* words64_count, ...@@ -2380,7 +2392,7 @@ void BigInt::ToWordsArray64(int* sign_bit, int* words64_count,
} }
} }
uint64_t MutableBigInt::GetRawBits(BigIntBase* x, bool* lossless) { uint64_t MutableBigInt::GetRawBits(BigIntBase x, bool* lossless) {
if (lossless != nullptr) *lossless = true; if (lossless != nullptr) *lossless = true;
if (x->is_zero()) return 0; if (x->is_zero()) return 0;
int len = x->length(); int len = x->length();
...@@ -2395,14 +2407,14 @@ uint64_t MutableBigInt::GetRawBits(BigIntBase* x, bool* lossless) { ...@@ -2395,14 +2407,14 @@ uint64_t MutableBigInt::GetRawBits(BigIntBase* x, bool* lossless) {
} }
int64_t BigInt::AsInt64(bool* lossless) { int64_t BigInt::AsInt64(bool* lossless) {
uint64_t raw = MutableBigInt::GetRawBits(this, lossless); uint64_t raw = MutableBigInt::GetRawBits(*this, lossless);
int64_t result = static_cast<int64_t>(raw); int64_t result = static_cast<int64_t>(raw);
if (lossless != nullptr && (result < 0) != sign()) *lossless = false; if (lossless != nullptr && (result < 0) != sign()) *lossless = false;
return result; return result;
} }
uint64_t BigInt::AsUint64(bool* lossless) { uint64_t BigInt::AsUint64(bool* lossless) {
uint64_t result = MutableBigInt::GetRawBits(this, lossless); uint64_t result = MutableBigInt::GetRawBits(*this, lossless);
if (lossless != nullptr && sign()) *lossless = false; if (lossless != nullptr && sign()) *lossless = false;
return result; return result;
} }
...@@ -2585,7 +2597,7 @@ void MutableBigInt::set_64_bits(uint64_t bits) { ...@@ -2585,7 +2597,7 @@ void MutableBigInt::set_64_bits(uint64_t bits) {
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
void BigInt::BigIntPrint(std::ostream& os) { void BigInt::BigIntPrint(std::ostream& os) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
HeapObject::PrintHeader(os, "BigInt"); PrintHeader(os, "BigInt");
int len = length(); int len = length();
os << "\n- length: " << len; os << "\n- length: " << len;
os << "\n- sign: " << sign(); os << "\n- sign: " << sign();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/globals.h" #include "src/globals.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/objects/heap-object.h"
#include "src/utils.h" #include "src/utils.h"
// Has to be the last include (doesn't have include guards): // Has to be the last include (doesn't have include guards):
...@@ -21,7 +22,7 @@ class ValueSerializer; ...@@ -21,7 +22,7 @@ class ValueSerializer;
// BigIntBase is just the raw data object underlying a BigInt. Use with care! // BigIntBase is just the raw data object underlying a BigInt. Use with care!
// Most code should be using BigInts instead. // Most code should be using BigInts instead.
class BigIntBase : public HeapObject { class BigIntBase : public HeapObjectPtr {
public: public:
inline int length() const { inline int length() const {
int32_t bitfield = RELAXED_READ_INT32_FIELD(this, kBitfieldOffset); int32_t bitfield = RELAXED_READ_INT32_FIELD(this, kBitfieldOffset);
...@@ -34,6 +35,9 @@ class BigIntBase : public HeapObject { ...@@ -34,6 +35,9 @@ class BigIntBase : public HeapObject {
return LengthBits::decode(static_cast<uint32_t>(bitfield)); return LengthBits::decode(static_cast<uint32_t>(bitfield));
} }
static inline BigIntBase unchecked_cast(ObjectPtr o) {
return bit_cast<BigIntBase>(o);
}
// Increasing kMaxLength will require code changes. // Increasing kMaxLength will require code changes.
static const int kMaxLengthBits = static const int kMaxLengthBits =
kMaxInt - kSystemPointerSize * kBitsPerByte - 1; kMaxInt - kSystemPointerSize * kBitsPerByte - 1;
...@@ -86,7 +90,10 @@ class BigIntBase : public HeapObject { ...@@ -86,7 +90,10 @@ class BigIntBase : public HeapObject {
bool is_zero() const { return length() == 0; } bool is_zero() const { return length() == 0; }
DISALLOW_IMPLICIT_CONSTRUCTORS(BigIntBase); // Only serves to make macros happy; other code should use IsBigInt.
bool IsBigIntBase() const { return true; }
OBJECT_CONSTRUCTORS(BigIntBase, HeapObjectPtr);
}; };
class FreshlyAllocatedBigInt : public BigIntBase { class FreshlyAllocatedBigInt : public BigIntBase {
...@@ -102,7 +109,10 @@ class FreshlyAllocatedBigInt : public BigIntBase { ...@@ -102,7 +109,10 @@ class FreshlyAllocatedBigInt : public BigIntBase {
// (and no explicit operator is provided either). // (and no explicit operator is provided either).
public: public:
inline static FreshlyAllocatedBigInt* cast(Object* object); inline static FreshlyAllocatedBigInt cast(Object* object);
inline static FreshlyAllocatedBigInt unchecked_cast(ObjectPtr o) {
return bit_cast<FreshlyAllocatedBigInt>(o);
}
// Clear uninitialized padding space. // Clear uninitialized padding space.
inline void clear_padding() { inline void clear_padding() {
...@@ -114,10 +124,12 @@ class FreshlyAllocatedBigInt : public BigIntBase { ...@@ -114,10 +124,12 @@ class FreshlyAllocatedBigInt : public BigIntBase {
} }
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(FreshlyAllocatedBigInt); // Only serves to make macros happy; other code should use IsBigInt.
bool IsFreshlyAllocatedBigInt() const { return true; }
OBJECT_CONSTRUCTORS(FreshlyAllocatedBigInt, BigIntBase);
}; };
// UNDER CONSTRUCTION!
// Arbitrary precision integers in JavaScript. // Arbitrary precision integers in JavaScript.
class V8_EXPORT_PRIVATE BigInt : public BigIntBase { class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
public: public:
...@@ -148,7 +160,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase { ...@@ -148,7 +160,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
Handle<BigInt> y); Handle<BigInt> y);
// More convenient version of "bool LessThan(x, y)". // More convenient version of "bool LessThan(x, y)".
static ComparisonResult CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y); static ComparisonResult CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y);
static bool EqualToBigInt(BigInt* x, BigInt* y); static bool EqualToBigInt(BigInt x, BigInt y);
static MaybeHandle<BigInt> BitwiseAnd(Isolate* isolate, Handle<BigInt> x, static MaybeHandle<BigInt> BitwiseAnd(Isolate* isolate, Handle<BigInt> x,
Handle<BigInt> y); Handle<BigInt> y);
static MaybeHandle<BigInt> BitwiseXor(Isolate* isolate, Handle<BigInt> x, static MaybeHandle<BigInt> BitwiseXor(Isolate* isolate, Handle<BigInt> x,
...@@ -189,7 +201,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase { ...@@ -189,7 +201,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
int Words64Count(); int Words64Count();
void ToWordsArray64(int* sign_bit, int* words64_count, uint64_t* words); void ToWordsArray64(int* sign_bit, int* words64_count, uint64_t* words);
DECL_CAST(BigInt) DECL_CAST2(BigInt)
DECL_VERIFIER(BigInt) DECL_VERIFIER(BigInt)
DECL_PRINTER(BigInt) DECL_PRINTER(BigInt)
void BigIntShortPrint(std::ostream& os); void BigIntShortPrint(std::ostream& os);
...@@ -239,7 +251,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase { ...@@ -239,7 +251,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage, Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage,
PretenureFlag pretenure); PretenureFlag pretenure);
DISALLOW_IMPLICIT_CONSTRUCTORS(BigInt); OBJECT_CONSTRUCTORS(BigInt, BigIntBase);
}; };
} // namespace internal } // namespace internal
......
...@@ -265,7 +265,7 @@ void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) { ...@@ -265,7 +265,7 @@ void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16)); WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16));
} }
void ValueSerializer::WriteBigIntContents(BigInt* bigint) { void ValueSerializer::WriteBigIntContents(BigInt bigint) {
uint32_t bitfield = bigint->GetBitfieldForSerialization(); uint32_t bitfield = bigint->GetBitfieldForSerialization();
int bytelength = BigInt::DigitsByteLengthForBitfield(bitfield); int bytelength = BigInt::DigitsByteLengthForBitfield(bitfield);
WriteVarint<uint32_t>(bitfield); WriteVarint<uint32_t>(bitfield);
...@@ -435,7 +435,7 @@ void ValueSerializer::WriteMutableHeapNumber(MutableHeapNumber* number) { ...@@ -435,7 +435,7 @@ void ValueSerializer::WriteMutableHeapNumber(MutableHeapNumber* number) {
WriteDouble(number->value()); WriteDouble(number->value());
} }
void ValueSerializer::WriteBigInt(BigInt* bigint) { void ValueSerializer::WriteBigInt(BigInt bigint) {
WriteTag(SerializationTag::kBigInt); WriteTag(SerializationTag::kBigInt);
WriteBigIntContents(bigint); WriteBigIntContents(bigint);
} }
......
...@@ -110,7 +110,7 @@ class ValueSerializer { ...@@ -110,7 +110,7 @@ class ValueSerializer {
void WriteZigZag(T value); void WriteZigZag(T value);
void WriteOneByteString(Vector<const uint8_t> chars); void WriteOneByteString(Vector<const uint8_t> chars);
void WriteTwoByteString(Vector<const uc16> chars); void WriteTwoByteString(Vector<const uc16> chars);
void WriteBigIntContents(BigInt* bigint); void WriteBigIntContents(BigInt bigint);
Maybe<uint8_t*> ReserveRawBytes(size_t bytes); Maybe<uint8_t*> ReserveRawBytes(size_t bytes);
// Writing V8 objects of various kinds. // Writing V8 objects of various kinds.
...@@ -118,7 +118,7 @@ class ValueSerializer { ...@@ -118,7 +118,7 @@ class ValueSerializer {
void WriteSmi(Smi smi); void WriteSmi(Smi smi);
void WriteHeapNumber(HeapNumber* number); void WriteHeapNumber(HeapNumber* number);
void WriteMutableHeapNumber(MutableHeapNumber* number); void WriteMutableHeapNumber(MutableHeapNumber* number);
void WriteBigInt(BigInt* bigint); void WriteBigInt(BigInt bigint);
void WriteString(Handle<String> string); void WriteString(Handle<String> string);
Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver) Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver)
V8_WARN_UNUSED_RESULT; V8_WARN_UNUSED_RESULT;
......
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