[runtime] Remove useless IN builtin.
authorbmeurer <bmeurer@chromium.org>
Fri, 4 Sep 2015 08:44:27 +0000 (01:44 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 4 Sep 2015 08:44:38 +0000 (08:44 +0000)
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}

32 files changed:
src/compiler/js-generic-lowering.cc
src/compiler/js-generic-lowering.h
src/compiler/js-intrinsic-lowering.cc
src/compiler/js-intrinsic-lowering.h
src/compiler/opcodes.h
src/compiler/simplified-lowering.cc
src/compiler/simplified-operator.cc
src/compiler/simplified-operator.h
src/compiler/typer.cc
src/compiler/verifier.cc
src/contexts.h
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/full-codegen.h
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/hydrogen.cc
src/runtime.js
src/runtime/runtime-numbers.cc
src/runtime/runtime-object.cc
src/runtime/runtime.h
test/cctest/compiler/test-run-inlining.cc
test/cctest/compiler/test-run-intrinsics.cc
test/cctest/test-api.cc
test/unittests/compiler/js-intrinsic-lowering-unittest.cc
test/unittests/compiler/node-test-utils.cc
test/unittests/compiler/node-test-utils.h
test/unittests/compiler/simplified-operator-unittest.cc

index d51ee9d..2a9e6da 100644 (file)
@@ -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);
 }
 
 
index 1f997e4..ffce912 100644 (file)
@@ -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;
index 2b889b2..c786c80 100644 (file)
@@ -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());
 }
index c14882c..15e9b40 100644 (file)
@@ -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);
index dcf71eb..c5b6c81 100644 (file)
   V(StoreField)                    \
   V(StoreBuffer)                   \
   V(StoreElement)                  \
-  V(ObjectIsSmi)                   \
-  V(ObjectIsNonNegativeSmi)
+  V(ObjectIsSmi)
 
 // Opcodes for Machine-level operators.
 #define MACHINE_COMPARE_BINOP_LIST(V) \
index bf7daad..0d4593f 100644 (file)
@@ -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.
index d401fb7..dbb29ea 100644 (file)
@@ -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 {
index 447bf9e..53b6b04 100644 (file)
@@ -164,7 +164,6 @@ class SimplifiedOperatorBuilder final {
   const Operator* ChangeBitToBool();
 
   const Operator* ObjectIsSmi();
-  const Operator* ObjectIsNonNegativeSmi();
 
   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
 
index d75639c..594e4bd 100644 (file)
@@ -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) {
index 43fe9ad..595d9be 100644 (file)
@@ -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());
index dc35d97..6c23cb7 100644 (file)
@@ -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)                             \
index 7d81817..24dc516 100644 (file)
@@ -3280,27 +3280,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index 8b32fc9..59d5920 100644 (file)
@@ -2987,28 +2987,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index a4af52d..78304c4 100644 (file)
@@ -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)                             \
index df7ae9c..1f1c19e 100644 (file)
@@ -3173,27 +3173,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index 7764605..0a3e5bb 100644 (file)
@@ -3272,27 +3272,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index 154edcd..1052817 100644 (file)
@@ -3274,27 +3274,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index ae77956..3a24fd0 100644 (file)
@@ -3271,27 +3271,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index 2010590..e6bb7ed 100644 (file)
@@ -3162,27 +3162,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index c1451a5..b8ac906 100644 (file)
@@ -3193,27 +3193,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* 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<Expression*>* 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);
index ef6579e..99b4ddd 100644 (file)
@@ -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<HPushArguments>(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<HInvokeFunction>(function, 2);
+    HInstruction* result =
+        New<HCallRuntime>(Runtime::FunctionForId(Runtime::kHasProperty), 2);
     return ast_context()->ReturnInstruction(result, expr->id());
   }
 
index 880b7de..b2e9022 100644 (file)
@@ -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,
index d99d5fc..19f0278 100644 (file)
@@ -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);
index 5945488..6287c98 100644 (file)
@@ -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<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
 
+  // Convert the {key} to a name.
   Handle<Name> name;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
                                      Object::ToName(isolate, key));
-  Maybe<bool> 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<bool> maybe = JSReceiver::HasElement(receiver, index);
+  // Lookup the {name} on {receiver}.
+  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
   if (!maybe.IsJust()) return isolate->heap()->exception();
   return isolate->heap()->ToBoolean(maybe.FromJust());
 }
index 30ea5fc..d1f8783 100644 (file)
@@ -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)                       \
index 1b2559f..5119bb7 100644 (file)
@@ -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 () {"
index 2322959..ca61ee2 100644 (file)
@@ -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);
 
index 3a80397..c1b5ece 100644 (file)
@@ -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("
index 92be4e4..99f4574 100644 (file)
@@ -126,23 +126,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
 
 
index dc2bcb3..4cd7293 100644 (file)
@@ -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
 
index 5235d2f..2b68fdb 100644 (file)
@@ -242,7 +242,6 @@ Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
                               const Matcher<Node*>& effect_matcher,
                               const Matcher<Node*>& control_matcher);
 Matcher<Node*> IsObjectIsSmi(const Matcher<Node*>& value_matcher);
-Matcher<Node*> IsObjectIsNonNegativeSmi(const Matcher<Node*>& value_matcher);
 
 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
                       const Matcher<Node*>& base_matcher,
index 0772891..f4c74a5 100644 (file)
@@ -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
 };