OLD | NEW |
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 7174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7185 return ast_context()->ReturnInstruction(instr, expr->id()); | 7185 return ast_context()->ReturnInstruction(instr, expr->id()); |
7186 } | 7186 } |
7187 | 7187 |
7188 | 7188 |
7189 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 7189 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
7190 Assignment* expr, | 7190 Assignment* expr, |
7191 HValue* object, | 7191 HValue* object, |
7192 HValue* value, | 7192 HValue* value, |
7193 SmallMapList* types, | 7193 SmallMapList* types, |
7194 Handle<String> name) { | 7194 Handle<String> name) { |
| 7195 if (types->length() <= kMaxStorePolymorphism) { |
| 7196 int previous_field_offset = 0; |
| 7197 bool previous_field_is_in_object = false; |
| 7198 Representation previous_representation = Representation::None(); |
| 7199 |
| 7200 Handle<Map> map; |
| 7201 LookupResult lookup(isolate()); |
| 7202 int count; |
| 7203 for (count = 0; count < types->length(); ++count) { |
| 7204 map = types->at(count); |
| 7205 if (!ComputeLoadStoreField(map, name, &lookup, false) || |
| 7206 lookup.IsTransition()) { |
| 7207 break; |
| 7208 } |
| 7209 Representation representation = lookup.representation(); |
| 7210 int index = ComputeLoadStoreFieldIndex(map, &lookup); |
| 7211 bool is_in_object = index < 0; |
| 7212 int offset = index * kPointerSize; |
| 7213 if (index < 0) { |
| 7214 offset += map->instance_size(); |
| 7215 } else { |
| 7216 offset += FixedArray::kHeaderSize; |
| 7217 } |
| 7218 if (count == 0) { |
| 7219 previous_field_offset = offset; |
| 7220 previous_field_is_in_object = is_in_object; |
| 7221 previous_representation = representation; |
| 7222 } else if (offset != previous_field_offset || |
| 7223 is_in_object != previous_field_is_in_object || |
| 7224 !representation.IsCompatibleForStore( |
| 7225 previous_representation)) { |
| 7226 break; |
| 7227 } |
| 7228 } |
| 7229 |
| 7230 if (types->length() == count) { |
| 7231 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 7232 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 7233 HInstruction* instr = BuildStoreNamedField( |
| 7234 object, name, value, map, &lookup); |
| 7235 instr->set_position(expr->position()); |
| 7236 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 7237 } |
| 7238 } |
| 7239 |
7195 // TODO(ager): We should recognize when the prototype chains for different | 7240 // TODO(ager): We should recognize when the prototype chains for different |
7196 // maps are identical. In that case we can avoid repeatedly generating the | 7241 // maps are identical. In that case we can avoid repeatedly generating the |
7197 // same prototype map checks. | 7242 // same prototype map checks. |
7198 int count = 0; | 7243 int count = 0; |
7199 HBasicBlock* join = NULL; | 7244 HBasicBlock* join = NULL; |
7200 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 7245 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
7201 Handle<Map> map = types->at(i); | 7246 Handle<Map> map = types->at(i); |
7202 LookupResult lookup(isolate()); | 7247 LookupResult lookup(isolate()); |
7203 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 7248 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
7204 if (count == 0) { | 7249 if (count == 0) { |
(...skipping 5068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12273 } | 12318 } |
12274 } | 12319 } |
12275 | 12320 |
12276 #ifdef DEBUG | 12321 #ifdef DEBUG |
12277 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12322 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12278 if (allocator_ != NULL) allocator_->Verify(); | 12323 if (allocator_ != NULL) allocator_->Verify(); |
12279 #endif | 12324 #endif |
12280 } | 12325 } |
12281 | 12326 |
12282 } } // namespace v8::internal | 12327 } } // namespace v8::internal |
OLD | NEW |