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

Side by Side Diff: src/hydrogen.cc

Issue 146023004: inline api getters in crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5512 matching lines...) Expand 10 before | Expand all | Expand 10 after
5523 5523
5524 5524
5525 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { 5525 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
5526 if (lookup_.IsField()) { 5526 if (lookup_.IsField()) {
5527 access_ = HObjectAccess::ForField(map, &lookup_, name_); 5527 access_ = HObjectAccess::ForField(map, &lookup_, name_);
5528 } else if (lookup_.IsPropertyCallbacks()) { 5528 } else if (lookup_.IsPropertyCallbacks()) {
5529 Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate()); 5529 Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate());
5530 if (!callback->IsAccessorPair()) return false; 5530 if (!callback->IsAccessorPair()) return false;
5531 Object* getter = Handle<AccessorPair>::cast(callback)->getter(); 5531 Object* getter = Handle<AccessorPair>::cast(callback)->getter();
5532 if (!getter->IsJSFunction()) return false; 5532 if (!getter->IsJSFunction()) return false;
5533 Handle<JSFunction> accessor = handle(JSFunction::cast(getter)); 5533 accessor_ = handle(JSFunction::cast(getter));
5534 CallOptimization call_optimization(accessor);
5535 // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
5536 if (call_optimization.is_simple_api_call()) return false;
5537 accessor_ = accessor;
5538 } else if (lookup_.IsConstant()) { 5534 } else if (lookup_.IsConstant()) {
5539 constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); 5535 constant_ = handle(lookup_.GetConstantFromMap(*map), isolate());
5540 } 5536 }
5541 5537
5542 return true; 5538 return true;
5543 } 5539 }
5544 5540
5545 5541
5546 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 5542 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
5547 Handle<Map> map = this->map(); 5543 Handle<Map> map = this->map();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
5652 5648
5653 if (info->lookup()->IsPropertyCallbacks()) { 5649 if (info->lookup()->IsPropertyCallbacks()) {
5654 if (NeedsWrappingFor(info->type(), info->accessor())) { 5650 if (NeedsWrappingFor(info->type(), info->accessor())) {
5655 HValue* function = Add<HConstant>(info->accessor()); 5651 HValue* function = Add<HConstant>(info->accessor());
5656 Add<HPushArgument>(checked_object); 5652 Add<HPushArgument>(checked_object);
5657 return New<HCallFunction>(function, 1, WRAP_AND_CALL); 5653 return New<HCallFunction>(function, 1, WRAP_AND_CALL);
5658 } else { 5654 } else {
5659 Push(checked_object); 5655 Push(checked_object);
5660 if (FLAG_inline_accessors && 5656 if (FLAG_inline_accessors &&
5661 can_inline_accessor && 5657 can_inline_accessor &&
5662 TryInlineGetter(info->accessor(), ast_id, return_id)) { 5658 TryInlineGetter(info->accessor(),
5659 checked_object,
5660 info->map(),
5661 ast_id,
5662 return_id)) {
5663 return NULL; 5663 return NULL;
5664 } 5664 }
5665 Add<HPushArgument>(Pop()); 5665 Add<HPushArgument>(Pop());
5666 return BuildCallConstantFunction(info->accessor(), 1); 5666 return BuildCallConstantFunction(info->accessor(), 1);
5667 } 5667 }
5668 } 5668 }
5669 5669
5670 ASSERT(info->lookup()->IsConstant()); 5670 ASSERT(info->lookup()->IsConstant());
5671 return New<HConstant>(info->constant()); 5671 return New<HConstant>(info->constant());
5672 } 5672 }
(...skipping 1927 matching lines...) Expand 10 before | Expand all | Expand 10 after
7600 return TryInline(expr->target(), 7600 return TryInline(expr->target(),
7601 expr->arguments()->length(), 7601 expr->arguments()->length(),
7602 implicit_return_value, 7602 implicit_return_value,
7603 expr->id(), 7603 expr->id(),
7604 expr->ReturnId(), 7604 expr->ReturnId(),
7605 CONSTRUCT_CALL_RETURN); 7605 CONSTRUCT_CALL_RETURN);
7606 } 7606 }
7607 7607
7608 7608
7609 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 7609 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
7610 HValue * receiver,
Toon Verwaest 2014/02/04 13:25:31 Remove space between HValue and *
7611 Handle<Map> receiver_map,
7610 BailoutId ast_id, 7612 BailoutId ast_id,
7611 BailoutId return_id) { 7613 BailoutId return_id) {
7614 if (TryInlineApiGetter(getter, receiver, receiver_map, ast_id)) return true;
7612 return TryInline(getter, 7615 return TryInline(getter,
7613 0, 7616 0,
7614 NULL, 7617 NULL,
7615 ast_id, 7618 ast_id,
7616 return_id, 7619 return_id,
7617 GETTER_CALL_RETURN); 7620 GETTER_CALL_RETURN);
7618 } 7621 }
7619 7622
7620 7623
7621 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 7624 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
7884 default: 7887 default:
7885 // Not yet supported for inlining. 7888 // Not yet supported for inlining.
7886 break; 7889 break;
7887 } 7890 }
7888 return false; 7891 return false;
7889 } 7892 }
7890 7893
7891 7894
7892 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, 7895 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
7893 HValue* receiver) { 7896 HValue* receiver) {
7894 return TryInlineApiCall( 7897 if (!expr->IsMonomorphic()) return false;
Toon Verwaest 2014/02/04 13:25:31 These checks shouldn't be here, but rather in CanL
7895 expr, receiver, Handle<Map>::null(), true); 7898 Handle<JSFunction> function = expr->target();
7899 int argc = expr->arguments()->length();
7900 Handle<Map> receiver_map = Handle<Map>::null();
7901 return TryInlineApiCall(function,
7902 receiver,
7903 receiver_map,
7904 argc,
7905 expr->id(),
7906 kCallApiFunction);
7896 } 7907 }
7897 7908
7898 7909
7899 bool HOptimizedGraphBuilder::TryInlineApiMethodCall(Call* expr, 7910 bool HOptimizedGraphBuilder::TryInlineApiMethodCall(Call* expr,
7900 HValue* receiver, 7911 HValue* receiver,
7901 Handle<Map> receiver_map) { 7912 Handle<Map> receiver_map) {
7902 return TryInlineApiCall(expr, receiver, receiver_map, false); 7913 if (!expr->IsMonomorphic()) return false;
7914 Handle<JSFunction> function = expr->target();
7915 int argc = expr->arguments()->length();
7916 return TryInlineApiCall(function,
7917 receiver,
7918 receiver_map,
7919 argc,
7920 expr->id(),
7921 kCallApiMethod);
7903 } 7922 }
7904 7923
7905 bool HOptimizedGraphBuilder::TryInlineApiCall(Call* expr, 7924
7906 HValue* receiver, 7925 bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
7907 Handle<Map> receiver_map, 7926 HValue* receiver,
7908 bool is_function_call) { 7927 Handle<Map> receiver_map,
7909 if (!expr->IsMonomorphic()) return false; 7928 BailoutId ast_id) {
7910 CallOptimization optimization(expr->target()); 7929 return TryInlineApiCall(function,
7930 receiver,
7931 receiver_map,
7932 0,
7933 ast_id,
7934 kCallApiGetter);
7935 }
7936
7937
7938 bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
7939 HValue* receiver,
7940 Handle<Map> receiver_map,
7941 int argc,
7942 BailoutId ast_id,
7943 ApiCallType call_type) {
7944 CallOptimization optimization(function);
7911 if (!optimization.is_simple_api_call()) return false; 7945 if (!optimization.is_simple_api_call()) return false;
7912 Handle<Map> holder_map; 7946 Handle<Map> holder_map;
7913 if (is_function_call) { 7947 if (call_type == kCallApiFunction) {
7914 // Cannot embed a direct reference to the global proxy map 7948 // Cannot embed a direct reference to the global proxy map
7915 // as it maybe dropped on deserialization. 7949 // as it maybe dropped on deserialization.
7916 CHECK(!Serializer::enabled()); 7950 CHECK(!Serializer::enabled());
7917 receiver_map = Handle<Map>( 7951 receiver_map = handle(
7918 expr->target()->context()->global_object()->global_receiver()->map()); 7952 function->context()->global_object()->global_receiver()->map());
7919 } 7953 }
7920 CallOptimization::HolderLookup holder_lookup = 7954 CallOptimization::HolderLookup holder_lookup =
7921 CallOptimization::kHolderNotFound; 7955 CallOptimization::kHolderNotFound;
7922 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 7956 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
7923 receiver_map, &holder_lookup); 7957 receiver_map, &holder_lookup);
7924 if (holder_lookup == CallOptimization::kHolderNotFound) return false; 7958 if (holder_lookup == CallOptimization::kHolderNotFound) return false;
7925 7959
7926 if (FLAG_trace_inlining) { 7960 if (FLAG_trace_inlining) {
7927 PrintF("Inlining api function "); 7961 PrintF("Inlining api function ");
7928 expr->target()->ShortPrint(); 7962 function->ShortPrint();
7929 PrintF("\n"); 7963 PrintF("\n");
7930 } 7964 }
7931 7965
7932 const int argc = expr->arguments()->length(); 7966 if (call_type == kCallApiGetter) {
7933 // Includes receiver. 7967 ASSERT_EQ(0, argc);
7934 PushArgumentsFromEnvironment(argc + 1); 7968 Add<HPushArgument>(Pop()); // Receiver.
7969 } else {
7970 // Includes receiver.
7971 PushArgumentsFromEnvironment(argc + 1);
7972 }
7935 7973
7936 // Need to ensure the chain between receiver and api_holder is intact 7974 // Need to ensure the chain between receiver and api_holder is intact
7937 AddCheckMap(receiver, receiver_map); 7975 AddCheckMap(receiver, receiver_map);
7938 if (holder_lookup == CallOptimization::kHolderFound) { 7976 if (holder_lookup == CallOptimization::kHolderFound) {
7939 AddCheckPrototypeMaps(api_holder, receiver_map); 7977 AddCheckPrototypeMaps(api_holder, receiver_map);
7940 } else { 7978 } else {
7941 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); 7979 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver);
7942 } 7980 }
7943 7981
7944 HValue* holder = NULL; 7982 HValue* holder = NULL;
(...skipping 12 matching lines...) Expand all
7957 Handle<Object> call_data_obj(api_call_info->data(), isolate()); 7995 Handle<Object> call_data_obj(api_call_info->data(), isolate());
7958 bool call_data_is_undefined = call_data_obj->IsUndefined(); 7996 bool call_data_is_undefined = call_data_obj->IsUndefined();
7959 HValue* call_data = Add<HConstant>(call_data_obj); 7997 HValue* call_data = Add<HConstant>(call_data_obj);
7960 ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); 7998 ApiFunction fun(v8::ToCData<Address>(api_call_info->callback()));
7961 ExternalReference ref = ExternalReference(&fun, 7999 ExternalReference ref = ExternalReference(&fun,
7962 ExternalReference::DIRECT_API_CALL, 8000 ExternalReference::DIRECT_API_CALL,
7963 isolate()); 8001 isolate());
7964 HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 8002 HValue* api_function_address = Add<HConstant>(ExternalReference(ref));
7965 8003
7966 HValue* op_vals[] = { 8004 HValue* op_vals[] = {
7967 // callee 8005 Add<HConstant>(function),
7968 Add<HConstant>(expr->target()),
7969 call_data, 8006 call_data,
7970 holder, 8007 holder,
7971 api_function_address, 8008 api_function_address,
7972 context() 8009 context()
7973 }; 8010 };
7974 8011
7975 CallInterfaceDescriptor* descriptor = 8012 CallInterfaceDescriptor* descriptor =
7976 isolate()->call_descriptor(Isolate::ApiFunctionCall); 8013 isolate()->call_descriptor(Isolate::ApiFunctionCall);
7977 8014
7978 CallApiFunctionStub stub(true, call_data_is_undefined, argc); 8015 CallApiFunctionStub stub(true, call_data_is_undefined, argc);
7979 Handle<Code> code = stub.GetCode(isolate()); 8016 Handle<Code> code = stub.GetCode(isolate());
7980 HConstant* code_value = Add<HConstant>(code); 8017 HConstant* code_value = Add<HConstant>(code);
7981 8018
7982 ASSERT((sizeof(op_vals) / kPointerSize) == 8019 ASSERT((sizeof(op_vals) / kPointerSize) ==
7983 descriptor->environment_length()); 8020 descriptor->environment_length());
7984 8021
7985 HInstruction* call = New<HCallWithDescriptor>( 8022 HInstruction* call = New<HCallWithDescriptor>(
7986 code_value, argc + 1, descriptor, 8023 code_value, argc + 1, descriptor,
7987 Vector<HValue*>(op_vals, descriptor->environment_length())); 8024 Vector<HValue*>(op_vals, descriptor->environment_length()));
7988 8025
7989 Drop(1); // Drop function. 8026 switch (call_type) {
7990 ast_context()->ReturnInstruction(call, expr->id()); 8027 case kCallApiFunction:
8028 case kCallApiMethod:
8029 Drop(1); // Drop function.
8030 break;
8031 case kCallApiGetter:
8032 break;
8033 }
8034 ast_context()->ReturnInstruction(call, ast_id);
7991 return true; 8035 return true;
7992 } 8036 }
7993 8037
7994 8038
7995 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 8039 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
7996 ASSERT(expr->expression()->IsProperty()); 8040 ASSERT(expr->expression()->IsProperty());
7997 8041
7998 if (!expr->IsMonomorphic()) { 8042 if (!expr->IsMonomorphic()) {
7999 return false; 8043 return false;
8000 } 8044 }
(...skipping 3355 matching lines...) Expand 10 before | Expand all | Expand 10 after
11356 if (ShouldProduceTraceOutput()) { 11400 if (ShouldProduceTraceOutput()) {
11357 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11401 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11358 } 11402 }
11359 11403
11360 #ifdef DEBUG 11404 #ifdef DEBUG
11361 graph_->Verify(false); // No full verify. 11405 graph_->Verify(false); // No full verify.
11362 #endif 11406 #endif
11363 } 11407 }
11364 11408
11365 } } // namespace v8::internal 11409 } } // namespace v8::internal
OLDNEW
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698