Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 1818003002: [crankshaft] Check if the function is callable before generating a tail call via Call builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@tco-crank-4
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | test/mjsunit/regress/regress-crbug-595615.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | test/mjsunit/regress/regress-crbug-595615.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698