| 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 |