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

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, 11 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« src/builtins.cc ('K') | « src/crankshaft/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698