| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index fda129fe9e6c5aa13e700ee1273ed5a927678152..5c0843ee53a9ad6f2bcc3462d1cbce0c4bc9d456 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -6575,8 +6575,8 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
| info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
|
| HValue* function = Add<HConstant>(info->accessor());
|
| PushArgumentsFromEnvironment(argument_count);
|
| - return New<HCallFunction>(function, argument_count,
|
| - ConvertReceiverMode::kNotNullOrUndefined);
|
| + return NewCallFunction(function, argument_count,
|
| + ConvertReceiverMode::kNotNullOrUndefined);
|
| } else if (FLAG_inline_accessors && can_inline_accessor) {
|
| bool success = info->IsLoad()
|
| ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
|
| @@ -7989,20 +7989,20 @@ void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
|
| }
|
| }
|
|
|
| -
|
| -HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(HValue* fun,
|
| +HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(HValue* function,
|
| int argument_count) {
|
| - return New<HCallJSFunction>(fun, argument_count);
|
| + return New<HCallJSFunction>(function, argument_count);
|
| }
|
|
|
| -
|
| HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
|
| - HValue* fun, HValue* context,
|
| - int argument_count, HValue* expected_param_count) {
|
| + HValue* function, int argument_count, HValue* expected_param_count) {
|
| + HValue* context = Add<HLoadNamedField>(
|
| + function, nullptr, HObjectAccess::ForFunctionContextPointer());
|
| HValue* new_target = graph()->GetConstantUndefined();
|
| HValue* arity = Add<HConstant>(argument_count - 1);
|
|
|
| - HValue* op_vals[] = {context, fun, new_target, arity, expected_param_count};
|
| + HValue* op_vals[] = {context, function, new_target, arity,
|
| + expected_param_count};
|
|
|
| Callable callable = CodeFactory::ArgumentAdaptor(isolate());
|
| HConstant* stub = Add<HConstant>(callable.code());
|
| @@ -8011,6 +8011,36 @@ HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
|
| Vector<HValue*>(op_vals, arraysize(op_vals)));
|
| }
|
|
|
| +HInstruction* HOptimizedGraphBuilder::NewCallFunction(
|
| + HValue* function, int argument_count, ConvertReceiverMode convert_mode) {
|
| + HValue* arity = Add<HConstant>(argument_count - 1);
|
| +
|
| + HValue* op_vals[] = {context(), function, arity};
|
| +
|
| + Callable callable = CodeFactory::Call(isolate(), convert_mode);
|
| + HConstant* stub = Add<HConstant>(callable.code());
|
| +
|
| + return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
|
| + Vector<HValue*>(op_vals, arraysize(op_vals)));
|
| +}
|
| +
|
| +HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
|
| + HValue* function, int argument_count, ConvertReceiverMode convert_mode,
|
| + FeedbackVectorSlot slot) {
|
| + int arity = argument_count - 1;
|
| + Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
|
| + HValue* index_val = Add<HConstant>(vector->GetIndex(slot));
|
| + HValue* vector_val = Add<HConstant>(vector);
|
| +
|
| + HValue* op_vals[] = {context(), function, index_val, vector_val};
|
| +
|
| + Callable callable = CodeFactory::CallICInOptimizedCode(
|
| + isolate(), arity, ConvertReceiverMode::kNullOrUndefined);
|
| + HConstant* stub = Add<HConstant>(callable.code());
|
| +
|
| + return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
|
| + Vector<HValue*>(op_vals, arraysize(op_vals)));
|
| +}
|
|
|
| HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
|
| Handle<JSFunction> jsfun, int argument_count) {
|
| @@ -8032,10 +8062,7 @@ HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
|
| return NewPlainFunctionCall(target, argument_count);
|
| } else {
|
| HValue* param_count_value = Add<HConstant>(formal_parameter_count);
|
| - HValue* context = Add<HLoadNamedField>(
|
| - target, nullptr, HObjectAccess::ForFunctionContextPointer());
|
| - return NewArgumentAdaptorCall(target, context,
|
| - argument_count, param_count_value);
|
| + return NewArgumentAdaptorCall(target, argument_count, param_count_value);
|
| }
|
| UNREACHABLE();
|
| return NULL;
|
| @@ -8180,14 +8207,14 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
|
| if (HasStackOverflow()) return;
|
| } else {
|
| // Since HWrapReceiver currently cannot actually wrap numbers and strings,
|
| - // use the regular CallFunctionStub for method calls to wrap the receiver.
|
| + // use the regular call builtin for method calls to wrap the receiver.
|
| // TODO(verwaest): Support creation of value wrappers directly in
|
| // HWrapReceiver.
|
| HInstruction* call =
|
| - needs_wrapping ? NewUncasted<HCallFunction>(
|
| - function, argument_count,
|
| - ConvertReceiverMode::kNotNullOrUndefined)
|
| - : BuildCallConstantFunction(target, argument_count);
|
| + needs_wrapping
|
| + ? NewCallFunction(function, argument_count,
|
| + ConvertReceiverMode::kNotNullOrUndefined)
|
| + : BuildCallConstantFunction(target, argument_count);
|
| PushArgumentsFromEnvironment(argument_count);
|
| AddInstruction(call);
|
| Drop(1); // Drop the function.
|
| @@ -8216,7 +8243,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
|
| environment()->SetExpressionStackAt(0, receiver);
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
|
|
| - HInstruction* call = New<HCallFunction>(
|
| + HInstruction* call = NewCallFunction(
|
| function, argument_count, ConvertReceiverMode::kNotNullOrUndefined);
|
|
|
| PushArgumentsFromEnvironment(argument_count);
|
| @@ -9750,12 +9777,12 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| // Wrap the receiver if necessary.
|
| if (NeedsWrapping(maps->first(), known_function)) {
|
| // Since HWrapReceiver currently cannot actually wrap numbers and
|
| - // strings, use the regular CallFunctionStub for method calls to wrap
|
| + // strings, use the regular call builtin for method calls to wrap
|
| // the receiver.
|
| // TODO(verwaest): Support creation of value wrappers directly in
|
| // HWrapReceiver.
|
| - call = New<HCallFunction>(function, argument_count,
|
| - ConvertReceiverMode::kNotNullOrUndefined);
|
| + call = NewCallFunction(function, argument_count,
|
| + ConvertReceiverMode::kNotNullOrUndefined);
|
| } else if (TryInlineCall(expr)) {
|
| return;
|
| } else {
|
| @@ -9778,8 +9805,8 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| Push(receiver);
|
|
|
| CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
|
| - call = New<HCallFunction>(function, argument_count,
|
| - ConvertReceiverMode::kNotNullOrUndefined);
|
| + call = NewCallFunction(function, argument_count,
|
| + ConvertReceiverMode::kNotNullOrUndefined);
|
| }
|
| PushArgumentsFromEnvironment(argument_count);
|
|
|
| @@ -9829,17 +9856,16 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| call = BuildCallConstantFunction(expr->target(), argument_count);
|
| } else {
|
| PushArgumentsFromEnvironment(argument_count);
|
| - HCallFunction* call_function = New<HCallFunction>(
|
| - function, argument_count, ConvertReceiverMode::kNullOrUndefined);
|
| - call = call_function;
|
| if (expr->is_uninitialized() &&
|
| expr->IsUsingCallFeedbackICSlot(isolate())) {
|
| // We've never seen this call before, so let's have Crankshaft learn
|
| // through the type vector.
|
| - Handle<TypeFeedbackVector> vector =
|
| - handle(current_feedback_vector(), isolate());
|
| - FeedbackVectorSlot slot = expr->CallFeedbackICSlot();
|
| - call_function->SetVectorAndSlot(vector, slot);
|
| + call = NewCallFunctionViaIC(function, argument_count,
|
| + ConvertReceiverMode::kNullOrUndefined,
|
| + expr->CallFeedbackICSlot());
|
| + } else {
|
| + call = NewCallFunction(function, argument_count,
|
| + ConvertReceiverMode::kNullOrUndefined);
|
| }
|
| }
|
| }
|
|
|