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 6316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6327 access_ = HObjectAccess::ForField(map, index, representation(), name_); | 6327 access_ = HObjectAccess::ForField(map, index, representation(), name_); |
6328 | 6328 |
6329 // Load field map for heap objects. | 6329 // Load field map for heap objects. |
6330 return LoadFieldMaps(map); | 6330 return LoadFieldMaps(map); |
6331 } else if (IsAccessorConstant()) { | 6331 } else if (IsAccessorConstant()) { |
6332 Handle<Object> accessors = GetAccessorsFromMap(map); | 6332 Handle<Object> accessors = GetAccessorsFromMap(map); |
6333 if (!accessors->IsAccessorPair()) return false; | 6333 if (!accessors->IsAccessorPair()) return false; |
6334 Object* raw_accessor = | 6334 Object* raw_accessor = |
6335 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() | 6335 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() |
6336 : Handle<AccessorPair>::cast(accessors)->setter(); | 6336 : Handle<AccessorPair>::cast(accessors)->setter(); |
6337 if (!raw_accessor->IsJSFunction()) return false; | 6337 if (!raw_accessor->IsJSFunction() && |
6338 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); | 6338 !raw_accessor->IsFunctionTemplateInfo()) |
6339 if (accessor->shared()->IsApiFunction()) { | 6339 return false; |
6340 CallOptimization call_optimization(accessor); | 6340 Handle<Object> accessor = handle(HeapObject::cast(raw_accessor)); |
6341 if (call_optimization.is_simple_api_call()) { | 6341 CallOptimization call_optimization(accessor); |
6342 CallOptimization::HolderLookup holder_lookup; | 6342 if (call_optimization.is_simple_api_call()) { |
6343 api_holder_ = | 6343 CallOptimization::HolderLookup holder_lookup; |
6344 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); | 6344 api_holder_ = |
6345 } | 6345 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); |
6346 } | 6346 } |
6347 accessor_ = accessor; | 6347 accessor_ = accessor; |
6348 } else if (IsDataConstant()) { | 6348 } else if (IsDataConstant()) { |
6349 constant_ = GetConstantFromMap(map); | 6349 constant_ = GetConstantFromMap(map); |
6350 } | 6350 } |
6351 | 6351 |
6352 return true; | 6352 return true; |
6353 } | 6353 } |
6354 | 6354 |
6355 | 6355 |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6584 } | 6584 } |
6585 | 6585 |
6586 if (info->IsAccessorConstant()) { | 6586 if (info->IsAccessorConstant()) { |
6587 Push(checked_object); | 6587 Push(checked_object); |
6588 int argument_count = 1; | 6588 int argument_count = 1; |
6589 if (!info->IsLoad()) { | 6589 if (!info->IsLoad()) { |
6590 argument_count = 2; | 6590 argument_count = 2; |
6591 Push(value); | 6591 Push(value); |
6592 } | 6592 } |
6593 | 6593 |
6594 if (info->NeedsWrappingFor(info->accessor())) { | 6594 if (info->accessor()->IsJSFunction() && |
| 6595 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { |
6595 HValue* function = Add<HConstant>(info->accessor()); | 6596 HValue* function = Add<HConstant>(info->accessor()); |
6596 PushArgumentsFromEnvironment(argument_count); | 6597 PushArgumentsFromEnvironment(argument_count); |
6597 return New<HCallFunction>(function, argument_count, | 6598 return New<HCallFunction>(function, argument_count, |
6598 ConvertReceiverMode::kNotNullOrUndefined); | 6599 ConvertReceiverMode::kNotNullOrUndefined); |
6599 } else if (FLAG_inline_accessors && can_inline_accessor) { | 6600 } else if (FLAG_inline_accessors && can_inline_accessor) { |
6600 bool success = info->IsLoad() | 6601 bool success = info->IsLoad() |
6601 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) | 6602 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) |
6602 : TryInlineSetter( | 6603 : TryInlineSetter( |
6603 info->accessor(), info->map(), ast_id, return_id, value); | 6604 info->accessor(), info->map(), ast_id, return_id, value); |
6604 if (success || HasStackOverflow()) return NULL; | 6605 if (success || HasStackOverflow()) return NULL; |
6605 } | 6606 } |
6606 | 6607 |
6607 PushArgumentsFromEnvironment(argument_count); | 6608 PushArgumentsFromEnvironment(argument_count); |
6608 return BuildCallConstantFunction(info->accessor(), argument_count); | 6609 DCHECK(info->accessor()->IsJSFunction()); |
| 6610 return BuildCallConstantFunction(Handle<JSFunction>::cast(info->accessor()), |
| 6611 argument_count); |
6609 } | 6612 } |
6610 | 6613 |
6611 DCHECK(info->IsDataConstant()); | 6614 DCHECK(info->IsDataConstant()); |
6612 if (info->IsLoad()) { | 6615 if (info->IsLoad()) { |
6613 return New<HConstant>(info->constant()); | 6616 return New<HConstant>(info->constant()); |
6614 } else { | 6617 } else { |
6615 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); | 6618 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); |
6616 } | 6619 } |
6617 } | 6620 } |
6618 | 6621 |
(...skipping 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8629 | 8632 |
8630 | 8633 |
8631 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, | 8634 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
8632 HValue* implicit_return_value) { | 8635 HValue* implicit_return_value) { |
8633 return TryInline(expr->target(), expr->arguments()->length(), | 8636 return TryInline(expr->target(), expr->arguments()->length(), |
8634 implicit_return_value, expr->id(), expr->ReturnId(), | 8637 implicit_return_value, expr->id(), expr->ReturnId(), |
8635 CONSTRUCT_CALL_RETURN); | 8638 CONSTRUCT_CALL_RETURN); |
8636 } | 8639 } |
8637 | 8640 |
8638 | 8641 |
8639 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 8642 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter, |
8640 Handle<Map> receiver_map, | 8643 Handle<Map> receiver_map, |
8641 BailoutId ast_id, | 8644 BailoutId ast_id, |
8642 BailoutId return_id) { | 8645 BailoutId return_id) { |
8643 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; | 8646 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; |
8644 return TryInline(getter, 0, NULL, ast_id, return_id, GETTER_CALL_RETURN); | 8647 return getter->IsJSFunction() && |
| 8648 TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id, |
| 8649 GETTER_CALL_RETURN); |
8645 } | 8650 } |
8646 | 8651 |
8647 | 8652 |
8648 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 8653 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter, |
8649 Handle<Map> receiver_map, | 8654 Handle<Map> receiver_map, |
8650 BailoutId id, | 8655 BailoutId id, |
8651 BailoutId assignment_id, | 8656 BailoutId assignment_id, |
8652 HValue* implicit_return_value) { | 8657 HValue* implicit_return_value) { |
8653 if (TryInlineApiSetter(setter, receiver_map, id)) return true; | 8658 if (TryInlineApiSetter(setter, receiver_map, id)) return true; |
8654 return TryInline(setter, 1, implicit_return_value, id, assignment_id, | 8659 return setter->IsJSFunction() && |
8655 SETTER_CALL_RETURN); | 8660 TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value, |
| 8661 id, assignment_id, SETTER_CALL_RETURN); |
8656 } | 8662 } |
8657 | 8663 |
8658 | 8664 |
8659 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, | 8665 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, |
8660 Call* expr, | 8666 Call* expr, |
8661 int arguments_count) { | 8667 int arguments_count) { |
8662 return TryInline(function, arguments_count, NULL, expr->id(), | 8668 return TryInline(function, arguments_count, NULL, expr->id(), |
8663 expr->ReturnId(), NORMAL_RETURN); | 8669 expr->ReturnId(), NORMAL_RETURN); |
8664 } | 8670 } |
8665 | 8671 |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9140 int argc = expr->arguments()->length(); | 9146 int argc = expr->arguments()->length(); |
9141 return TryInlineApiCall(function, | 9147 return TryInlineApiCall(function, |
9142 receiver, | 9148 receiver, |
9143 receiver_maps, | 9149 receiver_maps, |
9144 argc, | 9150 argc, |
9145 expr->id(), | 9151 expr->id(), |
9146 kCallApiMethod); | 9152 kCallApiMethod); |
9147 } | 9153 } |
9148 | 9154 |
9149 | 9155 |
9150 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function, | 9156 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function, |
9151 Handle<Map> receiver_map, | 9157 Handle<Map> receiver_map, |
9152 BailoutId ast_id) { | 9158 BailoutId ast_id) { |
9153 SmallMapList receiver_maps(1, zone()); | 9159 SmallMapList receiver_maps(1, zone()); |
9154 receiver_maps.Add(receiver_map, zone()); | 9160 receiver_maps.Add(receiver_map, zone()); |
9155 return TryInlineApiCall(function, | 9161 return TryInlineApiCall(function, |
9156 NULL, // Receiver is on expression stack. | 9162 NULL, // Receiver is on expression stack. |
9157 &receiver_maps, | 9163 &receiver_maps, |
9158 0, | 9164 0, |
9159 ast_id, | 9165 ast_id, |
9160 kCallApiGetter); | 9166 kCallApiGetter); |
9161 } | 9167 } |
9162 | 9168 |
9163 | 9169 |
9164 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function, | 9170 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function, |
9165 Handle<Map> receiver_map, | 9171 Handle<Map> receiver_map, |
9166 BailoutId ast_id) { | 9172 BailoutId ast_id) { |
9167 SmallMapList receiver_maps(1, zone()); | 9173 SmallMapList receiver_maps(1, zone()); |
9168 receiver_maps.Add(receiver_map, zone()); | 9174 receiver_maps.Add(receiver_map, zone()); |
9169 return TryInlineApiCall(function, | 9175 return TryInlineApiCall(function, |
9170 NULL, // Receiver is on expression stack. | 9176 NULL, // Receiver is on expression stack. |
9171 &receiver_maps, | 9177 &receiver_maps, |
9172 1, | 9178 1, |
9173 ast_id, | 9179 ast_id, |
9174 kCallApiSetter); | 9180 kCallApiSetter); |
9175 } | 9181 } |
9176 | 9182 |
9177 | 9183 |
9178 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, | 9184 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function, |
9179 HValue* receiver, | 9185 HValue* receiver, |
9180 SmallMapList* receiver_maps, | 9186 SmallMapList* receiver_maps, |
9181 int argc, | 9187 int argc, BailoutId ast_id, |
9182 BailoutId ast_id, | 9188 ApiCallType call_type) { |
9183 ApiCallType call_type) { | 9189 if (function->IsJSFunction() && |
9184 if (function->context()->native_context() != | 9190 Handle<JSFunction>::cast(function)->context()->native_context() != |
9185 top_info()->closure()->context()->native_context()) { | 9191 top_info()->closure()->context()->native_context()) { |
9186 return false; | 9192 return false; |
9187 } | 9193 } |
9188 CallOptimization optimization(function); | 9194 CallOptimization optimization(function); |
9189 if (!optimization.is_simple_api_call()) return false; | 9195 if (!optimization.is_simple_api_call()) return false; |
9190 Handle<Map> holder_map; | 9196 Handle<Map> holder_map; |
9191 for (int i = 0; i < receiver_maps->length(); ++i) { | 9197 for (int i = 0; i < receiver_maps->length(); ++i) { |
9192 auto map = receiver_maps->at(i); | 9198 auto map = receiver_maps->at(i); |
9193 // Don't inline calls to receivers requiring accesschecks. | 9199 // Don't inline calls to receivers requiring accesschecks. |
9194 if (map->is_access_check_needed()) return false; | 9200 if (map->is_access_check_needed()) return false; |
9195 } | 9201 } |
9196 if (call_type == kCallApiFunction) { | 9202 if (call_type == kCallApiFunction) { |
9197 // Cannot embed a direct reference to the global proxy map | 9203 // Cannot embed a direct reference to the global proxy map |
9198 // as it maybe dropped on deserialization. | 9204 // as it maybe dropped on deserialization. |
9199 CHECK(!isolate()->serializer_enabled()); | 9205 CHECK(!isolate()->serializer_enabled()); |
| 9206 DCHECK(function->IsJSFunction()); |
9200 DCHECK_EQ(0, receiver_maps->length()); | 9207 DCHECK_EQ(0, receiver_maps->length()); |
9201 receiver_maps->Add(handle(function->global_proxy()->map()), zone()); | 9208 receiver_maps->Add( |
| 9209 handle(Handle<JSFunction>::cast(function)->global_proxy()->map()), |
| 9210 zone()); |
9202 } | 9211 } |
9203 CallOptimization::HolderLookup holder_lookup = | 9212 CallOptimization::HolderLookup holder_lookup = |
9204 CallOptimization::kHolderNotFound; | 9213 CallOptimization::kHolderNotFound; |
9205 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( | 9214 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( |
9206 receiver_maps->first(), &holder_lookup); | 9215 receiver_maps->first(), &holder_lookup); |
9207 if (holder_lookup == CallOptimization::kHolderNotFound) return false; | 9216 if (holder_lookup == CallOptimization::kHolderNotFound) return false; |
9208 | 9217 |
9209 if (FLAG_trace_inlining) { | 9218 if (FLAG_trace_inlining) { |
9210 PrintF("Inlining api function "); | 9219 PrintF("Inlining api function "); |
9211 function->ShortPrint(); | 9220 function->ShortPrint(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9271 ExternalReference ref = ExternalReference(&fun, | 9280 ExternalReference ref = ExternalReference(&fun, |
9272 ExternalReference::DIRECT_API_CALL, | 9281 ExternalReference::DIRECT_API_CALL, |
9273 isolate()); | 9282 isolate()); |
9274 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); | 9283 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); |
9275 | 9284 |
9276 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder, | 9285 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder, |
9277 api_function_address, nullptr}; | 9286 api_function_address, nullptr}; |
9278 | 9287 |
9279 HInstruction* call = nullptr; | 9288 HInstruction* call = nullptr; |
9280 if (!is_function) { | 9289 if (!is_function) { |
9281 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined); | 9290 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined, |
| 9291 !optimization.is_constant_call()); |
9282 Handle<Code> code = stub.GetCode(); | 9292 Handle<Code> code = stub.GetCode(); |
9283 HConstant* code_value = Add<HConstant>(code); | 9293 HConstant* code_value = Add<HConstant>(code); |
9284 ApiAccessorDescriptor descriptor(isolate()); | 9294 ApiAccessorDescriptor descriptor(isolate()); |
9285 call = New<HCallWithDescriptor>( | 9295 call = New<HCallWithDescriptor>( |
9286 code_value, argc + 1, descriptor, | 9296 code_value, argc + 1, descriptor, |
9287 Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); | 9297 Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); |
9288 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) { | 9298 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) { |
9289 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined); | 9299 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined); |
9290 Handle<Code> code = stub.GetCode(); | 9300 Handle<Code> code = stub.GetCode(); |
9291 HConstant* code_value = Add<HConstant>(code); | 9301 HConstant* code_value = Add<HConstant>(code); |
(...skipping 4316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13608 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13618 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13609 } | 13619 } |
13610 | 13620 |
13611 #ifdef DEBUG | 13621 #ifdef DEBUG |
13612 graph_->Verify(false); // No full verify. | 13622 graph_->Verify(false); // No full verify. |
13613 #endif | 13623 #endif |
13614 } | 13624 } |
13615 | 13625 |
13616 } // namespace internal | 13626 } // namespace internal |
13617 } // namespace v8 | 13627 } // namespace v8 |
OLD | NEW |