Commit f19ec926 authored by mvstanton's avatar mvstanton Committed by Commit bot

ES6: improve performance of ES6 instanceof

This CL restores special crankshaft optimizations for instance of when
--harmony-instanceof is true. Similar work has to happen for TurboFan.

I've added a flag to pile-up the optimizations to be done elsewhere, which
will follow over several CLs.

R=verwaest@chromium.org, mstarzinger@chromium.org
BUG=v8:4447
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#34930}
parent ac833557
...@@ -11509,6 +11509,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { ...@@ -11509,6 +11509,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
} }
if (op == Token::INSTANCEOF) { if (op == Token::INSTANCEOF) {
DCHECK(!FLAG_harmony_instanceof);
// Check to see if the rhs of the instanceof is a known function. // Check to see if the rhs of the instanceof is a known function.
if (right->IsConstant() && if (right->IsConstant() &&
HConstant::cast(right)->handle(isolate())->IsJSFunction()) { HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
...@@ -12629,6 +12630,45 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { ...@@ -12629,6 +12630,45 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) {
DCHECK_LE(2, call->arguments()->length()); DCHECK_LE(2, call->arguments()->length());
CHECK_ALIVE(VisitExpressions(call->arguments())); CHECK_ALIVE(VisitExpressions(call->arguments()));
// Try and customize ES6 instanceof here.
// We should at least have the constructor on the expression stack.
if (FLAG_harmony_instanceof && FLAG_harmony_instanceof_opt &&
call->arguments()->length() == 3) {
HValue* target = environment()->ExpressionStackAt(2);
if (target->IsConstant()) {
HConstant* constant_function = HConstant::cast(target);
if (constant_function->handle(isolate())->IsJSFunction()) {
Handle<JSFunction> func =
Handle<JSFunction>::cast(constant_function->handle(isolate()));
if (*func == isolate()->native_context()->ordinary_has_instance()) {
// Look at the function, which will be argument 1.
HValue* right = environment()->ExpressionStackAt(1);
if (right->IsConstant() &&
HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
Handle<JSFunction> constructor = Handle<JSFunction>::cast(
HConstant::cast(right)->handle(isolate()));
if (constructor->IsConstructor() &&
!constructor->map()->has_non_instance_prototype()) {
JSFunction::EnsureHasInitialMap(constructor);
DCHECK(constructor->has_initial_map());
Handle<Map> initial_map(constructor->initial_map(), isolate());
top_info()->dependencies()->AssumeInitialMapCantChange(
initial_map);
HInstruction* prototype =
Add<HConstant>(handle(initial_map->prototype(), isolate()));
HValue* left = environment()->ExpressionStackAt(0);
HHasInPrototypeChainAndBranch* result =
New<HHasInPrototypeChainAndBranch>(left, prototype);
Drop(3);
return ast_context()->ReturnControl(result, call->id());
}
}
}
}
}
}
CallTrampolineDescriptor descriptor(isolate()); CallTrampolineDescriptor descriptor(isolate());
PushArgumentsFromEnvironment(call->arguments()->length() - 1); PushArgumentsFromEnvironment(call->arguments()->length() - 1);
HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call());
......
...@@ -274,6 +274,7 @@ DEFINE_BOOL(track_fields, true, "track fields with only smi values") ...@@ -274,6 +274,7 @@ DEFINE_BOOL(track_fields, true, "track fields with only smi values")
DEFINE_BOOL(track_double_fields, true, "track fields with double values") DEFINE_BOOL(track_double_fields, true, "track fields with double values")
DEFINE_BOOL(track_heap_object_fields, true, "track fields with heap values") DEFINE_BOOL(track_heap_object_fields, true, "track fields with heap values")
DEFINE_BOOL(track_computed_fields, true, "track computed boilerplate fields") DEFINE_BOOL(track_computed_fields, true, "track computed boilerplate fields")
DEFINE_BOOL(harmony_instanceof_opt, false, "optimize ES6 instanceof support")
DEFINE_IMPLICATION(track_double_fields, track_fields) DEFINE_IMPLICATION(track_double_fields, track_fields)
DEFINE_IMPLICATION(track_heap_object_fields, track_fields) DEFINE_IMPLICATION(track_heap_object_fields, track_fields)
DEFINE_IMPLICATION(track_computed_fields, track_fields) DEFINE_IMPLICATION(track_computed_fields, track_fields)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment