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 6298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6309 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 6309 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
6310 AddCheckMapsWithTransitions(object, map); | 6310 AddCheckMapsWithTransitions(object, map); |
6311 return BuildStoreNamedField(object, name, value, map, &lookup); | 6311 return BuildStoreNamedField(object, name, value, map, &lookup); |
6312 } | 6312 } |
6313 | 6313 |
6314 // No luck, do a generic store. | 6314 // No luck, do a generic store. |
6315 return BuildStoreNamedGeneric(object, name, value); | 6315 return BuildStoreNamedGeneric(object, name, value); |
6316 } | 6316 } |
6317 | 6317 |
6318 | 6318 |
6319 bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad( | 6319 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
6320 Property* expr, | 6320 Property* expr, |
6321 HValue* object, | 6321 HValue* object, |
6322 SmallMapList* types, | 6322 SmallMapList* types, |
6323 Handle<String> name) { | 6323 Handle<String> name) { |
6324 if (!name->Equals(isolate()->heap()->length_string())) return false; | |
6325 | |
6326 for (int i = 0; i < types->length(); i++) { | |
6327 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; | |
6328 } | |
6329 | |
6330 BuildCheckNonSmi(object); | |
6331 | |
6332 HInstruction* typecheck = | |
6333 AddInstruction(HCheckMaps::New(object, types, zone())); | |
6334 HInstruction* instr = new(zone()) | |
6335 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck); | |
6336 | |
6337 instr->set_position(expr->position()); | |
6338 ast_context()->ReturnInstruction(instr, expr->id()); | |
6339 return true; | |
6340 } | |
6341 | |
6342 | |
6343 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | |
6344 HValue* object, | |
6345 SmallMapList* types, | |
6346 Handle<String> name) { | |
6347 | |
6348 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) | |
6349 return; | |
6350 | |
6351 BuildCheckNonSmi(object); | |
6352 | |
6353 // Use monomorphic load if property lookup results in the same field index | 6324 // Use monomorphic load if property lookup results in the same field index |
6354 // for all maps. Requires special map check on the set of all handled maps. | 6325 // for all maps. Requires special map check on the set of all handled maps. |
6355 HInstruction* instr = NULL; | |
6356 LookupResult lookup(isolate()); | 6326 LookupResult lookup(isolate()); |
6357 int count; | 6327 int count; |
6358 Representation representation = Representation::None(); | 6328 Representation representation = Representation::None(); |
6359 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. | 6329 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
6360 for (count = 0; | 6330 for (count = 0; |
6361 count < types->length() && count < kMaxLoadPolymorphism; | 6331 count < types->length() && count < kMaxLoadPolymorphism; |
6362 ++count) { | 6332 ++count) { |
6363 Handle<Map> map = types->at(count); | 6333 Handle<Map> map = types->at(count); |
6364 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 6334 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
6365 | 6335 |
(...skipping 10 matching lines...) Expand all Loading... |
6376 break; | 6346 break; |
6377 } else if (access.offset() != new_access.offset()) { | 6347 } else if (access.offset() != new_access.offset()) { |
6378 // Offsets did not match. | 6348 // Offsets did not match. |
6379 break; | 6349 break; |
6380 } else if (access.IsInobject() != new_access.IsInobject()) { | 6350 } else if (access.IsInobject() != new_access.IsInobject()) { |
6381 // In-objectness did not match. | 6351 // In-objectness did not match. |
6382 break; | 6352 break; |
6383 } | 6353 } |
6384 } | 6354 } |
6385 | 6355 |
6386 if (count == types->length()) { | 6356 if (count != types->length()) return NULL; |
6387 // Everything matched; can use monomorphic load. | 6357 |
6388 AddInstruction(HCheckMaps::New(object, types, zone())); | 6358 // Everything matched; can use monomorphic load. |
6389 instr = BuildLoadNamedField(object, access, representation); | 6359 BuildCheckNonSmi(object); |
6390 } else { | 6360 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6361 return BuildLoadNamedField(object, access, representation); |
| 6362 } |
| 6363 |
| 6364 |
| 6365 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
| 6366 Property* expr, |
| 6367 HValue* object, |
| 6368 SmallMapList* types, |
| 6369 Handle<String> name) { |
| 6370 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
| 6371 expr, object, types, name); |
| 6372 if (instr == NULL) { |
6391 // Something did not match; must use a polymorphic load. | 6373 // Something did not match; must use a polymorphic load. |
| 6374 BuildCheckNonSmi(object); |
6392 HValue* context = environment()->LookupContext(); | 6375 HValue* context = environment()->LookupContext(); |
6393 instr = new(zone()) HLoadNamedFieldPolymorphic( | 6376 instr = new(zone()) HLoadNamedFieldPolymorphic( |
6394 context, object, types, name, zone()); | 6377 context, object, types, name, zone()); |
6395 } | 6378 } |
6396 | 6379 |
6397 instr->set_position(expr->position()); | 6380 instr->set_position(expr->position()); |
6398 return ast_context()->ReturnInstruction(instr, expr->id()); | 6381 return ast_context()->ReturnInstruction(instr, expr->id()); |
6399 } | 6382 } |
6400 | 6383 |
6401 | 6384 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6676 return ast_context()->ReturnValue(Pop()); | 6659 return ast_context()->ReturnValue(Pop()); |
6677 | 6660 |
6678 } else if (prop != NULL) { | 6661 } else if (prop != NULL) { |
6679 if (prop->key()->IsPropertyName()) { | 6662 if (prop->key()->IsPropertyName()) { |
6680 // Named property. | 6663 // Named property. |
6681 CHECK_ALIVE(VisitForValue(prop->obj())); | 6664 CHECK_ALIVE(VisitForValue(prop->obj())); |
6682 HValue* object = Top(); | 6665 HValue* object = Top(); |
6683 | 6666 |
6684 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 6667 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
6685 Handle<Map> map; | 6668 Handle<Map> map; |
6686 HInstruction* load; | 6669 HInstruction* load = NULL; |
| 6670 SmallMapList* types = prop->GetReceiverTypes(); |
6687 bool monomorphic = prop->IsMonomorphic(); | 6671 bool monomorphic = prop->IsMonomorphic(); |
6688 if (monomorphic) { | 6672 if (monomorphic) { |
6689 map = prop->GetReceiverTypes()->first(); | 6673 map = types->first(); |
6690 // We can't generate code for a monomorphic dict mode load so | 6674 // We can't generate code for a monomorphic dict mode load so |
6691 // just pretend it is not monomorphic. | 6675 // just pretend it is not monomorphic. |
6692 if (map->is_dictionary_map()) monomorphic = false; | 6676 if (map->is_dictionary_map()) monomorphic = false; |
6693 } | 6677 } |
6694 if (monomorphic) { | 6678 if (monomorphic) { |
6695 Handle<JSFunction> getter; | 6679 Handle<JSFunction> getter; |
6696 Handle<JSObject> holder; | 6680 Handle<JSObject> holder; |
6697 if (LookupGetter(map, name, &getter, &holder)) { | 6681 if (LookupGetter(map, name, &getter, &holder)) { |
6698 load = BuildCallGetter(object, map, getter, holder); | 6682 load = BuildCallGetter(object, map, getter, holder); |
6699 } else { | 6683 } else { |
6700 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 6684 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
6701 } | 6685 } |
6702 } else { | 6686 } else if (types != NULL && types->length() > 1) { |
6703 load = BuildLoadNamedGeneric(object, name, prop); | 6687 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
6704 } | 6688 } |
| 6689 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
6705 PushAndAdd(load); | 6690 PushAndAdd(load); |
6706 if (load->HasObservableSideEffects()) { | 6691 if (load->HasObservableSideEffects()) { |
6707 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 6692 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
6708 } | 6693 } |
6709 | 6694 |
6710 CHECK_ALIVE(VisitForValue(expr->value())); | 6695 CHECK_ALIVE(VisitForValue(expr->value())); |
6711 HValue* right = Pop(); | 6696 HValue* right = Pop(); |
6712 HValue* left = Pop(); | 6697 HValue* left = Pop(); |
6713 | 6698 |
6714 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 6699 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6960 return field; | 6945 return field; |
6961 } | 6946 } |
6962 | 6947 |
6963 | 6948 |
6964 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 6949 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
6965 HValue* object, | 6950 HValue* object, |
6966 Handle<String> name, | 6951 Handle<String> name, |
6967 Property* expr) { | 6952 Property* expr) { |
6968 if (expr->IsUninitialized()) { | 6953 if (expr->IsUninitialized()) { |
6969 AddSoftDeoptimize(); | 6954 AddSoftDeoptimize(); |
| 6955 } else { |
| 6956 // OS::DebugBreak(); |
6970 } | 6957 } |
6971 HValue* context = environment()->LookupContext(); | 6958 HValue* context = environment()->LookupContext(); |
6972 return new(zone()) HLoadNamedGeneric(context, object, name); | 6959 return new(zone()) HLoadNamedGeneric(context, object, name); |
6973 } | 6960 } |
6974 | 6961 |
6975 | 6962 |
6976 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 6963 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
6977 HValue* object, | 6964 HValue* object, |
6978 Handle<Map> map, | 6965 Handle<Map> map, |
6979 Handle<JSFunction> getter, | 6966 Handle<JSFunction> getter, |
(...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9258 | 9245 |
9259 if (prop->key()->IsPropertyName()) { | 9246 if (prop->key()->IsPropertyName()) { |
9260 // Named property. | 9247 // Named property. |
9261 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 9248 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
9262 | 9249 |
9263 CHECK_ALIVE(VisitForValue(prop->obj())); | 9250 CHECK_ALIVE(VisitForValue(prop->obj())); |
9264 HValue* object = Top(); | 9251 HValue* object = Top(); |
9265 | 9252 |
9266 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 9253 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
9267 Handle<Map> map; | 9254 Handle<Map> map; |
9268 HInstruction* load; | 9255 HInstruction* load = NULL; |
9269 bool monomorphic = prop->IsMonomorphic(); | 9256 bool monomorphic = prop->IsMonomorphic(); |
| 9257 SmallMapList* types = prop->GetReceiverTypes(); |
9270 if (monomorphic) { | 9258 if (monomorphic) { |
9271 map = prop->GetReceiverTypes()->first(); | 9259 map = types->first(); |
9272 if (map->is_dictionary_map()) monomorphic = false; | 9260 if (map->is_dictionary_map()) monomorphic = false; |
9273 } | 9261 } |
9274 if (monomorphic) { | 9262 if (monomorphic) { |
9275 Handle<JSFunction> getter; | 9263 Handle<JSFunction> getter; |
9276 Handle<JSObject> holder; | 9264 Handle<JSObject> holder; |
9277 if (LookupGetter(map, name, &getter, &holder)) { | 9265 if (LookupGetter(map, name, &getter, &holder)) { |
9278 load = BuildCallGetter(object, map, getter, holder); | 9266 load = BuildCallGetter(object, map, getter, holder); |
9279 } else { | 9267 } else { |
9280 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 9268 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
9281 } | 9269 } |
9282 } else { | 9270 } else if (types != NULL && types->length() > 1) { |
9283 load = BuildLoadNamedGeneric(object, name, prop); | 9271 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
9284 } | 9272 } |
| 9273 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
9285 PushAndAdd(load); | 9274 PushAndAdd(load); |
9286 if (load->HasObservableSideEffects()) { | 9275 if (load->HasObservableSideEffects()) { |
9287 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 9276 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
9288 } | 9277 } |
9289 | 9278 |
9290 after = BuildIncrement(returns_original_input, expr); | 9279 after = BuildIncrement(returns_original_input, expr); |
9291 input = Pop(); | 9280 input = Pop(); |
9292 | 9281 |
9293 HInstruction* store; | 9282 HInstruction* store; |
9294 if (!monomorphic || map->is_observed()) { | 9283 if (!monomorphic || map->is_observed()) { |
(...skipping 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11614 } | 11603 } |
11615 } | 11604 } |
11616 | 11605 |
11617 #ifdef DEBUG | 11606 #ifdef DEBUG |
11618 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11607 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11619 if (allocator_ != NULL) allocator_->Verify(); | 11608 if (allocator_ != NULL) allocator_->Verify(); |
11620 #endif | 11609 #endif |
11621 } | 11610 } |
11622 | 11611 |
11623 } } // namespace v8::internal | 11612 } } // namespace v8::internal |
OLD | NEW |