Commit dd54b5b0 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[bigint,compiler] Adapt TruncatePointerTaggedToBit.

It reflects the semantics of ToBoolean, so it must be adapted for
bigints.

Bug: v8:6791
Change-Id: I18931df21528463dacf5ad50fa8264b1c968c6b5
Reviewed-on: https://chromium-review.googlesource.com/799831Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49776}
parent 08e623b4
......@@ -52,6 +52,14 @@ FieldAccess AccessBuilder::ForHeapNumberValue() {
return access;
}
// static
FieldAccess AccessBuilder::ForBigIntBitfield() {
FieldAccess access = {
kTaggedBase, BigInt::kBitfieldOffset, MaybeHandle<Name>(),
MaybeHandle<Map>(), TypeCache::Get().kInt32, MachineType::Int32(),
kNoWriteBarrier};
return access;
}
// static
FieldAccess AccessBuilder::ForJSObjectPropertiesOrHash() {
......
......@@ -38,6 +38,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final
// Provides access to HeapNumber::value() field.
static FieldAccess ForHeapNumberValue();
// Provides access to BigInt's bit field.
static FieldAccess ForBigIntBitfield();
// Provides access to JSObject::properties() field.
static FieldAccess ForJSObjectPropertiesOrHash();
......
......@@ -1137,6 +1137,7 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
Node* value = node->InputAt(0);
auto if_heapnumber = __ MakeDeferredLabel();
auto if_bigint = __ MakeDeferredLabel();
Node* zero = __ Int32Constant(0);
Node* fzero = __ Float64Constant(0.0);
......@@ -1164,6 +1165,12 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
__ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()),
&if_heapnumber);
// Check if {value} is a BigInt.
Node* value_instance_type =
__ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
__ GotoIf(__ Word32Equal(value_instance_type, __ Int32Constant(BIGINT_TYPE)),
&if_bigint);
// All other values that reach here are true.
__ Goto(done, __ Int32Constant(1));
......@@ -1175,6 +1182,15 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
__ LoadField(AccessBuilder::ForHeapNumberValue(), value);
__ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
}
__ Bind(&if_bigint);
{
Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value);
Node* length_is_zero = __ Word32Equal(
__ Word32And(bitfield, __ Int32Constant(BigInt::LengthBits::kMask)),
zero);
__ Goto(done, __ Word32Equal(length_is_zero, zero));
}
}
Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
......
......@@ -31,6 +31,15 @@ class BigIntBase : public HeapObject {
static const int kMaxLengthBits = 1024 * 1024;
static const int kMaxLength = kMaxLengthBits / (kPointerSize * kBitsPerByte);
static const int kLengthFieldBits = 20;
STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1));
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;
static const int kHeaderSize = kDigitsOffset;
private:
friend class BigInt;
friend class MutableBigInt;
......@@ -44,15 +53,6 @@ class BigIntBase : public HeapObject {
static const int kHalfDigitBits = kDigitBits / 2;
static const digit_t kHalfDigitMask = (1ull << kHalfDigitBits) - 1;
static const int kBitfieldOffset = HeapObject::kHeaderSize;
static const int kDigitsOffset = kBitfieldOffset + kPointerSize;
static const int kHeaderSize = kDigitsOffset;
static const int kLengthFieldBits = 20;
STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1));
class LengthBits : public BitField<int, 0, kLengthFieldBits> {};
class SignBits : public BitField<bool, LengthBits::kNext, 1> {};
// sign() == true means negative.
inline bool sign() const {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
......
......@@ -11,3 +11,13 @@ function foo(x) {
foo(42n);
%OptimizeFunctionOnNextCall(foo);
assertEquals(42, foo(42n));
function bar(x) {
return !x;
}
bar(0n);
%OptimizeFunctionOnNextCall(bar);
assertSame(true, bar(0n));
assertSame(false, bar(42n));
assertSame(false, bar(73786976294838206464n));
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