Revert "[bigint] Serialization support for BigInts"
This reverts commit 609aaa5549
.
Reason for revert:
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/22157
Original change's description:
> [bigint] Serialization support for BigInts
>
> Bug: v8:6791
> Change-Id: I6d428d0bfc08b7447cd4a961b9f4053c89ed158b
> Reviewed-on: https://chromium-review.googlesource.com/952626
> Reviewed-by: Adam Klein <adamk@chromium.org>
> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#51795}
TBR=adamk@chromium.org,jkummerow@chromium.org
Change-Id: I3c5ab51c40fcd897638d039d433cd764ca7f4e77
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:6791
Reviewed-on: https://chromium-review.googlesource.com/954942
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51796}
This commit is contained in:
parent
609aaa5549
commit
f48ab38a34
@ -2379,7 +2379,8 @@ TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumberWithValue(
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::AllocateBigInt(TNode<IntPtrT> length) {
|
||||
TNode<BigInt> result = AllocateRawBigInt(length);
|
||||
StoreBigIntBitfield(result, WordShl(length, BigInt::LengthBits::kShift));
|
||||
STATIC_ASSERT(BigInt::LengthBits::kShift == 0);
|
||||
StoreBigIntBitfield(result, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1753,51 +1753,6 @@ Handle<BigInt> BigInt::Finalize(Handle<FreshlyAllocatedBigInt> x, bool sign) {
|
||||
return MutableBigInt::MakeImmutable(bigint);
|
||||
}
|
||||
|
||||
// The serialization format MUST NOT CHANGE without updating the format
|
||||
// version in value-serializer.cc!
|
||||
uint32_t BigInt::GetBitfieldForSerialization() const {
|
||||
// In order to make the serialization format the same on 32/64 bit builds,
|
||||
// we convert the length-in-digits to length-in-bytes for serialization.
|
||||
// Being able to do this depends on having enough LengthBits:
|
||||
STATIC_ASSERT(kMaxLength * kDigitSize <= LengthBits::kMax);
|
||||
int bytelength = length() * kDigitSize;
|
||||
return SignBits::encode(sign()) | LengthBits::encode(bytelength);
|
||||
}
|
||||
|
||||
int BigInt::DigitsByteLengthForBitfield(uint32_t bitfield) {
|
||||
return LengthBits::decode(bitfield);
|
||||
}
|
||||
|
||||
// The serialization format MUST NOT CHANGE without updating the format
|
||||
// version in value-serializer.cc!
|
||||
void BigInt::SerializeDigits(uint8_t* storage) {
|
||||
int bytelength = length() * kDigitSize;
|
||||
void* digits = reinterpret_cast<void*>(reinterpret_cast<Address>(this) +
|
||||
kDigitsOffset - kHeapObjectTag);
|
||||
memcpy(storage, digits, bytelength);
|
||||
}
|
||||
|
||||
// The serialization format MUST NOT CHANGE without updating the format
|
||||
// version in value-serializer.cc!
|
||||
MaybeHandle<BigInt> BigInt::FromSerializedDigits(
|
||||
Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage,
|
||||
PretenureFlag pretenure) {
|
||||
int bytelength = LengthBits::decode(bitfield);
|
||||
DCHECK(digits_storage.length() == bytelength);
|
||||
bool sign = SignBits::decode(bitfield);
|
||||
int length = (bytelength + kDigitSize - 1) / kDigitSize; // Round up.
|
||||
Handle<MutableBigInt> result =
|
||||
MutableBigInt::Cast(isolate->factory()->NewBigInt(length, pretenure));
|
||||
result->initialize_bitfield(sign, length);
|
||||
void* digits = reinterpret_cast<void*>(reinterpret_cast<Address>(*result) +
|
||||
kDigitsOffset - kHeapObjectTag);
|
||||
memcpy(digits, digits_storage.start(), bytelength);
|
||||
void* padding_start =
|
||||
reinterpret_cast<void*>(reinterpret_cast<Address>(digits) + bytelength);
|
||||
memset(padding_start, 0, length * kDigitSize - bytelength);
|
||||
return MutableBigInt::MakeImmutable(result);
|
||||
}
|
||||
|
||||
static const char kConversionChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
MaybeHandle<String> MutableBigInt::ToStringBasePowerOfTwo(Handle<BigIntBase> x,
|
||||
|
@ -16,8 +16,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class BigInt;
|
||||
class ValueDeserializer;
|
||||
class ValueSerializer;
|
||||
|
||||
// BigIntBase is just the raw data object underlying a BigInt. Use with care!
|
||||
// Most code should be using BigInts instead.
|
||||
@ -34,9 +32,8 @@ class BigIntBase : public HeapObject {
|
||||
|
||||
static const int kLengthFieldBits = 30;
|
||||
STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1));
|
||||
class SignBits : public BitField<bool, 0, 1> {};
|
||||
class LengthBits : public BitField<int, SignBits::kNext, kLengthFieldBits> {};
|
||||
STATIC_ASSERT(LengthBits::kNext <= 32);
|
||||
class LengthBits : public BitField<int, 0, kLengthFieldBits> {};
|
||||
class SignBits : public BitField<bool, LengthBits::kNext, 1> {};
|
||||
|
||||
static const int kBitfieldOffset = HeapObject::kHeaderSize;
|
||||
static const int kDigitsOffset = kBitfieldOffset + kPointerSize;
|
||||
@ -173,8 +170,6 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
|
||||
|
||||
private:
|
||||
friend class StringToBigIntHelper;
|
||||
friend class ValueDeserializer;
|
||||
friend class ValueSerializer;
|
||||
|
||||
// Special functions for StringToBigIntHelper:
|
||||
static Handle<BigInt> Zero(Isolate* isolate);
|
||||
@ -185,16 +180,6 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
|
||||
uintptr_t factor, uintptr_t summand);
|
||||
static Handle<BigInt> Finalize(Handle<FreshlyAllocatedBigInt> x, bool sign);
|
||||
|
||||
// Special functions for ValueSerializer/ValueDeserializer:
|
||||
uint32_t GetBitfieldForSerialization() const;
|
||||
static int DigitsByteLengthForBitfield(uint32_t bitfield);
|
||||
// Expects {storage} to have a length of at least
|
||||
// {DigitsByteLengthForBitfield(GetBitfieldForSerialization())}.
|
||||
void SerializeDigits(uint8_t* storage);
|
||||
MUST_USE_RESULT static MaybeHandle<BigInt> FromSerializedDigits(
|
||||
Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage,
|
||||
PretenureFlag pretenure);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BigInt);
|
||||
};
|
||||
|
||||
|
@ -80,8 +80,6 @@ enum class SerializationTag : uint8_t {
|
||||
// Number represented as a 64-bit double.
|
||||
// Host byte order is used (N.B. this makes the format non-portable).
|
||||
kDouble = 'N',
|
||||
// BigInt. Bitfield:uint32_t, then raw digits storage.
|
||||
kBigInt = 'K',
|
||||
// byteLength:uint32_t, then raw data
|
||||
kUtf8String = 'S',
|
||||
kOneByteString = '"',
|
||||
@ -109,8 +107,6 @@ enum class SerializationTag : uint8_t {
|
||||
kFalseObject = 'x',
|
||||
// Number object. value:double
|
||||
kNumberObject = 'n',
|
||||
// BigInt object. Bitfield:uint32_t, then raw digits storage.
|
||||
kBigIntObject = 'k',
|
||||
// String object, UTF-8 encoding. byteLength:uint32_t, then raw data.
|
||||
kStringObject = 's',
|
||||
// Regular expression, UTF-8 encoding. byteLength:uint32_t, raw data,
|
||||
@ -257,16 +253,6 @@ void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
|
||||
WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16));
|
||||
}
|
||||
|
||||
void ValueSerializer::WriteBigIntContents(BigInt* bigint) {
|
||||
uint32_t bitfield = bigint->GetBitfieldForSerialization();
|
||||
int bytelength = BigInt::DigitsByteLengthForBitfield(bitfield);
|
||||
WriteVarint<uint32_t>(bitfield);
|
||||
uint8_t* dest;
|
||||
if (ReserveRawBytes(bytelength).To(&dest)) {
|
||||
bigint->SerializeDigits(dest);
|
||||
}
|
||||
}
|
||||
|
||||
void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
|
||||
uint8_t* dest;
|
||||
if (ReserveRawBytes(length).To(&dest)) {
|
||||
@ -354,9 +340,6 @@ Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
|
||||
case MUTABLE_HEAP_NUMBER_TYPE:
|
||||
WriteHeapNumber(HeapNumber::cast(*object));
|
||||
return ThrowIfOutOfMemory();
|
||||
case BIGINT_TYPE:
|
||||
WriteBigInt(BigInt::cast(*object));
|
||||
return ThrowIfOutOfMemory();
|
||||
case JS_TYPED_ARRAY_TYPE:
|
||||
case JS_DATA_VIEW_TYPE: {
|
||||
// Despite being JSReceivers, these have their wrapped buffer serialized
|
||||
@ -420,11 +403,6 @@ void ValueSerializer::WriteHeapNumber(HeapNumber* number) {
|
||||
WriteDouble(number->value());
|
||||
}
|
||||
|
||||
void ValueSerializer::WriteBigInt(BigInt* bigint) {
|
||||
WriteTag(SerializationTag::kBigInt);
|
||||
WriteBigIntContents(bigint);
|
||||
}
|
||||
|
||||
void ValueSerializer::WriteString(Handle<String> string) {
|
||||
string = String::Flatten(string);
|
||||
DisallowHeapAllocation no_gc;
|
||||
@ -709,9 +687,6 @@ Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
|
||||
} else if (inner_value->IsNumber()) {
|
||||
WriteTag(SerializationTag::kNumberObject);
|
||||
WriteDouble(inner_value->Number());
|
||||
} else if (inner_value->IsBigInt()) {
|
||||
WriteTag(SerializationTag::kBigIntObject);
|
||||
WriteBigIntContents(BigInt::cast(inner_value));
|
||||
} else if (inner_value->IsString()) {
|
||||
WriteTag(SerializationTag::kStringObject);
|
||||
WriteString(handle(String::cast(inner_value), isolate_));
|
||||
@ -1179,8 +1154,6 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {
|
||||
if (number.IsNothing()) return MaybeHandle<Object>();
|
||||
return isolate_->factory()->NewNumber(number.FromJust(), pretenure_);
|
||||
}
|
||||
case SerializationTag::kBigInt:
|
||||
return ReadBigInt();
|
||||
case SerializationTag::kUtf8String:
|
||||
return ReadUtf8String();
|
||||
case SerializationTag::kOneByteString:
|
||||
@ -1203,7 +1176,6 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {
|
||||
case SerializationTag::kTrueObject:
|
||||
case SerializationTag::kFalseObject:
|
||||
case SerializationTag::kNumberObject:
|
||||
case SerializationTag::kBigIntObject:
|
||||
case SerializationTag::kStringObject:
|
||||
return ReadJSValue(tag);
|
||||
case SerializationTag::kRegExp:
|
||||
@ -1251,18 +1223,6 @@ MaybeHandle<String> ValueDeserializer::ReadString() {
|
||||
return Handle<String>::cast(object);
|
||||
}
|
||||
|
||||
MaybeHandle<BigInt> ValueDeserializer::ReadBigInt() {
|
||||
uint32_t bitfield;
|
||||
if (!ReadVarint<uint32_t>().To(&bitfield)) return MaybeHandle<BigInt>();
|
||||
int bytelength = BigInt::DigitsByteLengthForBitfield(bitfield);
|
||||
Vector<const uint8_t> digits_storage;
|
||||
if (!ReadRawBytes(bytelength).To(&digits_storage)) {
|
||||
return MaybeHandle<BigInt>();
|
||||
}
|
||||
return BigInt::FromSerializedDigits(isolate_, bitfield, digits_storage,
|
||||
pretenure_);
|
||||
}
|
||||
|
||||
MaybeHandle<String> ValueDeserializer::ReadUtf8String() {
|
||||
uint32_t utf8_length;
|
||||
Vector<const uint8_t> utf8_bytes;
|
||||
@ -1504,14 +1464,6 @@ MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) {
|
||||
value->set_value(*number_object);
|
||||
break;
|
||||
}
|
||||
case SerializationTag::kBigIntObject: {
|
||||
Handle<BigInt> bigint;
|
||||
if (!ReadBigInt().ToHandle(&bigint)) return MaybeHandle<JSValue>();
|
||||
value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
|
||||
isolate_->bigint_function(), pretenure_));
|
||||
value->set_value(*bigint);
|
||||
break;
|
||||
}
|
||||
case SerializationTag::kStringObject: {
|
||||
Handle<String> string;
|
||||
if (!ReadString().ToHandle(&string)) return MaybeHandle<JSValue>();
|
||||
|
@ -19,7 +19,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class BigInt;
|
||||
class HeapNumber;
|
||||
class Isolate;
|
||||
class JSArrayBuffer;
|
||||
@ -108,14 +107,12 @@ class ValueSerializer {
|
||||
void WriteZigZag(T value);
|
||||
void WriteOneByteString(Vector<const uint8_t> chars);
|
||||
void WriteTwoByteString(Vector<const uc16> chars);
|
||||
void WriteBigIntContents(BigInt* bigint);
|
||||
Maybe<uint8_t*> ReserveRawBytes(size_t bytes);
|
||||
|
||||
// Writing V8 objects of various kinds.
|
||||
void WriteOddball(Oddball* oddball);
|
||||
void WriteSmi(Smi* smi);
|
||||
void WriteHeapNumber(HeapNumber* number);
|
||||
void WriteBigInt(BigInt* bigint);
|
||||
void WriteString(Handle<String> string);
|
||||
Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver) WARN_UNUSED_RESULT;
|
||||
Maybe<bool> WriteJSObject(Handle<JSObject> object) WARN_UNUSED_RESULT;
|
||||
@ -258,7 +255,6 @@ class ValueDeserializer {
|
||||
|
||||
// Reading V8 objects of specific kinds.
|
||||
// The tag is assumed to have already been read.
|
||||
MaybeHandle<BigInt> ReadBigInt() WARN_UNUSED_RESULT;
|
||||
MaybeHandle<String> ReadUtf8String() WARN_UNUSED_RESULT;
|
||||
MaybeHandle<String> ReadOneByteString() WARN_UNUSED_RESULT;
|
||||
MaybeHandle<String> ReadTwoByteString() WARN_UNUSED_RESULT;
|
||||
|
@ -387,72 +387,6 @@ TEST_F(ValueSerializerTest, DecodeNumber) {
|
||||
// TODO(jbroman): Equivalent test for big-endian machines.
|
||||
}
|
||||
|
||||
TEST_F(ValueSerializerTest, RoundTripBigInt) {
|
||||
Local<Value> value = RoundTripTest(BigInt::New(isolate(), -42));
|
||||
ASSERT_TRUE(value->IsBigInt());
|
||||
ExpectScriptTrue("result === -42n");
|
||||
|
||||
value = RoundTripTest(BigInt::New(isolate(), 42));
|
||||
ExpectScriptTrue("result === 42n");
|
||||
|
||||
value = RoundTripTest(BigInt::New(isolate(), 0));
|
||||
ExpectScriptTrue("result === 0n");
|
||||
|
||||
value = RoundTripTest("0x1234567890abcdef777888999n");
|
||||
ExpectScriptTrue("result === 0x1234567890abcdef777888999n");
|
||||
|
||||
value = RoundTripTest("-0x1234567890abcdef777888999123n");
|
||||
ExpectScriptTrue("result === -0x1234567890abcdef777888999123n");
|
||||
|
||||
Context::Scope scope(serialization_context());
|
||||
value = RoundTripTest(BigIntObject::New(isolate(), 23));
|
||||
ASSERT_TRUE(value->IsBigIntObject());
|
||||
ExpectScriptTrue("result == 23n");
|
||||
}
|
||||
|
||||
TEST_F(ValueSerializerTest, DecodeBigInt) {
|
||||
Local<Value> value = DecodeTest({
|
||||
0xFF, 0x0D, // Version 13
|
||||
0x4B, // BigInt
|
||||
0x08, // Bitfield: sign = false, bytelength = 4
|
||||
0x2A, 0x00, 0x00, 0x00, // Digit: 42
|
||||
});
|
||||
ASSERT_TRUE(value->IsBigInt());
|
||||
ExpectScriptTrue("result === 42n");
|
||||
|
||||
value = DecodeTest({
|
||||
0xFF, 0x0D, // Version 13
|
||||
0x6B, // BigIntObject
|
||||
0x11, // Bitfield: sign = true, bytelength = 8
|
||||
0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Digit: 42
|
||||
});
|
||||
ASSERT_TRUE(value->IsBigIntObject());
|
||||
ExpectScriptTrue("result == -42n");
|
||||
|
||||
value = DecodeTest({
|
||||
0xFF, 0x0D, // Version 13
|
||||
0x4B, // BigInt
|
||||
0x10, // Bitfield: sign = false, bytelength = 8
|
||||
0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12 // Digit(s).
|
||||
});
|
||||
ExpectScriptTrue("result === 0x1234567890abcdefn");
|
||||
|
||||
value = DecodeTest({0xFF, 0x0D, // Version 13
|
||||
0x4B, // BigInt
|
||||
0x17, // Bitfield: sign = true, bytelength = 11
|
||||
0xEF, 0xCD, 0xAB, 0x90, // Digits.
|
||||
0x78, 0x56, 0x34, 0x12, 0x33, 0x44, 0x55});
|
||||
ExpectScriptTrue("result === -0x5544331234567890abcdefn");
|
||||
|
||||
value = DecodeTest({
|
||||
0xFF, 0x0D, // Version 13
|
||||
0x4B, // BigInt
|
||||
0x02, // Bitfield: sign = false, bytelength = 1
|
||||
0x2A, // Digit: 42
|
||||
});
|
||||
ExpectScriptTrue("result === 42n");
|
||||
}
|
||||
|
||||
// String constants (in UTF-8) used for string encoding tests.
|
||||
static const char kHelloString[] = "Hello";
|
||||
static const char kQuebecString[] = "\x51\x75\xC3\xA9\x62\x65\x63";
|
||||
|
Loading…
Reference in New Issue
Block a user