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

Side by Side Diff: src/hydrogen.cc

Issue 9616014: Improve polymorphic loads on single slots. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix two minor issues. Created 8 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3853 matching lines...) Expand 10 before | Expand all | Expand 10 after
3864 UNREACHABLE(); 3864 UNREACHABLE();
3865 break; 3865 break;
3866 } 3866 }
3867 3867
3868 AddSimulate(expr->GetIdForElement(i)); 3868 AddSimulate(expr->GetIdForElement(i));
3869 } 3869 }
3870 return ast_context()->ReturnValue(Pop()); 3870 return ast_context()->ReturnValue(Pop());
3871 } 3871 }
3872 3872
3873 3873
3874 // Sets the lookup result and returns true if the store can be inlined. 3874 // Sets the lookup result and returns true if the load/store can be inlined.
3875 static bool ComputeStoredField(Handle<Map> type, 3875 static bool ComputeStoredField(Handle<Map> type,
danno 2012/03/09 11:52:58 Rename to something like ComputeLoadStoreField
Michael Starzinger 2012/03/12 11:37:11 Done.
3876 Handle<String> name, 3876 Handle<String> name,
3877 LookupResult* lookup) { 3877 LookupResult* lookup,
3878 bool is_store) {
3878 type->LookupInDescriptors(NULL, *name, lookup); 3879 type->LookupInDescriptors(NULL, *name, lookup);
3879 if (!lookup->IsFound()) return false; 3880 if (!lookup->IsFound()) return false;
3880 if (lookup->type() == FIELD) return true; 3881 if (lookup->type() == FIELD) return true;
3881 return (lookup->type() == MAP_TRANSITION) && 3882 return is_store && (lookup->type() == MAP_TRANSITION) &&
3882 (type->unused_property_fields() > 0); 3883 (type->unused_property_fields() > 0);
3883 } 3884 }
3884 3885
3885 3886
3886 static int ComputeStoredFieldIndex(Handle<Map> type, 3887 static int ComputeStoredFieldIndex(Handle<Map> type,
3887 Handle<String> name, 3888 Handle<String> name,
3888 LookupResult* lookup) { 3889 LookupResult* lookup) {
3889 ASSERT(lookup->type() == FIELD || lookup->type() == MAP_TRANSITION); 3890 ASSERT(lookup->type() == FIELD || lookup->type() == MAP_TRANSITION);
3890 if (lookup->type() == FIELD) { 3891 if (lookup->type() == FIELD) {
3891 return lookup->GetLocalFieldIndexFromMap(*type); 3892 return lookup->GetLocalFieldIndexFromMap(*type);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3950 Property* prop = (expr->AsProperty() != NULL) 3951 Property* prop = (expr->AsProperty() != NULL)
3951 ? expr->AsProperty() 3952 ? expr->AsProperty()
3952 : expr->AsAssignment()->target()->AsProperty(); 3953 : expr->AsAssignment()->target()->AsProperty();
3953 Literal* key = prop->key()->AsLiteral(); 3954 Literal* key = prop->key()->AsLiteral();
3954 Handle<String> name = Handle<String>::cast(key->handle()); 3955 Handle<String> name = Handle<String>::cast(key->handle());
3955 ASSERT(!name.is_null()); 3956 ASSERT(!name.is_null());
3956 3957
3957 LookupResult lookup(isolate()); 3958 LookupResult lookup(isolate());
3958 SmallMapList* types = expr->GetReceiverTypes(); 3959 SmallMapList* types = expr->GetReceiverTypes();
3959 bool is_monomorphic = expr->IsMonomorphic() && 3960 bool is_monomorphic = expr->IsMonomorphic() &&
3960 ComputeStoredField(types->first(), name, &lookup); 3961 ComputeStoredField(types->first(), name, &lookup, true);
3961 3962
3962 return is_monomorphic 3963 return is_monomorphic
3963 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, 3964 ? BuildStoreNamedField(object, name, value, types->first(), &lookup,
3964 true) // Needs smi and map check. 3965 true) // Needs smi and map check.
3965 : BuildStoreNamedGeneric(object, name, value); 3966 : BuildStoreNamedGeneric(object, name, value);
3966 } 3967 }
3967 3968
3968 3969
3970 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
3971 HValue* object,
3972 SmallMapList* types,
3973 Handle<String> name) {
3974 int count = 0;
3975 int previous_field_index = 0;
3976 bool is_monomorphic_field = true;
3977 Handle<Map> map;
3978 LookupResult lookup(isolate());
3979 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
danno 2012/03/09 11:52:58 kMaxStorePolymorphism seems to be inappropriately
Michael Starzinger 2012/03/12 11:37:11 Done. That actually should have been kMaxLoadPolym
3980 map = types->at(i);
3981 if (ComputeStoredField(map, name, &lookup, false)) {
3982 int index = ComputeStoredFieldIndex(map, name, &lookup);
3983 if (count == 0) {
3984 previous_field_index = index;
3985 } else if (is_monomorphic_field) {
3986 is_monomorphic_field = (index == previous_field_index);
3987 }
3988 ++count;
3989 }
3990 }
3991
3992 // Use monomorphic load if property lookup results in the same field index
3993 // for all maps. Requires special map check on the set of all handled maps.
3994 HInstruction* instr;
3995 if (count == types->length() && is_monomorphic_field) {
3996 AddInstruction(new(zone()) HCheckMapSet(object, types));
3997 instr = BuildLoadNamedField(object, expr, map, &lookup, false);
3998 } else {
3999 HValue* context = environment()->LookupContext();
4000 instr = new(zone()) HLoadNamedFieldPolymorphic(context,
4001 object,
4002 types,
4003 name);
4004 }
4005
4006 instr->set_position(expr->position());
4007 return ast_context()->ReturnInstruction(instr, expr->id());
4008 }
4009
4010
3969 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, 4011 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
3970 HValue* object, 4012 HValue* object,
3971 HValue* value, 4013 HValue* value,
3972 SmallMapList* types, 4014 SmallMapList* types,
3973 Handle<String> name) { 4015 Handle<String> name) {
3974 // TODO(ager): We should recognize when the prototype chains for different 4016 // TODO(ager): We should recognize when the prototype chains for different
3975 // maps are identical. In that case we can avoid repeatedly generating the 4017 // maps are identical. In that case we can avoid repeatedly generating the
3976 // same prototype map checks. 4018 // same prototype map checks.
3977 int count = 0; 4019 int count = 0;
3978 HBasicBlock* join = NULL; 4020 HBasicBlock* join = NULL;
3979 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 4021 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
3980 Handle<Map> map = types->at(i); 4022 Handle<Map> map = types->at(i);
3981 LookupResult lookup(isolate()); 4023 LookupResult lookup(isolate());
3982 if (ComputeStoredField(map, name, &lookup)) { 4024 if (ComputeStoredField(map, name, &lookup, true)) {
3983 if (count == 0) { 4025 if (count == 0) {
3984 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. 4026 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once.
3985 join = graph()->CreateBasicBlock(); 4027 join = graph()->CreateBasicBlock();
3986 } 4028 }
3987 ++count; 4029 ++count;
3988 HBasicBlock* if_true = graph()->CreateBasicBlock(); 4030 HBasicBlock* if_true = graph()->CreateBasicBlock();
3989 HBasicBlock* if_false = graph()->CreateBasicBlock(); 4031 HBasicBlock* if_false = graph()->CreateBasicBlock();
3990 HCompareMap* compare = 4032 HCompareMap* compare =
3991 new(zone()) HCompareMap(object, map, if_true, if_false); 4033 new(zone()) HCompareMap(object, map, if_true, if_false);
3992 current_block()->Finish(compare); 4034 current_block()->Finish(compare);
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
4946 4988
4947 } else if (expr->key()->IsPropertyName()) { 4989 } else if (expr->key()->IsPropertyName()) {
4948 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 4990 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
4949 SmallMapList* types = expr->GetReceiverTypes(); 4991 SmallMapList* types = expr->GetReceiverTypes();
4950 4992
4951 HValue* obj = Pop(); 4993 HValue* obj = Pop();
4952 if (expr->IsMonomorphic()) { 4994 if (expr->IsMonomorphic()) {
4953 instr = BuildLoadNamed(obj, expr, types->first(), name); 4995 instr = BuildLoadNamed(obj, expr, types->first(), name);
4954 } else if (types != NULL && types->length() > 1) { 4996 } else if (types != NULL && types->length() > 1) {
4955 AddInstruction(new(zone()) HCheckNonSmi(obj)); 4997 AddInstruction(new(zone()) HCheckNonSmi(obj));
4956 HValue* context = environment()->LookupContext(); 4998 HandlePolymorphicLoadNamedField(expr, obj, types, name);
4957 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); 4999 return;
4958 } else { 5000 } else {
4959 instr = BuildLoadNamedGeneric(obj, expr); 5001 instr = BuildLoadNamedGeneric(obj, expr);
4960 } 5002 }
4961 5003
4962 } else { 5004 } else {
4963 CHECK_ALIVE(VisitForValue(expr->key())); 5005 CHECK_ALIVE(VisitForValue(expr->key()));
4964 5006
4965 HValue* key = Pop(); 5007 HValue* key = Pop();
4966 HValue* obj = Pop(); 5008 HValue* obj = Pop();
4967 5009
(...skipping 3079 matching lines...) Expand 10 before | Expand all | Expand 10 after
8047 } 8089 }
8048 } 8090 }
8049 8091
8050 #ifdef DEBUG 8092 #ifdef DEBUG
8051 if (graph_ != NULL) graph_->Verify(false); // No full verify. 8093 if (graph_ != NULL) graph_->Verify(false); // No full verify.
8052 if (allocator_ != NULL) allocator_->Verify(); 8094 if (allocator_ != NULL) allocator_->Verify();
8053 #endif 8095 #endif
8054 } 8096 }
8055 8097
8056 } } // namespace v8::internal 8098 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698