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() { ...@@ -52,6 +52,14 @@ FieldAccess AccessBuilder::ForHeapNumberValue() {
return access; return access;
} }
// static
FieldAccess AccessBuilder::ForBigIntBitfield() {
FieldAccess access = {
kTaggedBase, BigInt::kBitfieldOffset, MaybeHandle<Name>(),
MaybeHandle<Map>(), TypeCache::Get().kInt32, MachineType::Int32(),
kNoWriteBarrier};
return access;
}
// static // static
FieldAccess AccessBuilder::ForJSObjectPropertiesOrHash() { FieldAccess AccessBuilder::ForJSObjectPropertiesOrHash() {
......
...@@ -38,6 +38,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final ...@@ -38,6 +38,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final
// Provides access to HeapNumber::value() field. // Provides access to HeapNumber::value() field.
static FieldAccess ForHeapNumberValue(); static FieldAccess ForHeapNumberValue();
// Provides access to BigInt's bit field.
static FieldAccess ForBigIntBitfield();
// Provides access to JSObject::properties() field. // Provides access to JSObject::properties() field.
static FieldAccess ForJSObjectPropertiesOrHash(); static FieldAccess ForJSObjectPropertiesOrHash();
......
...@@ -1137,6 +1137,7 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( ...@@ -1137,6 +1137,7 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
auto if_heapnumber = __ MakeDeferredLabel(); auto if_heapnumber = __ MakeDeferredLabel();
auto if_bigint = __ MakeDeferredLabel();
Node* zero = __ Int32Constant(0); Node* zero = __ Int32Constant(0);
Node* fzero = __ Float64Constant(0.0); Node* fzero = __ Float64Constant(0.0);
...@@ -1164,6 +1165,12 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( ...@@ -1164,6 +1165,12 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
__ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()), __ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()),
&if_heapnumber); &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. // All other values that reach here are true.
__ Goto(done, __ Int32Constant(1)); __ Goto(done, __ Int32Constant(1));
...@@ -1175,6 +1182,15 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( ...@@ -1175,6 +1182,15 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit(
__ LoadField(AccessBuilder::ForHeapNumberValue(), value); __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
__ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_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) { Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
......
...@@ -31,6 +31,15 @@ class BigIntBase : public HeapObject { ...@@ -31,6 +31,15 @@ class BigIntBase : public HeapObject {
static const int kMaxLengthBits = 1024 * 1024; static const int kMaxLengthBits = 1024 * 1024;
static const int kMaxLength = kMaxLengthBits / (kPointerSize * kBitsPerByte); 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: private:
friend class BigInt; friend class BigInt;
friend class MutableBigInt; friend class MutableBigInt;
...@@ -44,15 +53,6 @@ class BigIntBase : public HeapObject { ...@@ -44,15 +53,6 @@ class BigIntBase : public HeapObject {
static const int kHalfDigitBits = kDigitBits / 2; static const int kHalfDigitBits = kDigitBits / 2;
static const digit_t kHalfDigitMask = (1ull << kHalfDigitBits) - 1; 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. // sign() == true means negative.
inline bool sign() const { inline bool sign() const {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset); intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
......
...@@ -11,3 +11,13 @@ function foo(x) { ...@@ -11,3 +11,13 @@ function foo(x) {
foo(42n); foo(42n);
%OptimizeFunctionOnNextCall(foo); %OptimizeFunctionOnNextCall(foo);
assertEquals(42, foo(42n)); 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