[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}
This commit is contained in:
parent
40fbed0609
commit
3dc9b122fa
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -164,7 +164,6 @@ class SimplifiedOperatorBuilder final {
|
||||
const Operator* ChangeBitToBool();
|
||||
|
||||
const Operator* ObjectIsSmi();
|
||||
const Operator* ObjectIsNonNegativeSmi();
|
||||
|
||||
const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -753,33 +753,33 @@ 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));
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
if (!maybe.IsJust()) return isolate->heap()->exception();
|
||||
return isolate->heap()->ToBoolean(maybe.FromJust());
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
|
@ -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) \
|
||||
|
@ -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 () {"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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("
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user