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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 8680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8691 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( | 8691 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( |
8692 receiver_maps->first(), &holder_lookup); | 8692 receiver_maps->first(), &holder_lookup); |
8693 if (holder_lookup == CallOptimization::kHolderNotFound) return false; | 8693 if (holder_lookup == CallOptimization::kHolderNotFound) return false; |
8694 | 8694 |
8695 if (FLAG_trace_inlining) { | 8695 if (FLAG_trace_inlining) { |
8696 PrintF("Inlining api function "); | 8696 PrintF("Inlining api function "); |
8697 function->ShortPrint(); | 8697 function->ShortPrint(); |
8698 PrintF("\n"); | 8698 PrintF("\n"); |
8699 } | 8699 } |
8700 | 8700 |
8701 bool drop_extra = false; | 8701 bool is_function = false; |
8702 bool is_store = false; | 8702 bool is_store = false; |
8703 switch (call_type) { | 8703 switch (call_type) { |
8704 case kCallApiFunction: | 8704 case kCallApiFunction: |
8705 case kCallApiMethod: | 8705 case kCallApiMethod: |
8706 // Need to check that none of the receiver maps could have changed. | 8706 // Need to check that none of the receiver maps could have changed. |
8707 Add<HCheckMaps>(receiver, receiver_maps); | 8707 Add<HCheckMaps>(receiver, receiver_maps); |
8708 // Need to ensure the chain between receiver and api_holder is intact. | 8708 // Need to ensure the chain between receiver and api_holder is intact. |
8709 if (holder_lookup == CallOptimization::kHolderFound) { | 8709 if (holder_lookup == CallOptimization::kHolderFound) { |
8710 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); | 8710 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); |
8711 } else { | 8711 } else { |
8712 DCHECK_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); | 8712 DCHECK_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); |
8713 } | 8713 } |
8714 // Includes receiver. | 8714 // Includes receiver. |
8715 PushArgumentsFromEnvironment(argc + 1); | 8715 PushArgumentsFromEnvironment(argc + 1); |
8716 // Drop function after call. | 8716 is_function = true; |
8717 drop_extra = true; | |
8718 break; | 8717 break; |
8719 case kCallApiGetter: | 8718 case kCallApiGetter: |
8720 // Receiver and prototype chain cannot have changed. | 8719 // Receiver and prototype chain cannot have changed. |
8721 DCHECK_EQ(0, argc); | 8720 DCHECK_EQ(0, argc); |
8722 DCHECK_EQ(NULL, receiver); | 8721 DCHECK_EQ(NULL, receiver); |
8723 // Receiver is on expression stack. | 8722 // Receiver is on expression stack. |
8724 receiver = Pop(); | 8723 receiver = Pop(); |
8725 Add<HPushArguments>(receiver); | 8724 Add<HPushArguments>(receiver); |
8726 break; | 8725 break; |
8727 case kCallApiSetter: | 8726 case kCallApiSetter: |
(...skipping 17 matching lines...) Expand all Loading... |
8745 break; | 8744 break; |
8746 case CallOptimization::kHolderIsReceiver: | 8745 case CallOptimization::kHolderIsReceiver: |
8747 holder = receiver; | 8746 holder = receiver; |
8748 break; | 8747 break; |
8749 case CallOptimization::kHolderNotFound: | 8748 case CallOptimization::kHolderNotFound: |
8750 UNREACHABLE(); | 8749 UNREACHABLE(); |
8751 break; | 8750 break; |
8752 } | 8751 } |
8753 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 8752 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
8754 Handle<Object> call_data_obj(api_call_info->data(), isolate()); | 8753 Handle<Object> call_data_obj(api_call_info->data(), isolate()); |
8755 bool call_data_is_undefined = call_data_obj->IsUndefined(); | |
8756 HValue* call_data = Add<HConstant>(call_data_obj); | 8754 HValue* call_data = Add<HConstant>(call_data_obj); |
| 8755 bool call_data_undefined = call_data_obj->IsUndefined(); |
8757 ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); | 8756 ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); |
8758 ExternalReference ref = ExternalReference(&fun, | 8757 ExternalReference ref = ExternalReference(&fun, |
8759 ExternalReference::DIRECT_API_CALL, | 8758 ExternalReference::DIRECT_API_CALL, |
8760 isolate()); | 8759 isolate()); |
8761 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); | 8760 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); |
8762 | 8761 |
8763 HValue* op_vals[] = { | 8762 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder, |
8764 context(), | 8763 api_function_address, nullptr}; |
8765 Add<HConstant>(function), | |
8766 call_data, | |
8767 holder, | |
8768 api_function_address | |
8769 }; | |
8770 | 8764 |
8771 ApiFunctionDescriptor descriptor(isolate()); | 8765 HInstruction* call = nullptr; |
8772 CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc); | 8766 if (!is_function) { |
8773 Handle<Code> code = stub.GetCode(); | 8767 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined); |
8774 HConstant* code_value = Add<HConstant>(code); | 8768 Handle<Code> code = stub.GetCode(); |
| 8769 HConstant* code_value = Add<HConstant>(code); |
| 8770 ApiAccessorDescriptor descriptor(isolate()); |
| 8771 DCHECK(arraysize(op_vals) - 1 == descriptor.GetEnvironmentLength()); |
| 8772 call = New<HCallWithDescriptor>( |
| 8773 code_value, argc + 1, descriptor, |
| 8774 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); |
| 8775 } else { |
| 8776 op_vals[arraysize(op_vals) - 1] = Add<HConstant>(argc); |
| 8777 CallApiFunctionStub stub(isolate(), call_data_undefined); |
| 8778 Handle<Code> code = stub.GetCode(); |
| 8779 HConstant* code_value = Add<HConstant>(code); |
| 8780 ApiFunctionDescriptor descriptor(isolate()); |
| 8781 DCHECK(arraysize(op_vals) == descriptor.GetEnvironmentLength()); |
| 8782 call = New<HCallWithDescriptor>( |
| 8783 code_value, argc + 1, descriptor, |
| 8784 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); |
| 8785 Drop(1); // Drop function. |
| 8786 } |
8775 | 8787 |
8776 DCHECK((sizeof(op_vals) / kPointerSize) == descriptor.GetEnvironmentLength()); | |
8777 | |
8778 HInstruction* call = New<HCallWithDescriptor>( | |
8779 code_value, argc + 1, descriptor, | |
8780 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); | |
8781 | |
8782 if (drop_extra) Drop(1); // Drop function. | |
8783 ast_context()->ReturnInstruction(call, ast_id); | 8788 ast_context()->ReturnInstruction(call, ast_id); |
8784 return true; | 8789 return true; |
8785 } | 8790 } |
8786 | 8791 |
8787 | 8792 |
8788 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, | 8793 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, |
8789 int arguments_count) { | 8794 int arguments_count) { |
8790 Handle<JSFunction> known_function; | 8795 Handle<JSFunction> known_function; |
8791 int args_count_no_receiver = arguments_count - 1; | 8796 int args_count_no_receiver = arguments_count - 1; |
8792 if (function->IsConstant() && | 8797 if (function->IsConstant() && |
(...skipping 4655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13448 if (ShouldProduceTraceOutput()) { | 13453 if (ShouldProduceTraceOutput()) { |
13449 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13454 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13450 } | 13455 } |
13451 | 13456 |
13452 #ifdef DEBUG | 13457 #ifdef DEBUG |
13453 graph_->Verify(false); // No full verify. | 13458 graph_->Verify(false); // No full verify. |
13454 #endif | 13459 #endif |
13455 } | 13460 } |
13456 | 13461 |
13457 } } // namespace v8::internal | 13462 } } // namespace v8::internal |
OLD | NEW |