Chromium Code Reviews| 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::LoadPolymorphicAsMonomorphic( |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
Would it make more sense to name this method TryLo
Toon Verwaest
2013/06/13 16:33:58
Done.
| |
| 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(Property* expr, | |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
Can you move "Property* expr" to the next line?
Toon Verwaest
2013/06/13 16:33:58
Done.
| |
| 6366 HValue* object, | |
| 6367 SmallMapList* types, | |
| 6368 Handle<String> name) { | |
| 6369 | |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
remove this newline
Toon Verwaest
2013/06/13 16:33:58
Done.
| |
| 6370 HInstruction* instr = LoadPolymorphicAsMonomorphic(expr, object, types, name); | |
| 6371 if (instr == NULL) { | |
| 6391 // Something did not match; must use a polymorphic load. | 6372 // Something did not match; must use a polymorphic load. |
| 6373 BuildCheckNonSmi(object); | |
| 6392 HValue* context = environment()->LookupContext(); | 6374 HValue* context = environment()->LookupContext(); |
| 6393 instr = new(zone()) HLoadNamedFieldPolymorphic( | 6375 instr = new(zone()) HLoadNamedFieldPolymorphic( |
| 6394 context, object, types, name, zone()); | 6376 context, object, types, name, zone()); |
| 6395 } | 6377 } |
| 6396 | 6378 |
| 6397 instr->set_position(expr->position()); | 6379 instr->set_position(expr->position()); |
| 6398 return ast_context()->ReturnInstruction(instr, expr->id()); | 6380 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 6399 } | 6381 } |
| 6400 | 6382 |
| 6401 | 6383 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6676 return ast_context()->ReturnValue(Pop()); | 6658 return ast_context()->ReturnValue(Pop()); |
| 6677 | 6659 |
| 6678 } else if (prop != NULL) { | 6660 } else if (prop != NULL) { |
| 6679 if (prop->key()->IsPropertyName()) { | 6661 if (prop->key()->IsPropertyName()) { |
| 6680 // Named property. | 6662 // Named property. |
| 6681 CHECK_ALIVE(VisitForValue(prop->obj())); | 6663 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 6682 HValue* object = Top(); | 6664 HValue* object = Top(); |
| 6683 | 6665 |
| 6684 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 6666 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 6685 Handle<Map> map; | 6667 Handle<Map> map; |
| 6686 HInstruction* load; | 6668 HInstruction* load = NULL; |
| 6669 SmallMapList* types = prop->GetReceiverTypes(); | |
| 6687 bool monomorphic = prop->IsMonomorphic(); | 6670 bool monomorphic = prop->IsMonomorphic(); |
| 6688 if (monomorphic) { | 6671 if (monomorphic) { |
| 6689 map = prop->GetReceiverTypes()->first(); | 6672 map = types->first(); |
| 6690 // We can't generate code for a monomorphic dict mode load so | 6673 // We can't generate code for a monomorphic dict mode load so |
| 6691 // just pretend it is not monomorphic. | 6674 // just pretend it is not monomorphic. |
| 6692 if (map->is_dictionary_map()) monomorphic = false; | 6675 if (map->is_dictionary_map()) monomorphic = false; |
| 6693 } | 6676 } |
| 6694 if (monomorphic) { | 6677 if (monomorphic) { |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
can you restructure the code
monomorphic = fals
Toon Verwaest
2013/06/13 16:33:58
It kinda minimizes the number of branches. We shou
| |
| 6695 Handle<JSFunction> getter; | 6678 Handle<JSFunction> getter; |
| 6696 Handle<JSObject> holder; | 6679 Handle<JSObject> holder; |
| 6697 if (LookupGetter(map, name, &getter, &holder)) { | 6680 if (LookupGetter(map, name, &getter, &holder)) { |
| 6698 load = BuildCallGetter(object, map, getter, holder); | 6681 load = BuildCallGetter(object, map, getter, holder); |
| 6699 } else { | 6682 } else { |
| 6700 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 6683 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 6701 } | 6684 } |
| 6702 } else { | 6685 } else if (types != NULL && types->length() > 1) { |
| 6703 load = BuildLoadNamedGeneric(object, name, prop); | 6686 load = LoadPolymorphicAsMonomorphic(prop, object, types, name); |
| 6704 } | 6687 } |
| 6688 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); | |
| 6705 PushAndAdd(load); | 6689 PushAndAdd(load); |
| 6706 if (load->HasObservableSideEffects()) { | 6690 if (load->HasObservableSideEffects()) { |
| 6707 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 6691 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 6708 } | 6692 } |
| 6709 | 6693 |
| 6710 CHECK_ALIVE(VisitForValue(expr->value())); | 6694 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6711 HValue* right = Pop(); | 6695 HValue* right = Pop(); |
| 6712 HValue* left = Pop(); | 6696 HValue* left = Pop(); |
| 6713 | 6697 |
| 6714 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 6698 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6960 return field; | 6944 return field; |
| 6961 } | 6945 } |
| 6962 | 6946 |
| 6963 | 6947 |
| 6964 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 6948 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
| 6965 HValue* object, | 6949 HValue* object, |
| 6966 Handle<String> name, | 6950 Handle<String> name, |
| 6967 Property* expr) { | 6951 Property* expr) { |
| 6968 if (expr->IsUninitialized()) { | 6952 if (expr->IsUninitialized()) { |
| 6969 AddSoftDeoptimize(); | 6953 AddSoftDeoptimize(); |
| 6954 } else { | |
| 6955 // OS::DebugBreak(); | |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
I guess you do not need that anymore.
Toon Verwaest
2013/06/13 16:33:58
Done.
| |
| 6970 } | 6956 } |
| 6971 HValue* context = environment()->LookupContext(); | 6957 HValue* context = environment()->LookupContext(); |
| 6972 return new(zone()) HLoadNamedGeneric(context, object, name); | 6958 return new(zone()) HLoadNamedGeneric(context, object, name); |
| 6973 } | 6959 } |
| 6974 | 6960 |
| 6975 | 6961 |
| 6976 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 6962 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
| 6977 HValue* object, | 6963 HValue* object, |
| 6978 Handle<Map> map, | 6964 Handle<Map> map, |
| 6979 Handle<JSFunction> getter, | 6965 Handle<JSFunction> getter, |
| (...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9258 | 9244 |
| 9259 if (prop->key()->IsPropertyName()) { | 9245 if (prop->key()->IsPropertyName()) { |
| 9260 // Named property. | 9246 // Named property. |
| 9261 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 9247 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 9262 | 9248 |
| 9263 CHECK_ALIVE(VisitForValue(prop->obj())); | 9249 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 9264 HValue* object = Top(); | 9250 HValue* object = Top(); |
| 9265 | 9251 |
| 9266 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 9252 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 9267 Handle<Map> map; | 9253 Handle<Map> map; |
| 9268 HInstruction* load; | 9254 HInstruction* load = NULL; |
| 9269 bool monomorphic = prop->IsMonomorphic(); | 9255 bool monomorphic = prop->IsMonomorphic(); |
| 9256 SmallMapList* types = prop->GetReceiverTypes(); | |
| 9270 if (monomorphic) { | 9257 if (monomorphic) { |
| 9271 map = prop->GetReceiverTypes()->first(); | 9258 map = types->first(); |
| 9272 if (map->is_dictionary_map()) monomorphic = false; | 9259 if (map->is_dictionary_map()) monomorphic = false; |
| 9273 } | 9260 } |
| 9274 if (monomorphic) { | 9261 if (monomorphic) { |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
can you restructure the code
monomorphic = fals
Toon Verwaest
2013/06/13 16:33:58
Same thing here
On 2013/06/13 15:26:36, Hannes Pa
| |
| 9275 Handle<JSFunction> getter; | 9262 Handle<JSFunction> getter; |
| 9276 Handle<JSObject> holder; | 9263 Handle<JSObject> holder; |
| 9277 if (LookupGetter(map, name, &getter, &holder)) { | 9264 if (LookupGetter(map, name, &getter, &holder)) { |
| 9278 load = BuildCallGetter(object, map, getter, holder); | 9265 load = BuildCallGetter(object, map, getter, holder); |
| 9279 } else { | 9266 } else { |
| 9280 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 9267 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 9281 } | 9268 } |
| 9282 } else { | 9269 } else if (types != NULL && types->length() > 1) { |
| 9283 load = BuildLoadNamedGeneric(object, name, prop); | 9270 load = LoadPolymorphicAsMonomorphic(prop, object, types, name); |
| 9284 } | 9271 } |
| 9272 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); | |
|
Hannes Payer (out of office)
2013/06/13 15:26:36
This sequence of code is exactly the same as in li
Toon Verwaest
2013/06/13 16:33:58
True, but lets do that in a different CL.
On 2013
| |
| 9285 PushAndAdd(load); | 9273 PushAndAdd(load); |
| 9286 if (load->HasObservableSideEffects()) { | 9274 if (load->HasObservableSideEffects()) { |
| 9287 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 9275 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 9288 } | 9276 } |
| 9289 | 9277 |
| 9290 after = BuildIncrement(returns_original_input, expr); | 9278 after = BuildIncrement(returns_original_input, expr); |
| 9291 input = Pop(); | 9279 input = Pop(); |
| 9292 | 9280 |
| 9293 HInstruction* store; | 9281 HInstruction* store; |
| 9294 if (!monomorphic || map->is_observed()) { | 9282 if (!monomorphic || map->is_observed()) { |
| (...skipping 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11614 } | 11602 } |
| 11615 } | 11603 } |
| 11616 | 11604 |
| 11617 #ifdef DEBUG | 11605 #ifdef DEBUG |
| 11618 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11606 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11619 if (allocator_ != NULL) allocator_->Verify(); | 11607 if (allocator_ != NULL) allocator_->Verify(); |
| 11620 #endif | 11608 #endif |
| 11621 } | 11609 } |
| 11622 | 11610 |
| 11623 } } // namespace v8::internal | 11611 } } // namespace v8::internal |
| OLD | NEW |