From: bmeurer Date: Fri, 4 Sep 2015 08:44:27 +0000 (-0700) Subject: [runtime] Remove useless IN builtin. X-Git-Tag: upstream/4.7.83~458 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3dc9b122fa9f7d551e05f5b9d7415bcfdcac92db;p=platform%2Fupstream%2Fv8.git [runtime] Remove useless IN builtin. Similar to DELETE, the IN builtin is just a thin wrapper for %HasElement and %HasProperty anyway, and cannot be optimized, plus it had a weird special fast case (which also involved at least one LOAD_IC plus some intrinsic magic). R=yangguo@chromium.org,jarin@chromium.org CQ_INCLUDE_TRYBOTS=tryserver.v8:v8_win_nosnap_shared_rel Committed: https://crrev.com/72d60a1e80e81e2e68ca402665e2acbc46c5e471 Cr-Commit-Position: refs/heads/master@{#30154} Review URL: https://codereview.chromium.org/1295433002 Cr-Commit-Position: refs/heads/master@{#30582} --- diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index d51ee9d1b..2a9e6dafa 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -223,38 +223,6 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, } -void JSGenericLowering::ReplaceWithBuiltinCall(Node* node, int context_index, - int nargs) { - Node* context_input = NodeProperties::GetContextInput(node); - Node* effect_input = NodeProperties::GetEffectInput(node); - - CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); - Operator::Properties properties = node->op()->properties(); - Callable callable = - CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS); - CallDescriptor* desc = Linkage::GetStubCallDescriptor( - isolate(), zone(), callable.descriptor(), nargs, flags, properties); - Node* global_object = - graph()->NewNode(machine()->Load(kMachAnyTagged), context_input, - jsgraph()->IntPtrConstant( - Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), - effect_input, graph()->start()); - Node* native_context = - graph()->NewNode(machine()->Load(kMachAnyTagged), global_object, - jsgraph()->IntPtrConstant( - GlobalObject::kNativeContextOffset - kHeapObjectTag), - effect_input, graph()->start()); - Node* function = graph()->NewNode( - machine()->Load(kMachAnyTagged), native_context, - jsgraph()->IntPtrConstant(Context::SlotOffset(context_index)), - effect_input, graph()->start()); - Node* stub_code = jsgraph()->HeapConstant(callable.code()); - node->InsertInput(zone(), 0, stub_code); - node->InsertInput(zone(), 1, function); - node->set_op(common()->Call(desc)); -} - - void JSGenericLowering::ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int nargs_override) { @@ -447,7 +415,7 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) { void JSGenericLowering::LowerJSHasProperty(Node* node) { - ReplaceWithBuiltinCall(node, Context::IN_BUILTIN_INDEX, 2); + ReplaceWithRuntimeCall(node, Runtime::kHasProperty); } diff --git a/src/compiler/js-generic-lowering.h b/src/compiler/js-generic-lowering.h index 1f997e4d6..ffce9126d 100644 --- a/src/compiler/js-generic-lowering.h +++ b/src/compiler/js-generic-lowering.h @@ -38,7 +38,6 @@ class JSGenericLowering final : public Reducer { // Helpers to replace existing nodes with a generic call. void ReplaceWithCompareIC(Node* node, Token::Value token, Strength strength); void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags); - void ReplaceWithBuiltinCall(Node* node, int context_index, int args); void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1); Zone* zone() const; diff --git a/src/compiler/js-intrinsic-lowering.cc b/src/compiler/js-intrinsic-lowering.cc index 2b889b27e..c786c809e 100644 --- a/src/compiler/js-intrinsic-lowering.cc +++ b/src/compiler/js-intrinsic-lowering.cc @@ -54,8 +54,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE); case Runtime::kInlineIsFunction: return ReduceIsInstanceType(node, JS_FUNCTION_TYPE); - case Runtime::kInlineIsNonNegativeSmi: - return ReduceIsNonNegativeSmi(node); case Runtime::kInlineIsRegExp: return ReduceIsInstanceType(node, JS_REGEXP_TYPE); case Runtime::kInlineIsSmi: @@ -241,11 +239,6 @@ Reduction JSIntrinsicLowering::ReduceIsInstanceType( } -Reduction JSIntrinsicLowering::ReduceIsNonNegativeSmi(Node* node) { - return Change(node, simplified()->ObjectIsNonNegativeSmi()); -} - - Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) { return Change(node, simplified()->ObjectIsSmi()); } diff --git a/src/compiler/js-intrinsic-lowering.h b/src/compiler/js-intrinsic-lowering.h index c14882c73..15e9b4053 100644 --- a/src/compiler/js-intrinsic-lowering.h +++ b/src/compiler/js-intrinsic-lowering.h @@ -41,7 +41,6 @@ class JSIntrinsicLowering final : public AdvancedReducer { Reduction ReduceIncrementStatsCounter(Node* node); Reduction ReduceIsMinusZero(Node* node); Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type); - Reduction ReduceIsNonNegativeSmi(Node* node); Reduction ReduceIsSmi(Node* node); Reduction ReduceJSValueGetValue(Node* node); Reduction ReduceMapGetInstanceType(Node* node); diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index dcf71eb43..c5b6c81c1 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -192,8 +192,7 @@ V(StoreField) \ V(StoreBuffer) \ V(StoreElement) \ - V(ObjectIsSmi) \ - V(ObjectIsNonNegativeSmi) + V(ObjectIsSmi) // Opcodes for Machine-level operators. #define MACHINE_COMPARE_BINOP_LIST(V) \ diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index bf7daad79..0d4593f7c 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -919,25 +919,6 @@ class RepresentationSelector { } break; } - case IrOpcode::kObjectIsNonNegativeSmi: { - ProcessInput(node, 0, kMachAnyTagged); - SetOutput(node, kRepBit | kTypeBool); - if (lower()) { - Node* is_tagged = jsgraph_->graph()->NewNode( - jsgraph_->machine()->WordAnd(), node->InputAt(0), - jsgraph_->IntPtrConstant(kSmiTagMask)); - Node* is_smi = jsgraph_->graph()->NewNode( - jsgraph_->machine()->WordEqual(), is_tagged, - jsgraph_->IntPtrConstant(kSmiTag)); - Node* is_non_neg = jsgraph_->graph()->NewNode( - jsgraph_->machine()->IntLessThanOrEqual(), - jsgraph_->IntPtrConstant(0), node->InputAt(0)); - Node* is_non_neg_smi = jsgraph_->graph()->NewNode( - jsgraph_->machine()->Word32And(), is_smi, is_non_neg); - DeferReplacement(node, is_non_neg_smi); - } - break; - } //------------------------------------------------------------------ // Machine-level operators. diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc index d401fb786..dbb29eadd 100644 --- a/src/compiler/simplified-operator.cc +++ b/src/compiler/simplified-operator.cc @@ -185,8 +185,7 @@ const ElementAccess& ElementAccessOf(const Operator* op) { V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \ V(ChangeBoolToBit, Operator::kNoProperties, 1) \ V(ChangeBitToBool, Operator::kNoProperties, 1) \ - V(ObjectIsSmi, Operator::kNoProperties, 1) \ - V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1) + V(ObjectIsSmi, Operator::kNoProperties, 1) struct SimplifiedOperatorGlobalCache final { diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index 447bf9e5e..53b6b044a 100644 --- a/src/compiler/simplified-operator.h +++ b/src/compiler/simplified-operator.h @@ -164,7 +164,6 @@ class SimplifiedOperatorBuilder final { const Operator* ChangeBitToBool(); const Operator* ObjectIsSmi(); - const Operator* ObjectIsNonNegativeSmi(); const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED); diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index d75639c8b..594e4bd61 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -1455,7 +1455,6 @@ Bounds Typer::Visitor::TypeJSCallFunction(Node* node) { Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) { switch (CallRuntimeParametersOf(node->op()).id()) { case Runtime::kInlineIsSmi: - case Runtime::kInlineIsNonNegativeSmi: case Runtime::kInlineIsArray: case Runtime::kInlineIsDate: case Runtime::kInlineIsTypedArray: @@ -1757,11 +1756,6 @@ Bounds Typer::Visitor::TypeObjectIsSmi(Node* node) { } -Bounds Typer::Visitor::TypeObjectIsNonNegativeSmi(Node* node) { - return Bounds(Type::Boolean()); -} - - // Machine operators. Bounds Typer::Visitor::TypeLoad(Node* node) { diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 43fe9ada2..595d9be0d 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -684,10 +684,6 @@ void Verifier::Visitor::Check(Node* node) { CheckValueInputIs(node, 0, Type::Any()); CheckUpperIs(node, Type::Boolean()); break; - case IrOpcode::kObjectIsNonNegativeSmi: - CheckValueInputIs(node, 0, Type::Any()); - CheckUpperIs(node, Type::Boolean()); - break; case IrOpcode::kAllocate: CheckValueInputIs(node, 0, Type::PlainNumber()); CheckUpperIs(node, Type::TaggedPointer()); diff --git a/src/contexts.h b/src/contexts.h index dc35d9719..6c23cb719 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -114,7 +114,6 @@ enum BindingFlags { V(DIV_BUILTIN_INDEX, JSFunction, div_builtin) \ V(DIV_STRONG_BUILTIN_INDEX, JSFunction, div_strong_builtin) \ V(EQUALS_BUILTIN_INDEX, JSFunction, equals_builtin) \ - V(IN_BUILTIN_INDEX, JSFunction, in_builtin) \ V(MOD_BUILTIN_INDEX, JSFunction, mod_builtin) \ V(MOD_STRONG_BUILTIN_INDEX, JSFunction, mod_strong_builtin) \ V(MUL_BUILTIN_INDEX, JSFunction, mul_builtin) \ diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc index 7d8181774..24dc51608 100644 --- a/src/full-codegen/arm/full-codegen-arm.cc +++ b/src/full-codegen/arm/full-codegen-arm.cc @@ -3280,27 +3280,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ NonNegativeSmiTst(r0); - Split(eq, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -5042,7 +5021,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ CompareRoot(r0, Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc index 8b32fc9dc..59d59202b 100644 --- a/src/full-codegen/arm64/full-codegen-arm64.cc +++ b/src/full-codegen/arm64/full-codegen-arm64.cc @@ -2987,28 +2987,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - uint64_t sign_mask = V8_UINT64_C(1) << (kSmiShift + kSmiValueSize - 1); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ TestAndSplit(x0, kSmiTagMask | sign_mask, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -4771,7 +4749,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ CompareRoot(x0, Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/full-codegen.h b/src/full-codegen/full-codegen.h index a4af52d0a..78304c4fa 100644 --- a/src/full-codegen/full-codegen.h +++ b/src/full-codegen/full-codegen.h @@ -488,7 +488,6 @@ class FullCodeGenerator: public AstVisitor { #define FOR_EACH_FULL_CODE_INTRINSIC(F) \ F(IsSmi) \ - F(IsNonNegativeSmi) \ F(IsArray) \ F(IsTypedArray) \ F(IsRegExp) \ diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc b/src/full-codegen/ia32/full-codegen-ia32.cc index df7ae9c5e..1f1c19e2d 100644 --- a/src/full-codegen/ia32/full-codegen-ia32.cc +++ b/src/full-codegen/ia32/full-codegen-ia32.cc @@ -3173,27 +3173,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ test(eax, Immediate(kSmiTagMask | 0x80000000)); - Split(zero, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -4983,7 +4962,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ cmp(eax, isolate()->factory()->true_value()); Split(equal, if_true, if_false, fall_through); diff --git a/src/full-codegen/mips/full-codegen-mips.cc b/src/full-codegen/mips/full-codegen-mips.cc index 7764605f8..0a3e5bbb2 100644 --- a/src/full-codegen/mips/full-codegen-mips.cc +++ b/src/full-codegen/mips/full-codegen-mips.cc @@ -3272,27 +3272,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ NonNegativeSmiTst(v0, at); - Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -5072,7 +5051,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ LoadRoot(t0, Heap::kTrueValueRootIndex); Split(eq, v0, Operand(t0), if_true, if_false, fall_through); diff --git a/src/full-codegen/mips64/full-codegen-mips64.cc b/src/full-codegen/mips64/full-codegen-mips64.cc index 154edcd18..105281791 100644 --- a/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/src/full-codegen/mips64/full-codegen-mips64.cc @@ -3274,27 +3274,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ NonNegativeSmiTst(v0, at); - Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -5075,7 +5054,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ LoadRoot(a4, Heap::kTrueValueRootIndex); Split(eq, v0, Operand(a4), if_true, if_false, fall_through); diff --git a/src/full-codegen/ppc/full-codegen-ppc.cc b/src/full-codegen/ppc/full-codegen-ppc.cc index ae77956a1..3a24fd0c6 100644 --- a/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/src/full-codegen/ppc/full-codegen-ppc.cc @@ -3271,27 +3271,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, &if_true, - &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ TestIfPositiveSmi(r3, r0); - Split(eq, if_true, if_false, fall_through, cr0); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -5059,7 +5038,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ CompareRoot(r3, Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc index 2010590a0..e6bb7ed40 100644 --- a/src/full-codegen/x64/full-codegen-x64.cc +++ b/src/full-codegen/x64/full-codegen-x64.cc @@ -3162,27 +3162,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - Condition non_negative_smi = masm()->CheckNonNegativeSmi(rax); - Split(non_negative_smi, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -4989,7 +4968,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasProperty, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ CompareRoot(rax, Heap::kTrueValueRootIndex); Split(equal, if_true, if_false, fall_through); diff --git a/src/full-codegen/x87/full-codegen-x87.cc b/src/full-codegen/x87/full-codegen-x87.cc index c1451a58f..b8ac90660 100644 --- a/src/full-codegen/x87/full-codegen-x87.cc +++ b/src/full-codegen/x87/full-codegen-x87.cc @@ -3193,27 +3193,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { } -void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - DCHECK(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - __ test(eax, Immediate(kSmiTagMask | 0x80000000)); - Split(zero, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { ZoneList* args = expr->arguments(); DCHECK(args->length() == 1); @@ -4973,7 +4952,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { switch (op) { case Token::IN: VisitForStackValue(expr->right()); - __ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION); + __ CallRuntime(Runtime::kHasPropert, 2); PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); __ cmp(eax, isolate()->factory()->true_value()); Split(equal, if_true, if_false, fall_through); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index ef6579e43..99b4ddd1e 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -11394,11 +11394,9 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { return ast_context()->ReturnInstruction(result, expr->id()); } else if (op == Token::IN) { - HValue* function = AddLoadJSBuiltin(Context::IN_BUILTIN_INDEX); Add(left, right); - // TODO(olivf) InvokeFunction produces a check for the parameter count, - // even though we are certain to pass the correct number of arguments here. - HInstruction* result = New(function, 2); + HInstruction* result = + New(Runtime::FunctionForId(Runtime::kHasProperty), 2); return ast_context()->ReturnInstruction(result, expr->id()); } diff --git a/src/runtime.js b/src/runtime.js index 880b7dea1..b2e902288 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -424,21 +424,6 @@ function SHR_STRONG(y) { ----------------------------- */ -// ECMA-262, section 11.8.7, page 54. -function IN(x) { - if (!IS_SPEC_OBJECT(x)) { - throw %make_type_error(kInvalidInOperatorUse, this, x); - } - if (%_IsNonNegativeSmi(this)) { - if (IS_ARRAY(x) && %_HasFastPackedElements(x)) { - return this < x.length; - } - return %HasElement(x, this); - } - return %HasProperty(x, this); -} - - function CALL_NON_FUNCTION() { var delegate = %GetFunctionDelegate(this); return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); @@ -826,7 +811,6 @@ $toString = ToString; "div_builtin", DIV, "div_strong_builtin", DIV_STRONG, "equals_builtin", EQUALS, - "in_builtin", IN, "mod_builtin", MOD, "mod_strong_builtin", MOD_STRONG, "mul_builtin", MUL, diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc index d99d5fc54..19f02788f 100644 --- a/src/runtime/runtime-numbers.cc +++ b/src/runtime/runtime-numbers.cc @@ -477,15 +477,6 @@ RUNTIME_FUNCTION(Runtime_IsSmi) { } -RUNTIME_FUNCTION(Runtime_IsNonNegativeSmi) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(Object, obj, 0); - return isolate->heap()->ToBoolean(obj->IsSmi() && - Smi::cast(obj)->value() >= 0); -} - - RUNTIME_FUNCTION(Runtime_GetRootNaN) { SealHandleScope shs(isolate); DCHECK(args.length() == 0); diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index 594548883..6287c98f3 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -753,28 +753,28 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) { } +// ES6 section 12.9.3, operator in. RUNTIME_FUNCTION(Runtime_HasProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 1); + + // Check that {object} is actually a receiver. + if (!object->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object)); + } + Handle receiver = Handle::cast(object); + // Convert the {key} to a name. Handle name; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key)); - Maybe maybe = JSReceiver::HasProperty(receiver, name); - if (!maybe.IsJust()) return isolate->heap()->exception(); - return isolate->heap()->ToBoolean(maybe.FromJust()); -} - -RUNTIME_FUNCTION(Runtime_HasElement) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_SMI_ARG_CHECKED(index, 1); - - Maybe maybe = JSReceiver::HasElement(receiver, index); + // Lookup the {name} on {receiver}. + Maybe maybe = JSReceiver::HasProperty(receiver, name); if (!maybe.IsJust()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(maybe.FromJust()); } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 30ea5fc64..d1f8783c3 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -425,7 +425,6 @@ namespace internal { F(SmiLexicographicCompare, 2, 1) \ F(MaxSmi, 0, 1) \ F(IsSmi, 1, 1) \ - F(IsNonNegativeSmi, 1, 1) \ F(GetRootNaN, 0, 1) @@ -454,7 +453,6 @@ namespace internal { F(DeleteProperty_Strict, 2, 1) \ F(HasOwnProperty, 2, 1) \ F(HasProperty, 2, 1) \ - F(HasElement, 2, 1) \ F(IsPropertyEnumerable, 2, 1) \ F(GetPropertyNamesFast, 1, 1) \ F(GetOwnPropertyNames, 2, 1) \ diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc index 1b2559fc5..5119bb73e 100644 --- a/test/cctest/compiler/test-run-inlining.cc +++ b/test/cctest/compiler/test-run-inlining.cc @@ -415,20 +415,6 @@ TEST(InlineIntrinsicIsSmi) { } -TEST(InlineIntrinsicIsNonNegativeSmi) { - FunctionTester T( - "(function () {" - " var x = 42;" - " function bar(s,t) { return %_IsNonNegativeSmi(x); };" - " return bar;" - "})();", - kInlineFlags); - - InstallAssertInlineCountHelper(CcTest::isolate()); - T.CheckCall(T.true_value(), T.Val(12), T.Val(4)); -} - - TEST(InlineIntrinsicIsArray) { FunctionTester T( "(function () {" diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc index 232295965..ca61ee221 100644 --- a/test/cctest/compiler/test-run-intrinsics.cc +++ b/test/cctest/compiler/test-run-intrinsics.cc @@ -128,18 +128,6 @@ TEST(IsMinusZero) { } -TEST(IsNonNegativeSmi) { - FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags); - - T.CheckTrue(T.Val(1)); - T.CheckFalse(T.Val(1.1)); - T.CheckFalse(T.Val(-0.0)); - T.CheckFalse(T.Val(-2)); - T.CheckFalse(T.Val(-2.3)); - T.CheckFalse(T.undefined()); -} - - TEST(IsRegExp) { FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 3a80397e7..c1b5ecec0 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19303,8 +19303,7 @@ TEST(AccessCheckThrows) { CheckCorrectThrow("%DeleteProperty_Sloppy(other, '1')"); CheckCorrectThrow("%DeleteProperty_Strict(other, '1')"); CheckCorrectThrow("%HasOwnProperty(other, 'x')"); - CheckCorrectThrow("%HasProperty(other, 'x')"); - CheckCorrectThrow("%HasElement(other, 1)"); + CheckCorrectThrow("%HasProperty('x', other)"); CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')"); // PROPERTY_ATTRIBUTES_NONE = 0 CheckCorrectThrow("%DefineAccessorPropertyUnchecked(" diff --git a/test/unittests/compiler/js-intrinsic-lowering-unittest.cc b/test/unittests/compiler/js-intrinsic-lowering-unittest.cc index 92be4e43e..99f457496 100644 --- a/test/unittests/compiler/js-intrinsic-lowering-unittest.cc +++ b/test/unittests/compiler/js-intrinsic-lowering-unittest.cc @@ -125,23 +125,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineIsSmi) { } -// ----------------------------------------------------------------------------- -// %_IsNonNegativeSmi - - -TEST_F(JSIntrinsicLoweringTest, InlineIsNonNegativeSmi) { - Node* const input = Parameter(0); - Node* const context = Parameter(1); - Node* const effect = graph()->start(); - Node* const control = graph()->start(); - Reduction const r = Reduce(graph()->NewNode( - javascript()->CallRuntime(Runtime::kInlineIsNonNegativeSmi, 1), input, - context, effect, control)); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), IsObjectIsNonNegativeSmi(input)); -} - - // ----------------------------------------------------------------------------- // %_IsArray diff --git a/test/unittests/compiler/node-test-utils.cc b/test/unittests/compiler/node-test-utils.cc index dc2bcb396..4cd7293a1 100644 --- a/test/unittests/compiler/node-test-utils.cc +++ b/test/unittests/compiler/node-test-utils.cc @@ -2046,7 +2046,6 @@ IS_UNOP_MATCHER(Float64ExtractHighWord32) IS_UNOP_MATCHER(NumberToInt32) IS_UNOP_MATCHER(NumberToUint32) IS_UNOP_MATCHER(ObjectIsSmi) -IS_UNOP_MATCHER(ObjectIsNonNegativeSmi) IS_UNOP_MATCHER(Word32Clz) #undef IS_UNOP_MATCHER diff --git a/test/unittests/compiler/node-test-utils.h b/test/unittests/compiler/node-test-utils.h index 5235d2f4a..2b68fdbfe 100644 --- a/test/unittests/compiler/node-test-utils.h +++ b/test/unittests/compiler/node-test-utils.h @@ -242,7 +242,6 @@ Matcher IsStoreElement(const Matcher& access_matcher, const Matcher& effect_matcher, const Matcher& control_matcher); Matcher IsObjectIsSmi(const Matcher& value_matcher); -Matcher IsObjectIsNonNegativeSmi(const Matcher& value_matcher); Matcher IsLoad(const Matcher& rep_matcher, const Matcher& base_matcher, diff --git a/test/unittests/compiler/simplified-operator-unittest.cc b/test/unittests/compiler/simplified-operator-unittest.cc index 07728913b..f4c74a535 100644 --- a/test/unittests/compiler/simplified-operator-unittest.cc +++ b/test/unittests/compiler/simplified-operator-unittest.cc @@ -62,8 +62,7 @@ const PureOperator kPureOperators[] = { PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1), PURE(ChangeBoolToBit, Operator::kNoProperties, 1), PURE(ChangeBitToBool, Operator::kNoProperties, 1), - PURE(ObjectIsSmi, Operator::kNoProperties, 1), - PURE(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1) + PURE(ObjectIsSmi, Operator::kNoProperties, 1) #undef PURE };