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

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: Make GCMole happy again. 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
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 6353 matching lines...) Expand 10 before | Expand all | Expand 10 after
6364 access_ = HObjectAccess::ForField(map, index, representation(), name_); 6364 access_ = HObjectAccess::ForField(map, index, representation(), name_);
6365 6365
6366 // Load field map for heap objects. 6366 // Load field map for heap objects.
6367 return LoadFieldMaps(map); 6367 return LoadFieldMaps(map);
6368 } else if (IsAccessorConstant()) { 6368 } else if (IsAccessorConstant()) {
6369 Handle<Object> accessors = GetAccessorsFromMap(map); 6369 Handle<Object> accessors = GetAccessorsFromMap(map);
6370 if (!accessors->IsAccessorPair()) return false; 6370 if (!accessors->IsAccessorPair()) return false;
6371 Object* raw_accessor = 6371 Object* raw_accessor =
6372 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() 6372 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter()
6373 : Handle<AccessorPair>::cast(accessors)->setter(); 6373 : Handle<AccessorPair>::cast(accessors)->setter();
6374 if (!raw_accessor->IsJSFunction()) return false; 6374 if (!raw_accessor->IsJSFunction() &&
6375 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); 6375 !raw_accessor->IsFunctionTemplateInfo())
6376 if (accessor->shared()->IsApiFunction()) { 6376 return false;
6377 CallOptimization call_optimization(accessor); 6377 Handle<Object> accessor = handle(HeapObject::cast(raw_accessor));
6378 if (call_optimization.is_simple_api_call()) { 6378 CallOptimization call_optimization(accessor);
6379 CallOptimization::HolderLookup holder_lookup; 6379 if (call_optimization.is_simple_api_call()) {
6380 api_holder_ = 6380 CallOptimization::HolderLookup holder_lookup;
6381 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); 6381 api_holder_ =
6382 } 6382 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup);
6383 } 6383 }
6384 accessor_ = accessor; 6384 accessor_ = accessor;
6385 } else if (IsDataConstant()) { 6385 } else if (IsDataConstant()) {
6386 constant_ = GetConstantFromMap(map); 6386 constant_ = GetConstantFromMap(map);
6387 } 6387 }
6388 6388
6389 return true; 6389 return true;
6390 } 6390 }
6391 6391
6392 6392
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
6610 } 6610 }
6611 6611
6612 if (info->IsAccessorConstant()) { 6612 if (info->IsAccessorConstant()) {
6613 Push(checked_object); 6613 Push(checked_object);
6614 int argument_count = 1; 6614 int argument_count = 1;
6615 if (!info->IsLoad()) { 6615 if (!info->IsLoad()) {
6616 argument_count = 2; 6616 argument_count = 2;
6617 Push(value); 6617 Push(value);
6618 } 6618 }
6619 6619
6620 if (info->NeedsWrappingFor(info->accessor())) { 6620 if (info->accessor()->IsJSFunction() &&
6621 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
6621 HValue* function = Add<HConstant>(info->accessor()); 6622 HValue* function = Add<HConstant>(info->accessor());
6622 PushArgumentsFromEnvironment(argument_count); 6623 PushArgumentsFromEnvironment(argument_count);
6623 return New<HCallFunction>(function, argument_count, 6624 return New<HCallFunction>(function, argument_count,
6624 ConvertReceiverMode::kNotNullOrUndefined, 6625 ConvertReceiverMode::kNotNullOrUndefined,
6625 TailCallMode::kDisallow); 6626 TailCallMode::kDisallow);
6626 } else if (FLAG_inline_accessors && can_inline_accessor) { 6627 } else if (FLAG_inline_accessors && can_inline_accessor) {
6627 bool success = info->IsLoad() 6628 bool success = info->IsLoad()
6628 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6629 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6629 : TryInlineSetter( 6630 : TryInlineSetter(
6630 info->accessor(), info->map(), ast_id, return_id, value); 6631 info->accessor(), info->map(), ast_id, return_id, value);
6631 if (success || HasStackOverflow()) return NULL; 6632 if (success || HasStackOverflow()) return NULL;
6632 } 6633 }
6633 6634
6634 PushArgumentsFromEnvironment(argument_count); 6635 PushArgumentsFromEnvironment(argument_count);
6635 return BuildCallConstantFunction(info->accessor(), argument_count); 6636 if (!info->accessor()->IsJSFunction()) {
6637 Bailout(kInliningBailedOut);
6638 return nullptr;
6639 }
6640 return BuildCallConstantFunction(Handle<JSFunction>::cast(info->accessor()),
6641 argument_count);
6636 } 6642 }
6637 6643
6638 DCHECK(info->IsDataConstant()); 6644 DCHECK(info->IsDataConstant());
6639 if (info->IsLoad()) { 6645 if (info->IsLoad()) {
6640 return New<HConstant>(info->constant()); 6646 return New<HConstant>(info->constant());
6641 } else { 6647 } else {
6642 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6648 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6643 } 6649 }
6644 } 6650 }
6645 6651
(...skipping 2013 matching lines...) Expand 10 before | Expand all | Expand 10 after
8659 } 8665 }
8660 8666
8661 8667
8662 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 8668 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
8663 HValue* implicit_return_value) { 8669 HValue* implicit_return_value) {
8664 return TryInline(expr->target(), expr->arguments()->length(), 8670 return TryInline(expr->target(), expr->arguments()->length(),
8665 implicit_return_value, expr->id(), expr->ReturnId(), 8671 implicit_return_value, expr->id(), expr->ReturnId(),
8666 CONSTRUCT_CALL_RETURN); 8672 CONSTRUCT_CALL_RETURN);
8667 } 8673 }
8668 8674
8669 8675 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter,
8670 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
8671 Handle<Map> receiver_map, 8676 Handle<Map> receiver_map,
8672 BailoutId ast_id, 8677 BailoutId ast_id,
8673 BailoutId return_id) { 8678 BailoutId return_id) {
8674 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 8679 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
8675 return TryInline(getter, 0, NULL, ast_id, return_id, GETTER_CALL_RETURN); 8680 return getter->IsJSFunction() &&
8681 TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id,
8682 GETTER_CALL_RETURN);
8676 } 8683 }
8677 8684
8678 8685 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter,
8679 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
8680 Handle<Map> receiver_map, 8686 Handle<Map> receiver_map,
8681 BailoutId id, 8687 BailoutId id,
8682 BailoutId assignment_id, 8688 BailoutId assignment_id,
8683 HValue* implicit_return_value) { 8689 HValue* implicit_return_value) {
8684 if (TryInlineApiSetter(setter, receiver_map, id)) return true; 8690 if (TryInlineApiSetter(setter, receiver_map, id)) return true;
8685 return TryInline(setter, 1, implicit_return_value, id, assignment_id, 8691 return setter->IsJSFunction() &&
8686 SETTER_CALL_RETURN); 8692 TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value,
8693 id, assignment_id, SETTER_CALL_RETURN);
8687 } 8694 }
8688 8695
8689 8696
8690 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, 8697 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function,
8691 Call* expr, 8698 Call* expr,
8692 int arguments_count) { 8699 int arguments_count) {
8693 return TryInline(function, arguments_count, NULL, expr->id(), 8700 return TryInline(function, arguments_count, NULL, expr->id(),
8694 expr->ReturnId(), NORMAL_RETURN); 8701 expr->ReturnId(), NORMAL_RETURN);
8695 } 8702 }
8696 8703
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
9170 Handle<JSFunction> function = expr->target(); 9177 Handle<JSFunction> function = expr->target();
9171 int argc = expr->arguments()->length(); 9178 int argc = expr->arguments()->length();
9172 return TryInlineApiCall(function, 9179 return TryInlineApiCall(function,
9173 receiver, 9180 receiver,
9174 receiver_maps, 9181 receiver_maps,
9175 argc, 9182 argc,
9176 expr->id(), 9183 expr->id(),
9177 kCallApiMethod); 9184 kCallApiMethod);
9178 } 9185 }
9179 9186
9180 9187 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function,
9181 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
9182 Handle<Map> receiver_map, 9188 Handle<Map> receiver_map,
9183 BailoutId ast_id) { 9189 BailoutId ast_id) {
9184 SmallMapList receiver_maps(1, zone()); 9190 SmallMapList receiver_maps(1, zone());
9185 receiver_maps.Add(receiver_map, zone()); 9191 receiver_maps.Add(receiver_map, zone());
9186 return TryInlineApiCall(function, 9192 return TryInlineApiCall(function,
9187 NULL, // Receiver is on expression stack. 9193 NULL, // Receiver is on expression stack.
9188 &receiver_maps, 9194 &receiver_maps,
9189 0, 9195 0,
9190 ast_id, 9196 ast_id,
9191 kCallApiGetter); 9197 kCallApiGetter);
9192 } 9198 }
9193 9199
9194 9200 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function,
9195 bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function,
9196 Handle<Map> receiver_map, 9201 Handle<Map> receiver_map,
9197 BailoutId ast_id) { 9202 BailoutId ast_id) {
9198 SmallMapList receiver_maps(1, zone()); 9203 SmallMapList receiver_maps(1, zone());
9199 receiver_maps.Add(receiver_map, zone()); 9204 receiver_maps.Add(receiver_map, zone());
9200 return TryInlineApiCall(function, 9205 return TryInlineApiCall(function,
9201 NULL, // Receiver is on expression stack. 9206 NULL, // Receiver is on expression stack.
9202 &receiver_maps, 9207 &receiver_maps,
9203 1, 9208 1,
9204 ast_id, 9209 ast_id,
9205 kCallApiSetter); 9210 kCallApiSetter);
9206 } 9211 }
9207 9212
9208 9213 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function,
9209 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, 9214 HValue* receiver,
9210 HValue* receiver, 9215 SmallMapList* receiver_maps,
9211 SmallMapList* receiver_maps, 9216 int argc, BailoutId ast_id,
9212 int argc, 9217 ApiCallType call_type) {
9213 BailoutId ast_id, 9218 if (function->IsJSFunction() &&
9214 ApiCallType call_type) { 9219 Handle<JSFunction>::cast(function)->context()->native_context() !=
9215 if (function->context()->native_context() != 9220 top_info()->closure()->context()->native_context()) {
9216 top_info()->closure()->context()->native_context()) {
9217 return false; 9221 return false;
9218 } 9222 }
9219 CallOptimization optimization(function); 9223 CallOptimization optimization(function);
9220 if (!optimization.is_simple_api_call()) return false; 9224 if (!optimization.is_simple_api_call()) return false;
9221 Handle<Map> holder_map; 9225 Handle<Map> holder_map;
9222 for (int i = 0; i < receiver_maps->length(); ++i) { 9226 for (int i = 0; i < receiver_maps->length(); ++i) {
9223 auto map = receiver_maps->at(i); 9227 auto map = receiver_maps->at(i);
9224 // Don't inline calls to receivers requiring accesschecks. 9228 // Don't inline calls to receivers requiring accesschecks.
9225 if (map->is_access_check_needed()) return false; 9229 if (map->is_access_check_needed()) return false;
9226 } 9230 }
9227 if (call_type == kCallApiFunction) { 9231 if (call_type == kCallApiFunction) {
9228 // Cannot embed a direct reference to the global proxy map 9232 // Cannot embed a direct reference to the global proxy map
9229 // as it maybe dropped on deserialization. 9233 // as it maybe dropped on deserialization.
9230 CHECK(!isolate()->serializer_enabled()); 9234 CHECK(!isolate()->serializer_enabled());
9235 DCHECK(function->IsJSFunction());
9231 DCHECK_EQ(0, receiver_maps->length()); 9236 DCHECK_EQ(0, receiver_maps->length());
9232 receiver_maps->Add(handle(function->global_proxy()->map()), zone()); 9237 receiver_maps->Add(
9238 handle(Handle<JSFunction>::cast(function)->global_proxy()->map()),
9239 zone());
9233 } 9240 }
9234 CallOptimization::HolderLookup holder_lookup = 9241 CallOptimization::HolderLookup holder_lookup =
9235 CallOptimization::kHolderNotFound; 9242 CallOptimization::kHolderNotFound;
9236 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 9243 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
9237 receiver_maps->first(), &holder_lookup); 9244 receiver_maps->first(), &holder_lookup);
9238 if (holder_lookup == CallOptimization::kHolderNotFound) return false; 9245 if (holder_lookup == CallOptimization::kHolderNotFound) return false;
9239 9246
9240 if (FLAG_trace_inlining) { 9247 if (FLAG_trace_inlining) {
9241 PrintF("Inlining api function "); 9248 PrintF("Inlining api function ");
9242 function->ShortPrint(); 9249 function->ShortPrint();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
9302 ExternalReference ref = ExternalReference(&fun, 9309 ExternalReference ref = ExternalReference(&fun,
9303 ExternalReference::DIRECT_API_CALL, 9310 ExternalReference::DIRECT_API_CALL,
9304 isolate()); 9311 isolate());
9305 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 9312 HValue* api_function_address = Add<HConstant>(ExternalReference(ref));
9306 9313
9307 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder, 9314 HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder,
9308 api_function_address, nullptr}; 9315 api_function_address, nullptr};
9309 9316
9310 HInstruction* call = nullptr; 9317 HInstruction* call = nullptr;
9311 if (!is_function) { 9318 if (!is_function) {
9312 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined); 9319 CallApiAccessorStub stub(isolate(), is_store, call_data_undefined,
9320 !optimization.is_constant_call());
9313 Handle<Code> code = stub.GetCode(); 9321 Handle<Code> code = stub.GetCode();
9314 HConstant* code_value = Add<HConstant>(code); 9322 HConstant* code_value = Add<HConstant>(code);
9315 ApiAccessorDescriptor descriptor(isolate()); 9323 ApiAccessorDescriptor descriptor(isolate());
9316 call = New<HCallWithDescriptor>( 9324 call = New<HCallWithDescriptor>(
9317 code_value, argc + 1, descriptor, 9325 code_value, argc + 1, descriptor,
9318 Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); 9326 Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
9319 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) { 9327 } else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) {
9320 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined); 9328 CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined);
9321 Handle<Code> code = stub.GetCode(); 9329 Handle<Code> code = stub.GetCode();
9322 HConstant* code_value = Add<HConstant>(code); 9330 HConstant* code_value = Add<HConstant>(code);
(...skipping 4334 matching lines...) Expand 10 before | Expand all | Expand 10 after
13657 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13665 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13658 } 13666 }
13659 13667
13660 #ifdef DEBUG 13668 #ifdef DEBUG
13661 graph_->Verify(false); // No full verify. 13669 graph_->Verify(false); // No full verify.
13662 #endif 13670 #endif
13663 } 13671 }
13664 13672
13665 } // namespace internal 13673 } // namespace internal
13666 } // namespace v8 13674 } // namespace v8
OLDNEW
« no previous file with comments | « 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