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

Side by Side Diff: src/hydrogen.cc

Issue 8354003: Handle keyed stores after elements transition monomorphically if possible (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 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
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 4016 matching lines...) Expand 10 before | Expand all | Expand 10 after
4027 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key); 4027 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key);
4028 } else { // FAST_ELEMENTS or FAST_SMI_ONLY_ELEMENTS. 4028 } else { // FAST_ELEMENTS or FAST_SMI_ONLY_ELEMENTS.
4029 return new(zone()) HLoadKeyedFastElement(elements, checked_key); 4029 return new(zone()) HLoadKeyedFastElement(elements, checked_key);
4030 } 4030 }
4031 } 4031 }
4032 4032
4033 4033
4034 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, 4034 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
4035 HValue* key, 4035 HValue* key,
4036 HValue* val, 4036 HValue* val,
4037 Expression* expr, 4037 Handle<Map> map,
4038 bool is_store) { 4038 bool is_store) {
4039 ASSERT(expr->IsMonomorphic());
4040 Handle<Map> map = expr->GetMonomorphicReceiverType();
4041 AddInstruction(new(zone()) HCheckNonSmi(object));
4042 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); 4039 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map));
4043 bool fast_smi_only_elements = map->has_fast_smi_only_elements(); 4040 bool fast_smi_only_elements = map->has_fast_smi_only_elements();
4044 bool fast_elements = map->has_fast_elements(); 4041 bool fast_elements = map->has_fast_elements();
4045 bool fast_double_elements = map->has_fast_double_elements(); 4042 bool fast_double_elements = map->has_fast_double_elements();
4046 if (!fast_smi_only_elements && 4043 if (!fast_smi_only_elements &&
4047 !fast_elements && 4044 !fast_elements &&
4048 !fast_double_elements && 4045 !fast_double_elements &&
4049 !map->has_external_array_elements()) { 4046 !map->has_external_array_elements()) {
4050 return is_store ? BuildStoreKeyedGeneric(object, key, val) 4047 return is_store ? BuildStoreKeyedGeneric(object, key, val)
4051 : BuildLoadKeyedGeneric(object, key); 4048 : BuildLoadKeyedGeneric(object, key);
(...skipping 29 matching lines...) Expand all
4081 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, 4078 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
4082 HValue* key, 4079 HValue* key,
4083 HValue* val, 4080 HValue* val,
4084 Expression* prop, 4081 Expression* prop,
4085 int ast_id, 4082 int ast_id,
4086 int position, 4083 int position,
4087 bool is_store, 4084 bool is_store,
4088 bool* has_side_effects) { 4085 bool* has_side_effects) {
4089 *has_side_effects = false; 4086 *has_side_effects = false;
4090 AddInstruction(new(zone()) HCheckNonSmi(object)); 4087 AddInstruction(new(zone()) HCheckNonSmi(object));
4091 AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
4092 SmallMapList* maps = prop->GetReceiverTypes(); 4088 SmallMapList* maps = prop->GetReceiverTypes();
4093 bool todo_external_array = false; 4089 bool todo_external_array = false;
4094 4090
4095 static const int kNumElementTypes = kElementsKindCount; 4091 static const int kNumElementTypes = kElementsKindCount;
4096 bool type_todo[kNumElementTypes]; 4092 bool type_todo[kNumElementTypes];
4097 for (int i = 0; i < kNumElementTypes; ++i) { 4093 for (int i = 0; i < kNumElementTypes; ++i) {
4098 type_todo[i] = false; 4094 type_todo[i] = false;
4099 } 4095 }
4100 4096
4101 // Elements_kind transition support. 4097 // Elements_kind transition support.
(...skipping 11 matching lines...) Expand all
4113 } 4109 }
4114 // Get transition target for each map (NULL == no transition). 4110 // Get transition target for each map (NULL == no transition).
4115 for (int i = 0; i < maps->length(); ++i) { 4111 for (int i = 0; i < maps->length(); ++i) {
4116 Handle<Map> map = maps->at(i); 4112 Handle<Map> map = maps->at(i);
4117 Map* transitioned_map = 4113 Map* transitioned_map =
4118 map->FindTransitionedMap(&possible_transitioned_maps); 4114 map->FindTransitionedMap(&possible_transitioned_maps);
4119 transition_target.Add(transitioned_map); 4115 transition_target.Add(transitioned_map);
4120 } 4116 }
4121 } 4117 }
4122 4118
4119 int num_untransitionable_maps = 0;
4120 Handle<Map> untransitionable_map;
4123 for (int i = 0; i < maps->length(); ++i) { 4121 for (int i = 0; i < maps->length(); ++i) {
4124 Handle<Map> map = maps->at(i); 4122 Handle<Map> map = maps->at(i);
4125 ASSERT(map->IsMap()); 4123 ASSERT(map->IsMap());
4126 ASSERT(!is_store || (transition_target.length() == maps->length())); 4124 ASSERT(!is_store || (transition_target.length() == maps->length()));
4127 if (is_store && transition_target.at(i) != NULL) { 4125 if (is_store && transition_target.at(i) != NULL) {
4128 object = AddInstruction(new(zone()) HTransitionElementsKind( 4126 object = AddInstruction(new(zone()) HTransitionElementsKind(
4129 object, map, Handle<Map>(transition_target.at(i)))); 4127 object, map, Handle<Map>(transition_target.at(i))));
4130 } else { 4128 } else {
4131 type_todo[map->elements_kind()] = true; 4129 type_todo[map->elements_kind()] = true;
4132 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { 4130 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
4133 todo_external_array = true; 4131 todo_external_array = true;
4134 } 4132 }
4133 num_untransitionable_maps++;
4134 untransitionable_map = map;
4135 } 4135 }
4136 } 4136 }
4137 4137
4138 // If only one map is left after transitioning, handle this case
4139 // monomorphically.
4140 if (num_untransitionable_maps == 1) {
4141 HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess(
4142 object, key, val, untransitionable_map, is_store));
4143 *has_side_effects |= instr->HasSideEffects();
4144 instr->set_position(position);
4145 return is_store ? NULL : instr;
4146 }
4147
4148 AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
4138 HBasicBlock* join = graph()->CreateBasicBlock(); 4149 HBasicBlock* join = graph()->CreateBasicBlock();
4139 4150
4140 HInstruction* elements_kind_instr = 4151 HInstruction* elements_kind_instr =
4141 AddInstruction(new(zone()) HElementsKind(object)); 4152 AddInstruction(new(zone()) HElementsKind(object));
4142 HCompareConstantEqAndBranch* elements_kind_branch = NULL; 4153 HCompareConstantEqAndBranch* elements_kind_branch = NULL;
4143 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); 4154 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
4144 HLoadExternalArrayPointer* external_elements = NULL; 4155 HLoadExternalArrayPointer* external_elements = NULL;
4145 HInstruction* checked_key = NULL; 4156 HInstruction* checked_key = NULL;
4146 4157
4147 // Generated code assumes that FAST_SMI_ONLY_ELEMENTS, FAST_ELEMENTS, 4158 // Generated code assumes that FAST_SMI_ONLY_ELEMENTS, FAST_ELEMENTS,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
4259 HValue* key, 4270 HValue* key,
4260 HValue* val, 4271 HValue* val,
4261 Expression* expr, 4272 Expression* expr,
4262 int ast_id, 4273 int ast_id,
4263 int position, 4274 int position,
4264 bool is_store, 4275 bool is_store,
4265 bool* has_side_effects) { 4276 bool* has_side_effects) {
4266 ASSERT(!expr->IsPropertyName()); 4277 ASSERT(!expr->IsPropertyName());
4267 HInstruction* instr = NULL; 4278 HInstruction* instr = NULL;
4268 if (expr->IsMonomorphic()) { 4279 if (expr->IsMonomorphic()) {
4269 instr = BuildMonomorphicElementAccess(obj, key, val, expr, is_store); 4280 Handle<Map> map = expr->GetMonomorphicReceiverType();
4281 AddInstruction(new(zone()) HCheckNonSmi(obj));
4282 instr = BuildMonomorphicElementAccess(obj, key, val, map, is_store);
4270 } else if (expr->GetReceiverTypes() != NULL && 4283 } else if (expr->GetReceiverTypes() != NULL &&
4271 !expr->GetReceiverTypes()->is_empty()) { 4284 !expr->GetReceiverTypes()->is_empty()) {
4272 return HandlePolymorphicElementAccess( 4285 return HandlePolymorphicElementAccess(
4273 obj, key, val, expr, ast_id, position, is_store, has_side_effects); 4286 obj, key, val, expr, ast_id, position, is_store, has_side_effects);
4274 } else { 4287 } else {
4275 if (is_store) { 4288 if (is_store) {
4276 instr = BuildStoreKeyedGeneric(obj, key, val); 4289 instr = BuildStoreKeyedGeneric(obj, key, val);
4277 } else { 4290 } else {
4278 instr = BuildLoadKeyedGeneric(obj, key); 4291 instr = BuildLoadKeyedGeneric(obj, key);
4279 } 4292 }
(...skipping 2723 matching lines...) Expand 10 before | Expand all | Expand 10 after
7003 } 7016 }
7004 } 7017 }
7005 7018
7006 #ifdef DEBUG 7019 #ifdef DEBUG
7007 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7020 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7008 if (allocator_ != NULL) allocator_->Verify(); 7021 if (allocator_ != NULL) allocator_->Verify();
7009 #endif 7022 #endif
7010 } 7023 }
7011 7024
7012 } } // namespace v8::internal 7025 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698