From 9d023c6327f527e5e73f4d4fcca878a4decdefca Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Mon, 13 Nov 2017 13:00:05 +0100 Subject: [PATCH] [bigint,compiler] Add ObjectIsBigInt simplified operator. R=jarin@chromium.org Bug: v8:6791 Change-Id: I29249640c4612421cd3bf938c465fc823aaa916d Reviewed-on: https://chromium-review.googlesource.com/765967 Reviewed-by: Jaroslav Sevcik Commit-Queue: Georg Neis Cr-Commit-Position: refs/heads/master@{#49360} --- src/compiler/bytecode-graph-builder.cc | 7 +++---- src/compiler/effect-control-linearizer.cc | 25 +++++++++++++++++++++++ src/compiler/effect-control-linearizer.h | 1 + src/compiler/opcodes.h | 1 + src/compiler/simplified-lowering.cc | 4 ++++ src/compiler/simplified-operator.cc | 1 + src/compiler/simplified-operator.h | 1 + src/compiler/typer.cc | 11 ++++++++++ src/compiler/verifier.cc | 1 + 9 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc index 02d16bc84c..fe0197f94c 100644 --- a/src/compiler/bytecode-graph-builder.cc +++ b/src/compiler/bytecode-graph-builder.cc @@ -2448,6 +2448,9 @@ void BytecodeGraphBuilder::VisitTestTypeOf() { case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol: result = NewNode(simplified()->ObjectIsSymbol(), object); break; + case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt: + result = NewNode(simplified()->ObjectIsBigInt(), object); + break; case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean: result = NewNode(common()->Select(MachineRepresentation::kTagged), NewNode(simplified()->ReferenceEqual(), object, @@ -2476,10 +2479,6 @@ void BytecodeGraphBuilder::VisitTestTypeOf() { graph()->NewNode(simplified()->ReferenceEqual(), object, jsgraph()->NullConstant())); break; - case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt: - // TODO(neis): Implement. - UNIMPLEMENTED(); - break; case interpreter::TestTypeOfFlags::LiteralFlag::kOther: UNREACHABLE(); // Should never be emitted. break; diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc index d324c31269..0c2d3e5af0 100644 --- a/src/compiler/effect-control-linearizer.cc +++ b/src/compiler/effect-control-linearizer.cc @@ -715,6 +715,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kObjectIsArrayBufferView: result = LowerObjectIsArrayBufferView(node); break; + case IrOpcode::kObjectIsBigInt: + result = LowerObjectIsBigInt(node); + break; case IrOpcode::kObjectIsCallable: result = LowerObjectIsCallable(node); break; @@ -1952,6 +1955,28 @@ Node* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) { return done.PhiAt(0); } +Node* EffectControlLinearizer::LowerObjectIsBigInt(Node* node) { + Node* value = node->InputAt(0); + + auto if_smi = __ MakeDeferredLabel(); + auto done = __ MakeLabel(MachineRepresentation::kBit); + + Node* check = ObjectIsSmi(value); + __ GotoIf(check, &if_smi); + Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); + Node* value_instance_type = + __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); + Node* vfalse = + __ Word32Equal(value_instance_type, __ Uint32Constant(BIGINT_TYPE)); + __ Goto(&done, vfalse); + + __ Bind(&if_smi); + __ Goto(&done, __ Int32Constant(0)); + + __ Bind(&done); + return done.PhiAt(0); +} + Node* EffectControlLinearizer::LowerObjectIsCallable(Node* node) { Node* value = node->InputAt(0); diff --git a/src/compiler/effect-control-linearizer.h b/src/compiler/effect-control-linearizer.h index 4419d0799d..8a1a26642f 100644 --- a/src/compiler/effect-control-linearizer.h +++ b/src/compiler/effect-control-linearizer.h @@ -86,6 +86,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { Node* LowerCheckedTruncateTaggedToWord32(Node* node, Node* frame_state); Node* LowerAllocate(Node* node); Node* LowerObjectIsArrayBufferView(Node* node); + Node* LowerObjectIsBigInt(Node* node); Node* LowerObjectIsCallable(Node* node); Node* LowerObjectIsConstructor(Node* node); Node* LowerObjectIsDetectableCallable(Node* node); diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index bcc81bfd01..99b960447f 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -358,6 +358,7 @@ V(TransitionAndStoreNonNumberElement) \ V(ToBoolean) \ V(ObjectIsArrayBufferView) \ + V(ObjectIsBigInt) \ V(ObjectIsCallable) \ V(ObjectIsConstructor) \ V(ObjectIsDetectableCallable) \ diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index 1d45f234c4..abd926c3e3 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -2735,6 +2735,10 @@ class RepresentationSelector { VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); return; } + case IrOpcode::kObjectIsBigInt: { + VisitObjectIs(node, Type::BigInt(), lowering); + return; + } case IrOpcode::kObjectIsCallable: { VisitObjectIs(node, Type::Callable(), lowering); return; diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc index 3ac4fb3aed..d96d25c223 100644 --- a/src/compiler/simplified-operator.cc +++ b/src/compiler/simplified-operator.cc @@ -618,6 +618,7 @@ DeoptimizeReason DeoptimizeReasonOf(const Operator* op) { V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \ V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \ V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \ + V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \ V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \ V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \ diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index b6fae8bd7b..78d3f91a09 100644 --- a/src/compiler/simplified-operator.h +++ b/src/compiler/simplified-operator.h @@ -481,6 +481,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final const Operator* CheckEqualsSymbol(); const Operator* ObjectIsArrayBufferView(); + const Operator* ObjectIsBigInt(); const Operator* ObjectIsCallable(); const Operator* ObjectIsConstructor(); const Operator* ObjectIsDetectableCallable(); diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index 7beba496ef..a62edc7777 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -288,6 +288,7 @@ class Typer::Visitor : public Reducer { #undef DECLARE_METHOD static Type* ObjectIsArrayBufferView(Type*, Typer*); + static Type* ObjectIsBigInt(Type*, Typer*); static Type* ObjectIsCallable(Type*, Typer*); static Type* ObjectIsConstructor(Type*, Typer*); static Type* ObjectIsDetectableCallable(Type*, Typer*); @@ -520,6 +521,12 @@ Type* Typer::Visitor::ObjectIsArrayBufferView(Type* type, Typer* t) { return Type::Boolean(); } +Type* Typer::Visitor::ObjectIsBigInt(Type* type, Typer* t) { + if (type->Is(Type::BigInt())) return t->singleton_true_; + if (!type->Maybe(Type::BigInt())) return t->singleton_false_; + return Type::Boolean(); +} + Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) { if (type->Is(Type::Callable())) return t->singleton_true_; if (!type->Maybe(Type::Callable())) return t->singleton_false_; @@ -1993,6 +2000,10 @@ Type* Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) { return TypeUnaryOp(node, ObjectIsArrayBufferView); } +Type* Typer::Visitor::TypeObjectIsBigInt(Node* node) { + return TypeUnaryOp(node, ObjectIsBigInt); +} + Type* Typer::Visitor::TypeObjectIsCallable(Node* node) { return TypeUnaryOp(node, ObjectIsCallable); } diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 1284c27fd5..3bd86122ea 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -1038,6 +1038,7 @@ void Verifier::Visitor::Check(Node* node) { break; case IrOpcode::kObjectIsArrayBufferView: + case IrOpcode::kObjectIsBigInt: case IrOpcode::kObjectIsCallable: case IrOpcode::kObjectIsConstructor: case IrOpcode::kObjectIsDetectableCallable: