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 7980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7991 | 7991 |
7992 | 7992 |
7993 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 7993 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
7994 Handle<Map> receiver_map) { | 7994 Handle<Map> receiver_map) { |
7995 if (!holder.is_null()) { | 7995 if (!holder.is_null()) { |
7996 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 7996 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
7997 BuildCheckPrototypeMaps(prototype, holder); | 7997 BuildCheckPrototypeMaps(prototype, holder); |
7998 } | 7998 } |
7999 } | 7999 } |
8000 | 8000 |
| 8001 void HOptimizedGraphBuilder::BuildEnsureCallable(HValue* object) { |
| 8002 NoObservableSideEffectsScope scope(this); |
| 8003 const Runtime::Function* throw_called_non_callable = |
| 8004 Runtime::FunctionForId(Runtime::kThrowCalledNonCallable); |
| 8005 |
| 8006 IfBuilder is_not_function(this); |
| 8007 HValue* smi_check = is_not_function.If<HIsSmiAndBranch>(object); |
| 8008 is_not_function.Or(); |
| 8009 HValue* map = AddLoadMap(object, smi_check); |
| 8010 HValue* bit_field = |
| 8011 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField()); |
| 8012 HValue* bit_field_masked = AddUncasted<HBitwise>( |
| 8013 Token::BIT_AND, bit_field, Add<HConstant>(1 << Map::kIsCallable)); |
| 8014 is_not_function.IfNot<HCompareNumericAndBranch>( |
| 8015 bit_field_masked, Add<HConstant>(1 << Map::kIsCallable), Token::EQ); |
| 8016 is_not_function.Then(); |
| 8017 { |
| 8018 Add<HPushArguments>(object); |
| 8019 Add<HCallRuntime>(throw_called_non_callable, 1); |
| 8020 } |
| 8021 is_not_function.End(); |
| 8022 } |
| 8023 |
8001 HInstruction* HOptimizedGraphBuilder::NewCallFunction( | 8024 HInstruction* HOptimizedGraphBuilder::NewCallFunction( |
8002 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, | 8025 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, |
8003 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) { | 8026 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) { |
| 8027 if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
| 8028 BuildEnsureCallable(function); |
| 8029 } else { |
| 8030 DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); |
| 8031 } |
8004 HValue* arity = Add<HConstant>(argument_count - 1); | 8032 HValue* arity = Add<HConstant>(argument_count - 1); |
8005 | 8033 |
8006 HValue* op_vals[] = {context(), function, arity}; | 8034 HValue* op_vals[] = {context(), function, arity}; |
8007 | 8035 |
8008 Callable callable = | 8036 Callable callable = |
8009 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); | 8037 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); |
8010 HConstant* stub = Add<HConstant>(callable.code()); | 8038 HConstant* stub = Add<HConstant>(callable.code()); |
8011 | 8039 |
8012 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8040 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
8013 Vector<HValue*>(op_vals, arraysize(op_vals)), | 8041 Vector<HValue*>(op_vals, arraysize(op_vals)), |
8014 syntactic_tail_call_mode); | 8042 syntactic_tail_call_mode); |
8015 } | 8043 } |
8016 | 8044 |
8017 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( | 8045 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( |
8018 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, | 8046 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, |
8019 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, | 8047 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, |
8020 FeedbackVectorSlot slot) { | 8048 FeedbackVectorSlot slot) { |
| 8049 if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
| 8050 BuildEnsureCallable(function); |
| 8051 } else { |
| 8052 DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); |
| 8053 } |
8021 int arity = argument_count - 1; | 8054 int arity = argument_count - 1; |
8022 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); | 8055 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); |
8023 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); | 8056 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); |
8024 HValue* vector_val = Add<HConstant>(vector); | 8057 HValue* vector_val = Add<HConstant>(vector); |
8025 | 8058 |
8026 HValue* op_vals[] = {context(), function, index_val, vector_val}; | 8059 HValue* op_vals[] = {context(), function, index_val, vector_val}; |
8027 | 8060 |
8028 Callable callable = CodeFactory::CallICInOptimizedCode( | 8061 Callable callable = CodeFactory::CallICInOptimizedCode( |
8029 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode); | 8062 isolate(), arity, convert_mode, tail_call_mode); |
8030 HConstant* stub = Add<HConstant>(callable.code()); | 8063 HConstant* stub = Add<HConstant>(callable.code()); |
8031 | 8064 |
8032 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8065 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
8033 Vector<HValue*>(op_vals, arraysize(op_vals)), | 8066 Vector<HValue*>(op_vals, arraysize(op_vals)), |
8034 syntactic_tail_call_mode); | 8067 syntactic_tail_call_mode); |
8035 } | 8068 } |
8036 | 8069 |
8037 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( | 8070 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( |
8038 Handle<JSFunction> function, int argument_count, | 8071 Handle<JSFunction> function, int argument_count, |
8039 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { | 8072 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { |
(...skipping 5496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13536 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13569 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13537 } | 13570 } |
13538 | 13571 |
13539 #ifdef DEBUG | 13572 #ifdef DEBUG |
13540 graph_->Verify(false); // No full verify. | 13573 graph_->Verify(false); // No full verify. |
13541 #endif | 13574 #endif |
13542 } | 13575 } |
13543 | 13576 |
13544 } // namespace internal | 13577 } // namespace internal |
13545 } // namespace v8 | 13578 } // namespace v8 |
OLD | NEW |