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