Provide optimized support for the %GetOrdinaryHasInstance intrinsic.

This new intrinsic is used by the desugared ES6 instanceof implementation for
the cases when the F[@@hasInstance] property is null or undefined.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/1809993002

Cr-Commit-Position: refs/heads/master@{#34866}
This commit is contained in:
mvstanton 2016-03-17 08:45:47 -07:00 committed by Commit bot
parent 680f50a9b9
commit 992ae64de0
12 changed files with 69 additions and 1 deletions

View File

@ -97,6 +97,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceCall(node);
case Runtime::kInlineGetSuperConstructor:
return ReduceGetSuperConstructor(node);
case Runtime::kInlineGetOrdinaryHasInstance:
return ReduceGetOrdinaryHasInstance(node);
default:
break;
}
@ -516,6 +518,16 @@ Reduction JSIntrinsicLowering::ReduceGetSuperConstructor(Node* node) {
active_function_map, effect, control);
}
Reduction JSIntrinsicLowering::ReduceGetOrdinaryHasInstance(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* context = NodeProperties::GetContextInput(node);
Node* native_context = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
context, context, effect);
return Change(node, javascript()->LoadContext(
0, Context::ORDINARY_HAS_INSTANCE_INDEX, true),
native_context, context, effect);
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b) {

View File

@ -67,6 +67,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
Reduction ReduceToString(Node* node);
Reduction ReduceCall(Node* node);
Reduction ReduceGetSuperConstructor(Node* node);
Reduction ReduceGetOrdinaryHasInstance(Node* node);
Reduction Change(Node* node, const Operator* op);
Reduction Change(Node* node, const Operator* op, Node* a, Node* b);

View File

@ -12885,6 +12885,12 @@ void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) {
return ast_context()->ReturnValue(value);
}
void HOptimizedGraphBuilder::GenerateGetOrdinaryHasInstance(CallRuntime* call) {
DCHECK(call->arguments()->length() == 0);
// ordinary_has_instance is immutable so we can treat it as a constant.
HValue* value = Add<HConstant>(isolate()->ordinary_has_instance());
return ast_context()->ReturnValue(value);
}
#undef CHECK_BAILOUT
#undef CHECK_ALIVE

View File

@ -2230,6 +2230,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
F(RegExpSource) \
F(NumberToString) \
F(DebugIsActive) \
F(GetOrdinaryHasInstance) \
/* Typed Arrays */ \
F(TypedArrayInitialize) \
F(MaxSmi) \

View File

@ -3316,6 +3316,11 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(r0);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ LoadNativeContextSlot(Context::ORDINARY_HAS_INSTANCE_INDEX, r0);
context()->Plug(r0);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -3121,6 +3121,11 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(x0);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ LoadNativeContextSlot(Context::ORDINARY_HAS_INSTANCE_INDEX, x0);
context()->Plug(x0);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -530,6 +530,7 @@ class FullCodeGenerator: public AstVisitor {
F(ToName) \
F(ToObject) \
F(DebugIsActive) \
F(GetOrdinaryHasInstance) \
F(CreateIterResultObject)
#define GENERATOR_DECLARATION(Name) void Emit##Name(CallRuntime* call);

View File

@ -3205,6 +3205,12 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(eax);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ mov(eax, NativeContextOperand());
__ mov(eax, ContextOperand(eax, Context::ORDINARY_HAS_INSTANCE_INDEX));
context()->Plug(eax);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -3327,6 +3327,11 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(v0);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ LoadNativeContextSlot(Context::ORDINARY_HAS_INSTANCE_INDEX, v0);
context()->Plug(v0);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -3330,6 +3330,11 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(v0);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ LoadNativeContextSlot(Context::ORDINARY_HAS_INSTANCE_INDEX, v0);
context()->Plug(v0);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -3193,6 +3193,11 @@ void FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
context()->Plug(rax);
}
void FullCodeGenerator::EmitGetOrdinaryHasInstance(CallRuntime* expr) {
DCHECK_EQ(0, expr->arguments()->length());
__ LoadNativeContextSlot(Context::ORDINARY_HAS_INSTANCE_INDEX, rax);
context()->Plug(rax);
}
void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);

View File

@ -277,7 +277,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineMathSqrt) {
// -----------------------------------------------------------------------------
// %_MathClz32
TEST_F(JSIntrinsicLoweringTest, InlineMathClz32) {
Node* const input = Parameter(0);
Node* const context = Parameter(1);
@ -334,6 +333,23 @@ TEST_F(JSIntrinsicLoweringTest, InlineValueOf) {
AllOf(CaptureEq(&if_false0), IsIfFalse(CaptureEq(&branch0))))));
}
// -----------------------------------------------------------------------------
// %_GetOrdinaryHasInstance
TEST_F(JSIntrinsicLoweringTest, InlineGetOrdinaryHasInstance) {
Node* const context = Parameter(0);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction const r = Reduce(graph()->NewNode(
javascript()->CallRuntime(Runtime::kInlineGetOrdinaryHasInstance, 0),
context, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsLoadContext(
ContextAccess(0, Context::ORDINARY_HAS_INSTANCE_INDEX, true), _));
}
} // namespace compiler
} // namespace internal
} // namespace v8