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

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

Issue 1609233002: Do not eagerly instantiate accessors' JSFunction. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 4 years, 10 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
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 6316 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
6573 } 6573 }
6574 6574
6575 if (info->IsAccessorConstant()) { 6575 if (info->IsAccessorConstant()) {
6576 Push(checked_object); 6576 Push(checked_object);
6577 int argument_count = 1; 6577 int argument_count = 1;
6578 if (!info->IsLoad()) { 6578 if (!info->IsLoad()) {
6579 argument_count = 2; 6579 argument_count = 2;
6580 Push(value); 6580 Push(value);
6581 } 6581 }
6582 6582
6583 if (info->NeedsWrappingFor(info->accessor())) { 6583 if (info->accessor()->IsJSFunction() &&
6584 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
Toon Verwaest 2016/01/28 12:05:19 If you could get a FunctionTemplate here, shouldn'
epertoso 2016/02/01 16:18:03 Technically, it seems unlikely that TryInlineGette
6584 HValue* function = Add<HConstant>(info->accessor()); 6585 HValue* function = Add<HConstant>(info->accessor());
6585 PushArgumentsFromEnvironment(argument_count); 6586 PushArgumentsFromEnvironment(argument_count);
6586 return New<HCallFunction>(function, argument_count, 6587 return New<HCallFunction>(function, argument_count,
6587 ConvertReceiverMode::kNotNullOrUndefined, 6588 ConvertReceiverMode::kNotNullOrUndefined,
6588 TailCallMode::kDisallow); 6589 TailCallMode::kDisallow);
6589 } else if (FLAG_inline_accessors && can_inline_accessor) { 6590 } else if (FLAG_inline_accessors && can_inline_accessor) {
6590 bool success = info->IsLoad() 6591 bool success = info->IsLoad()
6591 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6592 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6592 : TryInlineSetter( 6593 : TryInlineSetter(
6593 info->accessor(), info->map(), ast_id, return_id, value); 6594 info->accessor(), info->map(), ast_id, return_id, value);
6594 if (success || HasStackOverflow()) return NULL; 6595 if (success || HasStackOverflow()) return NULL;
6595 } 6596 }
6596 6597
6597 PushArgumentsFromEnvironment(argument_count); 6598 PushArgumentsFromEnvironment(argument_count);
6598 return BuildCallConstantFunction(info->accessor(), argument_count); 6599 DCHECK(info->accessor()->IsJSFunction());
6600 return BuildCallConstantFunction(Handle<JSFunction>::cast(info->accessor()),
6601 argument_count);
6599 } 6602 }
6600 6603
6601 DCHECK(info->IsDataConstant()); 6604 DCHECK(info->IsDataConstant());
6602 if (info->IsLoad()) { 6605 if (info->IsLoad()) {
6603 return New<HConstant>(info->constant()); 6606 return New<HConstant>(info->constant());
6604 } else { 6607 } else {
6605 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6608 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6606 } 6609 }
6607 } 6610 }
6608 6611
(...skipping 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after
8620 } 8623 }
8621 8624
8622 8625
8623 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 8626 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
8624 HValue* implicit_return_value) { 8627 HValue* implicit_return_value) {
8625 return TryInline(expr->target(), expr->arguments()->length(), 8628 return TryInline(expr->target(), expr->arguments()->length(),
8626 implicit_return_value, expr->id(), expr->ReturnId(), 8629 implicit_return_value, expr->id(), expr->ReturnId(),
8627 CONSTRUCT_CALL_RETURN); 8630 CONSTRUCT_CALL_RETURN);
8628 } 8631 }
8629 8632
8630 8633 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter,
8631 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
8632 Handle<Map> receiver_map, 8634 Handle<Map> receiver_map,
8633 BailoutId ast_id, 8635 BailoutId ast_id,
8634 BailoutId return_id) { 8636 BailoutId return_id) {
8635 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 8637 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
8636 return TryInline(getter, 0, NULL, ast_id, return_id, GETTER_CALL_RETURN); 8638 return getter->IsJSFunction() &&
8639 TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id,
8640 GETTER_CALL_RETURN);
8637 } 8641 }
8638 8642
8639 8643 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter,
8640 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
8641 Handle<Map> receiver_map, 8644 Handle<Map> receiver_map,
8642 BailoutId id, 8645 BailoutId id,
8643 BailoutId assignment_id, 8646 BailoutId assignment_id,
8644 HValue* implicit_return_value) { 8647 HValue* implicit_return_value) {
8645 if (TryInlineApiSetter(setter, receiver_map, id)) return true; 8648 if (TryInlineApiSetter(setter, receiver_map, id)) return true;
8646 return TryInline(setter, 1, implicit_return_value, id, assignment_id, 8649 return setter->IsJSFunction() &&
8647 SETTER_CALL_RETURN); 8650 TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value,
8651 id, assignment_id, SETTER_CALL_RETURN);
8648 } 8652 }
8649 8653
8650 8654
8651 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, 8655 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function,
8652 Call* expr, 8656 Call* expr,
8653 int arguments_count) { 8657 int arguments_count) {
8654 return TryInline(function, arguments_count, NULL, expr->id(), 8658 return TryInline(function, arguments_count, NULL, expr->id(),
8655 expr->ReturnId(), NORMAL_RETURN); 8659 expr->ReturnId(), NORMAL_RETURN);
8656 } 8660 }
8657 8661
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
9131 Handle<JSFunction> function = expr->target(); 9135 Handle<JSFunction> function = expr->target();
9132 int argc = expr->arguments()->length(); 9136 int argc = expr->arguments()->length();
9133 return TryInlineApiCall(function, 9137 return TryInlineApiCall(function,
9134 receiver, 9138 receiver,
9135 receiver_maps, 9139 receiver_maps,
9136 argc, 9140 argc,
9137 expr->id(), 9141 expr->id(),
9138 kCallApiMethod); 9142 kCallApiMethod);
9139 } 9143 }
9140 9144
9141 9145 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function,
9142 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
9143 Handle<Map> receiver_map, 9146 Handle<Map> receiver_map,
9144 BailoutId ast_id) { 9147 BailoutId ast_id) {
9145 SmallMapList receiver_maps(1, zone()); 9148 SmallMapList receiver_maps(1, zone());
9146 receiver_maps.Add(receiver_map, zone()); 9149 receiver_maps.Add(receiver_map, zone());
9147 return TryInlineApiCall(function, 9150 return TryInlineApiCall(function,
9148 NULL, // Receiver is on expression stack. 9151 NULL, // Receiver is on expression stack.
9149 &receiver_maps, 9152 &receiver_maps,
9150 0, 9153 0,
9151 ast_id, 9154 ast_id,
9152 kCallApiGetter); 9155 kCallApiGetter);
9153 } 9156 }
9154 9157
9155 9158 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function,
9156 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function,
9157 Handle<Map> receiver_map, 9159 Handle<Map> receiver_map,
9158 BailoutId ast_id) { 9160 BailoutId ast_id) {
9159 SmallMapList receiver_maps(1, zone()); 9161 SmallMapList receiver_maps(1, zone());
9160 receiver_maps.Add(receiver_map, zone()); 9162 receiver_maps.Add(receiver_map, zone());
9161 return TryInlineApiCall(function, 9163 return TryInlineApiCall(function,
9162 NULL, // Receiver is on expression stack. 9164 NULL, // Receiver is on expression stack.
9163 &receiver_maps, 9165 &receiver_maps,
9164 1, 9166 1,
9165 ast_id, 9167 ast_id,
9166 kCallApiSetter); 9168 kCallApiSetter);
9167 } 9169 }
9168 9170
9169 9171 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function,
9170 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, 9172 HValue* receiver,
9171 HValue* receiver, 9173 SmallMapList* receiver_maps,
9172 SmallMapList* receiver_maps, 9174 int argc, BailoutId ast_id,
9173 int argc, 9175 ApiCallType call_type) {
9174 BailoutId ast_id, 9176 if (function->IsJSFunction() &&
9175 ApiCallType call_type) { 9177 Handle<JSFunction>::cast(function)->context()->native_context() !=
9176 if (function->context()->native_context() != 9178 top_info()->closure()->context()->native_context()) {
9177 top_info()->closure()->context()->native_context()) {
9178 return false; 9179 return false;
9179 } 9180 }
9180 CallOptimization optimization(function); 9181 CallOptimization optimization(function);
9181 if (!optimization.is_simple_api_call()) return false; 9182 if (!optimization.is_simple_api_call()) return false;
9182 Handle<Map> holder_map; 9183 Handle<Map> holder_map;
9183 for (int i = 0; i < receiver_maps->length(); ++i) { 9184 for (int i = 0; i < receiver_maps->length(); ++i) {
9184 auto map = receiver_maps->at(i); 9185 auto map = receiver_maps->at(i);
9185 // Don't inline calls to receivers requiring accesschecks. 9186 // Don't inline calls to receivers requiring accesschecks.
9186 if (map->is_access_check_needed()) return false; 9187 if (map->is_access_check_needed()) return false;
9187 } 9188 }
9188 if (call_type == kCallApiFunction) { 9189 if (call_type == kCallApiFunction) {
9189 // Cannot embed a direct reference to the global proxy map 9190 // Cannot embed a direct reference to the global proxy map
9190 // as it maybe dropped on deserialization. 9191 // as it maybe dropped on deserialization.
9191 CHECK(!isolate()->serializer_enabled()); 9192 CHECK(!isolate()->serializer_enabled());
9193 DCHECK(function->IsJSFunction());
9192 DCHECK_EQ(0, receiver_maps->length()); 9194 DCHECK_EQ(0, receiver_maps->length());
9193 receiver_maps->Add(handle(function->global_proxy()->map()), zone()); 9195 receiver_maps->Add(
9196 handle(Handle<JSFunction>::cast(function)->global_proxy()->map()),
9197 zone());
9194 } 9198 }
9195 CallOptimization::HolderLookup holder_lookup = 9199 CallOptimization::HolderLookup holder_lookup =
9196 CallOptimization::kHolderNotFound; 9200 CallOptimization::kHolderNotFound;
9197 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 9201 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
9198 receiver_maps->first(), &holder_lookup); 9202 receiver_maps->first(), &holder_lookup);
9199 if (holder_lookup == CallOptimization::kHolderNotFound) return false; 9203 if (holder_lookup == CallOptimization::kHolderNotFound) return false;
9200 9204
9201 if (FLAG_trace_inlining) { 9205 if (FLAG_trace_inlining) {
9202 PrintF("Inlining api function "); 9206 PrintF("Inlining api function ");
9203 function->ShortPrint(); 9207 function->ShortPrint();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
9263 ExternalReference ref = ExternalReference(&fun, 9267 ExternalReference ref = ExternalReference(&fun,
9264 ExternalReference::DIRECT_API_CALL, 9268 ExternalReference::DIRECT_API_CALL,
9265 isolate()); 9269 isolate());
9266 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 9270 HValue* api_function_address = Add<HConstant>(ExternalReference(ref));
9267 9271
9268 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder, 9272 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder,
9269 api_function_address, nullptr}; 9273 api_function_address, nullptr};
9270 9274
9271 HInstruction* call = nullptr; 9275 HInstruction* call = nullptr;
9272 if (!is_function) { 9276 if (!is_function) {
9273 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined); 9277 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined,
9278 !optimization.is_constant_call());
9274 Handle<Code> code = stub.GetCode(); 9279 Handle<Code> code = stub.GetCode();
9275 HConstant* code_value = Add<HConstant>(code); 9280 HConstant* code_value = Add<HConstant>(code);
9276 ApiAccessorDescriptor descriptor(isolate()); 9281 ApiAccessorDescriptor descriptor(isolate());
9277 call = New<HCallWithDescriptor>( 9282 call = New<HCallWithDescriptor>(
9278 code_value, argc + 1, descriptor, 9283 code_value, argc + 1, descriptor,
9279 Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); 9284 Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
9280 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) { 9285 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) {
9281 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined); 9286 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined);
9282 Handle<Code> code = stub.GetCode(); 9287 Handle<Code> code = stub.GetCode();
9283 HConstant* code_value = Add<HConstant>(code); 9288 HConstant* code_value = Add<HConstant>(code);
(...skipping 4343 matching lines...) Expand 10 before | Expand all | Expand 10 after
13627 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13632 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13628 } 13633 }
13629 13634
13630 #ifdef DEBUG 13635 #ifdef DEBUG
13631 graph_->Verify(false); // No full verify. 13636 graph_->Verify(false); // No full verify.
13632 #endif 13637 #endif
13633 } 13638 }
13634 13639
13635 } // namespace internal 13640 } // namespace internal
13636 } // namespace v8 13641 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698