OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 11662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11673 HValue* left = Pop(); | 11673 HValue* left = Pop(); |
11674 Token::Value op = expr->op(); | 11674 Token::Value op = expr->op(); |
11675 | 11675 |
11676 if (IsLiteralCompareBool(isolate(), left, op, right)) { | 11676 if (IsLiteralCompareBool(isolate(), left, op, right)) { |
11677 HCompareObjectEqAndBranch* result = | 11677 HCompareObjectEqAndBranch* result = |
11678 New<HCompareObjectEqAndBranch>(left, right); | 11678 New<HCompareObjectEqAndBranch>(left, right); |
11679 return ast_context()->ReturnControl(result, expr->id()); | 11679 return ast_context()->ReturnControl(result, expr->id()); |
11680 } | 11680 } |
11681 | 11681 |
11682 if (op == Token::INSTANCEOF) { | 11682 if (op == Token::INSTANCEOF) { |
11683 DCHECK(!FLAG_harmony_instanceof); | |
11684 // Check to see if the rhs of the instanceof is a known function. | 11683 // Check to see if the rhs of the instanceof is a known function. |
11685 if (right->IsConstant() && | 11684 if (right->IsConstant() && |
11686 HConstant::cast(right)->handle(isolate())->IsJSFunction()) { | 11685 HConstant::cast(right)->handle(isolate())->IsJSFunction()) { |
11687 Handle<JSFunction> constructor = | 11686 Handle<JSFunction> function = |
11688 Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate())); | 11687 Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate())); |
11689 if (constructor->IsConstructor() && | 11688 if (function->has_initial_map() && |
Igor Sheludko
2016/05/17 08:40:32
Please copy respective comments from js-typed-lowe
Benedikt Meurer
2016/05/17 10:23:21
Done.
| |
11690 !constructor->map()->has_non_instance_prototype()) { | 11689 function->map()->prototype() == |
11691 JSFunction::EnsureHasInitialMap(constructor); | 11690 function->native_context()->closure() && |
11692 DCHECK(constructor->has_initial_map()); | 11691 !function->map()->has_non_instance_prototype() && |
11693 Handle<Map> initial_map(constructor->initial_map(), isolate()); | 11692 isolate()->IsHasInstanceLookupChainIntact()) { |
11693 Handle<Map> initial_map(function->initial_map(), isolate()); | |
11694 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); | 11694 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); |
11695 top_info()->dependencies()->AssumePropertyCell( | |
11696 isolate()->factory()->has_instance_protector()); | |
11695 HInstruction* prototype = | 11697 HInstruction* prototype = |
11696 Add<HConstant>(handle(initial_map->prototype(), isolate())); | 11698 Add<HConstant>(handle(initial_map->prototype(), isolate())); |
11697 HHasInPrototypeChainAndBranch* result = | 11699 HHasInPrototypeChainAndBranch* result = |
11698 New<HHasInPrototypeChainAndBranch>(left, prototype); | 11700 New<HHasInPrototypeChainAndBranch>(left, prototype); |
11699 return ast_context()->ReturnControl(result, expr->id()); | 11701 return ast_context()->ReturnControl(result, expr->id()); |
11700 } | 11702 } |
11701 } | 11703 } |
11702 | 11704 |
11703 HInstanceOf* result = New<HInstanceOf>(left, right); | 11705 Callable callable = CodeFactory::InstanceOf(isolate()); |
11706 HValue* stub = Add<HConstant>(callable.code()); | |
11707 HValue* values[] = {context(), left, right}; | |
11708 HCallWithDescriptor* result = New<HCallWithDescriptor>( | |
11709 stub, 0, callable.descriptor(), ArrayVector(values)); | |
11710 result->set_type(HType::Boolean()); | |
11704 return ast_context()->ReturnInstruction(result, expr->id()); | 11711 return ast_context()->ReturnInstruction(result, expr->id()); |
11705 | 11712 |
11706 } else if (op == Token::IN) { | 11713 } else if (op == Token::IN) { |
11707 Callable callable = CodeFactory::HasProperty(isolate()); | 11714 Callable callable = CodeFactory::HasProperty(isolate()); |
11708 HValue* stub = Add<HConstant>(callable.code()); | 11715 HValue* stub = Add<HConstant>(callable.code()); |
11709 HValue* values[] = {context(), left, right}; | 11716 HValue* values[] = {context(), left, right}; |
11710 HInstruction* result = | 11717 HInstruction* result = |
11711 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 11718 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), |
11712 Vector<HValue*>(values, arraysize(values))); | 11719 Vector<HValue*>(values, arraysize(values))); |
11713 return ast_context()->ReturnInstruction(result, expr->id()); | 11720 return ast_context()->ReturnInstruction(result, expr->id()); |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12794 HValue* number = Pop(); | 12801 HValue* number = Pop(); |
12795 HValue* result = BuildNumberToString(number, Type::Any()); | 12802 HValue* result = BuildNumberToString(number, Type::Any()); |
12796 return ast_context()->ReturnValue(result); | 12803 return ast_context()->ReturnValue(result); |
12797 } | 12804 } |
12798 | 12805 |
12799 | 12806 |
12800 // Fast support for calls. | 12807 // Fast support for calls. |
12801 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { | 12808 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { |
12802 DCHECK_LE(2, call->arguments()->length()); | 12809 DCHECK_LE(2, call->arguments()->length()); |
12803 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12810 CHECK_ALIVE(VisitExpressions(call->arguments())); |
12804 | |
12805 // Try and customize ES6 instanceof here. | |
12806 // We should at least have the constructor on the expression stack. | |
12807 if (FLAG_harmony_instanceof && FLAG_harmony_instanceof_opt && | |
12808 call->arguments()->length() == 3) { | |
12809 HValue* target = environment()->ExpressionStackAt(2); | |
12810 if (target->IsConstant()) { | |
12811 HConstant* constant_function = HConstant::cast(target); | |
12812 if (constant_function->handle(isolate())->IsJSFunction()) { | |
12813 Handle<JSFunction> func = | |
12814 Handle<JSFunction>::cast(constant_function->handle(isolate())); | |
12815 if (*func == isolate()->native_context()->ordinary_has_instance()) { | |
12816 // Look at the function, which will be argument 1. | |
12817 HValue* right = environment()->ExpressionStackAt(1); | |
12818 if (right->IsConstant() && | |
12819 HConstant::cast(right)->handle(isolate())->IsJSFunction()) { | |
12820 Handle<JSFunction> constructor = Handle<JSFunction>::cast( | |
12821 HConstant::cast(right)->handle(isolate())); | |
12822 if (constructor->IsConstructor() && | |
12823 !constructor->map()->has_non_instance_prototype()) { | |
12824 JSFunction::EnsureHasInitialMap(constructor); | |
12825 DCHECK(constructor->has_initial_map()); | |
12826 Handle<Map> initial_map(constructor->initial_map(), isolate()); | |
12827 top_info()->dependencies()->AssumeInitialMapCantChange( | |
12828 initial_map); | |
12829 HInstruction* prototype = | |
12830 Add<HConstant>(handle(initial_map->prototype(), isolate())); | |
12831 HValue* left = environment()->ExpressionStackAt(0); | |
12832 HHasInPrototypeChainAndBranch* result = | |
12833 New<HHasInPrototypeChainAndBranch>(left, prototype); | |
12834 Drop(3); | |
12835 return ast_context()->ReturnControl(result, call->id()); | |
12836 } | |
12837 } | |
12838 } | |
12839 } | |
12840 } | |
12841 } | |
12842 | |
12843 CallTrampolineDescriptor descriptor(isolate()); | 12811 CallTrampolineDescriptor descriptor(isolate()); |
12844 PushArgumentsFromEnvironment(call->arguments()->length() - 1); | 12812 PushArgumentsFromEnvironment(call->arguments()->length() - 1); |
12845 HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); | 12813 HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); |
12846 HValue* target = Pop(); | 12814 HValue* target = Pop(); |
12847 HValue* values[] = {context(), target, | 12815 HValue* values[] = {context(), target, |
12848 Add<HConstant>(call->arguments()->length() - 2)}; | 12816 Add<HConstant>(call->arguments()->length() - 2)}; |
12849 HInstruction* result = | 12817 HInstruction* result = |
12850 New<HCallWithDescriptor>(trampoline, call->arguments()->length() - 1, | 12818 New<HCallWithDescriptor>(trampoline, call->arguments()->length() - 1, |
12851 descriptor, ArrayVector(values)); | 12819 descriptor, ArrayVector(values)); |
12852 return ast_context()->ReturnInstruction(result, call->id()); | 12820 return ast_context()->ReturnInstruction(result, call->id()); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13073 | 13041 |
13074 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { | 13042 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { |
13075 DCHECK(call->arguments()->length() == 0); | 13043 DCHECK(call->arguments()->length() == 0); |
13076 HValue* ref = | 13044 HValue* ref = |
13077 Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); | 13045 Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); |
13078 HValue* value = | 13046 HValue* value = |
13079 Add<HLoadNamedField>(ref, nullptr, HObjectAccess::ForExternalUInteger8()); | 13047 Add<HLoadNamedField>(ref, nullptr, HObjectAccess::ForExternalUInteger8()); |
13080 return ast_context()->ReturnValue(value); | 13048 return ast_context()->ReturnValue(value); |
13081 } | 13049 } |
13082 | 13050 |
13083 void HOptimizedGraphBuilder::GenerateGetOrdinaryHasInstance(CallRuntime* call) { | |
13084 DCHECK(call->arguments()->length() == 0); | |
13085 // ordinary_has_instance is immutable so we can treat it as a constant. | |
13086 HValue* value = Add<HConstant>(isolate()->ordinary_has_instance()); | |
13087 return ast_context()->ReturnValue(value); | |
13088 } | |
13089 | |
13090 #undef CHECK_BAILOUT | 13051 #undef CHECK_BAILOUT |
13091 #undef CHECK_ALIVE | 13052 #undef CHECK_ALIVE |
13092 | 13053 |
13093 | 13054 |
13094 HEnvironment::HEnvironment(HEnvironment* outer, | 13055 HEnvironment::HEnvironment(HEnvironment* outer, |
13095 Scope* scope, | 13056 Scope* scope, |
13096 Handle<JSFunction> closure, | 13057 Handle<JSFunction> closure, |
13097 Zone* zone) | 13058 Zone* zone) |
13098 : closure_(closure), | 13059 : closure_(closure), |
13099 values_(0, zone), | 13060 values_(0, zone), |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13743 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13704 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13744 } | 13705 } |
13745 | 13706 |
13746 #ifdef DEBUG | 13707 #ifdef DEBUG |
13747 graph_->Verify(false); // No full verify. | 13708 graph_->Verify(false); // No full verify. |
13748 #endif | 13709 #endif |
13749 } | 13710 } |
13750 | 13711 |
13751 } // namespace internal | 13712 } // namespace internal |
13752 } // namespace v8 | 13713 } // namespace v8 |
OLD | NEW |